From: Arran Cudbard-Bell Date: Tue, 28 Jul 2020 04:53:27 +0000 (-0400) Subject: sbuff: Convert hex functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4bdb5ba761c58214e189eedaf5a35e4e871a8ec;p=thirdparty%2Ffreeradius-server.git sbuff: Convert hex functions --- diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index e2fa6079b54..a011a925804 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -28,14 +28,15 @@ RCSID("$Id$") #include #include -#include -#include #include +#include +#include #include +#include +#include #include #include -#include #ifdef HAVE_COLLECTDC_H # include @@ -486,7 +487,8 @@ static void rs_packet_print_fancy(uint64_t count, rs_status_t status, fr_pcap_t fr_pair_list_log(&default_log, packet->vps); } - fr_bin2hex(vector, packet->vector, RADIUS_AUTH_VECTOR_LENGTH); + fr_bin2hex(&FR_SBUFF_OUT(vector, sizeof(vector)), + &FR_DBUFF_TMP(packet->vector, RADIUS_AUTH_VECTOR_LENGTH)); INFO("\tAuthenticator-Field = 0x%s", vector); } } diff --git a/src/lib/ldap/util.c b/src/lib/ldap/util.c index 6efad3bb169..f65ecb74fbf 100644 --- a/src/lib/ldap/util.c +++ b/src/lib/ldap/util.c @@ -28,6 +28,7 @@ RCSID("$Id$") USES_APPLE_DEPRECATED_API #include +#include #include #include @@ -215,7 +216,7 @@ bool fr_ldap_util_is_dn(char const *in, size_t inlen) /* * Hex encoding, consume three chars */ - if (fr_hex2bin((uint8_t *) &c, 1, p + 1, 2) == 1) { + if (fr_hex2bin(&FR_DBUFF_TMP((uint8_t *) &c, 1), &FR_SBUFF_IN(p + 1, 2)) == 1) { inlen -= 2; p += 2; continue; @@ -416,7 +417,7 @@ size_t fr_ldap_util_normalise_dn(char *out, char const *in) * special encoding, get rewritten to the * special encoding. */ - if (fr_hex2bin((uint8_t *) &c, 1, p + 1, 2) == 1) { + if (fr_hex2bin(&FR_DBUFF_TMP((uint8_t *) &c, 1), &FR_SBUFF_IN(p + 1, 2)) == 1) { switch (c) { case ' ': case '#': diff --git a/src/lib/server/client.c b/src/lib/server/client.c index 58f80a2b780..6ab9855e4fb 100644 --- a/src/lib/server/client.c +++ b/src/lib/server/client.c @@ -26,14 +26,15 @@ */ RCSID("$Id$") +#include +#include #include #include #include -#include #include -#include -#include +#include +#include #include #include @@ -740,7 +741,7 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_SECTION *serv hex_len = talloc_array_length(value) - 3; bin_len = (hex_len / 2) + 1; MEM(bin = talloc_array(c, uint8_t, bin_len)); - converted = fr_hex2bin(bin, bin_len, value + 2, hex_len); + converted = fr_hex2bin(&FR_DBUFF_TMP(bin, bin_len), &FR_SBUFF_IN(value + 2, hex_len)); if (converted < (bin_len - 1)) { cf_log_err(cs, "Invalide hex string in shared secret"); goto error; diff --git a/src/lib/server/map.c b/src/lib/server/map.c index 707e2eb07b4..9962633dbd9 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -31,8 +31,9 @@ RCSID("$Id$") #include #include #include -#include +#include +#include #include #include #include @@ -112,7 +113,7 @@ bool map_cast_from_hex(vp_map_t *map, fr_token_t rhs_type, char const *rhs) ptr = talloc_array(map, uint8_t, len >> 1); if (!ptr) return false; - fr_hex2bin(ptr, len >> 1, rhs + 2, len); + fr_hex2bin(&FR_DBUFF_TMP(ptr, len >> 1), &FR_SBUFF_IN(rhs + 2, len)); /* * Convert to da->type (if possible); diff --git a/src/lib/server/password.c b/src/lib/server/password.c index 1aa59ac2707..22f1284c7e1 100644 --- a/src/lib/server/password.c +++ b/src/lib/server/password.c @@ -26,6 +26,7 @@ RCSID("$Id$") #include #include +#include #include #include #include @@ -417,7 +418,7 @@ static ssize_t normify(normalise_t *action, uint8_t *buffer, size_t bufflen, if (!(len & 0x01) && len >= (2 * min_len)) { size_t decoded; - decoded = fr_hex2bin(buffer, bufflen, known_good, len); + decoded = fr_hex2bin(&FR_DBUFF_TMP(buffer, bufflen), &FR_SBUFF_IN(known_good, len)); if (decoded == (len >> 1)) { if (action) *action = NORMALISED_HEX; return decoded; diff --git a/src/lib/server/tmpl.c b/src/lib/server/tmpl.c index 9938a2433b3..bb8acecb029 100644 --- a/src/lib/server/tmpl.c +++ b/src/lib/server/tmpl.c @@ -30,8 +30,9 @@ RCSID("$Id$") #include #include -#include +#include +#include #include #include @@ -1732,7 +1733,7 @@ ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, in, inlen, type); (void)fr_value_box_mem_alloc(vpt, &bin, &vpt->data.literal, NULL, binlen, false); - len = fr_hex2bin(bin, binlen, in + 2, inlen - 2); + len = fr_hex2bin(&FR_DBUFF_TMP(bin, binlen), &FR_SBUFF_IN(in + 2, inlen - 2)); if (len != binlen) { fr_strerror_printf("Hex string contains non-hex char"); talloc_free(vpt); diff --git a/src/lib/server/util.c b/src/lib/server/util.c index 12614165d0d..0e664be4302 100644 --- a/src/lib/server/util.c +++ b/src/lib/server/util.c @@ -22,11 +22,13 @@ RCSID("$Id$") + #include -#include #include #include +#include +#include #include #include @@ -250,7 +252,8 @@ size_t rad_filename_escape(UNUSED REQUEST *request, char *out, size_t outlen, ch * Unsafe chars */ *out++ = '-'; - fr_bin2hex(out, (uint8_t const *)in++, 1); + in++; + fr_bin2hex(&FR_SBUFF_OUT(out, freespace), &FR_DBUFF_TMP((uint8_t const *)in, 1)); out += 2; freespace -= 3; } @@ -308,7 +311,7 @@ ssize_t rad_filename_unescape(char *out, size_t outlen, char const *in, size_t i /* * If hex2bin returns 0 the next two chars weren't hexits. */ - if (fr_hex2bin((uint8_t *) out, 1, in, 1) == 0) return in - (p + 1); + if (fr_hex2bin(&FR_DBUFF_TMP((uint8_t *) out, 1), &FR_SBUFF_IN(in, 1)) == 0) return in - (p + 1); in += 2; out++; freespace--; diff --git a/src/lib/tls/ctx.c b/src/lib/tls/ctx.c index 1296dd52b36..9ee80745d9c 100644 --- a/src/lib/tls/ctx.c +++ b/src/lib/tls/ctx.c @@ -30,9 +30,10 @@ USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */ #ifdef WITH_TLS #define LOG_PREFIX "tls - " +#include +#include #include #include -#include #include #include @@ -394,7 +395,7 @@ SSL_CTX *fr_tls_ctx_alloc(fr_tls_conf_t const *conf, bool client) * Check the password now, so that we don't have * errors at run-time. */ - hex_len = fr_hex2bin(buffer, sizeof(buffer), conf->psk_password, psk_len); + hex_len = fr_hex2bin(&FR_DBUFF_TMP(buffer, sizeof(buffer)), &FR_SBUFF_IN(conf->psk_password, psk_len)); if (psk_len != (2 * hex_len)) { ERROR("psk_hexphrase is not all hex"); goto error; @@ -748,7 +749,7 @@ post_ca: goto error; } X509_STORE_set_flags(cert_vpstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); -#ifdef X509_V_FLAG_USE_DELTAS +#ifdef X509_V_FLAG_USE_DELTAS /* * If set, delta CRLs (if present) are used to * determine certificate status. If not set diff --git a/src/lib/tls/session.c b/src/lib/tls/session.c index 6d14824e9c1..815a9d8f0a4 100644 --- a/src/lib/tls/session.c +++ b/src/lib/tls/session.c @@ -28,9 +28,10 @@ #ifdef HAVE_OPENSSL_OCSP_H #define LOG_PREFIX "tls - " -#include #include +#include +#include #include #include @@ -391,7 +392,8 @@ unsigned int fr_tls_session_psk_client_cb(SSL *ssl, UNUSED char const *hint, strlcpy(identity, conf->psk_identity, max_identity_len); - return fr_hex2bin(psk, max_psk_len, conf->psk_password, psk_len); + return fr_hex2bin(&FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len), + &FR_SBUFF_IN(conf->psk_password, (size_t)psk_len)); } /** Determine the PSK to use for an incoming connection @@ -405,9 +407,9 @@ unsigned int fr_tls_session_psk_client_cb(SSL *ssl, UNUSED char const *hint, * - >0 if a PSK matching identity was found (the length of bytes written to psk). */ unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity, - unsigned char *psk, unsigned int max_psk_len) + unsigned char *psk, unsigned int max_psk_len) { - unsigned int psk_len = 0; + size_t psk_len = 0; fr_tls_conf_t *conf; REQUEST *request; @@ -456,7 +458,7 @@ unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity, * convert the expansion from printable string * back to hex. */ - return fr_hex2bin(psk, max_psk_len, buffer, hex_len); + return fr_hex2bin(&FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len), &FR_SBUFF_IN(buffer, hex_len)); } if (!conf->psk_identity) { @@ -477,7 +479,7 @@ unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity, psk_len = strlen(conf->psk_password); if (psk_len > (2 * max_psk_len)) return 0; - return fr_hex2bin(psk, max_psk_len, conf->psk_password, psk_len); + return fr_hex2bin(&FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len), &FR_SBUFF_IN(conf->psk_password, psk_len)); } #endif /* PSK_MAX_IDENTITY_LEN */ diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index aaab34a2c7f..cce0b3ed129 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -32,11 +32,12 @@ RCSID("$Id$") #include #include -#include #include #include #include +#include +#include #include #include #include @@ -1741,7 +1742,7 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(result = fr_value_box_alloc_null(ctx)); MEM(fr_value_box_mem_alloc(result, &bin, result, NULL, outlen, fr_value_box_list_tainted(*in)) == 0); - fr_hex2bin(bin, outlen, p, end - p); + fr_hex2bin(&FR_DBUFF_TMP(bin, outlen), &FR_SBUFF_IN(p, end - p)); fr_cursor_append(out, result); @@ -1841,7 +1842,7 @@ static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_cursor_t *out, MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false)); vb->vb_length = ((*in)->vb_length * 2); vb->vb_strvalue = p = talloc_zero_array(vb, char, vb->vb_length + 1); - fr_bin2hex(p, (*in)->vb_octets, (*in)->vb_length); + fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP((*in)->vb_octets, (*in)->vb_length)); fr_cursor_append(out, vb); diff --git a/src/lib/util/ascend.c b/src/lib/util/ascend.c index 8ba72f4404d..791f46b2d3f 100644 --- a/src/lib/util/ascend.c +++ b/src/lib/util/ascend.c @@ -25,6 +25,7 @@ RCSID("$Id$") #ifdef WITH_ASCEND_BINARY #include "ascend.h" +#include #include #include @@ -395,7 +396,7 @@ static int ascend_parse_ipx_net(int argc, char **argv, /* * Node must be 6 octets long. */ - token = fr_hex2bin(net->node, IPX_NODE_ADDR_LEN, p, strlen(p)); + token = fr_hex2bin(&FR_DBUFF_TMP(net->node, IPX_NODE_ADDR_LEN), &FR_SBUFF_IN(p, strlen(p))); if (token != IPX_NODE_ADDR_LEN) return -1; /* @@ -893,10 +894,10 @@ static int ascend_parse_generic(int argc, char **argv, filter->offset = rcode; filter->offset = htons(filter->offset); - rcode = fr_hex2bin(filter->mask, sizeof(filter->mask), argv[1], strlen(argv[1])); + rcode = fr_hex2bin(&FR_DBUFF_TMP(filter->mask, sizeof(filter->mask)), &FR_SBUFF_IN(argv[1], strlen(argv[1]))); if (rcode != sizeof(filter->mask)) return -1; - token = fr_hex2bin(filter->value, sizeof(filter->value), argv[2], strlen(argv[2])); + token = fr_hex2bin(&FR_DBUFF_TMP(filter->value, sizeof(filter->value)), &FR_SBUFF_IN(argv[2], strlen(argv[2]))); if (token != sizeof(filter->value)) return -1; filter->len = rcode; diff --git a/src/lib/util/dbuff.h b/src/lib/util/dbuff.h index 8a2268ded28..f2e385e0e4c 100644 --- a/src/lib/util/dbuff.h +++ b/src/lib/util/dbuff.h @@ -209,6 +209,9 @@ _fr_dbuff_init(_out, \ (uint8_t const *)(_start), \ _Generic((_len_or_end), \ size_t : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + long : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + unsigned int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ uint8_t * : (uint8_t const *)(_len_or_end), \ uint8_t const * : (uint8_t const *)(_len_or_end), \ char * : (uint8_t const *)(_len_or_end), \ @@ -236,6 +239,9 @@ _fr_dbuff_init(_out, \ .start_i = (uint8_t const *)(_start), \ .end_i = _Generic((_len_or_end), \ size_t : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + long : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ + unsigned int : (uint8_t const *)(_start) + (size_t)(_len_or_end), \ uint8_t * : (uint8_t const *)(_len_or_end), \ uint8_t const * : (uint8_t const *)(_len_or_end), \ char * : (uint8_t const *)(_len_or_end), \ diff --git a/src/lib/util/hex.c b/src/lib/util/hex.c new file mode 100644 index 00000000000..2ad75cdcc16 --- /dev/null +++ b/src/lib/util/hex.c @@ -0,0 +1,100 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** A generic string buffer structure for string printing and parsing + * + * @file src/lib/util/sbuff.c + * + * @copyright 2020 Arran Cudbard-Bell \ + */ +RCSID("$Id$") + +#include + +static char const hextab[] = "0123456789abcdef"; + +/** Convert hex strings to binary data + * + * @param[out] out Output buffer to write to. + * @param[in] in Input string. + * @return + * - >=0 the number of bytes written to out. + * - <0 number of bytes we would have needed to copy the next hexit. + */ +ssize_t fr_hex2bin(fr_dbuff_t *out, fr_sbuff_t *in) +{ + size_t total = 0; + + while (!FR_SBUFF_CANT_EXTEND_LOWAT(in, 2)) { + char *c1, *c2; + + if(!(c1 = memchr(hextab, tolower((int) *in->p), sizeof(hextab))) || + !(c2 = memchr(hextab, tolower((int) *(in->p + 1)), sizeof(hextab)))) break; + + FR_DBUFF_BYTES_IN_RETURN(out, ((c1 - hextab) << 4) + (c2 - hextab)); + + fr_sbuff_advance(in, 2); + total++; + }; + + return total; +} + +/** Convert binary data to a hex string + * + * Ascii encoded hex string will not be prefixed with '0x' + * + * @warning If the output buffer isn't long enough, we have a buffer overflow. + * + * @param[out] out Output buffer to write to. + * @param[in] in input. + * @return + * - >=0 the number of bytes written to out. + * - <0 number of bytes we would have needed to print the next hexit. + */ +ssize_t fr_bin2hex(fr_sbuff_t *out, fr_dbuff_t *in) +{ + size_t total = 0; + + while (fr_dbuff_remaining(in) > 0) { /* Fixme to be extension check */ + FR_SBUFF_IN_CHAR_RETURN(out, hextab[((*in->p) >> 4) & 0x0f], hextab[*in->p & 0x0f]); + + fr_dbuff_advance(in, 1); + total += 2; + }; + return total; +} + +/** Convert binary data to a hex string + * + * Ascii encoded hex string will not be prefixed with '0x' + * + * @param[in] ctx to alloc buffer in. + * @param[in] bin input. + * @param[in] inlen of bin input. + * @return length of data written to buffer. + */ +char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen) +{ + char *buff; + + buff = talloc_array(ctx, char, (inlen << 2)); + if (!buff) return NULL; + + fr_bin2hex(&FR_SBUFF_OUT(buff, (inlen * 2) + 1), &FR_DBUFF_TMP(bin, inlen)); + + return buff; +} diff --git a/src/lib/util/hex.h b/src/lib/util/hex.h new file mode 100644 index 00000000000..80e84e72628 --- /dev/null +++ b/src/lib/util/hex.h @@ -0,0 +1,43 @@ +#pragma once +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** A generic buffer structure for string printing and parsing strings + * + * Because doing manual length checks is error prone and a waste of everyones time. + * + * @file src/lib/util/sbuff.h + * + * @copyright 2020 Arran Cudbard-Bell + */ +RCSIDH(hex_h, "$Id$") + +# ifdef __cplusplus +extern "C" { +# endif +#include +#include +#include + +ssize_t fr_hex2bin(fr_dbuff_t *out, fr_sbuff_t *in); + +ssize_t fr_bin2hex(fr_sbuff_t *out, fr_dbuff_t *in); + +char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen); + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/util/libfreeradius-util.mk b/src/lib/util/libfreeradius-util.mk index 94c3933eef9..3fb7e4746d6 100644 --- a/src/lib/util/libfreeradius-util.mk +++ b/src/lib/util/libfreeradius-util.mk @@ -26,6 +26,7 @@ SOURCES := \ getaddrinfo.c \ hash.c \ heap.c \ + hex.c \ hmac_md5.c \ hmac_sha1.c \ hw.c \ diff --git a/src/lib/util/misc.c b/src/lib/util/misc.c index e3b554b5354..d2223e3de4c 100644 --- a/src/lib/util/misc.c +++ b/src/lib/util/misc.c @@ -22,8 +22,10 @@ */ RCSID("$Id$") +#include #include #include +#include #include #include #include @@ -158,86 +160,6 @@ int rad_unlockfd(int fd, int lock_len) return rad_lock(fd, lock_len, F_SETLK, F_UNLCK); } -static char const hextab[] = "0123456789abcdef"; - -/** Convert hex strings to binary data - * - * @param bin Buffer to write output to. - * @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, size_t outlen, char const *hex, size_t inlen) -{ - size_t i; - size_t len; - char *c1, *c2; - - /* - * 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]), sizeof(hextab))) || - !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), sizeof(hextab)))) - break; - bin[i] = ((c1-hextab)<<4) + (c2-hextab); - } - - return i; -} - -/** Convert binary data to a hex string - * - * Ascii encoded hex string will not be prefixed with '0x' - * - * @warning If the output buffer isn't long enough, we have a buffer overflow. - * - * @param[out] hex Buffer to write hex output. - * @param[in] bin input. - * @param[in] inlen of bin input. - * @return length of data written to buffer. - */ -size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen) -{ - size_t i; - - for (i = 0; i < inlen; i++) { - hex[0] = hextab[((*bin) >> 4) & 0x0f]; - hex[1] = hextab[*bin & 0x0f]; - hex += 2; - bin++; - } - - *hex = '\0'; - return inlen * 2; -} - -/** Convert binary data to a hex string - * - * Ascii encoded hex string will not be prefixed with '0x' - * - * @param[in] ctx to alloc buffer in. - * @param[in] bin input. - * @param[in] inlen of bin input. - * @return length of data written to buffer. - */ -char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen) -{ - char *buff; - - buff = talloc_array(ctx, char, (inlen << 2)); - if (!buff) return NULL; - - fr_bin2hex(buff, bin, inlen); - - return buff; -} - /** Consume the integer (or hex) portion of a value string * * Allows integer or hex representations of integers (but not octal, diff --git a/src/lib/util/misc.h b/src/lib/util/misc.h index 42eb10aeee6..e88edebde28 100644 --- a/src/lib/util/misc.h +++ b/src/lib/util/misc.h @@ -191,9 +191,6 @@ int fr_unset_signal(int sig); 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); -char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen); -size_t fr_bin2hex(char * restrict hex, uint8_t const * restrict bin, size_t inlen); -size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen); int fr_strtoull(uint64_t *out, char **end, char const *value); int fr_strtoll(int64_t *out, char **end, char const *value); char *fr_trim(char const *str, size_t size); diff --git a/src/lib/util/print.c b/src/lib/util/print.c index 285e48a974e..2bf5c21dc9e 100644 --- a/src/lib/util/print.c +++ b/src/lib/util/print.c @@ -26,6 +26,7 @@ RCSID("$Id$") #include #include #include +#include #include #include @@ -741,13 +742,13 @@ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) case FR_TYPE_OCTETS: subst = talloc_array(NULL, char, (in->vb_length * 2) + 1); if (!subst) goto oom; - fr_bin2hex(subst, in->vb_octets, in->vb_length); + fr_bin2hex(&FR_SBUFF_OUT(subst, talloc_array_length(subst)), &FR_DBUFF_TMP(in->vb_octets, in->vb_length)); break; case FR_TYPE_STRING: subst = talloc_array(NULL, char, (in->vb_length * 2) + 1); if (!subst) goto oom; - fr_bin2hex(subst, (uint8_t const *)in->vb_strvalue, in->vb_length); + fr_bin2hex(&FR_SBUFF_OUT(subst, talloc_array_length(subst)), &FR_DBUFF_TMP((uint8_t const *)in->vb_strvalue, in->vb_length)); break; default: @@ -764,7 +765,7 @@ char *fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) subst = talloc_array(NULL, char, (dst.vb_length * 2) + 1); if (!subst) goto oom; - fr_bin2hex(subst, dst.vb_octets, dst.vb_length); + fr_bin2hex(&FR_SBUFF_OUT(subst, talloc_array_length(subst)), &FR_DBUFF_TMP(dst.vb_octets, dst.vb_length)); fr_value_box_clear(&dst); break; diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index f56659ca4bb..9c9542b16a2 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -847,28 +847,6 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t SBUFF_PARSE_FLOAT_DEF(float32, float, strtof, 100); SBUFF_PARSE_FLOAT_DEF(float64, double, strtod, 100); -/** Copy char into the sbuff - * - * @param[in] sbuff to copy into. - * @param[in] c to copy into buffer. - * @return - * - >= 0 the number of bytes copied into the sbuff. - * - <0 the number of bytes required to complete the copy operation. - */ -ssize_t fr_sbuff_in_char(fr_sbuff_t *sbuff, char c) -{ - CHECK_SBUFF_INIT(sbuff); - - if (unlikely(sbuff->is_const)) return 0; - - FR_SBUFF_EXTEND_OR_RETURN(sbuff, 1); - - *sbuff->p = c; - *(sbuff->p + 1) = '\0'; - - return fr_sbuff_advance(sbuff, 1); -} - /** Copy bytes into the sbuff up to the first \0 * * @param[in] sbuff to copy into. diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index 7da48c88815..3df44668d44 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -183,6 +183,7 @@ do { \ size_t : (char const *)(_start) + ((size_t)(_len_or_end) - 1), \ long : (char const *)(_start) + ((size_t)(_len_or_end) - 1), \ int : (char const *)(_start) + ((size_t)(_len_or_end) - 1), \ + unsigned int : (char const *)(_start) + ((size_t)(_len_or_end) - 1), \ char * : (char const *)(_len_or_end), \ char const * : (char const *)(_len_or_end) \ ), \ @@ -209,6 +210,7 @@ do { \ size_t : (char const *)(_start) + (size_t)(_len_or_end), \ long : (char const *)(_start) + (size_t)(_len_or_end), \ int : (char const *)(_start) + (size_t)(_len_or_end), \ + unsigned int : (char const *)(_start) + (size_t)(_len_or_end), \ char * : (char const *)(_len_or_end), \ char const * : (char const *)(_len_or_end) \ ), \ @@ -709,8 +711,8 @@ static inline void fr_sbuff_set_to_marker(fr_sbuff_marker_t *m) * * @{ */ -ssize_t fr_sbuff_in_char(fr_sbuff_t *sbuff, char c); -#define FR_SBUFF_IN_CHAR_RETURN(...) FR_SBUFF_RETURN(fr_sbuff_in_char, ##__VA_ARGS__) +#define fr_sbuff_in_char(_sbuff, ...) fr_sbuff_in_bstrncpy(_sbuff, ((char []){ __VA_ARGS__ }), sizeof((char []){ __VA_ARGS__ })) +#define FR_SBUFF_IN_CHAR_RETURN(_sbuff, ...) FR_SBUFF_RETURN(fr_sbuff_in_bstrncpy, _sbuff, ((char []){ __VA_ARGS__ }), sizeof((char []){ __VA_ARGS__ })) ssize_t fr_sbuff_in_strcpy(fr_sbuff_t *sbuff, char const *str); #define FR_SBUFF_IN_STRCPY_RETURN(...) FR_SBUFF_RETURN(fr_sbuff_in_strcpy, ##__VA_ARGS__) diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 2b21c486e32..4fef355b4eb 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -51,10 +51,10 @@ RCSID("$Id$") #include #include #include -#include +#include +#include #include #include -#include #include #include @@ -4432,7 +4432,7 @@ parse: ret = len >> 1; p = talloc_array(ctx, uint8_t, ret); - if (fr_hex2bin(p, ret, in + 2, len) != (size_t)ret) { + if (fr_hex2bin(&FR_DBUFF_TMP(p, ret), &FR_SBUFF_IN(in + 2, len)) != (ssize_t)ret) { talloc_free(p); fr_strerror_printf("Invalid hex data"); return -1; @@ -4452,7 +4452,7 @@ parse: return -1; } - bin = fr_hex2bin((uint8_t *) &dst->datum.filter, ret, in + 2, len - 2); + bin = fr_hex2bin(&FR_DBUFF_TMP((uint8_t *) &dst->datum.filter, (len - 2) / 2), &FR_SBUFF_IN(in + 2, len - 2)); if (bin < ret) { memset(((uint8_t *) &dst->datum.filter) + bin, 0, ret - bin); } @@ -4785,8 +4785,8 @@ char *fr_value_box_asprint(TALLOC_CTX *ctx, fr_value_box_t const *data, char quo p[0] = '0'; p[1] = 'x'; - if (data->vb_octets) { - fr_bin2hex(p + 2, data->vb_octets, data->datum.length); + if (data->vb_octets && data->datum.length) { + fr_bin2hex(&FR_SBUFF_OUT(p + 2, (data->datum.length * 2) + 1), &FR_DBUFF_TMP(data->vb_octets, data->datum.length)); p[2 + (data->datum.length * 2)] = '\0'; } else { p[2] = '\0'; @@ -5535,10 +5535,11 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data } /* Get maximum number of uint8s we can encode given (end - p) */ - if (data->vb_octets) { + if (data->vb_octets && data->datum.length) { max = (((end - p) % 2) ? (end - p) - 1 : (end - p) - 2) / 2; - fr_bin2hex(p, data->vb_octets, - ((size_t)data->datum.length > max) ? max : (size_t)data->datum.length); + fr_bin2hex(&FR_SBUFF_OUT(p, end), + &FR_DBUFF_TMP(data->vb_octets, + (size_t)data->datum.length > max ? max : (size_t)data->datum.length)); } else { *p = '\0'; } diff --git a/src/modules/proto_bfd/proto_bfd.c b/src/modules/proto_bfd/proto_bfd.c index e631e2a4126..557c4a84f17 100644 --- a/src/modules/proto_bfd/proto_bfd.c +++ b/src/modules/proto_bfd/proto_bfd.c @@ -28,8 +28,8 @@ #include #include +#include #include -#include #include #include #include @@ -456,7 +456,7 @@ static ssize_t bfd_parse_secret(CONF_SECTION *cs, uint8_t secret[BFD_MAX_SECRET_ return -1; } - return fr_hex2bin(secret, BFD_MAX_SECRET_LENGTH, value + 2, (len - 2)); + return fr_hex2bin(&FR_DBUFF_TMP(secret, BFD_MAX_SECRET_LENGTH), &FR_SBUFF_IN(value + 2, (len - 2))); } if (len >= 20) { diff --git a/src/modules/rlm_digest/rlm_digest.c b/src/modules/rlm_digest/rlm_digest.c index c9d17376b49..a6d4d916ec6 100644 --- a/src/modules/rlm_digest/rlm_digest.c +++ b/src/modules/rlm_digest/rlm_digest.c @@ -26,6 +26,8 @@ RCSID("$Id$") #include #include + +#include #include typedef struct { @@ -203,7 +205,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED module_ctx_t const * * Set A1 to Digest-HA1 if no User-Password found */ if (passwd->da == attr_digest_ha1) { - if (fr_hex2bin(&a1[0], sizeof(a1), passwd->vp_strvalue, passwd->vp_length) != 16) { + if (fr_hex2bin(&FR_DBUFF_TMP(&a1[0], sizeof(a1)), &FR_SBUFF_IN(passwd->vp_strvalue, passwd->vp_length)) != 16) { RDEBUG2("Invalid text in Digest-HA1"); return RLM_MODULE_INVALID; } @@ -218,7 +220,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED module_ctx_t const * */ if (passwd->da == attr_cleartext_password) { fr_md5_calc(hash, &a1[0], a1_len); - fr_bin2hex((char *) &a1[0], hash, 16); + fr_bin2hex(&FR_SBUFF_OUT((char *) &a1[0], 32 + 1), &FR_DBUFF_TMP(hash, 16)); } else { /* MUST be Digest-HA1 */ memcpy(&a1[0], passwd->vp_strvalue, 32); } @@ -339,7 +341,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED module_ctx_t const * } else { memcpy(&hash[0], &a1[0], a1_len); } - fr_bin2hex((char *) kd, hash, sizeof(hash)); + fr_bin2hex(&FR_SBUFF_OUT((char *) kd, (sizeof(hash) * 2) + 1), &FR_DBUFF_TMP(hash, sizeof(hash))); RHEXDUMP_INLINE3(hash, sizeof(hash), "H(A1)"); @@ -401,7 +403,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED module_ctx_t const * fr_md5_calc(&hash[0], &a2[0], a2_len); - fr_bin2hex((char *) kd + kd_len, hash, sizeof(hash)); + fr_bin2hex(&FR_SBUFF_OUT((char *) kd + kd_len, (sizeof(hash) * 2) + 1), &FR_DBUFF_TMP(hash, sizeof(hash))); RHEXDUMP_INLINE3(hash, sizeof(hash), "H(A2)"); @@ -426,7 +428,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(UNUSED module_ctx_t const * return RLM_MODULE_INVALID; } - if (fr_hex2bin(&hash[0], sizeof(hash), vp->vp_strvalue, vp->vp_length) != (vp->vp_length >> 1)) { + if (fr_hex2bin(&FR_DBUFF_TMP(&hash[0], sizeof(hash)), &FR_SBUFF_IN(vp->vp_strvalue, vp->vp_length)) != (vp->vp_length >> 1)) { RDEBUG2("Invalid text in Digest-Response"); return RLM_MODULE_INVALID; } diff --git a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c index 8755074353f..1098688e8c4 100644 --- a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c +++ b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c @@ -22,8 +22,9 @@ RCSID("$Id$") -#include #include +#include +#include #include "eap_mschapv2.h" @@ -389,7 +390,7 @@ static rlm_rcode_t mschap_finalize(REQUEST *request, rlm_eap_mschapv2_t const *i if (n == 3) { RDEBUG2("Found new challenge from MS-CHAP-Error: err=%d retry=%d challenge=%s", err, retry, buf); - fr_hex2bin(data->auth_challenge, 16, buf, strlen(buf)); + fr_hex2bin(&FR_DBUFF_TMP(data->auth_challenge, 16), &FR_SBUFF_IN(buf, strlen(buf))); } else { RDEBUG2("Could not parse new challenge from MS-CHAP-Error: %d", n); } diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 4e97cc92008..071b10f6898 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -33,6 +33,7 @@ RCSID("$Id$") #include #include +#include #include #include #include @@ -581,7 +582,7 @@ static ssize_t mschap_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, return -1; } - fr_bin2hex(*out, buffer, NT_DIGEST_LENGTH); + fr_bin2hex(&FR_SBUFF_OUT(*out, (NT_DIGEST_LENGTH * 2) + 1), &FR_DBUFF_TMP(buffer, NT_DIGEST_LENGTH)); (*out)[32] = '\0'; RDEBUG2("NT-Hash of \"known-good\" password: %s", *out); return 32; @@ -599,7 +600,7 @@ static ssize_t mschap_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, fr_skip_whitespace(p); smbdes_lmpwdhash(p, buffer); - fr_bin2hex(*out, buffer, LM_DIGEST_LENGTH); + fr_bin2hex(&FR_SBUFF_OUT(*out, (LM_DIGEST_LENGTH * 2) + 1), &FR_DBUFF_TMP(buffer, LM_DIGEST_LENGTH)); (*out)[32] = '\0'; RDEBUG2("LM-Hash of %s = %s", p, *out); return 32; @@ -797,7 +798,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5)) do_mschap_cpw(rlm_mschap_t const *inst, /* now the password blobs */ len = sprintf(buf, "new-nt-password-blob: "); - fr_bin2hex(buf+len, new_nt_password, 516); + fr_bin2hex(&FR_SBUFF_OUT(buf + len, sizeof(buf) - len), &FR_DBUFF_TMP(new_nt_password, 516)); buf[len+1032] = '\n'; buf[len+1033] = '\0'; len = strlen(buf); @@ -807,7 +808,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5)) do_mschap_cpw(rlm_mschap_t const *inst, } len = sprintf(buf, "old-nt-hash-blob: "); - fr_bin2hex(buf+len, old_nt_hash, NT_DIGEST_LENGTH); + fr_bin2hex(&FR_SBUFF_OUT(buf + len, sizeof(buf) - len), &FR_DBUFF_TMP(old_nt_hash, NT_DIGEST_LENGTH)); buf[len+32] = '\n'; buf[len+33] = '\0'; len = strlen(buf); @@ -1221,7 +1222,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5, 6)) do_mschap(rlm_mschap_t const *inst, /* * Update the NT hash hash, from the NT key. */ - if (fr_hex2bin(nthashhash, NT_DIGEST_LENGTH, buffer + 8, len) != NT_DIGEST_LENGTH) { + if (fr_hex2bin(&FR_DBUFF_TMP(nthashhash, NT_DIGEST_LENGTH), &FR_SBUFF_IN(buffer + 8, len)) != NT_DIGEST_LENGTH) { REDEBUG("Invalid output from ntlm_auth: NT_KEY has non-hex values"); return -1; } diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c index f0fb6729447..ba69a30f34c 100644 --- a/src/modules/rlm_pap/rlm_pap.c +++ b/src/modules/rlm_pap/rlm_pap.c @@ -30,9 +30,11 @@ USES_APPLE_DEPRECATED_API #include #include #include -#include #include + #include +#include +#include #include #include @@ -715,7 +717,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_lm(UNUSED rlm_pap_t const *inst, RE len = xlat_eval(charbuf, sizeof(charbuf), request, "%{mschap:LM-Hash %{User-Password}}", NULL, NULL); if (len < 0) return RLM_MODULE_FAIL; - if ((fr_hex2bin(digest, sizeof(digest), charbuf, len) != known_good->vp_length) || + if ((fr_hex2bin(&FR_DBUFF_TMP(digest, sizeof(digest)), &FR_SBUFF_IN(charbuf, len)) != (ssize_t)known_good->vp_length) || (fr_digest_cmp(digest, known_good->vp_octets, known_good->vp_length) != 0)) { REDEBUG("LM digest does not match \"known good\" digest"); REDEBUG3("Calculated : %pH", fr_box_octets(digest, sizeof(digest))); @@ -744,7 +746,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_ns_mta_md5(UNUSED rlm_pap_t const * /* * Sanity check the value of NS-MTA-MD5-Password */ - if (fr_hex2bin(digest, sizeof(digest), known_good->vp_strvalue, known_good->vp_length) != 16) { + if (fr_hex2bin(&FR_DBUFF_TMP(digest, sizeof(digest)), &FR_SBUFF_IN(known_good->vp_strvalue, known_good->vp_length)) != 16) { REDEBUG("\"known good\" NS-MTA-MD5-Password has invalid value"); return RLM_MODULE_INVALID; } diff --git a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c index 5fe9d757dae..d29df7edc8c 100644 --- a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c +++ b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c @@ -44,7 +44,9 @@ RCSID("$Id$") #include #include #include + #include +#include #include #include @@ -1364,17 +1366,17 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) fr_sha1_init(&sha1_ctx); fr_sha1_update(&sha1_ctx, (uint8_t const *)lua_alloc_cmd, sizeof(lua_alloc_cmd) - 1); fr_sha1_final(digest, &sha1_ctx); - fr_bin2hex(lua_alloc_digest, digest, sizeof(digest)); + fr_bin2hex(&FR_SBUFF_OUT(lua_alloc_digest, sizeof(lua_alloc_digest)), &FR_DBUFF_TMP(digest, sizeof(digest))); fr_sha1_init(&sha1_ctx); fr_sha1_update(&sha1_ctx, (uint8_t const *)lua_update_cmd, sizeof(lua_update_cmd) - 1); fr_sha1_final(digest, &sha1_ctx); - fr_bin2hex(lua_update_digest, digest, sizeof(digest)); + fr_bin2hex(&FR_SBUFF_OUT(lua_update_digest, sizeof(lua_update_digest)), &FR_DBUFF_TMP(digest, sizeof(digest))); fr_sha1_init(&sha1_ctx); fr_sha1_update(&sha1_ctx, (uint8_t const *)lua_release_cmd, sizeof(lua_release_cmd) - 1); fr_sha1_final(digest, &sha1_ctx); - fr_bin2hex(lua_release_digest, digest, sizeof(digest)); + fr_bin2hex(&FR_SBUFF_OUT(lua_release_digest, sizeof(lua_release_digest)), &FR_DBUFF_TMP(digest, sizeof(digest))); } /* diff --git a/src/modules/rlm_unpack/rlm_unpack.c b/src/modules/rlm_unpack/rlm_unpack.c index a4442002777..166cadca98b 100644 --- a/src/modules/rlm_unpack/rlm_unpack.c +++ b/src/modules/rlm_unpack/rlm_unpack.c @@ -26,6 +26,9 @@ RCSID("$Id$") #include #include + +#include + #include static fr_dict_t const *dict_freeradius; @@ -130,7 +133,7 @@ static ssize_t unpack_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, goto nothing; } input = blob; - input_len = fr_hex2bin(blob, sizeof(blob), data_name + 2, len); + input_len = fr_hex2bin(&FR_DBUFF_TMP(blob, sizeof(blob)), &FR_SBUFF_IN(data_name + 2, len)); } else { GOTO_ERROR; diff --git a/src/modules/rlm_wimax/rlm_wimax.c b/src/modules/rlm_wimax/rlm_wimax.c index 0c5bb91b8a6..35f37d90048 100644 --- a/src/modules/rlm_wimax/rlm_wimax.c +++ b/src/modules/rlm_wimax/rlm_wimax.c @@ -30,6 +30,7 @@ USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */ #include #include #include +#include /* * FIXME: Add check for this header to configure.ac @@ -138,7 +139,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(UNUSED module_ctx_t const *mct * so we fix it here. */ for (i = 0; i < 6; i++) { - fr_bin2hex(&p[i * 3], &buffer[i], 1); + fr_bin2hex(&FR_SBUFF_OUT(&p[i * 3], 2 + 1), &FR_DBUFF_TMP(&buffer[i], 1)); p[(i * 3) + 2] = '-'; }