Support signing of RADIUS response messages
[strongswan.git] / src / libcharon / plugins / eap_radius / radius_message.c
index b62745a..9d7bf3e 100644 (file)
@@ -74,7 +74,14 @@ ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONS
        "Accounting-Response");
 ENUM_NEXT(radius_message_code_names, RMC_ACCESS_CHALLENGE, RMC_ACCESS_CHALLENGE, RMC_ACCOUNTING_RESPONSE,
        "Access-Challenge");
-ENUM_END(radius_message_code_names, RMC_ACCESS_CHALLENGE);
+ENUM_NEXT(radius_message_code_names, RMC_DISCONNECT_REQUEST, RMC_COA_NAK, RMC_ACCESS_CHALLENGE,
+       "Disconnect-Request",
+       "Disconnect-ACK",
+       "Disconnect-NAK",
+       "CoA-Request",
+       "CoA-ACK",
+       "CoA-NAK");
+ENUM_END(radius_message_code_names, RMC_COA_NAK);
 
 ENUM(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX,
        "User-Name",
@@ -272,14 +279,21 @@ METHOD(radius_message_t, add, void,
 }
 
 METHOD(radius_message_t, sign, void,
-       private_radius_message_t *this, rng_t *rng, signer_t *signer,
-       hasher_t *hasher, chunk_t secret)
+       private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
+       hasher_t *hasher, signer_t *signer, rng_t *rng)
 {
-       if (this->msg->code == RMC_ACCOUNTING_REQUEST)
+       if (rng == NULL)
        {
                chunk_t msg;
 
-               memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
+               if (req_auth)
+               {
+                       memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+               }
+               else
+               {
+                       memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
+               }
                msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
                hasher->get_hash(hasher, msg, NULL);
                hasher->get_hash(hasher, secret, this->msg->authenticator);
@@ -312,7 +326,14 @@ METHOD(radius_message_t, verify, bool,
 
        /* replace Response by Request Authenticator for verification */
        memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5);
-       memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+       if (req_auth)
+       {
+               memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+       }
+       else
+       {
+               memset(this->msg->authenticator, 0, HASH_SIZE_MD5);
+       }
        msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
 
        /* verify Response-Authenticator */
@@ -411,7 +432,7 @@ METHOD(radius_message_t, destroy, void,
 /**
  * Generic constructor
  */
-static private_radius_message_t *radius_message_create()
+static private_radius_message_t *radius_message_create_empty()
 {
        private_radius_message_t *this;
 
@@ -436,9 +457,9 @@ static private_radius_message_t *radius_message_create()
 /**
  * See header
  */
-radius_message_t *radius_message_create_request(radius_message_code_t code)
+radius_message_t *radius_message_create(radius_message_code_t code)
 {
-       private_radius_message_t *this = radius_message_create();
+       private_radius_message_t *this = radius_message_create_empty();
 
        INIT(this->msg,
                .code = code,
@@ -452,9 +473,9 @@ radius_message_t *radius_message_create_request(radius_message_code_t code)
 /**
  * See header
  */
-radius_message_t *radius_message_parse_response(chunk_t data)
+radius_message_t *radius_message_parse(chunk_t data)
 {
-       private_radius_message_t *this = radius_message_create();
+       private_radius_message_t *this = radius_message_create_empty();
 
        this->msg = malloc(data.len);
        memcpy(this->msg, data.ptr, data.len);