Line data Source code
1 : /* gssapi.c --- Test the GSSAPI mechanism.
2 : * Copyright (C) 2002-2023 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 : #include <stdbool.h>
30 :
31 : #include "utils.h"
32 :
33 : #define SERVICE "host"
34 : #define HOST "latte.josefsson.org"
35 : #define GSSAPI_USER "jas"
36 :
37 : static const char *USERNAME[] = {
38 : "foo", "BABABA", "jas", "hepp", "@", NULL
39 : };
40 :
41 : size_t i;
42 :
43 : static int
44 0 : callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop)
45 : {
46 0 : int rc = GSASL_NO_CALLBACK;
47 :
48 0 : switch (prop)
49 : {
50 0 : case GSASL_AUTHID:
51 0 : fail ("AUTHID should never be invoked by GSS-API mechanism!\n");
52 0 : break;
53 :
54 0 : case GSASL_AUTHZID:
55 0 : rc = gsasl_property_set (sctx, GSASL_AUTHZID, USERNAME[i]);
56 0 : break;
57 :
58 0 : case GSASL_SERVICE:
59 0 : rc = gsasl_property_set (sctx, prop, SERVICE);
60 0 : break;
61 :
62 0 : case GSASL_HOSTNAME:
63 0 : rc = gsasl_property_set (sctx, prop, HOST);
64 0 : break;
65 :
66 0 : case GSASL_VALIDATE_GSSAPI:
67 : {
68 : const char *client_name =
69 0 : gsasl_property_fast (sctx, GSASL_GSSAPI_DISPLAY_NAME);
70 0 : const char *authzid = gsasl_property_fast (sctx, GSASL_AUTHZID);
71 :
72 0 : printf ("GSSAPI user: %s\n", client_name);
73 0 : printf ("Authorization ID: %s\n", authzid);
74 :
75 0 : if (strcmp (client_name, GSSAPI_USER) == 0 &&
76 0 : ((USERNAME[i] == NULL && authzid == NULL)
77 0 : || (USERNAME[i] != NULL && strcmp (authzid, USERNAME[i]) == 0)))
78 0 : rc = GSASL_OK;
79 : else
80 0 : rc = GSASL_AUTHENTICATION_ERROR;
81 : }
82 0 : break;
83 :
84 0 : default:
85 0 : fail ("Unknown callback property %u\n", prop);
86 0 : break;
87 : }
88 :
89 0 : return rc;
90 : }
91 :
92 : void
93 1 : doit (void)
94 : {
95 1 : Gsasl *ctx = NULL;
96 1 : Gsasl_session *server = NULL, *client = NULL;
97 1 : char *s1 = NULL, *s2 = NULL;
98 : int rc, res1, res2;
99 :
100 1 : if (getenv ("GNUGSS") == NULL || strcmp (getenv ("GNUGSS"), "yes") != 0)
101 : {
102 1 : fail ("Not using GNU GSS, skipping self-test.\n");
103 1 : exit (77);
104 : }
105 :
106 0 : rc = gsasl_init (&ctx);
107 0 : if (rc != GSASL_OK)
108 : {
109 0 : fail ("gsasl_init() failed (%d):\n%s\n", rc, gsasl_strerror (rc));
110 0 : return;
111 : }
112 :
113 0 : if (!gsasl_client_support_p (ctx, "GSSAPI")
114 0 : || !gsasl_server_support_p (ctx, "GSSAPI"))
115 : {
116 0 : gsasl_done (ctx);
117 0 : fail ("No support for GSSAPI.\n");
118 0 : exit (77);
119 : }
120 :
121 0 : gsasl_callback_set (ctx, callback);
122 :
123 0 : for (i = 0; i < 6; i++)
124 : {
125 0 : bool server_first = (i % 2) == 0;
126 :
127 0 : rc = gsasl_server_start (ctx, "GSSAPI", &server);
128 0 : if (rc != GSASL_OK)
129 : {
130 0 : fail ("gsasl_server_start() failed (%d):\n%s\n",
131 : rc, gsasl_strerror (rc));
132 0 : return;
133 : }
134 0 : rc = gsasl_client_start (ctx, "GSSAPI", &client);
135 0 : if (rc != GSASL_OK)
136 : {
137 0 : fail ("gsasl_client_start() failed (%d):\n%s\n",
138 : rc, gsasl_strerror (rc));
139 0 : return;
140 : }
141 :
142 : do
143 : {
144 0 : res1 = gsasl_step64 (server_first ? server : client, s1, &s2);
145 0 : if (s1)
146 : {
147 0 : gsasl_free (s1);
148 0 : s1 = NULL;
149 : }
150 0 : if (res1 != GSASL_OK && res1 != GSASL_NEEDS_MORE)
151 : {
152 0 : fail ("gsasl_step64 (1) failed (%d):\n%s\n", res1,
153 : gsasl_strerror (res1));
154 0 : return;
155 : }
156 :
157 0 : if (debug)
158 0 : printf ("%c: %s [%c]\n", server_first ? 'S' : 'C',
159 : s2, res1 == GSASL_OK ? 'O' : 'N');
160 :
161 0 : if (res1 == GSASL_OK && strcmp (s2, "") == 0)
162 : {
163 0 : gsasl_free (s2);
164 0 : break;
165 : }
166 :
167 0 : res2 = gsasl_step64 (server_first ? client : server, s2, &s1);
168 0 : gsasl_free (s2);
169 0 : if (res2 != GSASL_OK && res2 != GSASL_NEEDS_MORE)
170 : {
171 0 : fail ("gsasl_step64 (2) failed (%d):\n%s\n", res2,
172 : gsasl_strerror (res2));
173 : /* likely gss without krb5 */
174 0 : if (res2 == GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR)
175 0 : exit (77);
176 0 : return;
177 : }
178 :
179 0 : if (debug)
180 0 : printf ("%c: %s [%c]\n", server_first ? 'C' : 'S',
181 : s1, res2 == GSASL_OK ? 'O' : 'N');
182 : }
183 0 : while (res1 != GSASL_OK || res2 != GSASL_OK);
184 :
185 0 : if (s1)
186 : {
187 0 : gsasl_free (s1);
188 0 : s1 = NULL;
189 : }
190 :
191 0 : if (debug)
192 0 : printf ("\n");
193 :
194 0 : gsasl_finish (client);
195 0 : gsasl_finish (server);
196 : }
197 :
198 0 : gsasl_done (ctx);
199 : }
|