gsasl  1.8.0
scram/printer.c
Go to the documentation of this file.
00001 /* printer.h --- Convert SCRAM token structures into strings.
00002  * Copyright (C) 2009-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 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 : "", username, cf->client_nonce);
00109 
00110   free (username);
00111   free (authzid);
00112 
00113   if (n <= 0 || *out == NULL)
00114     return -1;
00115 
00116   return 0;
00117 }
00118 
00119 /* Print SCRAM server-first token into newly allocated output string
00120    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00121    allocation errors. */
00122 int
00123 scram_print_server_first (struct scram_server_first *sf, char **out)
00124 {
00125   int n;
00126 
00127   /* Below we assume fields are sensible, so first verify that to
00128      avoid crashes. */
00129   if (!scram_valid_server_first (sf))
00130     return -1;
00131 
00132   n = asprintf (out, "r=%s,s=%s,i=%lu",
00133                 sf->nonce, sf->salt, (unsigned long) sf->iter);
00134   if (n <= 0 || *out == NULL)
00135     return -1;
00136 
00137   return 0;
00138 }
00139 
00140 /* Print SCRAM client-final token into newly allocated output string
00141    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00142    allocation errors. */
00143 int
00144 scram_print_client_final (struct scram_client_final *cl, char **out)
00145 {
00146   int n;
00147 
00148   /* Below we assume fields are sensible, so first verify that to
00149      avoid crashes. */
00150   if (!scram_valid_client_final (cl))
00151     return -1;
00152 
00153   n = asprintf (out, "c=%s,r=%s,p=%s", cl->cbind, cl->nonce, cl->proof);
00154   if (n <= 0 || *out == NULL)
00155     return -1;
00156 
00157   return 0;
00158 }
00159 
00160 /* Print SCRAM server-final token into newly allocated output string
00161    OUT.  Returns 0 on success, -1 on invalid token, and -2 on memory
00162    allocation errors. */
00163 int
00164 scram_print_server_final (struct scram_server_final *sl, char **out)
00165 {
00166   int n;
00167 
00168   /* Below we assume fields are sensible, so first verify that to
00169      avoid crashes. */
00170   if (!scram_valid_server_final (sl))
00171     return -1;
00172 
00173   n = asprintf (out, "v=%s", sl->verifier);
00174   if (n <= 0 || *out == NULL)
00175     return -1;
00176 
00177   return 0;
00178 }