gsasl  1.8.0
digest-md5/printer.c
Go to the documentation of this file.
00001 /* printer.h --- Convert DIGEST-MD5 token structures into strings.
00002  * Copyright (C) 2004-2012 Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with GNU SASL Library; if not, write to the Free
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 /* Get prototypes. */
00028 #include "printer.h"
00029 
00030 /* Get free. */
00031 #include <stdlib.h>
00032 
00033 /* Get asprintf. */
00034 #include <stdio.h>
00035 
00036 /* Get token validator. */
00037 #include "validate.h"
00038 
00039 /* Append a key/value pair to a comma'd string list.  Additionally enclose
00040    the value in quotes if requested. */
00041 static int
00042 comma_append (char **dst, const char *key, const char *value, int quotes)
00043 {
00044   char *tmp;
00045   int result;
00046 
00047   if (*dst)
00048     if (value)
00049       if (quotes)
00050         result = asprintf (&tmp, "%s, %s=\"%s\"", *dst, key, value);
00051       else
00052         result = asprintf (&tmp, "%s, %s=%s", *dst, key, value);
00053     else
00054       result = asprintf (&tmp, "%s, %s", *dst, key);
00055   else if (value)
00056     if (quotes)
00057       result = asprintf (&tmp, "%s=\"%s\"", key, value);
00058     else
00059       result = asprintf (&tmp, "%s=%s", key, value);
00060   else
00061     result = asprintf (&tmp, "%s", key);
00062 
00063   if (result < 0)
00064     return result;
00065 
00066   free (*dst);
00067 
00068   *dst = tmp;
00069 
00070   return result;
00071 }
00072 
00073 char *
00074 digest_md5_print_challenge (digest_md5_challenge * c)
00075 {
00076   char *out = NULL;
00077   size_t i;
00078 
00079   /* Below we assume the mandatory fields are present, verify that
00080      first to avoid crashes. */
00081   if (digest_md5_validate_challenge (c) != 0)
00082     return NULL;
00083 
00084   for (i = 0; i < c->nrealms; i++)
00085     {
00086       if (comma_append (&out, "realm", c->realms[i], 1) < 0)
00087         {
00088           free (out);
00089           return NULL;
00090         }
00091     }
00092 
00093   if (c->nonce)
00094     if (comma_append (&out, "nonce", c->nonce, 1) < 0)
00095       {
00096         free (out);
00097         return NULL;
00098       }
00099 
00100   if (c->qops)
00101     {
00102       char *tmp = NULL;
00103 
00104       if (c->qops & DIGEST_MD5_QOP_AUTH)
00105         if (comma_append (&tmp, "auth", NULL, 0) < 0)
00106           {
00107             free (tmp);
00108             free (out);
00109             return NULL;
00110           }
00111 
00112       if (c->qops & DIGEST_MD5_QOP_AUTH_INT)
00113         if (comma_append (&tmp, "auth-int", NULL, 0) < 0)
00114           {
00115             free (tmp);
00116             free (out);
00117             return NULL;
00118           }
00119 
00120       if (c->qops & DIGEST_MD5_QOP_AUTH_CONF)
00121         if (comma_append (&tmp, "auth-conf", NULL, 0) < 0)
00122           {
00123             free (tmp);
00124             free (out);
00125             return NULL;
00126           }
00127 
00128       if (comma_append (&out, "qop", tmp, 1) < 0)
00129         {
00130           free (tmp);
00131           free (out);
00132           return NULL;
00133         }
00134 
00135       free (tmp);
00136     }
00137 
00138   if (c->stale)
00139     if (comma_append (&out, "stale", "true", 0) < 0)
00140       {
00141         free (out);
00142         return NULL;
00143       }
00144 
00145   if (c->servermaxbuf)
00146     {
00147       char *tmp;
00148 
00149       if (asprintf (&tmp, "%lu", c->servermaxbuf) < 0)
00150         {
00151           free (out);
00152           return NULL;
00153         }
00154 
00155       if (comma_append (&out, "maxbuf", tmp, 0) < 0)
00156         {
00157           free (out);
00158           return NULL;
00159         }
00160 
00161       free (tmp);
00162     }
00163 
00164   if (c->utf8)
00165     if (comma_append (&out, "charset", "utf-8", 0) < 0)
00166       {
00167         free (out);
00168         return NULL;
00169       }
00170 
00171   if (comma_append (&out, "algorithm", "md5-sess", 0) < 0)
00172     {
00173       free (out);
00174       return NULL;
00175     }
00176 
00177   if (c->ciphers)
00178     {
00179       char *tmp = NULL;
00180 
00181       if (c->ciphers & DIGEST_MD5_CIPHER_3DES)
00182         if (comma_append (&tmp, "3des", NULL, 0) < 0)
00183           {
00184             free (tmp);
00185             free (out);
00186             return NULL;
00187           }
00188 
00189       if (c->ciphers & DIGEST_MD5_CIPHER_DES)
00190         if (comma_append (&tmp, "des", NULL, 0) < 0)
00191           {
00192             free (tmp);
00193             free (out);
00194             return NULL;
00195           }
00196 
00197       if (c->ciphers & DIGEST_MD5_CIPHER_RC4_40)
00198         if (comma_append (&tmp, "rc4-40", NULL, 0) < 0)
00199           {
00200             free (tmp);
00201             free (out);
00202             return NULL;
00203           }
00204 
00205       if (c->ciphers & DIGEST_MD5_CIPHER_RC4)
00206         if (comma_append (&tmp, "rc4", NULL, 0) < 0)
00207           {
00208             free (tmp);
00209             free (out);
00210             return NULL;
00211           }
00212 
00213       if (c->ciphers & DIGEST_MD5_CIPHER_RC4_56)
00214         if (comma_append (&tmp, "rc4-56", NULL, 0) < 0)
00215           {
00216             free (tmp);
00217             free (out);
00218             return NULL;
00219           }
00220 
00221       if (c->ciphers & DIGEST_MD5_CIPHER_AES_CBC)
00222         if (comma_append (&tmp, "aes-cbc", NULL, 0) < 0)
00223           {
00224             free (tmp);
00225             free (out);
00226             return NULL;
00227           }
00228 
00229       if (comma_append (&out, "cipher", tmp, 1) < 0)
00230         {
00231           free (tmp);
00232           free (out);
00233           return NULL;
00234         }
00235 
00236       free (tmp);
00237     }
00238 
00239   return out;
00240 }
00241 
00242 char *
00243 digest_md5_print_response (digest_md5_response * r)
00244 {
00245   char *out = NULL;
00246   const char *qop = NULL;
00247   const char *cipher = NULL;
00248 
00249   /* Below we assume the mandatory fields are present, verify that
00250      first to avoid crashes. */
00251   if (digest_md5_validate_response (r) != 0)
00252     return NULL;
00253 
00254   if (r->qop & DIGEST_MD5_QOP_AUTH_CONF)
00255     qop = "qop=auth-conf";
00256   else if (r->qop & DIGEST_MD5_QOP_AUTH_INT)
00257     qop = "qop=auth-int";
00258   else if (r->qop & DIGEST_MD5_QOP_AUTH)
00259     qop = "qop=auth";
00260 
00261   if (r->cipher & DIGEST_MD5_CIPHER_3DES)
00262     cipher = "cipher=3des";
00263   else if (r->cipher & DIGEST_MD5_CIPHER_DES)
00264     cipher = "cipher=des";
00265   else if (r->cipher & DIGEST_MD5_CIPHER_RC4_40)
00266     cipher = "cipher=rc4-40";
00267   else if (r->cipher & DIGEST_MD5_CIPHER_RC4)
00268     cipher = "cipher=rc4";
00269   else if (r->cipher & DIGEST_MD5_CIPHER_RC4_56)
00270     cipher = "cipher=rc4-56";
00271   else if (r->cipher & DIGEST_MD5_CIPHER_AES_CBC)
00272     cipher = "cipher=aes-cbc";
00273   else if (r->cipher & DIGEST_MD5_CIPHER_3DES)
00274     cipher = "cipher=3des";
00275 
00276   if (r->username)
00277     if (comma_append (&out, "username", r->username, 1) < 0)
00278       {
00279         free (out);
00280         return NULL;
00281       }
00282 
00283   if (r->realm)
00284     if (comma_append (&out, "realm", r->realm, 1) < 0)
00285       {
00286         free (out);
00287         return NULL;
00288       }
00289 
00290   if (r->nonce)
00291     if (comma_append (&out, "nonce", r->nonce, 1) < 0)
00292       {
00293         free (out);
00294         return NULL;
00295       }
00296 
00297   if (r->cnonce)
00298     if (comma_append (&out, "cnonce", r->cnonce, 1) < 0)
00299       {
00300         free (out);
00301         return NULL;
00302       }
00303 
00304   if (r->nc)
00305     {
00306       char *tmp;
00307 
00308       if (asprintf (&tmp, "%08lx", r->nc) < 0)
00309         {
00310           free (out);
00311           return NULL;
00312         }
00313 
00314       if (comma_append (&out, "nc", tmp, 0) < 0)
00315         {
00316           free (tmp);
00317           free (out);
00318           return NULL;
00319         }
00320 
00321       free (tmp);
00322     }
00323 
00324   if (qop)
00325     if (comma_append (&out, qop, NULL, 0) < 0)
00326       {
00327         free (out);
00328         return NULL;
00329       }
00330 
00331   if (r->digesturi)
00332     if (comma_append (&out, "digest-uri", r->digesturi, 1) < 0)
00333       {
00334         free (out);
00335         return NULL;
00336       }
00337 
00338   if (r->response)
00339     if (comma_append (&out, "response", r->response, 0) < 0)
00340       {
00341         free (out);
00342         return NULL;
00343       }
00344 
00345   if (r->clientmaxbuf)
00346     {
00347       char *tmp;
00348 
00349       if (asprintf (&tmp, "%lu", r->clientmaxbuf) < 0)
00350         {
00351           free (out);
00352           return NULL;
00353         }
00354 
00355       if (comma_append (&out, "maxbuf", tmp, 0) < 0)
00356         {
00357           free (tmp);
00358           free (out);
00359           return NULL;
00360         }
00361 
00362       free (tmp);
00363     }
00364 
00365   if (r->utf8)
00366     if (comma_append (&out, "charset", "utf-8", 0) < 0)
00367       {
00368         free (out);
00369         return NULL;
00370       }
00371 
00372   if (cipher)
00373     if (comma_append (&out, cipher, NULL, 0) < 0)
00374       {
00375         free (out);
00376         return NULL;
00377       }
00378 
00379   if (r->authzid)
00380     if (comma_append (&out, "authzid", r->authzid, 1) < 0)
00381       {
00382         free (out);
00383         return NULL;
00384       }
00385 
00386   return out;
00387 }
00388 
00389 char *
00390 digest_md5_print_finish (digest_md5_finish * finish)
00391 {
00392   char *out;
00393 
00394   /* Below we assume the mandatory fields are present, verify that
00395      first to avoid crashes. */
00396   if (digest_md5_validate_finish (finish) != 0)
00397     return NULL;
00398 
00399   if (asprintf (&out, "rspauth=%s", finish->rspauth) < 0)
00400     return NULL;
00401 
00402   return out;
00403 }