Branch data Line data Source code
1 : : /* printer.h --- Convert DIGEST-MD5 token structures into strings.
2 : : * Copyright (C) 2004-2012 Simon Josefsson
3 : : *
4 : : * This file is part of GNU SASL Library.
5 : : *
6 : : * GNU SASL Library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public License
8 : : * as published by the Free Software Foundation; either version 2.1 of
9 : : * the License, or (at your option) any later version.
10 : : *
11 : : * GNU SASL Library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with GNU SASL Library; if not, write to the Free
18 : : * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 : : * Boston, MA 02110-1301, USA.
20 : : *
21 : : */
22 : :
23 : : #ifdef HAVE_CONFIG_H
24 : : #include "config.h"
25 : : #endif
26 : :
27 : : /* Get prototypes. */
28 : : #include "printer.h"
29 : :
30 : : /* Get free. */
31 : : #include <stdlib.h>
32 : :
33 : : /* Get asprintf. */
34 : : #include <stdio.h>
35 : :
36 : : /* Get token validator. */
37 : : #include "validate.h"
38 : :
39 : : /* Append a key/value pair to a comma'd string list. Additionally enclose
40 : : the value in quotes if requested. */
41 : : static int
42 : 258 : comma_append (char **dst, const char *key, const char *value, int quotes)
43 : : {
44 : : char *tmp;
45 : : int result;
46 : :
47 [ + + ]: 258 : if (*dst)
48 [ + + ]: 197 : if (value)
49 [ + + ]: 180 : if (quotes)
50 : 90 : result = asprintf (&tmp, "%s, %s=\"%s\"", *dst, key, value);
51 : : else
52 : 90 : result = asprintf (&tmp, "%s, %s=%s", *dst, key, value);
53 : : else
54 : 17 : result = asprintf (&tmp, "%s, %s", *dst, key);
55 [ + + ]: 61 : else if (value)
56 [ + - ]: 39 : if (quotes)
57 : 39 : result = asprintf (&tmp, "%s=\"%s\"", key, value);
58 : : else
59 : 0 : result = asprintf (&tmp, "%s=%s", key, value);
60 : : else
61 : 22 : result = asprintf (&tmp, "%s", key);
62 : :
63 [ - + ]: 258 : if (result < 0)
64 : 0 : return result;
65 : :
66 : 258 : free (*dst);
67 : :
68 : 258 : *dst = tmp;
69 : :
70 : 258 : return result;
71 : : }
72 : :
73 : : char *
74 : 23 : digest_md5_print_challenge (digest_md5_challenge * c)
75 : : {
76 : 23 : char *out = NULL;
77 : : size_t i;
78 : :
79 : : /* Below we assume the mandatory fields are present, verify that
80 : : first to avoid crashes. */
81 [ - + ]: 23 : if (digest_md5_validate_challenge (c) != 0)
82 : 0 : return NULL;
83 : :
84 [ + + ]: 31 : for (i = 0; i < c->nrealms; i++)
85 : : {
86 [ - + ]: 8 : if (comma_append (&out, "realm", c->realms[i], 1) < 0)
87 : : {
88 : 0 : free (out);
89 : 0 : return NULL;
90 : : }
91 : : }
92 : :
93 [ + - ]: 23 : if (c->nonce)
94 [ - + ]: 23 : if (comma_append (&out, "nonce", c->nonce, 1) < 0)
95 : : {
96 : 0 : free (out);
97 : 0 : return NULL;
98 : : }
99 : :
100 [ + + ]: 23 : if (c->qops)
101 : : {
102 : 21 : char *tmp = NULL;
103 : :
104 [ + + ]: 21 : if (c->qops & DIGEST_MD5_QOP_AUTH)
105 [ - + ]: 19 : if (comma_append (&tmp, "auth", NULL, 0) < 0)
106 : : {
107 : 0 : free (tmp);
108 : 0 : free (out);
109 : 0 : return NULL;
110 : : }
111 : :
112 [ + + ]: 21 : if (c->qops & DIGEST_MD5_QOP_AUTH_INT)
113 [ - + ]: 3 : if (comma_append (&tmp, "auth-int", NULL, 0) < 0)
114 : : {
115 : 0 : free (tmp);
116 : 0 : free (out);
117 : 0 : return NULL;
118 : : }
119 : :
120 [ + + ]: 21 : if (c->qops & DIGEST_MD5_QOP_AUTH_CONF)
121 [ - + ]: 1 : if (comma_append (&tmp, "auth-conf", NULL, 0) < 0)
122 : : {
123 : 0 : free (tmp);
124 : 0 : free (out);
125 : 0 : return NULL;
126 : : }
127 : :
128 [ - + ]: 21 : if (comma_append (&out, "qop", tmp, 1) < 0)
129 : : {
130 : 0 : free (tmp);
131 : 0 : free (out);
132 : 0 : return NULL;
133 : : }
134 : :
135 : 21 : free (tmp);
136 : : }
137 : :
138 [ - + ]: 23 : if (c->stale)
139 [ # # ]: 0 : if (comma_append (&out, "stale", "true", 0) < 0)
140 : : {
141 : 0 : free (out);
142 : 0 : return NULL;
143 : : }
144 : :
145 [ - + ]: 23 : if (c->servermaxbuf)
146 : : {
147 : : char *tmp;
148 : :
149 [ # # ]: 0 : if (asprintf (&tmp, "%lu", c->servermaxbuf) < 0)
150 : : {
151 : 0 : free (out);
152 : 0 : return NULL;
153 : : }
154 : :
155 [ # # ]: 0 : if (comma_append (&out, "maxbuf", tmp, 0) < 0)
156 : : {
157 : 0 : free (out);
158 : 0 : return NULL;
159 : : }
160 : :
161 : 0 : free (tmp);
162 : : }
163 : :
164 [ + + ]: 23 : if (c->utf8)
165 [ - + ]: 20 : if (comma_append (&out, "charset", "utf-8", 0) < 0)
166 : : {
167 : 0 : free (out);
168 : 0 : return NULL;
169 : : }
170 : :
171 [ - + ]: 23 : if (comma_append (&out, "algorithm", "md5-sess", 0) < 0)
172 : : {
173 : 0 : free (out);
174 : 0 : return NULL;
175 : : }
176 : :
177 [ + + ]: 23 : if (c->ciphers)
178 : : {
179 : 1 : char *tmp = NULL;
180 : :
181 [ - + ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_3DES)
182 [ # # ]: 0 : if (comma_append (&tmp, "3des", NULL, 0) < 0)
183 : : {
184 : 0 : free (tmp);
185 : 0 : free (out);
186 : 0 : return NULL;
187 : : }
188 : :
189 [ + - ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_DES)
190 [ - + ]: 1 : if (comma_append (&tmp, "des", NULL, 0) < 0)
191 : : {
192 : 0 : free (tmp);
193 : 0 : free (out);
194 : 0 : return NULL;
195 : : }
196 : :
197 [ - + ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_RC4_40)
198 [ # # ]: 0 : if (comma_append (&tmp, "rc4-40", NULL, 0) < 0)
199 : : {
200 : 0 : free (tmp);
201 : 0 : free (out);
202 : 0 : return NULL;
203 : : }
204 : :
205 [ - + ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_RC4)
206 [ # # ]: 0 : if (comma_append (&tmp, "rc4", NULL, 0) < 0)
207 : : {
208 : 0 : free (tmp);
209 : 0 : free (out);
210 : 0 : return NULL;
211 : : }
212 : :
213 [ - + ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_RC4_56)
214 [ # # ]: 0 : if (comma_append (&tmp, "rc4-56", NULL, 0) < 0)
215 : : {
216 : 0 : free (tmp);
217 : 0 : free (out);
218 : 0 : return NULL;
219 : : }
220 : :
221 [ - + ]: 1 : if (c->ciphers & DIGEST_MD5_CIPHER_AES_CBC)
222 [ # # ]: 0 : if (comma_append (&tmp, "aes-cbc", NULL, 0) < 0)
223 : : {
224 : 0 : free (tmp);
225 : 0 : free (out);
226 : 0 : return NULL;
227 : : }
228 : :
229 [ - + ]: 1 : if (comma_append (&out, "cipher", tmp, 1) < 0)
230 : : {
231 : 0 : free (tmp);
232 : 0 : free (out);
233 : 0 : return NULL;
234 : : }
235 : :
236 : 1 : free (tmp);
237 : : }
238 : :
239 : 23 : return out;
240 : : }
241 : :
242 : : char *
243 : 16 : digest_md5_print_response (digest_md5_response * r)
244 : : {
245 : 16 : char *out = NULL;
246 : 16 : const char *qop = NULL;
247 : 16 : const char *cipher = NULL;
248 : :
249 : : /* Below we assume the mandatory fields are present, verify that
250 : : first to avoid crashes. */
251 [ - + ]: 16 : if (digest_md5_validate_response (r) != 0)
252 : 0 : return NULL;
253 : :
254 [ - + ]: 16 : if (r->qop & DIGEST_MD5_QOP_AUTH_CONF)
255 : 0 : qop = "qop=auth-conf";
256 [ + + ]: 16 : else if (r->qop & DIGEST_MD5_QOP_AUTH_INT)
257 : 2 : qop = "qop=auth-int";
258 [ + + ]: 14 : else if (r->qop & DIGEST_MD5_QOP_AUTH)
259 : 13 : qop = "qop=auth";
260 : :
261 [ - + ]: 16 : if (r->cipher & DIGEST_MD5_CIPHER_3DES)
262 : 0 : cipher = "cipher=3des";
263 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_DES)
264 : 0 : cipher = "cipher=des";
265 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_RC4_40)
266 : 0 : cipher = "cipher=rc4-40";
267 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_RC4)
268 : 0 : cipher = "cipher=rc4";
269 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_RC4_56)
270 : 0 : cipher = "cipher=rc4-56";
271 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_AES_CBC)
272 : 0 : cipher = "cipher=aes-cbc";
273 [ - + ]: 16 : else if (r->cipher & DIGEST_MD5_CIPHER_3DES)
274 : 0 : cipher = "cipher=3des";
275 : :
276 [ + - ]: 16 : if (r->username)
277 [ - + ]: 16 : if (comma_append (&out, "username", r->username, 1) < 0)
278 : : {
279 : 0 : free (out);
280 : 0 : return NULL;
281 : : }
282 : :
283 [ + + ]: 16 : if (r->realm)
284 [ - + ]: 7 : if (comma_append (&out, "realm", r->realm, 1) < 0)
285 : : {
286 : 0 : free (out);
287 : 0 : return NULL;
288 : : }
289 : :
290 [ + - ]: 16 : if (r->nonce)
291 [ - + ]: 16 : if (comma_append (&out, "nonce", r->nonce, 1) < 0)
292 : : {
293 : 0 : free (out);
294 : 0 : return NULL;
295 : : }
296 : :
297 [ + - ]: 16 : if (r->cnonce)
298 [ - + ]: 16 : if (comma_append (&out, "cnonce", r->cnonce, 1) < 0)
299 : : {
300 : 0 : free (out);
301 : 0 : return NULL;
302 : : }
303 : :
304 [ + - ]: 16 : if (r->nc)
305 : : {
306 : : char *tmp;
307 : :
308 [ - + ]: 16 : if (asprintf (&tmp, "%08lx", r->nc) < 0)
309 : : {
310 : 0 : free (out);
311 : 0 : return NULL;
312 : : }
313 : :
314 [ - + ]: 16 : if (comma_append (&out, "nc", tmp, 0) < 0)
315 : : {
316 : 0 : free (tmp);
317 : 0 : free (out);
318 : 0 : return NULL;
319 : : }
320 : :
321 : 16 : free (tmp);
322 : : }
323 : :
324 [ + + ]: 16 : if (qop)
325 [ - + ]: 15 : if (comma_append (&out, qop, NULL, 0) < 0)
326 : : {
327 : 0 : free (out);
328 : 0 : return NULL;
329 : : }
330 : :
331 [ + - ]: 16 : if (r->digesturi)
332 [ - + ]: 16 : if (comma_append (&out, "digest-uri", r->digesturi, 1) < 0)
333 : : {
334 : 0 : free (out);
335 : 0 : return NULL;
336 : : }
337 : :
338 [ + - ]: 16 : if (r->response)
339 [ - + ]: 16 : if (comma_append (&out, "response", r->response, 0) < 0)
340 : : {
341 : 0 : free (out);
342 : 0 : return NULL;
343 : : }
344 : :
345 [ - + ]: 16 : if (r->clientmaxbuf)
346 : : {
347 : : char *tmp;
348 : :
349 [ # # ]: 0 : if (asprintf (&tmp, "%lu", r->clientmaxbuf) < 0)
350 : : {
351 : 0 : free (out);
352 : 0 : return NULL;
353 : : }
354 : :
355 [ # # ]: 0 : if (comma_append (&out, "maxbuf", tmp, 0) < 0)
356 : : {
357 : 0 : free (tmp);
358 : 0 : free (out);
359 : 0 : return NULL;
360 : : }
361 : :
362 : 0 : free (tmp);
363 : : }
364 : :
365 [ + + ]: 16 : if (r->utf8)
366 [ - + ]: 15 : if (comma_append (&out, "charset", "utf-8", 0) < 0)
367 : : {
368 : 0 : free (out);
369 : 0 : return NULL;
370 : : }
371 : :
372 [ - + ]: 16 : if (cipher)
373 [ # # ]: 0 : if (comma_append (&out, cipher, NULL, 0) < 0)
374 : : {
375 : 0 : free (out);
376 : 0 : return NULL;
377 : : }
378 : :
379 [ + + ]: 16 : if (r->authzid)
380 [ - + ]: 5 : if (comma_append (&out, "authzid", r->authzid, 1) < 0)
381 : : {
382 : 0 : free (out);
383 : 0 : return NULL;
384 : : }
385 : :
386 : 16 : return out;
387 : : }
388 : :
389 : : char *
390 : 15 : digest_md5_print_finish (digest_md5_finish * finish)
391 : : {
392 : : char *out;
393 : :
394 : : /* Below we assume the mandatory fields are present, verify that
395 : : first to avoid crashes. */
396 [ - + ]: 15 : if (digest_md5_validate_finish (finish) != 0)
397 : 0 : return NULL;
398 : :
399 [ - + ]: 15 : if (asprintf (&out, "rspauth=%s", finish->rspauth) < 0)
400 : 0 : return NULL;
401 : :
402 : 15 : return out;
403 : : }
|