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