Inform user that --password is only for testing.
[gsasl.git] / src / callbacks.c
blob5b0052ef49f00ea509cbac53c1b7bb52ce309841
1 /* callbacks.c implementation of gsasl callbacks
2 * Copyright (C) 2002 Simon Josefsson
4 * This file is part of libgsasl.
6 * Libgsasl 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 * Libgsasl 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 libgsasl; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdio.h>
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #ifdef HAVE_NETDB_H
30 #include <netdb.h>
31 #endif
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 #ifdef HAVE_LOCALE_H
36 #include <locale.h>
37 #endif
38 #if HAVE_STRING_H
39 # if !STDC_HEADERS && HAVE_MEMORY_H
40 # include <memory.h>
41 # endif
42 # include <string.h>
43 #endif
44 #if HAVE_STRINGS_H
45 # include <strings.h>
46 #endif
47 #include <argp.h>
48 #include <gsasl.h>
50 #include <stringprep.h>
52 #define MAX_LINE_LENGTH BUFSIZ
54 extern int silent;
55 extern int verbose;
56 extern char *anonymous_token;
57 extern char *authentication_id;
58 extern char *authorization_id;
59 extern char *password;
60 extern char *passcode;
61 extern char *mechanism;
62 extern char *service;
63 extern char *hostname;
64 extern char *servicename;
65 extern char **realms;
66 extern size_t nrealms;
67 extern int maxbuf;
68 extern int qop;
70 static char *
71 readline (const char *prompt)
73 static char line[MAX_LINE_LENGTH];
75 printf ("%s", prompt);
77 line[0] = '\0';
78 fgets (line, MAX_LINE_LENGTH, stdin);
79 line[strlen (line) - 1] = '\0';
81 return line;
84 static int
85 utf8cpy (char *dst, size_t * dstlen, char *src, size_t srclen)
87 int nonasciiflag = 0;
88 char *p;
90 if (srclen != strlen(src))
91 return !GSASL_OK;
93 p = stringprep_locale_to_utf8(src);
94 if (p)
96 int len = strlen(p);
98 if (len > *dstlen)
99 return GSASL_TOO_SMALL_BUFFER;
100 *dstlen = len;
101 if (dst)
102 strcpy(dst, p);
104 else
106 int i;
108 fprintf (stderr, " ** failed to convert data from %s to UTF-8\n",
109 stringprep_locale_charset());
110 fprintf (stderr, " ** check the system locale configuration\n");
111 fprintf (stderr, " ** treating input as ASCII\n");
113 if (dst && *dstlen < srclen)
114 return GSASL_TOO_SMALL_BUFFER;
116 *dstlen = srclen;
117 for (i = 0; i < srclen; i++)
119 if (src[i] & 0x80)
120 nonasciiflag = 1;
121 dst[i] = src[i] & 0x7F;
124 if (nonasciiflag)
126 fprintf (stderr, " ** bit 8 stripped from string\n");
127 fprintf (stderr, " ** original string: `%s'\n", src);
128 fprintf (stderr, " ** stripped string: `%s'\n", dst);
132 return GSASL_OK;
135 /* Client callbacks */
138 client_callback_anonymous (Gsasl_session_ctx * ctx,
139 char *out, size_t * outlen)
141 int rc;
143 if (anonymous_token == NULL)
144 anonymous_token =
145 strdup (readline ("Enter anonymous token (e.g., email address): "));
147 if (anonymous_token == NULL)
148 return GSASL_AUTHENTICATION_ERROR;
150 rc = utf8cpy (out, outlen, anonymous_token, strlen (anonymous_token));
151 if (rc != GSASL_OK)
152 return rc;
154 return GSASL_OK;
158 client_callback_authorization_id (Gsasl_session_ctx * ctx,
159 char *out, size_t * outlen)
161 int rc;
163 if (authorization_id == NULL)
164 authorization_id = strdup (readline ("Enter authorization ID: "));
166 if (authorization_id == NULL)
167 return GSASL_AUTHENTICATION_ERROR;
169 rc = utf8cpy (out, outlen, authorization_id, strlen (authorization_id));
170 if (rc != GSASL_OK)
171 return rc;
173 return GSASL_OK;
177 client_callback_authentication_id (Gsasl_session_ctx * ctx,
178 char *out, size_t * outlen)
180 int rc;
182 if (authentication_id == NULL)
183 authentication_id = strdup (readline ("Enter authentication ID: "));
185 if (authentication_id == NULL)
186 return GSASL_AUTHENTICATION_ERROR;
188 rc = utf8cpy (out, outlen, authentication_id, strlen (authentication_id));
189 if (rc != GSASL_OK)
190 return rc;
192 return GSASL_OK;
196 client_callback_password (Gsasl_session_ctx * ctx, char *out, size_t * outlen)
198 int rc;
200 if (password == NULL)
201 password = strdup (readline ("Enter password: "));
203 if (password == NULL)
204 return GSASL_AUTHENTICATION_ERROR;
206 rc = utf8cpy (out, outlen, password, strlen (password));
207 if (rc != GSASL_OK)
208 return rc;
210 return GSASL_OK;
214 client_callback_service (Gsasl_session_ctx * ctx,
215 char *srv,
216 size_t * srvlen,
217 char *host,
218 size_t * hostlen, char *srvname, size_t * srvnamelen)
220 int rc;
222 if (service == NULL)
223 service =
224 strdup (readline ("Enter GSSAPI service name (e.g. \"imap\"): "));
226 if (hostname == NULL)
227 hostname = strdup (readline ("Enter hostname of server: "));
229 if (srvnamelen && servicename == NULL)
230 servicename =
231 strdup (readline ("Enter generic server name (optional): "));
233 if (service == NULL)
234 return GSASL_AUTHENTICATION_ERROR;
236 if (hostname == NULL)
237 return GSASL_AUTHENTICATION_ERROR;
239 if (srvnamelen && servicename == NULL)
240 return GSASL_AUTHENTICATION_ERROR;
242 rc = utf8cpy (srv, srvlen, service, strlen (service));
243 if (rc != GSASL_OK)
244 return rc;
246 rc = utf8cpy (host, hostlen, hostname, strlen (hostname));
247 if (rc != GSASL_OK)
248 return rc;
250 if (srvnamelen)
252 rc = utf8cpy (srvname, srvnamelen, servicename, strlen (servicename));
253 if (rc != GSASL_OK)
254 return rc;
257 return GSASL_OK;
261 client_callback_passcode (Gsasl_session_ctx * ctx, char *out, size_t * outlen)
263 int rc;
265 if (passcode == NULL)
266 passcode = strdup (readline ("Enter passcode: "));
268 if (passcode == NULL)
269 return GSASL_AUTHENTICATION_ERROR;
271 rc = utf8cpy (out, outlen, passcode, strlen (passcode));
272 if (rc != GSASL_OK)
273 return rc;
275 return GSASL_OK;
278 Gsasl_qop
279 client_callback_qop (Gsasl_session_ctx * ctx, Gsasl_qop serverqops)
281 if (serverqops & qop == 0)
282 fprintf (stderr,
283 "Warning: Server QOPs %d does not include client QOP %d.\n",
284 serverqops, qop);
285 return qop;
289 client_callback_maxbuf (Gsasl_session_ctx * ctx, int servermaxbuf)
291 return maxbuf;
294 /* Server callbacks */
297 server_callback_cram_md5 (Gsasl_session_ctx * ctx,
298 char *username, char *challenge, char *response)
300 char *data;
302 printf ("User: `%s'\nChallenge: `%s'\nResponse: `%s'\n",
303 username, challenge, response);
305 data = readline ("Admit user? (y/n) ");
307 if (*data == 'y' || *data == 'Y')
308 return GSASL_OK;
309 else
310 return GSASL_AUTHENTICATION_ERROR;
314 server_callback_anonymous (Gsasl_session_ctx * ctx, const char *message)
316 char *data;
318 printf ("Anonymous user: `%s'\n", message);
320 data = readline ("Admit user? (y/n) ");
322 if (*data == 'y' || *data == 'Y')
323 return GSASL_OK;
324 else
325 return GSASL_AUTHENTICATION_ERROR;
328 Gsasl_qop
329 server_callback_qop (Gsasl_session_ctx * ctx)
331 return GSASL_QOP_AUTH | GSASL_QOP_AUTH_INT | GSASL_QOP_AUTH_CONF;
335 server_callback_maxbuf (Gsasl_session_ctx * ctx)
337 return maxbuf;
341 server_callback_realm (Gsasl_session_ctx * ctx,
342 char *out, size_t * outlen, size_t nth)
344 int rc;
346 if (nrealms == 0)
348 struct hostent *he;
349 char hostname[BUFSIZ];
351 rc = gethostname (hostname, BUFSIZ);
352 hostname[BUFSIZ - 1] = '\0';
353 if (rc != 0)
354 return GSASL_NO_MORE_REALMS;
356 he = gethostbyname (hostname);
357 if (he && strlen (he->h_name) < BUFSIZ)
358 strcpy (hostname, he->h_name);
360 realms = malloc (sizeof (*realms));
361 if (realms == NULL)
362 return GSASL_MALLOC_ERROR;
363 realms[nrealms++] = strdup (hostname);
366 if (nth >= nrealms)
367 return GSASL_NO_MORE_REALMS;
369 rc = utf8cpy (out, outlen, realms[nth], strlen (realms[nth]));
370 if (rc != GSASL_OK)
371 return rc;
373 return GSASL_OK;
377 server_callback_external (Gsasl_session_ctx * ctx)
379 char *data;
381 printf ("Validation information provided out of band (e.g., TLS)\n");
383 data = readline ("Admit user? (y/n) ");
385 if (*data == 'y' || *data == 'Y')
386 return GSASL_OK;
387 else
388 return GSASL_AUTHENTICATION_ERROR;
392 server_callback_validate (Gsasl_session_ctx * ctx,
393 char *authorization_id,
394 char *authentication_id, char *password)
396 char *data;
398 if (authorization_id && strlen (authorization_id) > 0)
399 printf ("Authorization ID: %s\n", authorization_id);
400 else
401 printf ("No authorization ID\n");
403 if (authentication_id && strlen (authentication_id) > 0)
404 printf ("Authentication ID: %s\n", authentication_id);
405 else
406 printf ("No authentication ID\n");
408 if (password && strlen (password) > 0)
409 printf ("Password: %s\n", password);
410 else
411 printf ("No password\n");
413 data = readline ("Admit user? (y/n) ");
415 if (*data == 'y' || *data == 'Y')
416 return GSASL_OK;
417 else
418 return GSASL_AUTHENTICATION_ERROR;
422 server_callback_retrieve (Gsasl_session_ctx * ctx,
423 char *authentication_id,
424 char *authorization_id,
425 char *realm, char *key, size_t * keylen)
427 int rc;
429 if (password == NULL)
430 password = strdup (readline ("Enter password: "));
432 if (password == NULL)
433 return GSASL_AUTHENTICATION_ERROR;
435 rc = utf8cpy (key, keylen, password, strlen (password));
436 if (rc != GSASL_OK)
437 return rc;
439 return GSASL_OK;
443 server_callback_service (Gsasl_session_ctx * ctx,
444 char *srv,
445 size_t * srvlen, char *host, size_t * hostlen)
447 int rc;
449 if (service == NULL)
450 service =
451 strdup (readline ("Enter GSSAPI service name (e.g. \"imap\"): "));
453 if (hostname == NULL)
454 hostname = strdup (readline ("Enter hostname of server: "));
456 if (service == NULL)
457 return GSASL_AUTHENTICATION_ERROR;
459 if (hostname == NULL)
460 return GSASL_AUTHENTICATION_ERROR;
462 rc = utf8cpy (srv, srvlen, service, strlen (service));
463 if (rc != GSASL_OK)
464 return rc;
466 rc = utf8cpy (host, hostlen, hostname, strlen (hostname));
467 if (rc != GSASL_OK)
468 return rc;
470 return GSASL_OK;
474 server_callback_gssapi (Gsasl_session_ctx * ctx,
475 char *client_name, char *authentication_id)
477 char *data;
479 if (client_name)
480 printf ("GSSAPI user: %s\n", client_name);
482 if (authentication_id)
483 printf ("Authentication ID: %s\n", authentication_id);
485 data = readline ("Admit user? (y/n) ");
487 if (*data == 'y' || *data == 'Y')
488 return GSASL_OK;
489 else
490 return GSASL_AUTHENTICATION_ERROR;