Various fixes for LEAP proxying
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 18 Nov 2015 16:32:23 +0000 (11:32 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 18 Nov 2015 16:34:07 +0000 (11:34 -0500)
src/include/libradius.h
src/lib/radius.c
src/modules/rlm_eap/rlm_eap.c

index 48f46e1..1e88beb 100644 (file)
@@ -528,9 +528,9 @@ int         rad_pwdecode(char *encpw, size_t len, char const *secret,
                             uint8_t const *vector);
 
 #define        FR_TUNNEL_PW_ENC_LENGTH(_x) (2 + 1 + _x + PAD(_x + 1, 16))
-int            rad_tunnel_pwencode(char *encpw, size_t *len, char const *secret,
+ssize_t                rad_tunnel_pwencode(char *encpw, size_t *len, char const *secret,
                                    uint8_t const *vector);
-int            rad_tunnel_pwdecode(uint8_t *encpw, size_t *len,
+ssize_t                rad_tunnel_pwdecode(uint8_t *encpw, size_t *len,
                                    char const *secret, uint8_t const *vector);
 int            rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output,
                                int id, VALUE_PAIR *password);
index 95cc7c9..c29cfb1 100644 (file)
@@ -4295,8 +4295,7 @@ int rad_pwdecode(char *passwd, size_t pwlen, char const *secret,
  * This is per RFC-2868 which adds a two char SALT to the initial intermediate
  * value MD5 hash.
  */
-int rad_tunnel_pwencode(char *passwd, size_t *pwlen, char const *secret,
-                       uint8_t const *vector)
+ssize_t rad_tunnel_pwencode(char *passwd, size_t *pwlen, char const *secret, uint8_t const *vector)
 {
        uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
        unsigned char   digest[AUTH_VECTOR_LEN];
@@ -4378,8 +4377,7 @@ int rad_tunnel_pwencode(char *passwd, size_t *pwlen, char const *secret,
  * initial intermediate value, to differentiate it from the
  * above.
  */
-int rad_tunnel_pwdecode(uint8_t *passwd, size_t *pwlen, char const *secret,
-                       uint8_t const *vector)
+ssize_t rad_tunnel_pwdecode(uint8_t *passwd, size_t *pwlen, char const *secret, uint8_t const *vector)
 {
        FR_MD5_CTX  context, old;
        uint8_t         digest[AUTH_VECTOR_LEN];
index af0ccd2..a5c0168 100644 (file)
@@ -523,6 +523,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *inst, REQUEST *request)
 {
        size_t          i;
        size_t          len;
+       ssize_t         ret;
        char            *p;
        VALUE_PAIR      *vp;
        eap_handler_t   *handler;
@@ -613,6 +614,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *inst, REQUEST *request)
         *      This is allowed.
         */
        if (!request->proxy_reply) return RLM_MODULE_NOOP;
+       if (handler->type != PW_EAP_LEAP) return RLM_MODULE_NOOP;
 
        /*
         *      There may be more than one Cisco-AVPair.
@@ -665,18 +667,30 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *inst, REQUEST *request)
        i = 34;
        p = talloc_memdup(vp, vp->vp_strvalue, vp->vp_length + 1);
        talloc_set_type(p, uint8_t);
-       len = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+       ret = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+       if (ret < 0) {
+               REDEBUG("Decoding leap:session-key failed");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
+       len = i;
 
-       /*
-        *      FIXME: Assert that i == 16.
-        */
+       if (i != 16) {
+               REDEBUG("Decoded key length is incorrect, must be 16 bytes");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
 
        /*
         *      Encrypt the session key again, using the request data.
         */
-       rad_tunnel_pwencode(p + 17, &len,
-                           request->client->secret,
-                           request->packet->vector);
+       ret = rad_tunnel_pwencode(p + 17, &len, request->client->secret, request->packet->vector);
+       if (ret < 0) {
+               REDEBUG("Decoding leap:session-key failed");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
+
        fr_pair_value_strsteal(vp, p);
 
        return RLM_MODULE_UPDATED;