Drop gnits mode.
[gsasl.git] / tests / external.c
blob27881d36c0998a43f2dd6f71d53fc8c6cfae7d5a
1 /* external.c --- Test the EXTERNAL mechanism.
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Simon Josefsson
4 * This file is part of GNU SASL.
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.
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.
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/>.
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "utils.h"
32 static const struct {
33 char *sendauthzid;
34 char *recvauthzid;
35 int clientrc;
36 int callbackrc;
37 int serverrc;
38 } tv[] = {
39 { NULL, "", GSASL_OK, GSASL_OK, GSASL_OK },
40 { "", "", GSASL_OK, GSASL_OK, GSASL_OK },
41 { "foo", "foo", GSASL_OK, GSASL_OK, GSASL_OK },
42 { "foo", "foo", GSASL_OK, GSASL_NO_CALLBACK, GSASL_NO_CALLBACK },
43 { "foo\0bar", "foo", GSASL_OK, GSASL_OK, GSASL_OK },
44 { "foo\0bar", "foo", GSASL_OK, GSASL_AUTHENTICATION_ERROR,
45 GSASL_AUTHENTICATION_ERROR }
48 static int
49 callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
51 static int c = 0;
52 static int s = 0;
53 int rc = GSASL_NO_CALLBACK;
55 c = c % sizeof (tv) / sizeof (tv[0]);
56 s = s % sizeof (tv) / sizeof (tv[0]);
58 /* Get user info from user. */
60 switch (prop)
62 case GSASL_AUTHZID:
63 gsasl_property_set (sctx, prop, tv[c++].sendauthzid);
64 rc = GSASL_OK;
65 break;
67 case GSASL_VALIDATE_EXTERNAL:
68 rc = tv[s++].callbackrc;
69 break;
71 default:
72 fail ("Unknown callback property %d\n", prop);
73 break;
76 return rc;
79 void
80 doit (void)
82 Gsasl *ctx = NULL;
83 Gsasl_session *server = NULL, *client = NULL;
84 char *s1, *s2;
85 size_t s1len, s2len;
86 size_t i;
87 int res;
89 res = gsasl_init (&ctx);
90 if (res != GSASL_OK)
92 fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
93 return;
96 gsasl_callback_set (ctx, callback);
98 for (i = 0; i < 2 * (sizeof (tv) / sizeof (tv[0])); i++)
100 int n = i % sizeof (tv) / sizeof (tv[0]);
102 res = gsasl_server_start (ctx, "EXTERNAL", &server);
103 if (res != GSASL_OK)
105 fail ("gsasl_server_start (%d):\n%s\n", res, gsasl_strerror (res));
106 return;
108 res = gsasl_client_start (ctx, "EXTERNAL", &client);
109 if (res != GSASL_OK)
111 fail ("gsasl_client_start (%d):\n%s\n", res, gsasl_strerror (res));
112 return;
115 res = gsasl_step (server, NULL, 0, &s1, &s1len);
116 if (res != GSASL_NEEDS_MORE)
118 fail ("gsasl_step server1 (%d):\n%s\n", res, gsasl_strerror (res));
119 return;
122 if (debug)
123 if (s1)
124 printf ("S[%d]: `%.*s' (%d)\n", i, s1len, s1, s1len);
125 else
126 printf ("S[%d] NULL\n", i);
128 res = gsasl_step (client, s1, s1len, &s2, &s2len);
129 if (res != tv[n].clientrc)
131 fail ("gsasl_step client1 (%d):\n%s\n", res, gsasl_strerror (res));
132 return;
134 if (s1)
135 free (s1);
137 if (debug)
138 if (s2)
139 printf ("C[%d]: `%.*s' (%d)\n", i, s2len, s2, s2len);
140 else
141 printf ("C[%d] NULL\n", i);
143 res = gsasl_step (server, s2, s2len, &s1, &s1len);
144 if (s2)
145 free (s2);
146 if (res != tv[n].serverrc)
148 fail ("gsasl_step server2 (%d):\n%s\n", res, gsasl_strerror (res));
149 return;
152 if (s1len != 0)
154 fail ("gsasl_step() failed, additional length=%d:\n%s", s1len, s1);
155 return;
158 if (memcmp (s1, tv[n].recvauthzid, s1len) != 0)
160 fail ("gsasl_step() failed, recv authzid mismatch: `%s' != `%s'\n",
161 s1, tv[n].recvauthzid);
162 return;
165 if (s1)
166 free (s1);
168 gsasl_finish (client);
169 gsasl_finish (server);
172 gsasl_done (ctx);