annotate httpauth.c @ 6114:10c9d304794f libavformat

Do not attempt to seek to index for streamed files and if the user explicitly requested us not to read the index.
author reimar
date Tue, 08 Jun 2010 19:31:08 +0000
parents 4518f83661f4
children 054de75e4a49
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
1 /*
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
2 * HTTP authentication
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
3 * Copyright (c) 2010 Martin Storsjo
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
4 *
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
5 * This file is part of FFmpeg.
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
6 *
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
11 *
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
15 * Lesser General Public License for more details.
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
16 *
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
20 */
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
21
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
22 #include "httpauth.h"
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
23 #include "libavutil/base64.h"
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
24 #include "libavutil/avstring.h"
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
25 #include "internal.h"
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
26 #include "libavutil/random_seed.h"
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
27 #include "libavutil/md5.h"
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
28 #include "avformat.h"
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
29 #include <ctype.h>
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
30
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
31 static void parse_key_value(const char *params,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
32 void (*callback_get_buf)(HTTPAuthState *state,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
33 const char *key, int key_len,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
34 char **dest, int *dest_len), HTTPAuthState *state)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
35 {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
36 const char *ptr = params;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
37
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
38 /* Parse key=value pairs. */
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
39 for (;;) {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
40 const char *key;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
41 char *dest = NULL, *dest_end;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
42 int key_len, dest_len = 0;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
43
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
44 /* Skip whitespace and potential commas. */
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
45 while (*ptr && (isspace(*ptr) || *ptr == ','))
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
46 ptr++;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
47 if (!*ptr)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
48 break;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
49
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
50 key = ptr;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
51
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
52 if (!(ptr = strchr(key, '=')))
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
53 break;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
54 ptr++;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
55 key_len = ptr - key;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
56
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
57 callback_get_buf(state, key, key_len, &dest, &dest_len);
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
58 dest_end = dest + dest_len - 1;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
59
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
60 if (*ptr == '\"') {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
61 ptr++;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
62 while (*ptr && *ptr != '\"') {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
63 if (*ptr == '\\') {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
64 if (!ptr[1])
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
65 break;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
66 if (dest && dest < dest_end)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
67 *dest++ = ptr[1];
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
68 ptr += 2;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
69 } else {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
70 if (dest && dest < dest_end)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
71 *dest++ = *ptr;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
72 ptr++;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
73 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
74 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
75 if (*ptr == '\"')
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
76 ptr++;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
77 } else {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
78 for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
79 if (dest && dest < dest_end)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
80 *dest++ = *ptr;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
81 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
82 if (dest)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
83 *dest = 0;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
84 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
85 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
86
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
87 static void handle_basic_params(HTTPAuthState *state, const char *key,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
88 int key_len, char **dest, int *dest_len)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
89 {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
90 if (!strncmp(key, "realm=", key_len)) {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
91 *dest = state->realm;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
92 *dest_len = sizeof(state->realm);
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
93 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
94 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
95
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
96 static void handle_digest_params(HTTPAuthState *state, const char *key,
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
97 int key_len, char **dest, int *dest_len)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
98 {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
99 DigestParams *digest = &state->digest_params;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
100
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
101 if (!strncmp(key, "realm=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
102 *dest = state->realm;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
103 *dest_len = sizeof(state->realm);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
104 } else if (!strncmp(key, "nonce=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
105 *dest = digest->nonce;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
106 *dest_len = sizeof(digest->nonce);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
107 } else if (!strncmp(key, "opaque=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
108 *dest = digest->opaque;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
109 *dest_len = sizeof(digest->opaque);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
110 } else if (!strncmp(key, "algorithm=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
111 *dest = digest->algorithm;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
112 *dest_len = sizeof(digest->algorithm);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
113 } else if (!strncmp(key, "qop=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
114 *dest = digest->qop;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
115 *dest_len = sizeof(digest->qop);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
116 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
117 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
118
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
119 static void handle_digest_update(HTTPAuthState *state, const char *key,
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
120 int key_len, char **dest, int *dest_len)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
121 {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
122 DigestParams *digest = &state->digest_params;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
123
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
124 if (!strncmp(key, "nextnonce=", key_len)) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
125 *dest = digest->nonce;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
126 *dest_len = sizeof(digest->nonce);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
127 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
128 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
129
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
130 static void choose_qop(char *qop, int size)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
131 {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
132 char *ptr = strstr(qop, "auth");
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
133 char *end = ptr + strlen("auth");
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
134
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
135 if (ptr && (!*end || isspace(*end) || *end == ',') &&
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
136 (ptr == qop || isspace(ptr[-1]) || ptr[-1] == ',')) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
137 av_strlcpy(qop, "auth", size);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
138 } else {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
139 qop[0] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
140 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
141 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
142
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
143 void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
144 const char *value)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
145 {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
146 if (!strcmp(key, "WWW-Authenticate")) {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
147 const char *p;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
148 if (av_stristart(value, "Basic ", &p) &&
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
149 state->auth_type <= HTTP_AUTH_BASIC) {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
150 state->auth_type = HTTP_AUTH_BASIC;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
151 state->realm[0] = 0;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
152 parse_key_value(p, handle_basic_params, state);
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
153 } else if (av_stristart(value, "Digest ", &p) &&
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
154 state->auth_type <= HTTP_AUTH_DIGEST) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
155 state->auth_type = HTTP_AUTH_DIGEST;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
156 memset(&state->digest_params, 0, sizeof(DigestParams));
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
157 state->realm[0] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
158 parse_key_value(p, handle_digest_params, state);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
159 choose_qop(state->digest_params.qop,
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
160 sizeof(state->digest_params.qop));
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
161 }
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
162 } else if (!strcmp(key, "Authentication-Info")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
163 parse_key_value(value, handle_digest_update, state);
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
164 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
165 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
166
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
167
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
168 static void update_md5_strings(struct AVMD5 *md5ctx, ...)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
169 {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
170 va_list vl;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
171
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
172 va_start(vl, md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
173 while (1) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
174 const char* str = va_arg(vl, const char*);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
175 if (!str)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
176 break;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
177 av_md5_update(md5ctx, str, strlen(str));
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
178 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
179 va_end(vl);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
180 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
181
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
182 /* Generate a digest reply, according to RFC 2617. */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
183 static char *make_digest_auth(HTTPAuthState *state, const char *username,
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
184 const char *password, const char *uri,
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
185 const char *method)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
186 {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
187 DigestParams *digest = &state->digest_params;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
188 int len;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
189 uint32_t cnonce_buf[2];
5928
9f1b267a30f5 Fix buffer size; should hold 2 32-bit integers in hex = 16 chars + terminating
rbultje
parents: 5892
diff changeset
190 char cnonce[17];
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
191 char nc[9];
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
192 int i;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
193 char A1hash[33], A2hash[33], response[33];
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
194 struct AVMD5 *md5ctx;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
195 uint8_t hash[16];
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
196 char *authstr;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
197
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
198 digest->nc++;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
199 snprintf(nc, sizeof(nc), "%08x", digest->nc);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
200
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
201 /* Generate a client nonce. */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
202 for (i = 0; i < 2; i++)
6036
201152a121b5 Make ff_random_get_seed public, rename to av_get_random_seed, export the header
mstorsjo
parents: 5928
diff changeset
203 cnonce_buf[i] = av_get_random_seed();
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
204 ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
205 cnonce[2*sizeof(cnonce_buf)] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
206
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
207 md5ctx = av_malloc(av_md5_size);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
208 if (!md5ctx)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
209 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
210
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
211 av_md5_init(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
212 update_md5_strings(md5ctx, username, ":", state->realm, ":", password, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
213 av_md5_final(md5ctx, hash);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
214 ff_data_to_hex(A1hash, hash, 16, 1);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
215 A1hash[32] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
216
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
217 if (!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
218 } else if (!strcmp(digest->algorithm, "MD5-sess")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
219 av_md5_init(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
220 update_md5_strings(md5ctx, A1hash, ":", digest->nonce, ":", cnonce, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
221 av_md5_final(md5ctx, hash);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
222 ff_data_to_hex(A1hash, hash, 16, 1);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
223 A1hash[32] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
224 } else {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
225 /* Unsupported algorithm */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
226 av_free(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
227 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
228 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
229
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
230 av_md5_init(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
231 update_md5_strings(md5ctx, method, ":", uri, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
232 av_md5_final(md5ctx, hash);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
233 ff_data_to_hex(A2hash, hash, 16, 1);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
234 A2hash[32] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
235
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
236 av_md5_init(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
237 update_md5_strings(md5ctx, A1hash, ":", digest->nonce, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
238 if (!strcmp(digest->qop, "auth") || !strcmp(digest->qop, "auth-int")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
239 update_md5_strings(md5ctx, ":", nc, ":", cnonce, ":", digest->qop, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
240 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
241 update_md5_strings(md5ctx, ":", A2hash, NULL);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
242 av_md5_final(md5ctx, hash);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
243 ff_data_to_hex(response, hash, 16, 1);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
244 response[32] = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
245
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
246 av_free(md5ctx);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
247
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
248 if (!strcmp(digest->qop, "") || !strcmp(digest->qop, "auth")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
249 } else if (!strcmp(digest->qop, "auth-int")) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
250 /* qop=auth-int not supported */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
251 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
252 } else {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
253 /* Unsupported qop value. */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
254 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
255 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
256
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
257 len = strlen(username) + strlen(state->realm) + strlen(digest->nonce) +
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
258 strlen(uri) + strlen(response) + strlen(digest->algorithm) +
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
259 strlen(digest->opaque) + strlen(digest->qop) + strlen(cnonce) +
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
260 strlen(nc) + 150;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
261
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
262 authstr = av_malloc(len);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
263 if (!authstr)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
264 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
265 snprintf(authstr, len, "Authorization: Digest ");
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
266
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
267 /* TODO: Escape the quoted strings properly. */
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
268 av_strlcatf(authstr, len, "username=\"%s\"", username);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
269 av_strlcatf(authstr, len, ",realm=\"%s\"", state->realm);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
270 av_strlcatf(authstr, len, ",nonce=\"%s\"", digest->nonce);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
271 av_strlcatf(authstr, len, ",uri=\"%s\"", uri);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
272 av_strlcatf(authstr, len, ",response=\"%s\"", response);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
273 if (digest->algorithm[0])
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
274 av_strlcatf(authstr, len, ",algorithm=%s", digest->algorithm);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
275 if (digest->opaque[0])
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
276 av_strlcatf(authstr, len, ",opaque=\"%s\"", digest->opaque);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
277 if (digest->qop[0]) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
278 av_strlcatf(authstr, len, ",qop=\"%s\"", digest->qop);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
279 av_strlcatf(authstr, len, ",cnonce=\"%s\"", cnonce);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
280 av_strlcatf(authstr, len, ",nc=%s", nc);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
281 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
282
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
283 av_strlcatf(authstr, len, "\r\n");
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
284
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
285 return authstr;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
286 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
287
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
288 char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth,
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
289 const char *path, const char *method)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
290 {
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
291 char *authstr = NULL;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
292
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
293 if (!auth || !strchr(auth, ':'))
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
294 return NULL;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
295
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
296 if (state->auth_type == HTTP_AUTH_BASIC) {
6079
4518f83661f4 Use AV_BASE64_SIZE() macro
hyc
parents: 6077
diff changeset
297 int auth_b64_len = AV_BASE64_SIZE(strlen(auth));
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
298 int len = auth_b64_len + 30;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
299 char *ptr;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
300 authstr = av_malloc(len);
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
301 if (!authstr)
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
302 return NULL;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
303 snprintf(authstr, len, "Authorization: Basic ");
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
304 ptr = authstr + strlen(authstr);
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
305 av_base64_encode(ptr, auth_b64_len, auth, strlen(auth));
6077
54d3a9240339 httpauth: Fix the length passed to av_strlcat
mstorsjo
parents: 6036
diff changeset
306 av_strlcat(ptr, "\r\n", len - (ptr - authstr));
5885
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
307 } else if (state->auth_type == HTTP_AUTH_DIGEST) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
308 char *username = av_strdup(auth), *password;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
309
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
310 if (!username)
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
311 return NULL;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
312
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
313 if ((password = strchr(username, ':'))) {
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
314 *password++ = 0;
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
315 authstr = make_digest_auth(state, username, password, path, method);
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
316 }
a1a309c4a751 Add support for http digest authentication
mstorsjo
parents: 5879
diff changeset
317 av_free(username);
5879
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
318 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
319 return authstr;
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
320 }
61062082488b Split out http authentication handling into a separate file
mstorsjo
parents:
diff changeset
321