Update.
[gsasl.git] / tests / digest-md5.c
blob5513291da331054c7d265eb1762620442635d833
1 /* digest-md5.c --- Test the DIGEST-MD5 mechanism.
2 * Copyright (C) 2002, 2003, 2004 Simon Josefsson
4 * This file is part of GNU SASL.
6 * GNU SASL 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 2 of the License, or
9 * (at your option) any later version.
11 * GNU SASL 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.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU SASL; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <string.h>
31 #include "utils.h"
33 #define PASSWORD "Open, Sesame"
34 #define USERNAME "Ali Baba"
35 /* "Ali " "\xC2\xAD" "Bab" "\xC2\xAA" */
36 /* "Al\xC2\xAA""dd\xC2\xAD""in\xC2\xAE" */
37 #define AUTHZID "joe"
38 #define SERVICE "imap"
39 #define HOSTNAME "hostname"
40 #define REALM "realm"
42 static int
43 callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
45 static int flip = 0;
46 static int flip2 = 0;
47 int rc = GSASL_NO_CALLBACK;
49 /* Get user info from user. */
51 switch (prop)
53 case GSASL_PASSWORD:
54 gsasl_property_set (sctx, prop, PASSWORD);
55 rc = GSASL_OK;
56 break;
58 case GSASL_AUTHID:
59 gsasl_property_set (sctx, prop, USERNAME);
60 rc = GSASL_OK;
61 break;
63 case GSASL_AUTHZID:
64 if (flip)
65 gsasl_property_set (sctx, prop, AUTHZID);
66 else
67 gsasl_property_set (sctx, prop, NULL);
68 flip = !flip;
69 rc = GSASL_OK;
70 break;
72 case GSASL_SERVICE:
73 gsasl_property_set (sctx, prop, SERVICE);
74 rc = GSASL_OK;
75 break;
77 case GSASL_REALM:
78 if (flip2)
79 gsasl_property_set (sctx, prop, REALM);
80 else
81 gsasl_property_set (sctx, prop, NULL);
82 flip2++;
83 if (flip2 == 3)
84 flip2 = 0;
85 rc = GSASL_OK;
86 break;
88 case GSASL_HOSTNAME:
89 gsasl_property_set (sctx, prop, HOSTNAME);
90 rc = GSASL_OK;
91 break;
93 default:
94 fail ("Unknown callback property %d\n", prop);
95 break;
98 return rc;
101 void
102 doit (void)
104 Gsasl *ctx = NULL;
105 Gsasl_session *server = NULL, *client = NULL;
106 char *s1, *s2;
107 size_t s1len, s2len;
108 size_t i;
109 int res;
111 res = gsasl_init (&ctx);
112 if (res != GSASL_OK)
114 fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
115 return;
118 gsasl_callback_set (ctx, callback);
120 for (i = 0; i < 5; i++)
122 res = gsasl_server_start (ctx, "DIGEST-MD5", &server);
123 if (res != GSASL_OK)
125 fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
126 return;
128 res = gsasl_client_start (ctx, "DIGEST-MD5", &client);
129 if (res != GSASL_OK)
131 fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
132 return;
135 /* Server begins... */
137 res = gsasl_step (server, NULL, 0, &s1, &s1len);
138 if (res != GSASL_NEEDS_MORE)
140 fail ("gsasl_step(1) failed (%d):\n%s\n", res,
141 gsasl_strerror (res));
142 return;
145 if (debug)
146 printf ("S: %.*s\n", s1len, s1);
148 /* Client respond... */
150 res = gsasl_step (client, s1, s1len, &s2, &s2len);
151 free (s1);
152 if (res != GSASL_NEEDS_MORE)
154 fail ("gsasl_step(2) failed (%d):\n%s\n", res,
155 gsasl_strerror (res));
156 return;
159 if (debug)
160 printf ("C: %.*s\n", s2len, s2);
162 /* Server finishes... */
164 res = gsasl_step (server, s2, s2len, &s1, &s1len);
165 free (s2);
166 if (res != GSASL_NEEDS_MORE)
168 fail ("gsasl_step(3) failed (%d):\n%s\n", res,
169 gsasl_strerror (res));
170 return;
173 if (debug)
174 printf ("S: %.*s\n", s1len, s1);
176 /* Client finishes... */
178 res = gsasl_step (client, s1, s1len, &s2, &s2len);
179 free (s1);
180 if (res != GSASL_OK)
182 fail ("gsasl_step(4) failed (%d):\n%s\n", res,
183 gsasl_strerror (res));
184 return;
187 if (debug)
189 /* Solaris x86 crashes here if s2 is NULL, even when s2len
190 is 0. */
191 if (s2len)
192 printf ("C: %.*s\n", s2len, s2);
193 else
194 printf ("C: \n");
197 /* Server is done. */
199 res = gsasl_step (server, s2, s2len, &s1, &s1len);
200 free (s2);
201 if (res != GSASL_OK)
203 fail ("gsasl_step(5) failed (%d):\n%s\n", res,
204 gsasl_strerror (res));
205 return;
208 if (s1len != 0)
210 fail ("gsasl_step() failed, additional length=%d:\n", s1len);
211 fail ("%s\n", s1);
212 return;
215 free (s1);
217 if (debug)
218 printf ("\n");
220 gsasl_finish (client);
221 gsasl_finish (server);
224 gsasl_done (ctx);