Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Robert Dubner
OpenLDAP
Commits
0cdafb7e
Commit
0cdafb7e
authored
Sep 24, 2021
by
Robert Dubner
Browse files
Moved AdjustServerPacketForSending() to rpacket.c
parent
85bec976
Pipeline
#3569
passed with stage
in 44 minutes and 57 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
contrib/slapd-modules/radiusov/radius.c
View file @
0cdafb7e
/* radius.c - RADIUS protocol implementation */
/* radius.c - RADIUS protocol implementation */
/* radius.c - RADIUS protocol implementation */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
...
...
@@ -26,65 +27,6 @@
//#define TEST_NT_RESPONSE 1
static
void
AdjustPacketForSending
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
const
char
*
shared_secret
)
{
// Our job is to fill in the data for the Message-Authenticator attribute, which comes first, followed
// by the response->ResponseAuthenticator, which has to come second because it includes
// the hash of the attributes.
size_t
length
=
get_length
(
response
);
if
(
length
)
{
RADIUS_ATTRIBUTE
*
ra
=
fetch_attribute_from_packet
(
response
,
RATV_Message_Authenticator
);
if
(
ra
)
{
//Debug( LDAP_DEBUG_TRACE,"We have found the response Message-Authenticator attribute\n" );
// Per RFC2869, section 5.14, the Message-Authenticator sixteen-byte payload is calculated
// this way:
//
// Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator, Attributes)
//
// For the purposes of the calculation, the sixteen bytes of the Message-Authenticator are set to zero,
// which they are at this point.
MD5_CTX
context
;
hmac_md5_init
(
&
context
,
(
uint8_t
*
)
shared_secret
,
strlen
(
shared_secret
)
);
hmac_md5_update
(
&
context
,
response
->
packet_data
,
4
);
// Type, Identifier, Length
hmac_md5_update
(
&
context
,
request
->
packet_data
+
AUTHENTICATOR_OFFSET
,
AUTHENTICATOR_LENGTH
);
hmac_md5_update
(
&
context
,
response
->
packet_data
+
ATTRIBUTES_OFFSET
,
length
-
ATTRIBUTES_OFFSET
);
// Finalize the HMAC-MD5 hash, putting the results into the Message-Authenticator attribute
hmac_md5_final
(
&
context
,
ra
->
Data
);
}
// With the Message-Authenticator attribute established, we can now calculate the response authenticator:
// Per RFC2865 section 3, the description of Response Authenticator
// ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
MD5_CTX
context
;
md5_init
(
&
context
);
// Hash the first four bytes, which are Code, Identifier, and Length
md5_update
(
&
context
,
response
->
packet_data
+
CODE_OFFSET
,
1
+
1
+
LENGTH_OF_PACKET_LENGTH
);
md5_update
(
&
context
,
request
->
packet_data
+
AUTHENTICATOR_OFFSET
,
AUTHENTICATOR_LENGTH
);
md5_update
(
&
context
,
response
->
packet_data
+
ATTRIBUTES_OFFSET
,
length
-
ATTRIBUTES_OFFSET
);
md5_update
(
&
context
,
(
uint8_t
*
)
shared_secret
,
strlen
(
shared_secret
));
// Finalize the MD5 hash, putting the result into the Authenticator slot:
md5_final
(
response
->
packet_data
+
AUTHENTICATOR_OFFSET
,
&
context
);
}
else
{
Debug
(
LDAP_DEBUG_ANY
,
"A zero-length RADIUS packet? Really? "
"You'd better be debugging in development, my friend.
\n
"
);
}
}
//extern FILE *ltiming;
//extern int64_t Nanoseconds(void);
...
...
@@ -137,49 +79,28 @@ SendThePacket( RADIUS_PACKET *response,
return
rc
;
}
static
int
CopyStateAttribute
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
)
static
void
get_or_create_state_string
(
char
*
state_string
,
RADIUS_PACKET
*
request
)
{
//
Find the RATV_State attribute in request, and copy it to response->packet_data
//
return 0 if we didn't find one to copy.
int
retval
=
0
;
//
RADIUS packet attribute payloads can be no more than 254 bytes. We
//
assume that the state_string pointer points to a buffer that is at
// least 255 bytes:
RADIUS_ATTRIBUTE
*
ra
=
fetch_attribute_from_packet
(
request
,
RATV_State
);
if
(
ra
)
{
//Debug( LDAP_DEBUG_TRACE,"Copying RATV_State attribute. DataLength is %d\n", ra->DataLength);
// We found the request's RATV_State attribute
// Update the list of attributes
add_attribute_to_radius_packet
(
response
,
ra
->
Type
,
ra
->
DataLength
,
ra
->
Data
);
retval
=
1
;
memcpy
(
state_string
,
ra
->
Data
,
ra
->
DataLength
);
state_string
[
ra
->
DataLength
]
=
'\0'
;
}
return
retval
;
}
static
void
IncorporateStateAttribute
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
)
{
if
(
!
CopyStateAttribute
(
response
,
request
)
)
else
{
// We didn't find a State to copy, so we create one.
static
unsigned
int
state_count
=
123
;
char
achState
[
IDENTIFIER_SIZE
];
static
unsigned
int
state_count
=
1
;
// Use a mutex to safely use and update the state_count
ldap_pvt_thread_mutex_lock
(
&
libradius_mutex
);
sprintf
(
achState
,
"Symas%6.6dSymas"
,
state_count
++
);
sprintf
(
state_string
,
"Symas%6.6dSymas"
,
state_count
++
);
ldap_pvt_thread_mutex_unlock
(
&
libradius_mutex
);
// And use that string as the RATV_State:
add_attribute_to_radius_packet
(
response
,
RATV_State
,
(
uint8_t
)
strlen
(
achState
),
(
uint8_t
*
)
achState
);
}
}
...
...
@@ -189,6 +110,7 @@ IncorporateStateAttribute(RADIUS_PACKET *response, RADIUS_PACKET *request)
static
void
build_response_postamble
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
const
char
*
state_string
,
const
char
*
shared_secret
,
int
include_state_attribute
)
{
...
...
@@ -203,9 +125,12 @@ build_response_postamble( RADIUS_PACKET *response,
MD5_DIGEST_LENGTH
,
message_authenticator
);
if
(
include_
state_
at
tri
bute
==
INCLUDE_STATE
)
if
(
state_
s
tri
ng
)
{
IncorporateStateAttribute
(
response
,
request
);
add_attribute_to_radius_packet
(
response
,
RATV_State
,
(
uint8_t
)
strlen
(
state_string
),
(
uint8_t
*
)
state_string
);
}
// We now know the length of the RADIUS packet:
...
...
@@ -213,9 +138,34 @@ build_response_postamble( RADIUS_PACKET *response,
// With the entire packet built, we can now polish it off by creating the
// MD5 hash and HMAC fields:
AdjustPacketForSending
(
response
,
request
,
shared_secret
);
if
(
response
)
{
// Since we are responding to something, we must be a server:
AdjustServerPacketForSending
(
response
,
request
,
shared_secret
);
}
else
{
AdjustClientPacketForSending
(
response
,
shared_secret
);
}
}
static
void
server_postamble
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
const
char
*
shared_secret
,
int
include_state_attribute
)
{
char
state_string
[
255
];
get_or_create_state_string
(
state_string
,
request
);
build_response_postamble
(
response
,
request
,
state_string
,
shared_secret
,
include_state_attribute
);
}
static
void
build_md5_challenge
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
...
...
@@ -224,7 +174,6 @@ build_md5_challenge(RADIUS_PACKET *response,
{
DENTER
;
build_response_preamble
(
response
,
get_identifier
(
request
));
// This brings us to the attributes portion of the RADIUS packet we are building.
// The first attribute we are going to build is an EAP-MD5 challenge.
...
...
@@ -244,7 +193,7 @@ build_md5_challenge(RADIUS_PACKET *response,
EAP_CHALLENGE_ATTRIBUTE_LENGTH
,
eap_message_data
);
build_response
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
server
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
}
static
void
...
...
@@ -273,7 +222,7 @@ build_peap_challenge( RADIUS_PACKET *response,
EAP_CHALLENGE_ATTRIBUTE_LENGTH
,
eap_message_data
);
build_response
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
server
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
}
static
void
...
...
@@ -301,7 +250,7 @@ build_ttls_challenge( RADIUS_PACKET *response,
EAP_CHALLENGE_ATTRIBUTE_LENGTH
,
eap_message_data
);
build_response
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
server
_postamble
(
response
,
request
,
shared_secret
,
INCLUDE_STATE
);
}
static
int
...
...
@@ -467,6 +416,9 @@ recover_state(RADIUS_INFO *radius_info, RADIUS_PACKET *request)
if
(
ra
)
{
// We found a State identifier. See if it is in our list
// The state identifier does not have a terminating NUL. But we are
// expecting a string, so we make sure we copy over the string from the
// ra in a way that ends it with a NUL:
memset
(
achIdentifier
,
0
,
IDENTIFIER_SIZE
);
memcpy
(
achIdentifier
,
ra
->
Data
,
ra
->
DataLength
);
Debug
(
LDAP_DEBUG_ARGS
,
...
...
@@ -822,7 +774,7 @@ build_tls_response( RADIUS_PACKET *response,
}
// With the PEAP messages out of the way, finish up the RADIUS packet:
build_response
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
INCLUDE_STATE
);
server
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
INCLUDE_STATE
);
Debug
(
LDAP_DEBUG_ARGS
,
DPREFIX
"Built eap_tls response with %d EAP-message attributes
\n
"
,
...
...
@@ -907,10 +859,10 @@ encrypt_and_send_response( STATE *state,
attribute_data
);
// With the PEAP message out of the way, finish up the RADIUS packet:
build_response
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
INCLUDE_STATE
);
server
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
INCLUDE_STATE
);
rc
=
SendThePacket
(
response
,
volatiles
->
radius_info
->
udp_socket
,
...
...
@@ -1659,10 +1611,10 @@ send_access_accept(STATE *state)
sizeof
(
framed_mtu
),
framed_mtu
);
build_response
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
DONT_INCLUDE_STATE
);
server
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
DONT_INCLUDE_STATE
);
return
SendThePacket
(
response
,
volatiles
->
radius_info
->
udp_socket
,
...
...
@@ -1702,10 +1654,10 @@ send_access_reject(STATE *state)
eap_message_length
,
eap_message_data
);
build_response
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
DONT_INCLUDE_STATE
);
server
_postamble
(
response
,
volatiles
->
request
,
volatiles
->
shared_secret
,
DONT_INCLUDE_STATE
);
return
SendThePacket
(
response
,
volatiles
->
radius_info
->
udp_socket
,
...
...
contrib/slapd-modules/radiusov/rpacket.c
View file @
0cdafb7e
...
...
@@ -14,6 +14,7 @@
* <http://www.OpenLDAP.org/license.html>.
*/
#include
<openssl/rand.h>
#include
"radiusov.h"
#include
"lber-int.h"
#include
"rpacket.h"
...
...
@@ -610,3 +611,109 @@ build_response_preamble(RADIUS_PACKET *response, uint8_t packet_id)
// calculation is described in RFC2865 section 3; see below
response
->
build_loc
+=
AUTHENTICATOR_LENGTH
;
}
void
AdjustServerPacketForSending
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
const
char
*
shared_secret
)
{
// Our job is to fill in the data for the Message-Authenticator attribute, which comes first, followed
// by the response->ResponseAuthenticator, which has to come second because it includes
// the hash of the attributes.
// See RFC2865 for the basic radius packet Authenticator field
// See RFC2869 for the Message-Authenticator attribute.
size_t
length
=
get_length
(
response
);
if
(
length
)
{
RADIUS_ATTRIBUTE
*
ra
=
fetch_attribute_from_packet
(
response
,
RATV_Message_Authenticator
);
if
(
ra
)
{
//Debug( LDAP_DEBUG_TRACE,"We have found the response Message-Authenticator attribute\n" );
// Per RFC2869, section 5.14, the Message-Authenticator sixteen-byte payload is calculated
// this way:
//
// Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator, Attributes)
//
// For the purposes of the calculation, the sixteen bytes of the Message-Authenticator are set to zero,
// which they are at this point.
MD5_CTX
context
;
hmac_md5_init
(
&
context
,
(
uint8_t
*
)
shared_secret
,
strlen
(
shared_secret
)
);
hmac_md5_update
(
&
context
,
response
->
packet_data
,
4
);
// Type, Identifier, Length
hmac_md5_update
(
&
context
,
request
->
packet_data
+
AUTHENTICATOR_OFFSET
,
AUTHENTICATOR_LENGTH
);
hmac_md5_update
(
&
context
,
response
->
packet_data
+
ATTRIBUTES_OFFSET
,
length
-
ATTRIBUTES_OFFSET
);
// Finalize the HMAC-MD5 hash, putting the results into the Message-Authenticator attribute
hmac_md5_final
(
&
context
,
ra
->
Data
);
}
// With the Message-Authenticator attribute established, we can now calculate the response authenticator:
// Per RFC2865 section 3, the description of Response Authenticator
// ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
MD5_CTX
context
;
md5_init
(
&
context
);
// Hash the first four bytes, which are Code, Identifier, and Length
md5_update
(
&
context
,
response
->
packet_data
+
CODE_OFFSET
,
1
+
1
+
LENGTH_OF_PACKET_LENGTH
);
md5_update
(
&
context
,
request
->
packet_data
+
AUTHENTICATOR_OFFSET
,
AUTHENTICATOR_LENGTH
);
md5_update
(
&
context
,
response
->
packet_data
+
ATTRIBUTES_OFFSET
,
length
-
ATTRIBUTES_OFFSET
);
md5_update
(
&
context
,
(
uint8_t
*
)
shared_secret
,
strlen
(
shared_secret
));
// Finalize the MD5 hash, putting the result into the Authenticator slot:
md5_final
(
response
->
packet_data
+
AUTHENTICATOR_OFFSET
,
&
context
);
}
else
{
Debug
(
LDAP_DEBUG_ANY
,
"A zero-length RADIUS packet? Really? "
"You'd better be debugging in development, my friend.
\n
"
);
}
}
void
AdjustClientPacketForSending
(
RADIUS_PACKET
*
request
,
const
char
*
shared_secret
)
{
// Nomenclature is a bit of a mess. In this routine, we are building
// a RADIUS request packet; when it's done, we'll be sending it to the
// server.
// As per RFC2865, we are going to set the sixteen packet RequestAuthenticator
// bits to a random sequence:
if
(
RAND_bytes
(
get_authenticator
(
request
),
AUTHENTICATOR_LENGTH
)
!=
1
)
{
printf
(
"%s(): Something went wrong with RAND_bytes
\n
"
,
__func__
);
abort
();
}
RADIUS_ATTRIBUTE
*
ra
=
fetch_attribute_from_packet
(
request
,
RATV_Message_Authenticator
);
if
(
ra
)
{
Debug
(
LDAP_DEBUG_ARGS
,
DPREFIX
"%s(): RADIUS client packet has a RATV_Message_Authenticator
\n
"
,
__func__
);
// Per RFC2869, we perform an HMAC-MD5 on the whole packet, but with the
// signature bytes set to zero:
uint8_t
save_the_signature
[
AUTHENTICATOR_LENGTH
];
memcpy
(
save_the_signature
,
ra
->
Data
,
AUTHENTICATOR_LENGTH
);
memset
(
ra
->
Data
,
0
,
AUTHENTICATOR_LENGTH
);
// Calculate the digest
uint8_t
digest
[
MD5_DIGEST_LENGTH
];
hmac_md5
(
digest
,
request
->
packet_data
,
get_length
(
request
),
(
uint8_t
*
)
shared_secret
,
strlen
(
shared_secret
)
);
// Restore the original packet:
memcpy
(
ra
->
Data
,
save_the_signature
,
AUTHENTICATOR_LENGTH
);
}
}
contrib/slapd-modules/radiusov/rpacket.h
View file @
0cdafb7e
...
...
@@ -293,6 +293,7 @@ uint16_t get_length(RADIUS_PACKET *radius_packet);
void
set_length
(
RADIUS_PACKET
*
radius_packet
,
int
length
);
uint8_t
*
get_authenticator
(
RADIUS_PACKET
*
radius_packet
);
void
debugging_display_of
(
RADIUS_PACKET
*
packet
);
char
*
radius_attribute_to_text
(
RADIUS_ATTRIBUTE
*
ra
,
char
*
buffer
,
size_t
buf_len
);
void
radius_packet_initialize
(
RADIUS_PACKET
*
radius_packet
);
...
...
@@ -303,7 +304,11 @@ int radiusov_get_packet_from_request( RADIUS_PACKET *radius_packet,
ssize_t
recv_len
);
RADIUS_ATTRIBUTE
*
fetch_attribute_from_packet
(
RADIUS_PACKET
*
radius_packet
,
uint8_t
Type
);
void
add_attribute_to_radius_packet
(
RADIUS_PACKET
*
radius_packet
,
uint8_t
Type
,
uint8_t
DataLength
,
uint8_t
*
Data
);
void
debugging_display_of
(
RADIUS_PACKET
*
packet
);
void
AdjustServerPacketForSending
(
RADIUS_PACKET
*
response
,
RADIUS_PACKET
*
request
,
const
char
*
shared_secret
);
void
AdjustClientPacketForSending
(
RADIUS_PACKET
*
response
,
const
char
*
shared_secret
);
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment