Branch data Line data Source code
1 : : /* digest-md5.c --- Test the DIGEST-MD5 mechanism.
2 : : * Copyright (C) 2002-2012 Simon Josefsson
3 : : *
4 : : * This file is part of GNU SASL.
5 : : *
6 : : * This program is free software: you can redistribute it and/or modify
7 : : * it under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation, either version 3 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * This program 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
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : : *
19 : : */
20 : :
21 : : #ifdef HAVE_CONFIG_H
22 : : #include "config.h"
23 : : #endif
24 : :
25 : : #include <stdio.h>
26 : : #include <stdarg.h>
27 : : #include <stdlib.h>
28 : : #include <string.h>
29 : :
30 : : #include "utils.h"
31 : :
32 : : #define PASSWORD "Open, Sesame"
33 : : #define USERNAME "Ali Baba"
34 : : /* "Ali " "\xC2\xAD" "Bab" "\xC2\xAA" */
35 : : /* "Al\xC2\xAA""dd\xC2\xAD""in\xC2\xAE" */
36 : :
37 : : static int
38 : 10 : server_cb_retrieve (Gsasl_session_ctx * xctx,
39 : : const char *authentication_id,
40 : : const char *authorization_id,
41 : : const char *realm, char *key, size_t * keylen)
42 : : {
43 : 10 : size_t needlen = strlen (PASSWORD);
44 : :
45 [ + - ][ - + ]: 10 : if (key && *keylen < needlen)
46 : 0 : return GSASL_TOO_SMALL_BUFFER;
47 : :
48 : 10 : *keylen = needlen;
49 [ + - ]: 10 : if (key)
50 : 10 : memcpy (key, PASSWORD, *keylen);
51 : :
52 : 10 : return GSASL_OK;
53 : : }
54 : :
55 : : static Gsasl_qop
56 : 5 : server_cb_qop (Gsasl_session_ctx * xctx)
57 : : {
58 : 5 : int i = *(int *) gsasl_appinfo_get (xctx);
59 [ + + ][ + + ]: 5 : if (i == 1 || i == 3)
60 : 2 : return GSASL_QOP_AUTH;
61 [ + + ]: 3 : else if (i == 2)
62 : 1 : return GSASL_QOP_AUTH | GSASL_QOP_AUTH_INT;
63 : : else
64 : 5 : return 0;
65 : : }
66 : :
67 : : static Gsasl_qop
68 : 2 : client_cb_qop (Gsasl_session * sctx, Gsasl_qop serverqops)
69 : : {
70 [ - + ]: 2 : if (serverqops & GSASL_QOP_AUTH_INT)
71 : 0 : return GSASL_QOP_AUTH_INT;
72 : 2 : return GSASL_QOP_AUTH;
73 : : }
74 : :
75 : : static int
76 : 10 : client_callback_service (Gsasl_session_ctx * ctx,
77 : : char *srv,
78 : : size_t * srvlen,
79 : : char *host,
80 : : size_t * hostlen, char *srvname, size_t * srvnamelen)
81 : : {
82 : 10 : return GSASL_OK;
83 : : }
84 : :
85 : : static int
86 : 5 : client_cb_authentication_id (Gsasl_session_ctx * xctx,
87 : : char *out, size_t * outlen)
88 : : {
89 : 5 : size_t needlen = strlen (USERNAME);
90 : :
91 [ + - ][ - + ]: 5 : if (out && *outlen < needlen)
92 : 0 : return GSASL_TOO_SMALL_BUFFER;
93 : :
94 : 5 : *outlen = needlen;
95 [ + - ]: 5 : if (out)
96 : 5 : memcpy (out, USERNAME, *outlen);
97 : :
98 : 5 : return GSASL_OK;
99 : : }
100 : :
101 : : static int
102 : 0 : client_cb_password (Gsasl_session_ctx * xctx, char *out, size_t * outlen)
103 : : {
104 : 0 : size_t needlen = strlen (PASSWORD);
105 : :
106 [ # # ][ # # ]: 0 : if (out && *outlen < needlen)
107 : 0 : return GSASL_TOO_SMALL_BUFFER;
108 : :
109 : 0 : *outlen = needlen;
110 [ # # ]: 0 : if (out)
111 : 0 : memcpy (out, PASSWORD, *outlen);
112 : :
113 : 0 : return GSASL_OK;
114 : : }
115 : :
116 : : void
117 : 1 : doit (void)
118 : : {
119 : 1 : Gsasl_ctx *ctx = NULL;
120 : 1 : Gsasl_session_ctx *server = NULL, *client = NULL;
121 : : char *s1, *s2;
122 : : size_t s1len, s2len;
123 : : size_t i;
124 : : int res;
125 : :
126 : 1 : res = gsasl_init (&ctx);
127 [ - + ]: 1 : if (res != GSASL_OK)
128 : : {
129 : 0 : fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
130 : 0 : return;
131 : : }
132 : :
133 [ + - ]: 1 : if (!gsasl_client_support_p (ctx, "DIGEST-MD5")
134 [ - + ]: 1 : || !gsasl_server_support_p (ctx, "DIGEST-MD5"))
135 : : {
136 : 0 : gsasl_done (ctx);
137 : 0 : fail ("No support for DIGEST-MD5.\n");
138 : 0 : exit (77);
139 : : }
140 : :
141 : 1 : gsasl_server_callback_retrieve_set (ctx, server_cb_retrieve);
142 : :
143 : 1 : gsasl_server_callback_qop_set (ctx, server_cb_qop);
144 : :
145 : 1 : gsasl_client_callback_service_set (ctx, client_callback_service);
146 : :
147 : 1 : gsasl_client_callback_authentication_id_set (ctx,
148 : : client_cb_authentication_id);
149 : 1 : gsasl_client_callback_password_set (ctx, client_cb_password);
150 : :
151 : :
152 [ + + ]: 6 : for (i = 0; i < 5; i++)
153 : : {
154 [ + + ]: 5 : if (i > 2)
155 : 2 : gsasl_client_callback_qop_set (ctx, client_cb_qop);
156 : :
157 : 5 : res = gsasl_server_start (ctx, "DIGEST-MD5", &server);
158 [ - + ]: 5 : if (res != GSASL_OK)
159 : : {
160 : 0 : fail ("gsasl_server_start() failed (%d):\n%s\n",
161 : : res, gsasl_strerror (res));
162 : 0 : return;
163 : : }
164 : 5 : res = gsasl_client_start (ctx, "DIGEST-MD5", &client);
165 [ - + ]: 5 : if (res != GSASL_OK)
166 : : {
167 : 0 : fail ("gsasl_client_start() failed (%d):\n%s\n",
168 : : res, gsasl_strerror (res));
169 : 0 : return;
170 : : }
171 : :
172 : 5 : gsasl_appinfo_set (server, (void *) &i);
173 : :
174 : : /* Server begins... */
175 : :
176 : 5 : res = gsasl_step (server, NULL, 0, &s1, &s1len);
177 [ - + ]: 5 : if (res != GSASL_NEEDS_MORE)
178 : : {
179 : 0 : fail ("gsasl_step(1) failed (%d):\n%s\n", res,
180 : : gsasl_strerror (res));
181 : 0 : return;
182 : : }
183 : :
184 [ + - ]: 5 : if (debug)
185 : 5 : printf ("S: %.*s\n", (int) s1len, s1);
186 : :
187 : : /* Client respond... */
188 : :
189 : 5 : res = gsasl_step (client, s1, s1len, &s2, &s2len);
190 : 5 : free (s1);
191 [ - + ]: 5 : if (res != GSASL_NEEDS_MORE)
192 : : {
193 : 0 : fail ("gsasl_step(2) failed (%d):\n%s\n", res,
194 : : gsasl_strerror (res));
195 : 0 : return;
196 : : }
197 : :
198 [ + - ]: 5 : if (debug)
199 : 5 : printf ("C: %.*s\n", (int) s2len, s2);
200 : :
201 : : /* Server finishes... */
202 : :
203 : 5 : res = gsasl_step (server, s2, s2len, &s1, &s1len);
204 : 5 : free (s2);
205 [ - + ]: 5 : if (res != GSASL_OK)
206 : : {
207 : 0 : fail ("gsasl_step(3) failed (%d):\n%s\n", res,
208 : : gsasl_strerror (res));
209 : 0 : return;
210 : : }
211 : :
212 [ + - ]: 5 : if (debug)
213 : 5 : printf ("S: %.*s\n", (int) s1len, s1);
214 : :
215 : : /* Client finishes... */
216 : :
217 : 5 : res = gsasl_step (client, s1, s1len, &s2, &s2len);
218 : 5 : free (s1);
219 [ - + ]: 5 : if (res != GSASL_OK)
220 : : {
221 : 0 : fail ("gsasl_step(4) failed (%d):\n%s\n", res,
222 : : gsasl_strerror (res));
223 : 0 : return;
224 : : }
225 : :
226 [ + - ]: 5 : if (debug)
227 : : {
228 : : /* Solaris x86 crashes here if s2 is NULL, even when s2len
229 : : is 0. */
230 [ - + ]: 5 : if (s2len)
231 : 0 : printf ("C: %.*s\n", (int) s2len, s2);
232 : : else
233 : 5 : printf ("C: \n");
234 : : }
235 : :
236 : 5 : free (s2);
237 : :
238 [ + - ]: 5 : if (debug)
239 : 5 : printf ("\n");
240 : :
241 : 5 : gsasl_client_finish (client);
242 : 5 : gsasl_server_finish (server);
243 : : }
244 : :
245 : 1 : gsasl_done (ctx);
246 : : }
|