#include "internal.h"
#include "libavutil/random_seed.h"
#include "libavutil/md5.h"
+#include "urldecode.h"
#include "avformat.h"
-#include <ctype.h>
static void handle_basic_params(HTTPAuthState *state, const char *key,
int key_len, char **dest, int *dest_len)
} else if (!strncmp(key, "qop=", key_len)) {
*dest = digest->qop;
*dest_len = sizeof(digest->qop);
+ } else if (!strncmp(key, "stale=", key_len)) {
+ *dest = digest->stale;
+ *dest_len = sizeof(digest->stale);
}
}
char *ptr = strstr(qop, "auth");
char *end = ptr + strlen("auth");
- if (ptr && (!*end || isspace(*end) || *end == ',') &&
- (ptr == qop || isspace(ptr[-1]) || ptr[-1] == ',')) {
+ if (ptr && (!*end || av_isspace(*end) || *end == ',') &&
+ (ptr == qop || av_isspace(ptr[-1]) || ptr[-1] == ',')) {
av_strlcpy(qop, "auth", size);
} else {
qop[0] = 0;
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
const char *value)
{
- if (!strcmp(key, "WWW-Authenticate")) {
+ if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) {
const char *p;
if (av_stristart(value, "Basic ", &p) &&
state->auth_type <= HTTP_AUTH_BASIC) {
state->auth_type = HTTP_AUTH_BASIC;
state->realm[0] = 0;
+ state->stale = 0;
ff_parse_key_value(p, (ff_parse_key_val_cb) handle_basic_params,
state);
} else if (av_stristart(value, "Digest ", &p) &&
state->auth_type = HTTP_AUTH_DIGEST;
memset(&state->digest_params, 0, sizeof(DigestParams));
state->realm[0] = 0;
+ state->stale = 0;
ff_parse_key_value(p, (ff_parse_key_val_cb) handle_digest_params,
state);
choose_qop(state->digest_params.qop,
sizeof(state->digest_params.qop));
+ if (!av_strcasecmp(state->digest_params.stale, "true"))
+ state->stale = 1;
}
} else if (!strcmp(key, "Authentication-Info")) {
ff_parse_key_value(value, (ff_parse_key_val_cb) handle_digest_update,
ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1);
cnonce[2*sizeof(cnonce_buf)] = 0;
- md5ctx = av_malloc(av_md5_size);
+ md5ctx = av_md5_alloc();
if (!md5ctx)
return NULL;
{
char *authstr = NULL;
+ /* Clear the stale flag, we assume the auth is ok now. It is reset
+ * by the server headers if there's a new issue. */
+ state->stale = 0;
if (!auth || !strchr(auth, ':'))
return NULL;
if (state->auth_type == HTTP_AUTH_BASIC) {
- int auth_b64_len = AV_BASE64_SIZE(strlen(auth));
- int len = auth_b64_len + 30;
- char *ptr;
+ int auth_b64_len, len;
+ char *ptr, *decoded_auth = ff_urldecode(auth);
+
+ if (!decoded_auth)
+ return NULL;
+
+ auth_b64_len = AV_BASE64_SIZE(strlen(decoded_auth));
+ len = auth_b64_len + 30;
+
authstr = av_malloc(len);
- if (!authstr)
+ if (!authstr) {
+ av_free(decoded_auth);
return NULL;
+ }
+
snprintf(authstr, len, "Authorization: Basic ");
ptr = authstr + strlen(authstr);
- av_base64_encode(ptr, auth_b64_len, auth, strlen(auth));
+ av_base64_encode(ptr, auth_b64_len, decoded_auth, strlen(decoded_auth));
av_strlcat(ptr, "\r\n", len - (ptr - authstr));
+ av_free(decoded_auth);
} else if (state->auth_type == HTTP_AUTH_DIGEST) {
- char *username = av_strdup(auth), *password;
+ char *username = ff_urldecode(auth), *password;
if (!username)
return NULL;
}
return authstr;
}
-