Branch data Line data Source code
1 : : /* cram-md5.c --- Test the CRAM-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 : :
38 : : static int
39 : 15 : callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
40 : : {
41 : 15 : int rc = GSASL_NO_CALLBACK;
42 : :
43 : : /* Get user info from user. */
44 : :
45 [ + + - ]: 15 : switch (prop)
46 : : {
47 : : case GSASL_PASSWORD:
48 : 10 : gsasl_property_set (sctx, GSASL_PASSWORD, PASSWORD);
49 : 10 : rc = GSASL_OK;
50 : 10 : break;
51 : :
52 : : case GSASL_AUTHID:
53 : 5 : gsasl_property_set (sctx, GSASL_AUTHID, USERNAME);
54 : 5 : rc = GSASL_OK;
55 : 5 : break;
56 : :
57 : : default:
58 : 0 : fail ("Unknown callback property %d\n", prop);
59 : 0 : break;
60 : : }
61 : :
62 : 15 : return rc;
63 : : }
64 : :
65 : : void
66 : 1 : doit (void)
67 : : {
68 : 1 : Gsasl *ctx = NULL;
69 : 1 : Gsasl_session *server = NULL, *client = NULL;
70 : : char *s1, *s2;
71 : : size_t s1len, s2len;
72 : : size_t i;
73 : : int res;
74 : 1 : char *last_server_challenge = NULL;
75 : 1 : size_t last_server_challenge_len = 0;
76 : :
77 : 1 : res = gsasl_init (&ctx);
78 [ - + ]: 1 : if (res != GSASL_OK)
79 : : {
80 : 0 : fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
81 : 0 : return;
82 : : }
83 : :
84 [ + - ]: 1 : if (!gsasl_client_support_p (ctx, "CRAM-MD5")
85 [ - + ]: 1 : || !gsasl_server_support_p (ctx, "CRAM-MD5"))
86 : : {
87 : 0 : gsasl_done (ctx);
88 : 0 : fail ("No support for CRAM-MD5.\n");
89 : 0 : exit (77);
90 : : }
91 : :
92 : 1 : gsasl_callback_set (ctx, callback);
93 : :
94 [ + + ]: 6 : for (i = 0; i < 5; i++)
95 : : {
96 : 5 : res = gsasl_server_start (ctx, "CRAM-MD5", &server);
97 [ - + ]: 5 : if (res != GSASL_OK)
98 : : {
99 : 0 : fail ("gsasl_server_start() failed (%d):\n%s\n",
100 : : res, gsasl_strerror (res));
101 : 0 : return;
102 : : }
103 : 5 : res = gsasl_client_start (ctx, "CRAM-MD5", &client);
104 [ - + ]: 5 : if (res != GSASL_OK)
105 : : {
106 : 0 : fail ("gsasl_client_start() failed (%d):\n%s\n",
107 : : res, gsasl_strerror (res));
108 : 0 : return;
109 : : }
110 : :
111 : 5 : res = gsasl_step (server, NULL, 0, &s1, &s1len);
112 [ - + ]: 5 : if (res != GSASL_NEEDS_MORE)
113 : : {
114 : 0 : fail ("gsasl_step() failed (%d):\n%s\n", res, gsasl_strerror (res));
115 : 0 : return;
116 : : }
117 : :
118 [ + - ]: 5 : if (debug)
119 : 5 : printf ("S: %.*s\n", (int) s1len, s1);
120 : :
121 [ + + ]: 5 : if (last_server_challenge)
122 : : {
123 [ + - ][ - + ]: 4 : if (last_server_challenge_len == s1len &&
124 : 4 : memcmp (last_server_challenge, s1, s1len) == 0)
125 : 0 : fail ("Server challenge same as last one!\n");
126 : :
127 : 4 : free (last_server_challenge);
128 : : }
129 : :
130 : 5 : last_server_challenge = malloc (s1len);
131 [ - + ]: 5 : if (!last_server_challenge)
132 : 0 : fail ("malloc() failure (%lu)\n", (unsigned long) s1len);
133 : 5 : memcpy (last_server_challenge, s1, s1len);
134 : 5 : last_server_challenge_len = s1len;
135 : :
136 : 5 : res = gsasl_step (client, s1, s1len, &s2, &s2len);
137 : 5 : gsasl_free (s1);
138 [ - + ]: 5 : if (res != GSASL_OK)
139 : : {
140 : 0 : fail ("gsasl_step() failed (%d):\n%s\n", res, gsasl_strerror (res));
141 : 0 : return;
142 : : }
143 : :
144 [ + - ]: 5 : if (debug)
145 : 5 : printf ("C: %.*s\n", (int) s2len, s2);
146 : :
147 : 5 : res = gsasl_step (server, s2, s2len, &s1, &s1len);
148 : 5 : gsasl_free (s2);
149 [ - + ]: 5 : if (res != GSASL_OK)
150 : : {
151 : 0 : fail ("gsasl_step() failed (%d):\n%s\n", res, gsasl_strerror (res));
152 : 0 : return;
153 : : }
154 : :
155 [ - + ]: 5 : if (s1len != 0)
156 : : {
157 : 0 : fail ("gsasl_step() failed, additional length=%lu:\n",
158 : : (unsigned long) s1len);
159 : 0 : fail ("%s\n", s1);
160 : 0 : return;
161 : : }
162 : :
163 : 5 : gsasl_free (s1);
164 : :
165 [ + - ]: 5 : if (debug)
166 : 5 : printf ("\n");
167 : :
168 : 5 : gsasl_finish (client);
169 : 5 : gsasl_finish (server);
170 : : }
171 : :
172 : 1 : free (last_server_challenge);
173 : :
174 : 1 : gsasl_done (ctx);
175 : : }
|