gsasl  2.2.1
digest-md5/printer.c
Go to the documentation of this file.
1 /* printer.h --- Convert DIGEST-MD5 token structures into strings.
2  * Copyright (C) 2004-2024 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 #include <config.h>
24 
25 /* Get prototypes. */
26 #include "printer.h"
27 
28 /* Get free. */
29 #include <stdlib.h>
30 
31 /* Get asprintf. */
32 #include <stdio.h>
33 
34 /* Get token validator. */
35 #include "validate.h"
36 
37 /* Append a key/value pair to a comma'd string list. Additionally enclose
38  the value in quotes if requested. */
39 static int
40 comma_append (char **dst, const char *key, const char *value, int quotes)
41 {
42  char *tmp;
43  int result;
44 
45  if (*dst)
46  if (value)
47  if (quotes)
48  result = asprintf (&tmp, "%s, %s=\"%s\"", *dst, key, value);
49  else
50  result = asprintf (&tmp, "%s, %s=%s", *dst, key, value);
51  else
52  result = asprintf (&tmp, "%s, %s", *dst, key);
53  else if (value)
54  if (quotes)
55  result = asprintf (&tmp, "%s=\"%s\"", key, value);
56  else
57  result = asprintf (&tmp, "%s=%s", key, value);
58  else
59  result = asprintf (&tmp, "%s", key);
60 
61  if (result < 0)
62  return result;
63 
64  free (*dst);
65 
66  *dst = tmp;
67 
68  return result;
69 }
70 
71 char *
73 {
74  char *out = NULL;
75  size_t i;
76 
77  /* Below we assume the mandatory fields are present, verify that
78  first to avoid crashes. */
79  if (digest_md5_validate_challenge (c) != 0)
80  return NULL;
81 
82  for (i = 0; i < c->nrealms; i++)
83  {
84  if (comma_append (&out, "realm", c->realms[i], 1) < 0)
85  {
86  free (out);
87  return NULL;
88  }
89  }
90 
91  if (c->nonce)
92  if (comma_append (&out, "nonce", c->nonce, 1) < 0)
93  {
94  free (out);
95  return NULL;
96  }
97 
98  if (c->qops)
99  {
100  char *tmp = NULL;
101 
102  if (c->qops & DIGEST_MD5_QOP_AUTH)
103  if (comma_append (&tmp, "auth", NULL, 0) < 0)
104  {
105  free (tmp);
106  free (out);
107  return NULL;
108  }
109 
110  if (c->qops & DIGEST_MD5_QOP_AUTH_INT)
111  if (comma_append (&tmp, "auth-int", NULL, 0) < 0)
112  {
113  free (tmp);
114  free (out);
115  return NULL;
116  }
117 
119  if (comma_append (&tmp, "auth-conf", NULL, 0) < 0)
120  {
121  free (tmp);
122  free (out);
123  return NULL;
124  }
125 
126  if (comma_append (&out, "qop", tmp, 1) < 0)
127  {
128  free (tmp);
129  free (out);
130  return NULL;
131  }
132 
133  free (tmp);
134  }
135 
136  if (c->stale)
137  if (comma_append (&out, "stale", "true", 0) < 0)
138  {
139  free (out);
140  return NULL;
141  }
142 
143  if (c->servermaxbuf)
144  {
145  char *tmp;
146 
147  if (asprintf (&tmp, "%lu", c->servermaxbuf) < 0)
148  {
149  free (out);
150  return NULL;
151  }
152 
153  if (comma_append (&out, "maxbuf", tmp, 0) < 0)
154  {
155  free (out);
156  return NULL;
157  }
158 
159  free (tmp);
160  }
161 
162  if (c->utf8)
163  if (comma_append (&out, "charset", "utf-8", 0) < 0)
164  {
165  free (out);
166  return NULL;
167  }
168 
169  if (comma_append (&out, "algorithm", "md5-sess", 0) < 0)
170  {
171  free (out);
172  return NULL;
173  }
174 
175  if (c->ciphers)
176  {
177  char *tmp = NULL;
178 
180  if (comma_append (&tmp, "3des", NULL, 0) < 0)
181  {
182  free (tmp);
183  free (out);
184  return NULL;
185  }
186 
188  if (comma_append (&tmp, "des", NULL, 0) < 0)
189  {
190  free (tmp);
191  free (out);
192  return NULL;
193  }
194 
196  if (comma_append (&tmp, "rc4-40", NULL, 0) < 0)
197  {
198  free (tmp);
199  free (out);
200  return NULL;
201  }
202 
204  if (comma_append (&tmp, "rc4", NULL, 0) < 0)
205  {
206  free (tmp);
207  free (out);
208  return NULL;
209  }
210 
212  if (comma_append (&tmp, "rc4-56", NULL, 0) < 0)
213  {
214  free (tmp);
215  free (out);
216  return NULL;
217  }
218 
220  if (comma_append (&tmp, "aes-cbc", NULL, 0) < 0)
221  {
222  free (tmp);
223  free (out);
224  return NULL;
225  }
226 
227  if (comma_append (&out, "cipher", tmp, 1) < 0)
228  {
229  free (tmp);
230  free (out);
231  return NULL;
232  }
233 
234  free (tmp);
235  }
236 
237  return out;
238 }
239 
240 char *
242 {
243  char *out = NULL;
244  const char *qop = NULL;
245  const char *cipher = NULL;
246 
247  /* Below we assume the mandatory fields are present, verify that
248  first to avoid crashes. */
249  if (digest_md5_validate_response (r) != 0)
250  return NULL;
251 
252  if (r->qop & DIGEST_MD5_QOP_AUTH_CONF)
253  qop = "qop=auth-conf";
254  else if (r->qop & DIGEST_MD5_QOP_AUTH_INT)
255  qop = "qop=auth-int";
256  else if (r->qop & DIGEST_MD5_QOP_AUTH)
257  qop = "qop=auth";
258 
260  cipher = "cipher=3des";
261  else if (r->cipher & DIGEST_MD5_CIPHER_DES)
262  cipher = "cipher=des";
263  else if (r->cipher & DIGEST_MD5_CIPHER_RC4_40)
264  cipher = "cipher=rc4-40";
265  else if (r->cipher & DIGEST_MD5_CIPHER_RC4)
266  cipher = "cipher=rc4";
267  else if (r->cipher & DIGEST_MD5_CIPHER_RC4_56)
268  cipher = "cipher=rc4-56";
269  else if (r->cipher & DIGEST_MD5_CIPHER_AES_CBC)
270  cipher = "cipher=aes-cbc";
271 
272  if (r->username)
273  if (comma_append (&out, "username", r->username, 1) < 0)
274  {
275  free (out);
276  return NULL;
277  }
278 
279  if (r->realm)
280  if (comma_append (&out, "realm", r->realm, 1) < 0)
281  {
282  free (out);
283  return NULL;
284  }
285 
286  if (r->nonce)
287  if (comma_append (&out, "nonce", r->nonce, 1) < 0)
288  {
289  free (out);
290  return NULL;
291  }
292 
293  if (r->cnonce)
294  if (comma_append (&out, "cnonce", r->cnonce, 1) < 0)
295  {
296  free (out);
297  return NULL;
298  }
299 
300  if (r->nc)
301  {
302  char *tmp;
303 
304  if (asprintf (&tmp, "%08lx", r->nc) < 0)
305  {
306  free (out);
307  return NULL;
308  }
309 
310  if (comma_append (&out, "nc", tmp, 0) < 0)
311  {
312  free (tmp);
313  free (out);
314  return NULL;
315  }
316 
317  free (tmp);
318  }
319 
320  if (qop)
321  if (comma_append (&out, qop, NULL, 0) < 0)
322  {
323  free (out);
324  return NULL;
325  }
326 
327  if (r->digesturi)
328  if (comma_append (&out, "digest-uri", r->digesturi, 1) < 0)
329  {
330  free (out);
331  return NULL;
332  }
333 
334  if (comma_append (&out, "response", r->response, 0) < 0)
335  {
336  free (out);
337  return NULL;
338  }
339 
340  if (r->clientmaxbuf)
341  {
342  char *tmp;
343 
344  if (asprintf (&tmp, "%lu", r->clientmaxbuf) < 0)
345  {
346  free (out);
347  return NULL;
348  }
349 
350  if (comma_append (&out, "maxbuf", tmp, 0) < 0)
351  {
352  free (tmp);
353  free (out);
354  return NULL;
355  }
356 
357  free (tmp);
358  }
359 
360  if (r->utf8)
361  if (comma_append (&out, "charset", "utf-8", 0) < 0)
362  {
363  free (out);
364  return NULL;
365  }
366 
367  if (cipher)
368  if (comma_append (&out, cipher, NULL, 0) < 0)
369  {
370  free (out);
371  return NULL;
372  }
373 
374  if (r->authzid)
375  if (comma_append (&out, "authzid", r->authzid, 1) < 0)
376  {
377  free (out);
378  return NULL;
379  }
380 
381  return out;
382 }
383 
384 char *
386 {
387  char *out;
388 
389  /* Below we assume the mandatory fields are present, verify that
390  first to avoid crashes. */
391  if (digest_md5_validate_finish (finish) != 0)
392  return NULL;
393 
394  if (asprintf (&out, "rspauth=%s", finish->rspauth) < 0)
395  return NULL;
396 
397  return out;
398 }
char * digest_md5_print_finish(digest_md5_finish *finish)
char * digest_md5_print_challenge(digest_md5_challenge *c)
char * digest_md5_print_response(digest_md5_response *r)
@ DIGEST_MD5_QOP_AUTH_INT
@ DIGEST_MD5_QOP_AUTH_CONF
@ DIGEST_MD5_QOP_AUTH
@ DIGEST_MD5_CIPHER_RC4_56
@ DIGEST_MD5_CIPHER_3DES
@ DIGEST_MD5_CIPHER_DES
@ DIGEST_MD5_CIPHER_AES_CBC
@ DIGEST_MD5_CIPHER_RC4
@ DIGEST_MD5_CIPHER_RC4_40
int digest_md5_validate_challenge(digest_md5_challenge *c)
int digest_md5_validate_response(digest_md5_response *r)
int digest_md5_validate_finish(digest_md5_finish *f)
unsigned long servermaxbuf
char rspauth[DIGEST_MD5_RESPONSE_LENGTH+1]
digest_md5_cipher cipher
char response[DIGEST_MD5_RESPONSE_LENGTH+1]
unsigned long clientmaxbuf