1/* printer.h --- Convert SCRAM token structures into strings.
2 * Copyright (C) 2009-2012 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 strdup. */
37#include <string.h>
38
39/* Get token validator. */
40#include "validate.h"
41
42static char *
43scram_escape (const char *str)
44{
45 char *out = malloc (strlen (str) * 3 + 1);
46 char *p = out;
47
48 if (!out)
49 return NULL;
50
51 while (*str)
52 {
53 if (*str == ',')
54 {
55 memcpy (p, "=2C", 3);
56 p += 3;
57 }
58 else if (*str == '=')
59 {
60 memcpy (p, "=3D", 3);
61 p += 3;
62 }
63 else
64 {
65 *p = *str;
66 p++;
67 }
68 str++;
69 }
70 *p = '\0';
71
72 return out;
73}
74
75/* Print SCRAM client-first token into newly allocated output string
76 OUT. Returns 0 on success, -1 on invalid token, and -2 on memory
77 allocation errors. */
78int
79scram_print_client_first (struct scram_client_first *cf, char **out)
80{
81 char *username = NULL;
82 char *authzid = NULL;
83 int n;
84
85 /* Below we assume fields are sensible, so first verify that to
86 avoid crashes. */
87 if (!scram_valid_client_first (cf))
88 return -1;
89
90 /* Escape username and authzid. */
91
92 username = scram_escape (cf->username);
93 if (!username)
94 return -2;
95
96 if (cf->authzid)
97 {
98 authzid = scram_escape (cf->authzid);
99 if (!authzid)
100 return -2;
101 }
102
103 n = asprintf (out, "%c%s%s,%s%s,n=%s,r=%s",
104 cf->cbflag,
105 cf->cbflag == 'p' ? "=" : "",
106 cf->cbflag == 'p' ? cf->cbname : "",
107 authzid ? "a=" : "",
108 authzid ? authzid : "", username, cf->client_nonce);
109
110 free (username);
111 free (authzid);
112
113 if (n <= 0 || *out == NULL)
114 return -1;
115
116 return 0;
117}
118
119/* Print SCRAM server-first token into newly allocated output string
120 OUT. Returns 0 on success, -1 on invalid token, and -2 on memory
121 allocation errors. */
122int
123scram_print_server_first (struct scram_server_first *sf, char **out)
124{
125 int n;
126
127 /* Below we assume fields are sensible, so first verify that to
128 avoid crashes. */
129 if (!scram_valid_server_first (sf))
130 return -1;
131
132 n = asprintf (out, "r=%s,s=%s,i=%lu",
133 sf->nonce, sf->salt, (unsigned long) sf->iter);
134 if (n <= 0 || *out == NULL)
135 return -1;
136
137 return 0;
138}
139
140/* Print SCRAM client-final token into newly allocated output string
141 OUT. Returns 0 on success, -1 on invalid token, and -2 on memory
142 allocation errors. */
143int
144scram_print_client_final (struct scram_client_final *cl, char **out)
145{
146 int n;
147
148 /* Below we assume fields are sensible, so first verify that to
149 avoid crashes. */
150 if (!scram_valid_client_final (cl))
151 return -1;
152
153 n = asprintf (out, "c=%s,r=%s,p=%s", cl->cbind, cl->nonce, cl->proof);
154 if (n <= 0 || *out == NULL)
155 return -1;
156
157 return 0;
158}
159
160/* Print SCRAM server-final token into newly allocated output string
161 OUT. Returns 0 on success, -1 on invalid token, and -2 on memory
162 allocation errors. */
163int
164scram_print_server_final (struct scram_server_final *sl, char **out)
165{
166 int n;
167
168 /* Below we assume fields are sensible, so first verify that to
169 avoid crashes. */
170 if (!scram_valid_server_final (sl))
171 return -1;
172
173 n = asprintf (out, "v=%s", sl->verifier);
174 if (n <= 0 || *out == NULL)
175 return -1;
176
177 return 0;
178}
179