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 | |
42 | static char * |
43 | scram_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. */ |
78 | int |
79 | scram_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. */ |
122 | int |
123 | scram_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. */ |
143 | int |
144 | scram_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. */ |
163 | int |
164 | scram_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 | |