Line data Source code
1 : /* printer.h --- Convert SCRAM token structures into strings.
2 : * Copyright (C) 2009-2023 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 75 : scram_escape (const char *str)
44 : {
45 75 : char *out = malloc (strlen (str) * 3 + 1);
46 75 : char *p = out;
47 :
48 75 : if (!out)
49 0 : return NULL;
50 :
51 435 : while (*str)
52 : {
53 360 : if (*str == ',')
54 : {
55 44 : memcpy (p, "=2C", 3);
56 44 : p += 3;
57 : }
58 316 : else if (*str == '=')
59 : {
60 40 : memcpy (p, "=3D", 3);
61 40 : p += 3;
62 : }
63 : else
64 : {
65 276 : *p = *str;
66 276 : p++;
67 : }
68 360 : str++;
69 : }
70 75 : *p = '\0';
71 :
72 75 : 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 53 : scram_print_client_first (struct scram_client_first *cf, char **out)
80 : {
81 53 : char *username = NULL;
82 53 : char *authzid = NULL;
83 : int n;
84 :
85 : /* Below we assume fields are sensible, so first verify that to
86 : avoid crashes. */
87 53 : if (!scram_valid_client_first (cf))
88 0 : return -1;
89 :
90 : /* Escape username and authzid. */
91 :
92 53 : username = scram_escape (cf->username);
93 53 : if (!username)
94 0 : return -2;
95 :
96 53 : if (cf->authzid)
97 : {
98 22 : authzid = scram_escape (cf->authzid);
99 22 : if (!authzid)
100 0 : return -2;
101 : }
102 :
103 159 : n = asprintf (out, "%c%s%s,%s%s,n=%s,r=%s",
104 53 : cf->cbflag,
105 53 : cf->cbflag == 'p' ? "=" : "",
106 53 : cf->cbflag == 'p' ? cf->cbname : "",
107 : authzid ? "a=" : "",
108 : authzid ? authzid : "", username, cf->client_nonce);
109 :
110 53 : free (username);
111 53 : free (authzid);
112 :
113 53 : if (n <= 0 || *out == NULL)
114 0 : return -1;
115 :
116 53 : 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 49 : 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 49 : if (!scram_valid_server_first (sf))
130 0 : return -1;
131 :
132 49 : n = asprintf (out, "r=%s,s=%s,i=%lu",
133 49 : sf->nonce, sf->salt, (unsigned long) sf->iter);
134 49 : if (n <= 0 || *out == NULL)
135 0 : return -1;
136 :
137 49 : 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 106 : 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 106 : if (!scram_valid_client_final (cl))
151 0 : return -1;
152 :
153 106 : n = asprintf (out, "c=%s,r=%s,p=%s", cl->cbind, cl->nonce, cl->proof);
154 106 : if (n <= 0 || *out == NULL)
155 0 : return -1;
156 :
157 106 : 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 40 : 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 40 : if (!scram_valid_server_final (sl))
171 0 : return -1;
172 :
173 40 : n = asprintf (out, "v=%s", sl->verifier);
174 40 : if (n <= 0 || *out == NULL)
175 0 : return -1;
176 :
177 40 : return 0;
178 : }
|