comparison httpauth.c @ 5879:61062082488b libavformat

Split out http authentication handling into a separate file This prepares for adding support for more authentication methods
author mstorsjo
date Wed, 24 Mar 2010 22:32:05 +0000
parents
children a1a309c4a751
comparison
equal deleted inserted replaced
5878:01b33a7f96ee 5879:61062082488b
1 /*
2 * HTTP authentication
3 * Copyright (c) 2010 Martin Storsjo
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "httpauth.h"
23 #include "libavutil/base64.h"
24 #include "libavutil/avstring.h"
25 #include "avformat.h"
26 #include <ctype.h>
27
28 static void parse_key_value(const char *params,
29 void (*callback_get_buf)(HTTPAuthState *state,
30 const char *key, int key_len,
31 char **dest, int *dest_len), HTTPAuthState *state)
32 {
33 const char *ptr = params;
34
35 /* Parse key=value pairs. */
36 for (;;) {
37 const char *key;
38 char *dest = NULL, *dest_end;
39 int key_len, dest_len = 0;
40
41 /* Skip whitespace and potential commas. */
42 while (*ptr && (isspace(*ptr) || *ptr == ','))
43 ptr++;
44 if (!*ptr)
45 break;
46
47 key = ptr;
48
49 if (!(ptr = strchr(key, '=')))
50 break;
51 ptr++;
52 key_len = ptr - key;
53
54 callback_get_buf(state, key, key_len, &dest, &dest_len);
55 dest_end = dest + dest_len - 1;
56
57 if (*ptr == '\"') {
58 ptr++;
59 while (*ptr && *ptr != '\"') {
60 if (*ptr == '\\') {
61 if (!ptr[1])
62 break;
63 if (dest && dest < dest_end)
64 *dest++ = ptr[1];
65 ptr += 2;
66 } else {
67 if (dest && dest < dest_end)
68 *dest++ = *ptr;
69 ptr++;
70 }
71 }
72 if (*ptr == '\"')
73 ptr++;
74 } else {
75 for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++)
76 if (dest && dest < dest_end)
77 *dest++ = *ptr;
78 }
79 if (dest)
80 *dest = 0;
81 }
82 }
83
84 static void handle_basic_params(HTTPAuthState *state, const char *key,
85 int key_len, char **dest, int *dest_len)
86 {
87 if (!strncmp(key, "realm=", key_len)) {
88 *dest = state->realm;
89 *dest_len = sizeof(state->realm);
90 }
91 }
92
93 void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
94 const char *value)
95 {
96 if (!state)
97 return;
98
99 if (!strcmp(key, "WWW-Authenticate")) {
100 const char *p;
101 if (av_stristart(value, "Basic ", &p) &&
102 state->auth_type <= HTTP_AUTH_BASIC) {
103 state->auth_type = HTTP_AUTH_BASIC;
104 state->realm[0] = 0;
105 parse_key_value(p, handle_basic_params, state);
106 }
107 }
108 }
109
110 char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth,
111 const char *path, const char *method)
112 {
113 char *authstr = NULL;
114
115 if (!auth || !strchr(auth, ':'))
116 return NULL;
117
118 if (state->auth_type == HTTP_AUTH_BASIC) {
119 int auth_b64_len = (strlen(auth) + 2) / 3 * 4 + 1;
120 int len = auth_b64_len + 30;
121 char *ptr;
122 authstr = av_malloc(len);
123 if (!authstr)
124 return NULL;
125 snprintf(authstr, len, "Authorization: Basic ");
126 ptr = authstr + strlen(authstr);
127 av_base64_encode(ptr, auth_b64_len, auth, strlen(auth));
128 av_strlcat(ptr, "\r\n", len);
129 }
130 return authstr;
131 }
132