scram/printer.c

Go to the documentation of this file.
00001 /* printer.h --- Convert SCRAM token structures into strings.
00002  * Copyright (C) 2009, 2010  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 strdup. */
00037 #include <string.h>
00038 
00039 /* Get token validator. */
00040 #include "validate.h"
00041 
00042 static char *
00043 scram_escape (const char *str)
00044 {
00045   char *out = malloc (strlen (str) * 3 + 1);
00046   char *p = out;
00047 
00048   if (!out)
00049     return NULL;
00050 
00051   while (*str)
00052     {
00053       if (*str == ',')
00054         {
00055           memcpy (p, "=2C", 3);
00056           p += 3;
00057         }
00058       else if (*str == '=')
00059         {
00060           memcpy (p, "=3D", 3);
00061           p += 3;
00062         }
00063       else
00064         {
00065           *p = *str;
00066           p++;
00067         }
00068       str++;
00069     }
00070   *p = '\0';
00071 
00072   return out;
00073 }
00074 
00075 /* Print SCRAM client-first token into newly allocated output string
00076    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00077    allocation errors. */
00078 int
00079 scram_print_client_first (struct scram_client_first *cf, char **out)
00080 {
00081   char *username = NULL;
00082   char *authzid = NULL;
00083   int n;
00084 
00085   /* Below we assume fields are sensible, so first verify that to
00086      avoid crashes. */
00087   if (!scram_valid_client_first (cf))
00088     return -1;
00089 
00090   /* Escape username and authzid. */
00091 
00092   username = scram_escape (cf->username);
00093   if (!username)
00094     return -2;
00095 
00096   if (cf->authzid)
00097     {
00098       authzid = scram_escape (cf->authzid);
00099       if (!authzid)
00100         return -2;
00101     }
00102 
00103   n = asprintf (out, "%c%s%s,%s%s,n=%s,r=%s",
00104                 cf->cbflag,
00105                 cf->cbflag == 'p' ? "=" : "",
00106                 cf->cbflag == 'p' ? cf->cbname : "",
00107                 authzid ? "a=" : "",
00108                 authzid ? authzid : "",
00109                 username,
00110                 cf->client_nonce);
00111 
00112   free (username);
00113   free (authzid);
00114 
00115   if (n <= 0 || *out == NULL)
00116     return -1;
00117 
00118   return 0;
00119 }
00120 
00121 /* Print SCRAM server-first token into newly allocated output string
00122    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00123    allocation errors. */
00124 int
00125 scram_print_server_first (struct scram_server_first *sf, char **out)
00126 {
00127   int n;
00128 
00129   /* Below we assume fields are sensible, so first verify that to
00130      avoid crashes. */
00131   if (!scram_valid_server_first (sf))
00132     return -1;
00133 
00134   n = asprintf (out, "r=%s,s=%s,i=%d",
00135                 sf->nonce, sf->salt, sf->iter);
00136   if (n <= 0 || *out == NULL)
00137     return -1;
00138 
00139   return 0;
00140 }
00141 
00142 /* Print SCRAM client-final token into newly allocated output string
00143    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00144    allocation errors. */
00145 int
00146 scram_print_client_final (struct scram_client_final *cl, char **out)
00147 {
00148   int n;
00149 
00150   /* Below we assume fields are sensible, so first verify that to
00151      avoid crashes. */
00152   if (!scram_valid_client_final (cl))
00153     return -1;
00154 
00155   n = asprintf (out, "c=%s,r=%s,p=%s",
00156                 cl->cbind, cl->nonce, cl->proof);
00157   if (n <= 0 || *out == NULL)
00158     return -1;
00159 
00160   return 0;
00161 }
00162 
00163 /* Print SCRAM server-final token into newly allocated output string
00164    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00165    allocation errors. */
00166 int
00167 scram_print_server_final (struct scram_server_final *sl, char **out)
00168 {
00169   int n;
00170 
00171   /* Below we assume fields are sensible, so first verify that to
00172      avoid crashes. */
00173   if (!scram_valid_server_final (sl))
00174     return -1;
00175 
00176   n = asprintf (out, "v=%s", sl->verifier);
00177   if (n <= 0 || *out == NULL)
00178     return -1;
00179 
00180   return 0;
00181 }