Add inlen to fr_hex2bin. rlm_pap used fr_hex2bin with the assumption that the VP...
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 10 Jun 2014 08:42:19 +0000 (09:42 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 10 Jun 2014 08:43:40 +0000 (09:43 +0100)
13 files changed:
src/include/libradius.h
src/lib/filters.c
src/lib/misc.c
src/lib/valuepair.c
src/main/tls.c
src/main/xlat.c
src/modules/rlm_digest/rlm_digest.c
src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.c
src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_otp/rlm_otp.c
src/modules/rlm_pap/rlm_pap.c
src/modules/rlm_unpack/rlm_unpack.c

index adf26de..db910e9 100644 (file)
@@ -661,7 +661,7 @@ int         rad_lockfd(int fd, int lock_len);
 int            rad_lockfd_nonblock(int fd, int lock_len);
 int            rad_unlockfd(int fd, int lock_len);
 size_t         fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen);
-size_t         fr_hex2bin(uint8_t *bin, char const *hex, size_t outlen);
+size_t         fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen);
 uint32_t       fr_strtoul(char const *value, char **end);
 bool           is_whitespace(char const *value);
 bool           is_integer(char const *value);
index fa436f5..07a0757 100644 (file)
@@ -390,7 +390,7 @@ static int ascend_parse_ipx_net(int argc, char **argv,
        /*
         *      Node must be 6 octets long.
         */
-       token = fr_hex2bin(net->node, p, IPX_NODE_ADDR_LEN);
+       token = fr_hex2bin(net->node, IPX_NODE_ADDR_LEN, p, strlen(p));
        if (token != IPX_NODE_ADDR_LEN) return -1;
 
        /*
@@ -889,10 +889,10 @@ static int ascend_parse_generic(int argc, char **argv,
        filter->offset = rcode;
        filter->offset = htons(filter->offset);
 
-       rcode = fr_hex2bin(filter->mask, argv[1], sizeof(filter->mask));
+       rcode = fr_hex2bin(filter->mask, sizeof(filter->mask), argv[1], strlen(argv[1]));
        if (rcode != sizeof(filter->mask)) return -1;
 
-       token = fr_hex2bin(filter->value, argv[2], sizeof(filter->value));
+       token = fr_hex2bin(filter->value, sizeof(filter->value), argv[2], strlen(argv[2]));
        if (token != sizeof(filter->value)) return -1;
 
        filter->len = rcode;
index 84b188b..2bf11c2 100644 (file)
@@ -996,20 +996,29 @@ static char const *hextab = "0123456789abcdef";
 /** Convert hex strings to binary data
  *
  * @param bin Buffer to write output to.
- * @param hex input string.
  * @param outlen length of output buffer (or length of input string / 2).
+ * @param hex input string.
+ * @param inlen length of the input string
  * @return length of data written to buffer.
  */
-size_t fr_hex2bin(uint8_t *bin, char const *hex, size_t outlen)
+size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
 {
        size_t i;
+       size_t len;
        char *c1, *c2;
 
-       for (i = 0; i < outlen; i++) {
+       /*
+        *      Smartly truncate output, caller should check number of bytes
+        *      written.
+        */
+       len = inlen >> 1;
+       if (len > outlen) len = outlen;
+
+       for (i = 0; i < len; i++) {
                if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), 16)) ||
                   !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), 16)))
                        break;
-                bin[i] = ((c1-hextab)<<4) + (c2-hextab);
+               bin[i] = ((c1-hextab)<<4) + (c2-hextab);
        }
 
        return i;
index 1e14fa9..2ed8ee5 100644 (file)
@@ -1337,7 +1337,7 @@ int pairparsevalue(VALUE_PAIR *vp, char const *value, size_t inlen)
 
                vp->length = len >> 1;
                p = talloc_array(vp, uint8_t, vp->length);
