Add.
[gsasl.git] / tests / external.c
blob22ea194ff13dc352888400918defb284c794ee31
1 /* external.c --- Test the EXTERNAL mechanism.
2 * Copyright (C) 2002, 2003, 2004, 2005 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 static const struct {
34 char *sendauthzid;
35 char *recvauthzid;
36 int clientrc;
37 int callbackrc;
38 int serverrc;
39 } tv[] = {
40 { NULL, "", GSASL_OK, GSASL_OK, GSASL_OK },
41 { "", "", GSASL_OK, GSASL_OK, GSASL_OK },
42 { "foo", "foo", GSASL_OK, GSASL_OK, GSASL_OK },
43 { "foo", "foo", GSASL_OK, GSASL_NO_CALLBACK, GSASL_NO_CALLBACK },
44 { "foo\0bar", "foo", GSASL_OK, GSASL_OK, GSASL_OK },
45 { "foo\0bar", "foo", GSASL_OK, GSASL_AUTHENTICATION_ERROR,
46 GSASL_AUTHENTICATION_ERROR }
49 static int
50 callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
52 static int c = 0;
53 static int s = 0;
54 int rc = GSASL_NO_CALLBACK;
56 c = c % sizeof (tv) / sizeof (tv[0]);
57 s = s % sizeof (tv) / sizeof (tv[0]);
59 /* Get user info from user. */
61 switch (prop)
63 case GSASL_AUTHZID:
64 gsasl_property_set (sctx, prop, tv[c++].sendauthzid);
65 rc = GSASL_OK;
66 break;
68 case GSASL_VALIDATE_EXTERNAL:
69 rc = tv[s++].callbackrc;
70 break;
72 default:
73 fail ("Unknown callback property %d\n", prop);
74 break;
77 return rc;
80 void
81 doit (void)
83 Gsasl *ctx = NULL;
84 Gsasl_session *server = NULL, *client = NULL;
85 char *s1, *s2;
86 size_t s1len, s2len;
87 size_t i;
88 int res;
90 res = gsasl_init (&ctx);
91 if (res != GSASL_OK)
93 fail ("gsasl_init() failed (%d):\n%s\n", res, gsasl_strerror (res));
94 return;
97 gsasl_callback_set (ctx, callback);
99 for (i = 0; i < 2 * (sizeof (tv) / sizeof (tv[0])); i++)
101 int n = i % sizeof (tv) / sizeof (tv[0]);
103 res = gsasl_server_start (ctx, "EXTERNAL", &server);
104 if (res != GSASL_OK)
106 fail ("gsasl_server_start (%d):\n%s\n", res, gsasl_strerror (res));
107 return;
109 res = gsasl_client_start (ctx, "EXTERNAL", &client);
110 if (res != GSASL_OK)
112 fail ("gsasl_client_start (%d):\n%s\n", res, gsasl_strerror (res));
113 return;
116 res = gsasl_step (server, NULL, 0, &s1, &s1len);
117 if (res != GSASL_NEEDS_MORE)
119 fail ("gsasl_step server1 (%d):\n%s\n", res, gsasl_strerror (res));
120 return;
123 if (debug)
124 if (s1)
125 printf ("S[%d]: `%.*s' (%d)\n", i, s1len, s1, s1len);
126 else
127 printf ("S[%d] NULL\n", i);
129 res = gsasl_step (client, s1, s1len, &s2, &s2len);
130 if (res != tv[n].clientrc)
132 fail ("gsasl_step client1 (%d):\n%s\n", res, gsasl_strerror (res));
133 return;
135 if (s1)
136 free (s1);
138 if (debug)
139 if (s2)
140 printf ("C[%d]: `%.*s' (%d)\n", i, s2len, s2, s2len);
141 else
142 printf ("C[%d] NULL\n", i);
144 res = gsasl_step (server, s2, s2len, &s1, &s1len);
145 if (s2)
146 free (s2);
147 if (res != tv[n].serverrc)
149 fail ("gsasl_step server2 (%d):\n%s\n", res, gsasl_strerror (res));
150 return;
153 if (s1len != 0)
155 fail ("gsasl_step() failed, additional length=%d:\n%s", s1len, s1);
156 return;
159 if (memcmp (s1, tv[n].recvauthzid, s1len) != 0)
161 fail ("gsasl_step() failed, recv authzid mismatch: `%s' != `%s'\n",
162 s1, tv[n].recvauthzid);
163 return;
166 if (s1)
167 free (s1);
169 gsasl_finish (client);
170 gsasl_finish (server);
173 gsasl_done (ctx);