From: Jaroslav Kysela Date: Fri, 8 Apr 2016 16:40:39 +0000 (+0200) Subject: http: improve digest authentisation, fix md5sum() fcn X-Git-Tag: v4.2.1~699 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ed53e70ddb14df89f3315b5040bd94089fb9d2be;p=thirdparty%2Ftvheadend.git http: improve digest authentisation, fix md5sum() fcn --- diff --git a/src/http.c b/src/http.c index c180066d1..508665d09 100644 --- a/src/http.c +++ b/src/http.c @@ -248,21 +248,29 @@ static char * http_get_nonce(void) { struct http_nonce *n = calloc(1, sizeof(*n)); - char stamp[16], *m; - int64_t mono = getmonoclock(); - mono ^= 0xa1687211885fcd30; - snprintf(stamp, sizeof(stamp), "%"PRId64, mono); - m = md5sum(stamp, 1); - strcpy(n->nonce, m); - pthread_mutex_lock(&global_lock); - RB_INSERT_SORTED(&http_nonces, n, link, http_nonce_cmp); - mtimer_arm_rel(&n->expire, http_nonce_timeout, n, sec2mono(10)); - pthread_mutex_unlock(&global_lock); + char stamp[32], *m; + int64_t mono; + + while (1) { + mono = getmonoclock(); + mono ^= 0xa1687211885fcd30; + snprintf(stamp, sizeof(stamp), "%"PRId64, mono); + m = md5sum(stamp, 1); + strcpy(n->nonce, m); + pthread_mutex_lock(&global_lock); + if (RB_INSERT_SORTED(&http_nonces, n, link, http_nonce_cmp)) { + pthread_mutex_unlock(&global_lock); + continue; /* get unique md5 */ + } + mtimer_arm_rel(&n->expire, http_nonce_timeout, n, sec2mono(10)); + pthread_mutex_unlock(&global_lock); + break; + } return m; } -static char * -http_find_nonce(const char *nonce) +static int +http_nonce_exists(const char *nonce) { struct http_nonce *n, tmp; @@ -271,14 +279,13 @@ http_find_nonce(const char *nonce) strcpy(tmp.nonce, nonce); pthread_mutex_lock(&global_lock); n = RB_FIND(&http_nonces, &tmp, link, http_nonce_cmp); - pthread_mutex_unlock(&global_lock); if (n) { - pthread_mutex_lock(&global_lock); mtimer_arm_rel(&n->expire, http_nonce_timeout, n, sec2mono(2*60)); pthread_mutex_unlock(&global_lock); - return n->nonce; + return 1; } - return NULL; + pthread_mutex_unlock(&global_lock); + return 0; } static char * @@ -535,11 +542,17 @@ void http_error(http_connection_t *hc, int error) { const char *errtxt = http_rc2str(error); + int level; if (!atomic_get(&http_server_running)) return; if (error != HTTP_STATUS_FOUND && error != HTTP_STATUS_MOVED) - tvhlog(error < 400 ? LOG_INFO : LOG_ERR, "http", "%s: %s %s %s -- %d", + level = LOG_INFO; + if (error == HTTP_STATUS_UNAUTHORIZED) + level = LOG_DEBUG; + else if (error == HTTP_STATUS_BAD_REQUEST || error > HTTP_STATUS_UNAUTHORIZED) + level = LOG_ERR; + tvhlog(level, "http", "%s: %s %s %s -- %d", hc->hc_peer_ipstr, http_ver2str(hc->hc_version), http_cmd2str(hc->hc_cmd), hc->hc_url, error); @@ -683,6 +696,7 @@ struct http_verify_structure { char *d_ha1; char *d_all; char *d_response; + http_connection_t *hc; }; static int @@ -760,6 +774,7 @@ set: snprintf(all, sizeof(all), "%s:%s", hc->hc_username, realm); v->d_ha1 = strdup(all); v->d_response = response; + v->hc = hc; response = NULL; } } @@ -1100,7 +1115,7 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) } } else if (strcasecmp(argv[0], "digest") == 0) { v = http_get_header_value(argv[1], "nonce"); - if (v == NULL || http_find_nonce(v) == NULL) { + if (v == NULL || !http_nonce_exists(v)) { http_error(hc, HTTP_STATUS_UNAUTHORIZED); free(v); return -1; diff --git a/src/utils.c b/src/utils.c index c4d8c24ad..5b13ccd62 100644 --- a/src/utils.c +++ b/src/utils.c @@ -470,9 +470,10 @@ sbuf_read(sbuf_t *sb, int fd) char * md5sum ( const char *str, int lowercase ) { - int i; - static unsigned char md5[MD5_DIGEST_LENGTH]; + uint8_t md5[MD5_DIGEST_LENGTH]; char *ret = malloc((MD5_DIGEST_LENGTH * 2) + 1); + int i; + MD5((const unsigned char*)str, strlen(str), md5); for (i = 0; i < MD5_DIGEST_LENGTH; i++) sprintf(&ret[i*2], lowercase ? "%02x" : "%02X", md5[i]);