-               if (fr_hex2bin(p, value + 2, len) != vp->length) {
+               if (fr_hex2bin(p, vp->length, value + 2, len) != vp->length) {
                        talloc_free(p);
                        fr_strerror_printf("Invalid hex data");
                        return -1;
@@ -1382,7 +1382,7 @@ int pairparsevalue(VALUE_PAIR *vp, char const *value, size_t inlen)
                        fr_strerror_printf("No memory");
                        return -1;
                }
-               if (fr_hex2bin(p, value + 2, len) != vp->length) {
+               if (fr_hex2bin(p, vp->length, value + 2, len) != vp->length) {
                        fr_strerror_printf("Invalid hex data in TLV");
                        return -1;
                }
@@ -1813,7 +1813,7 @@ static VALUE_PAIR *pairmake_any(TALLOC_CTX *ctx,
        vp->length = size >> 1;
        data = talloc_array(vp, uint8_t, vp->length);
 
-       if (fr_hex2bin(data, value + 2, size) != vp->length) {
+       if (fr_hex2bin(data, vp->length, value + 2, size) != vp->length) {
                fr_strerror_printf("Invalid hex string");
                talloc_free(vp);
                return NULL;
index 51dcd2e..c195d92 100644 (file)
@@ -101,7 +101,7 @@ static unsigned int psk_server_callback(SSL *ssl, char const *identity,
        psk_len = strlen(conf->psk_password);
        if (psk_len > (2 * max_psk_len)) return 0;
 
-       return fr_hex2bin(psk, conf->psk_password, psk_len);
+       return fr_hex2bin(psk, max_psk_len, conf->psk_password, psk_len);
 }
 
 static unsigned int psk_client_callback(SSL *ssl, UNUSED char const *hint,
@@ -120,7 +120,7 @@ static unsigned int psk_client_callback(SSL *ssl, UNUSED char const *hint,
 
        strlcpy(identity, conf->psk_identity, max_identity_len);
 
-       return fr_hex2bin(psk, conf->psk_password, psk_len);
+       return fr_hex2bin(psk, max_psk_len, conf->psk_password, psk_len);
 }
 
 #endif
@@ -2132,7 +2132,7 @@ static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf, int client)
                        return NULL;
                }
 
-               hex_len = fr_hex2bin((uint8_t *) buffer, conf->psk_password, psk_len);
+               hex_len = fr_hex2bin((uint8_t *) buffer, sizeof(buffer), conf->psk_password, psk_len);
                if (psk_len != (2 * hex_len)) {
                        ERROR("psk_hexphrase is not all hex");
                        return NULL;
index 8fda26d..3587de7 100644 (file)
@@ -1145,7 +1145,7 @@ static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **he
                                        return -(p - fmt);
                                }
 
-                               if (!fr_hex2bin((uint8_t *) q, p, 2)) {
+                               if (!fr_hex2bin((uint8_t *) q, 1, p, 2)) {
                                        talloc_free(node);
                                        *error = "Invalid hex characters";
                                        return -(p - fmt);
index bdf0922..4856359 100644 (file)
@@ -313,7 +313,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED void *instance, REQU
                 *      Set A1 to Digest-HA1 if no User-Password found
                 */
                if (passwd->da->attr == PW_DIGEST_HA1) {
-                       if (fr_hex2bin(&a1[0], passwd->vp_strvalue, 16) != 16) {
+                       if (fr_hex2bin(&a1[0], sizeof(a1), passwd->vp_strvalue, passwd->length) != 16) {
                                RDEBUG2("Invalid text in Digest-HA1");
                                return RLM_MODULE_INVALID;
                        }
@@ -552,7 +552,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED void *instance, REQU
                return RLM_MODULE_INVALID;
        }
 
-       if (fr_hex2bin(&hash[0], vp->vp_strvalue, vp->length >> 1) != (vp->length >> 1)) {
+       if (fr_hex2bin(&hash[0], sizeof(hash), vp->vp_strvalue, vp->length) != (vp->length >> 1)) {
                RDEBUG2("Invalid text in Digest-Response");
                return RLM_MODULE_INVALID;
        }
index 21fd84b..47a552c 100644 (file)
@@ -181,7 +181,7 @@ static int eapleap_ntpwdhash(uint8_t *out, REQUEST *request, VALUE_PAIR *passwor
 
                if (password->length == 32) {
                        p = talloc_array(password, uint8_t, 16);
-                       password->length = fr_hex2bin(p, password->vp_strvalue, 16);
+                       password->length = fr_hex2bin(p, 16, password->vp_strvalue, password->length);
                }
                if (password->length != 16) {
                        REDEBUG("Bad NT-Password");
index 26f874e..6538d4a 100644 (file)
@@ -707,7 +707,7 @@ packet_ready:
                        n = sscanf(response->vp_strvalue, "%*cE=%d R=%d C=%32s", &err, &retry, &buf[0]);
                        if (n == 3) {
                                DEBUG2("Found new challenge from MS-CHAP-Error: err=%d retry=%d challenge=%s", err, retry, buf);
-                               fr_hex2bin(data->challenge, buf, 16);
+                               fr_hex2bin(data->challenge, 16, buf, strlen(buf));
                        } else {
                                DEBUG2("Could not parse new challenge from MS-CHAP-Error: %d", n);
                        }
index 7908f11..05c1b6e 100644 (file)
@@ -1065,6 +1065,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5 ,6)) do_mschap(rlm_mschap_t *inst, REQUES
        } else {                /* run ntlm_auth */
                int     result;
                char    buffer[256];
+               size_t  len;
 
                memset(nthashhash, 0, 16);
 
@@ -1109,7 +1110,8 @@ static int CC_HINT(nonnull (1, 2, 4, 5 ,6)) do_mschap(rlm_mschap_t *inst, REQUES
                 *      Check the length.  It should be at least 32,
                 *      with an LF at the end.
                 */
-               if (strlen(buffer + 8) < 32) {
+               len = strlen(buffer + 8);
+               if (len < 32) {
                        REDEBUG2("Invalid output from ntlm_auth: NT_KEY has unexpected length");
                        return -1;
                }
@@ -1117,7 +1119,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5 ,6)) do_mschap(rlm_mschap_t *inst, REQUES
                /*
                 *      Update the NT hash hash, from the NT key.
                 */
-               if (fr_hex2bin(nthashhash, buffer + 8, 16) != 16) {
+               if (fr_hex2bin(nthashhash, sizeof(nthashhash), buffer + 8, len) != 16) {
                        REDEBUG("Invalid output from ntlm_auth: NT_KEY has non-hex values");
                        return -1;
                }
index 971b01c..4523717 100644 (file)
@@ -354,7 +354,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *re
                 *      There are notes in otp_radstate as to why the state
                 *      value is encoded as hexits.
                 */
-               len = fr_hex2bin(bin_state, vp->vp_strvalue, vp->length);
+               len = fr_hex2bin(bin_state, sizeof(bin_state), vp->vp_strvalue, vp->length);
                if (len != (vp->length / 2)) {
                        REDEBUG("bad radstate for [%s]: not hex", username);
 
index 3171ded..629bd64 100644 (file)
@@ -125,12 +125,15 @@ static void CC_HINT(nonnull) normify(REQUEST *request, VALUE_PAIR *vp, size_t mi
 
        if (min_length >= sizeof(buffer)) return; /* paranoia */
 
+       rad_assert((vp->da->type == PW_TYPE_OCTETS) || (vp->da->type == PW_TYPE_STRING));
+
        /*
         *      Hex encoding.
         */
        if (vp->length >= (2 * min_length)) {
                size_t decoded;
-               decoded = fr_hex2bin(buffer, vp->vp_strvalue, sizeof(buffer));
+
+               decoded = fr_hex2bin(buffer, sizeof(buffer), vp->vp_strvalue, vp->length);
                if (decoded == (vp->length >> 1)) {
                        RDEBUG2("Normalizing %s from hex encoding, %zu bytes -> %zu bytes",
                                vp->da->name, vp->length, decoded);
@@ -628,6 +631,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_nt(rlm_pap_t *inst, REQUEST *reques
 {
        uint8_t digest[16];
        char charbuf[32 + 1];
+       ssize_t len;
 
        RDEBUG("Comparing with \"known-good\" NT-Password");
 
@@ -639,11 +643,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_nt(rlm_pap_t *inst, REQUEST *reques
                return RLM_MODULE_INVALID;
        }
 
-       if (radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:NT-Hash %{User-Password}}", NULL, NULL) < 0){
+       len = radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:NT-Hash %{User-Password}}", NULL, NULL);
+       if (len < 0) {
                return RLM_MODULE_REJECT;
        }
 
-       if ((fr_hex2bin(digest, charbuf, sizeof(digest)) != vp->length) ||
+       if ((fr_hex2bin(digest, sizeof(digest), charbuf, len) != vp->length) ||
            (rad_digest_cmp(digest, vp->vp_octets, vp->length) != 0)) {
                REDEBUG("NT digest does not match \"known good\" digest");
                return RLM_MODULE_REJECT;
@@ -657,6 +662,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_lm(rlm_pap_t *inst, REQUEST *reques
 {
        uint8_t digest[16];
        char charbuf[32 + 1];
+       ssize_t len;
 
        RDEBUG("Comparing with \"known-good\" LM-Password");
 
@@ -668,11 +674,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_lm(rlm_pap_t *inst, REQUEST *reques
                return RLM_MODULE_INVALID;
        }
 
-       if (radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:LM-Hash %{User-Password}}", NULL, NULL) < 0){
+       len = radius_xlat(charbuf, sizeof(charbuf), request, "%{mschap:LM-Hash %{User-Password}}", NULL, NULL);
+       if (len < 0){
                return RLM_MODULE_FAIL;
        }
 
-       if ((fr_hex2bin(digest, charbuf, sizeof(digest)) != vp->length) ||
+       if ((fr_hex2bin(digest, sizeof(digest), charbuf, len) != vp->length) ||
            (rad_digest_cmp(digest, vp->vp_octets, vp->length) != 0)) {
                REDEBUG("LM digest does not match \"known good\" digest");
                return RLM_MODULE_REJECT;
@@ -698,7 +705,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_ns_mta_md5(UNUSED rlm_pap_t *inst,
        /*
         *      Sanity check the value of NS-MTA-MD5-Password
         */
-       if (fr_hex2bin(digest, vp->vp_strvalue, 32) != 16) {
+       if (fr_hex2bin(digest, sizeof(digest), vp->vp_strvalue, vp->length) != 16) {
                REDEBUG("\"known good\" NS-MTA-MD5-Password has invalid value");
                return RLM_MODULE_INVALID;
        }
index 3aeb7c2..02a3848 100644 (file)
@@ -111,7 +111,7 @@ static ssize_t unpack_xlat(UNUSED void *instance, REQUEST *request, char const *
                        goto nothing;
                }
                input = blob;
-               input_len = fr_hex2bin(blob, data_name + 2, sizeof(blob));
+               input_len = fr_hex2bin(blob, sizeof(blob), data_name + 2, len);
 
        } else {
                GOTO_ERROR;