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
39 # if !STDC_HEADERS && HAVE_MEMORY_H
50 #include <stringprep.h>
52 #define MAX_LINE_LENGTH BUFSIZ
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
;
63 extern char *hostname
;
64 extern char *servicename
;
66 extern size_t nrealms
;
71 readline (const char *prompt
)
73 static char line
[MAX_LINE_LENGTH
];
75 printf ("%s", prompt
);
78 fgets (line
, MAX_LINE_LENGTH
, stdin
);
79 line
[strlen (line
) - 1] = '\0';
85 utf8cpy (char *dst
, size_t * dstlen
, char *src
, size_t srclen
)
90 if (srclen
!= strlen(src
))
93 p
= stringprep_locale_to_utf8(src
);
99 return GSASL_TOO_SMALL_BUFFER
;
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
;
117 for (i
= 0; i
< srclen
; i
++)
121 dst
[i
] = src
[i
] & 0x7F;
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
);
135 /* Client callbacks */
138 client_callback_anonymous (Gsasl_session_ctx
* ctx
,
139 char *out
, size_t * outlen
)
143 if (anonymous_token
== NULL
)
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
));
158 client_callback_authorization_id (Gsasl_session_ctx
* ctx
,
159 char *out
, size_t * outlen
)
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
));
177 client_callback_authentication_id (Gsasl_session_ctx
* ctx
,
178 char *out
, size_t * outlen
)
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
));
196 client_callback_password (Gsasl_session_ctx
* ctx
, char *out
, size_t * outlen
)
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
));
214 client_callback_service (Gsasl_session_ctx
* ctx
,
218 size_t * hostlen
, char *srvname
, size_t * srvnamelen
)
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
)
231 strdup (readline ("Enter generic server name (optional): "));
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
));
246 rc
= utf8cpy (host
, hostlen
, hostname
, strlen (hostname
));
252 rc
= utf8cpy (srvname
, srvnamelen
, servicename
, strlen (servicename
));
261 client_callback_passcode (Gsasl_session_ctx
* ctx
, char *out
, size_t * outlen
)
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
));
279 client_callback_qop (Gsasl_session_ctx
* ctx
, Gsasl_qop serverqops
)
281 if (serverqops
& qop
== 0)
283 "Warning: Server QOPs %d does not include client QOP %d.\n",
289 client_callback_maxbuf (Gsasl_session_ctx
* ctx
, int servermaxbuf
)
294 /* Server callbacks */
297 server_callback_cram_md5 (Gsasl_session_ctx
* ctx
,
298 char *username
, char *challenge
, char *response
)
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')
310 return GSASL_AUTHENTICATION_ERROR
;
314 server_callback_anonymous (Gsasl_session_ctx
* ctx
, const char *message
)
318 printf ("Anonymous user: `%s'\n", message
);
320 data
= readline ("Admit user? (y/n) ");
322 if (*data
== 'y' || *data
== 'Y')
325 return GSASL_AUTHENTICATION_ERROR
;
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
)
341 server_callback_realm (Gsasl_session_ctx
* ctx
,
342 char *out
, size_t * outlen
, size_t nth
)
349 char hostname
[BUFSIZ
];
351 rc
= gethostname (hostname
, BUFSIZ
);
352 hostname
[BUFSIZ
- 1] = '\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
));
362 return GSASL_MALLOC_ERROR
;
363 realms
[nrealms
++] = strdup (hostname
);
367 return GSASL_NO_MORE_REALMS
;
369 rc
= utf8cpy (out
, outlen
, realms
[nth
], strlen (realms
[nth
]));
377 server_callback_external (Gsasl_session_ctx
* ctx
)
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')
388 return GSASL_AUTHENTICATION_ERROR
;
392 server_callback_validate (Gsasl_session_ctx
* ctx
,
393 char *authorization_id
,
394 char *authentication_id
, char *password
)
398 if (authorization_id
&& strlen (authorization_id
) > 0)
399 printf ("Authorization ID: %s\n", authorization_id
);
401 printf ("No authorization ID\n");
403 if (authentication_id
&& strlen (authentication_id
) > 0)
404 printf ("Authentication ID: %s\n", authentication_id
);
406 printf ("No authentication ID\n");
408 if (password
&& strlen (password
) > 0)
409 printf ("Password: %s\n", password
);
411 printf ("No password\n");
413 data
= readline ("Admit user? (y/n) ");
415 if (*data
== 'y' || *data
== 'Y')
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
)
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
));
443 server_callback_service (Gsasl_session_ctx
* ctx
,
445 size_t * srvlen
, char *host
, size_t * hostlen
)
451 strdup (readline ("Enter GSSAPI service name (e.g. \"imap\"): "));
453 if (hostname
== NULL
)
454 hostname
= strdup (readline ("Enter hostname of server: "));
457 return GSASL_AUTHENTICATION_ERROR
;
459 if (hostname
== NULL
)
460 return GSASL_AUTHENTICATION_ERROR
;
462 rc
= utf8cpy (srv
, srvlen
, service
, strlen (service
));
466 rc
= utf8cpy (host
, hostlen
, hostname
, strlen (hostname
));
474 server_callback_gssapi (Gsasl_session_ctx
* ctx
,
475 char *client_name
, char *authentication_id
)
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')
490 return GSASL_AUTHENTICATION_ERROR
;