X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuclient.git;a=blobdiff_plain;f=uclient-utils.c;h=3eaf2d5febe2f38bebdd4921f0c4a449a41f5537;hp=0d0997427986389b8c9dad6c4dd245eb99a89d5b;hb=HEAD;hpb=c280d54e1bc79de4424fabc3fad011cc15587b81 diff --git a/uclient-utils.c b/uclient-utils.c index 0d09974..3eaf2d5 100644 --- a/uclient-utils.c +++ b/uclient-utils.c @@ -1,7 +1,28 @@ +/* + * uclient - ustream based protocol client library + * + * Copyright (C) 2014 Felix Fietkau + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #include #include +#include #include +#include +#include + #include "uclient-utils.h" static const char *b64 = @@ -75,3 +96,89 @@ int uclient_urldecode(const char *in, char *out, bool decode_plus) *out = 0; return ret; } + +static char hex_digit(char val) +{ + val += val > 9 ? 'a' - 10 : '0'; + return val; +} + +void bin_to_hex(char *dest, const void *buf, int len) +{ + const uint8_t *data = buf; + int i; + + for (i = 0; i < len; i++) { + *(dest++) = hex_digit(data[i] >> 4); + *(dest++) = hex_digit(data[i] & 0xf); + } + *dest = 0; +} + +static void http_create_hash(char *dest, const char * const * str, int n_str) +{ + uint32_t hash[4]; + md5_ctx_t md5; + int i; + + md5_begin(&md5); + for (i = 0; i < n_str; i++) { + if (i) + md5_hash(":", 1, &md5); + md5_hash(str[i], strlen(str[i]), &md5); + } + md5_end(hash, &md5); + bin_to_hex(dest, &hash, sizeof(hash)); +} + +void http_digest_calculate_auth_hash(char *dest, const char *user, const char *realm, const char *password) +{ + const char *hash_str[] = { + user, + realm, + password + }; + + http_create_hash(dest, hash_str, ARRAY_SIZE(hash_str)); +} + +void http_digest_calculate_response(char *dest, const struct http_digest_data *data) +{ + const char *h_a2_strings[] = { + data->method, + data->uri, + }; + const char *resp_strings[] = { + data->auth_hash, + data->nonce, + data->nc, + data->cnonce, + data->qop, + dest, /* initialized to H(A2) first */ + }; + + http_create_hash(dest, h_a2_strings, ARRAY_SIZE(h_a2_strings)); + http_create_hash(dest, resp_strings, ARRAY_SIZE(resp_strings)); +} + +char *uclient_get_url_filename(const char *url, const char *default_name) +{ + const char *str; + int len = strcspn(url, ";&"); + + while (len > 0 && url[len - 1] == '/') + len--; + + for (str = url + len - 1; str >= url; str--) { + if (*str == '/') + break; + } + + str++; + len -= str - url; + + if (len > 0) + return strndup(str, len); + + return strdup(default_name); +}