gsasl  1.10.0
About: GNU SASL is an implementation of the Simple Authentication and Security Layer (SASL). Development version.
  Fossies Dox: gsasl-1.10.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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