1068e7061SPeter Avalos /*-
2068e7061SPeter Avalos * Copyright (c) 1991, 1993
3068e7061SPeter Avalos * The Regents of the University of California. All rights reserved.
4068e7061SPeter Avalos *
5068e7061SPeter Avalos * Redistribution and use in source and binary forms, with or without
6068e7061SPeter Avalos * modification, are permitted provided that the following conditions
7068e7061SPeter Avalos * are met:
8068e7061SPeter Avalos * 1. Redistributions of source code must retain the above copyright
9068e7061SPeter Avalos * notice, this list of conditions and the following disclaimer.
10068e7061SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
11068e7061SPeter Avalos * notice, this list of conditions and the following disclaimer in the
12068e7061SPeter Avalos * documentation and/or other materials provided with the distribution.
13*dc71b7abSJustin C. Sherrill * 3. Neither the name of the University nor the names of its contributors
14068e7061SPeter Avalos * may be used to endorse or promote products derived from this software
15068e7061SPeter Avalos * without specific prior written permission.
16068e7061SPeter Avalos *
17068e7061SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18068e7061SPeter Avalos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19068e7061SPeter Avalos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20068e7061SPeter Avalos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21068e7061SPeter Avalos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22068e7061SPeter Avalos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23068e7061SPeter Avalos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24068e7061SPeter Avalos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25068e7061SPeter Avalos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26068e7061SPeter Avalos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27068e7061SPeter Avalos * SUCH DAMAGE.
28068e7061SPeter Avalos *
29068e7061SPeter Avalos * $FreeBSD: src/crypto/telnet/libtelnet/auth.c,v 1.3.2.5 2002/04/13 10:59:07 markm Exp $
30068e7061SPeter Avalos *
31068e7061SPeter Avalos * @(#)auth.c 8.3 (Berkeley) 5/30/95
32068e7061SPeter Avalos * $FreeBSD: src/crypto/telnet/libtelnet/auth.c,v 1.3.2.5 2002/04/13 10:59:07 markm Exp $
33068e7061SPeter Avalos */
34068e7061SPeter Avalos
35068e7061SPeter Avalos /*
36068e7061SPeter Avalos * Copyright (C) 1990 by the Massachusetts Institute of Technology
37068e7061SPeter Avalos *
38068e7061SPeter Avalos * Export of this software from the United States of America is assumed
39068e7061SPeter Avalos * to require a specific license from the United States Government.
40068e7061SPeter Avalos * It is the responsibility of any person or organization contemplating
41068e7061SPeter Avalos * export to obtain such a license before exporting.
42068e7061SPeter Avalos *
43068e7061SPeter Avalos * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
44068e7061SPeter Avalos * distribute this software and its documentation for any purpose and
45068e7061SPeter Avalos * without fee is hereby granted, provided that the above copyright
46068e7061SPeter Avalos * notice appear in all copies and that both that copyright notice and
47068e7061SPeter Avalos * this permission notice appear in supporting documentation, and that
48068e7061SPeter Avalos * the name of M.I.T. not be used in advertising or publicity pertaining
49068e7061SPeter Avalos * to distribution of the software without specific, written prior
50068e7061SPeter Avalos * permission. M.I.T. makes no representations about the suitability of
51068e7061SPeter Avalos * this software for any purpose. It is provided "as is" without express
52068e7061SPeter Avalos * or implied warranty.
53068e7061SPeter Avalos */
54068e7061SPeter Avalos
55068e7061SPeter Avalos
56068e7061SPeter Avalos #ifdef AUTHENTICATION
57068e7061SPeter Avalos #define AUTH_NAMES
58068e7061SPeter Avalos #include <sys/types.h>
59068e7061SPeter Avalos #include <signal.h>
60068e7061SPeter Avalos #include <stdio.h>
61068e7061SPeter Avalos #include <stdlib.h>
62068e7061SPeter Avalos #include <string.h>
63068e7061SPeter Avalos #include <unistd.h>
64068e7061SPeter Avalos #include <arpa/telnet.h>
65068e7061SPeter Avalos
66068e7061SPeter Avalos #include "encrypt.h"
67068e7061SPeter Avalos #include "auth.h"
68068e7061SPeter Avalos #include "misc-proto.h"
69068e7061SPeter Avalos #include "auth-proto.h"
70068e7061SPeter Avalos
71068e7061SPeter Avalos #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
72068e7061SPeter Avalos
73068e7061SPeter Avalos #ifdef KRB4_ENCPWD
74068e7061SPeter Avalos extern krb4encpwd_init();
75068e7061SPeter Avalos extern krb4encpwd_send();
76068e7061SPeter Avalos extern krb4encpwd_is();
77068e7061SPeter Avalos extern krb4encpwd_reply();
78068e7061SPeter Avalos extern krb4encpwd_status();
79068e7061SPeter Avalos extern krb4encpwd_printsub();
80068e7061SPeter Avalos #endif
81068e7061SPeter Avalos
82068e7061SPeter Avalos #ifdef RSA_ENCPWD
83068e7061SPeter Avalos extern rsaencpwd_init();
84068e7061SPeter Avalos extern rsaencpwd_send();
85068e7061SPeter Avalos extern rsaencpwd_is();
86068e7061SPeter Avalos extern rsaencpwd_reply();
87068e7061SPeter Avalos extern rsaencpwd_status();
88068e7061SPeter Avalos extern rsaencpwd_printsub();
89068e7061SPeter Avalos #endif
90068e7061SPeter Avalos
91068e7061SPeter Avalos int auth_debug_mode = 0;
92068e7061SPeter Avalos static const char *Name = "Noname";
93068e7061SPeter Avalos static int Server = 0;
94678e8cc6SSascha Wildner static Authenticator *authenticated = NULL;
95068e7061SPeter Avalos static int authenticating = 0;
96068e7061SPeter Avalos static int validuser = 0;
97068e7061SPeter Avalos static unsigned char _auth_send_data[256];
98068e7061SPeter Avalos static unsigned char *auth_send_data;
99068e7061SPeter Avalos static int auth_send_cnt = 0;
100068e7061SPeter Avalos
101068e7061SPeter Avalos int auth_onoff(char *type, int on);
102068e7061SPeter Avalos void auth_encrypt_user(char *name);
103068e7061SPeter Avalos
104068e7061SPeter Avalos /*
105068e7061SPeter Avalos * Authentication types supported. Plese note that these are stored
106068e7061SPeter Avalos * in priority order, i.e. try the first one first.
107068e7061SPeter Avalos */
108068e7061SPeter Avalos Authenticator authenticators[] = {
109068e7061SPeter Avalos #ifdef KRB5
110068e7061SPeter Avalos # ifdef ENCRYPTION
111068e7061SPeter Avalos { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
112068e7061SPeter Avalos kerberos5_init,
113068e7061SPeter Avalos kerberos5_send_mutual,
114068e7061SPeter Avalos kerberos5_is,
115068e7061SPeter Avalos kerberos5_reply,
116068e7061SPeter Avalos kerberos5_status,
117068e7061SPeter Avalos kerberos5_printsub },
118068e7061SPeter Avalos # endif /* ENCRYPTION */
119068e7061SPeter Avalos { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
120068e7061SPeter Avalos kerberos5_init,
121068e7061SPeter Avalos kerberos5_send_oneway,
122068e7061SPeter Avalos kerberos5_is,
123068e7061SPeter Avalos kerberos5_reply,
124068e7061SPeter Avalos kerberos5_status,
125068e7061SPeter Avalos kerberos5_printsub },
126068e7061SPeter Avalos #endif
127068e7061SPeter Avalos #ifdef KRB4
128068e7061SPeter Avalos # ifdef ENCRYPTION
129068e7061SPeter Avalos { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
130068e7061SPeter Avalos kerberos4_init,
131068e7061SPeter Avalos kerberos4_send,
132068e7061SPeter Avalos kerberos4_is,
133068e7061SPeter Avalos kerberos4_reply,
134068e7061SPeter Avalos kerberos4_status,
135068e7061SPeter Avalos kerberos4_printsub },
136068e7061SPeter Avalos # endif /* ENCRYPTION */
137068e7061SPeter Avalos { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
138068e7061SPeter Avalos kerberos4_init,
139068e7061SPeter Avalos kerberos4_send,
140068e7061SPeter Avalos kerberos4_is,
141068e7061SPeter Avalos kerberos4_reply,
142068e7061SPeter Avalos kerberos4_status,
143068e7061SPeter Avalos kerberos4_printsub },
144068e7061SPeter Avalos #endif
145068e7061SPeter Avalos #ifdef KRB4_ENCPWD
146068e7061SPeter Avalos { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
147068e7061SPeter Avalos krb4encpwd_init,
148068e7061SPeter Avalos krb4encpwd_send,
149068e7061SPeter Avalos krb4encpwd_is,
150068e7061SPeter Avalos krb4encpwd_reply,
151068e7061SPeter Avalos krb4encpwd_status,
152068e7061SPeter Avalos krb4encpwd_printsub },
153068e7061SPeter Avalos #endif
154068e7061SPeter Avalos #ifdef RSA_ENCPWD
155068e7061SPeter Avalos { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
156068e7061SPeter Avalos rsaencpwd_init,
157068e7061SPeter Avalos rsaencpwd_send,
158068e7061SPeter Avalos rsaencpwd_is,
159068e7061SPeter Avalos rsaencpwd_reply,
160068e7061SPeter Avalos rsaencpwd_status,
161068e7061SPeter Avalos rsaencpwd_printsub },
162068e7061SPeter Avalos #endif
163068e7061SPeter Avalos #ifdef SRA
164068e7061SPeter Avalos { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
165068e7061SPeter Avalos sra_init,
166068e7061SPeter Avalos sra_send,
167068e7061SPeter Avalos sra_is,
168068e7061SPeter Avalos sra_reply,
169068e7061SPeter Avalos sra_status,
170068e7061SPeter Avalos sra_printsub },
171068e7061SPeter Avalos
172068e7061SPeter Avalos #endif
173068e7061SPeter Avalos { 0, 0, 0, 0, 0, 0, 0, 0 },
174068e7061SPeter Avalos };
175068e7061SPeter Avalos
176068e7061SPeter Avalos static Authenticator NoAuth = { 0, 0, 0, 0, 0, 0, 0, 0 };
177068e7061SPeter Avalos
178068e7061SPeter Avalos static int i_support = 0;
179068e7061SPeter Avalos static int i_wont_support = 0;
180068e7061SPeter Avalos
181068e7061SPeter Avalos Authenticator *
findauthenticator(int type,int way)182068e7061SPeter Avalos findauthenticator(int type, int way)
183068e7061SPeter Avalos {
184068e7061SPeter Avalos Authenticator *ap = authenticators;
185068e7061SPeter Avalos
186068e7061SPeter Avalos while (ap->type && (ap->type != type || ap->way != way))
187068e7061SPeter Avalos ++ap;
188068e7061SPeter Avalos return(ap->type ? ap : 0);
189068e7061SPeter Avalos }
190068e7061SPeter Avalos
191068e7061SPeter Avalos void
auth_init(const char * name,int server)192068e7061SPeter Avalos auth_init(const char *name, int server)
193068e7061SPeter Avalos {
194068e7061SPeter Avalos Authenticator *ap = authenticators;
195068e7061SPeter Avalos
196068e7061SPeter Avalos Server = server;
197068e7061SPeter Avalos Name = name;
198068e7061SPeter Avalos
199068e7061SPeter Avalos i_support = 0;
200678e8cc6SSascha Wildner authenticated = NULL;
201068e7061SPeter Avalos authenticating = 0;
202068e7061SPeter Avalos while (ap->type) {
203068e7061SPeter Avalos if (!ap->init || (*ap->init)(ap, server)) {
204068e7061SPeter Avalos i_support |= typemask(ap->type);
205068e7061SPeter Avalos if (auth_debug_mode)
206068e7061SPeter Avalos printf(">>>%s: I support auth type %d %d\r\n",
207068e7061SPeter Avalos Name,
208068e7061SPeter Avalos ap->type, ap->way);
209068e7061SPeter Avalos }
210068e7061SPeter Avalos else if (auth_debug_mode)
211068e7061SPeter Avalos printf(">>>%s: Init failed: auth type %d %d\r\n",
212068e7061SPeter Avalos Name, ap->type, ap->way);
213068e7061SPeter Avalos ++ap;
214068e7061SPeter Avalos }
215068e7061SPeter Avalos }
216068e7061SPeter Avalos
217068e7061SPeter Avalos void
auth_disable_name(char * name)218068e7061SPeter Avalos auth_disable_name(char *name)
219068e7061SPeter Avalos {
220068e7061SPeter Avalos int x;
221068e7061SPeter Avalos for (x = 0; x < AUTHTYPE_CNT; ++x) {
222068e7061SPeter Avalos if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) {
223068e7061SPeter Avalos i_wont_support |= typemask(x);
224068e7061SPeter Avalos break;
225068e7061SPeter Avalos }
226068e7061SPeter Avalos }
227068e7061SPeter Avalos }
228068e7061SPeter Avalos
229068e7061SPeter Avalos int
getauthmask(char * type,int * maskp)230068e7061SPeter Avalos getauthmask(char *type, int *maskp)
231068e7061SPeter Avalos {
232068e7061SPeter Avalos int x;
233068e7061SPeter Avalos
234068e7061SPeter Avalos if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) {
235068e7061SPeter Avalos *maskp = -1;
236068e7061SPeter Avalos return(1);
237068e7061SPeter Avalos }
238068e7061SPeter Avalos
239068e7061SPeter Avalos for (x = 1; x < AUTHTYPE_CNT; ++x) {
240068e7061SPeter Avalos if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) {
241068e7061SPeter Avalos *maskp = typemask(x);
242068e7061SPeter Avalos return(1);
243068e7061SPeter Avalos }
244068e7061SPeter Avalos }
245068e7061SPeter Avalos return(0);
246068e7061SPeter Avalos }
247068e7061SPeter Avalos
248068e7061SPeter Avalos int
auth_enable(char * type)249068e7061SPeter Avalos auth_enable(char *type)
250068e7061SPeter Avalos {
251068e7061SPeter Avalos return(auth_onoff(type, 1));
252068e7061SPeter Avalos }
253068e7061SPeter Avalos
254068e7061SPeter Avalos int
auth_disable(char * type)255068e7061SPeter Avalos auth_disable(char *type)
256068e7061SPeter Avalos {
257068e7061SPeter Avalos return(auth_onoff(type, 0));
258068e7061SPeter Avalos }
259068e7061SPeter Avalos
260068e7061SPeter Avalos int
auth_onoff(char * type,int on)261068e7061SPeter Avalos auth_onoff(char *type, int on)
262068e7061SPeter Avalos {
263068e7061SPeter Avalos int i, mask = -1;
264068e7061SPeter Avalos Authenticator *ap;
265068e7061SPeter Avalos
266068e7061SPeter Avalos if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
267068e7061SPeter Avalos printf("auth %s 'type'\n", on ? "enable" : "disable");
268068e7061SPeter Avalos printf("Where 'type' is one of:\n");
269068e7061SPeter Avalos printf("\t%s\n", AUTHTYPE_NAME(0));
270068e7061SPeter Avalos mask = 0;
271068e7061SPeter Avalos for (ap = authenticators; ap->type; ap++) {
272068e7061SPeter Avalos if ((mask & (i = typemask(ap->type))) != 0)
273068e7061SPeter Avalos continue;
274068e7061SPeter Avalos mask |= i;
275068e7061SPeter Avalos printf("\t%s\n", AUTHTYPE_NAME(ap->type));
276068e7061SPeter Avalos }
277068e7061SPeter Avalos return(0);
278068e7061SPeter Avalos }
279068e7061SPeter Avalos
280068e7061SPeter Avalos if (!getauthmask(type, &mask)) {
281068e7061SPeter Avalos printf("%s: invalid authentication type\n", type);
282068e7061SPeter Avalos return(0);
283068e7061SPeter Avalos }
284068e7061SPeter Avalos if (on)
285068e7061SPeter Avalos i_wont_support &= ~mask;
286068e7061SPeter Avalos else
287068e7061SPeter Avalos i_wont_support |= mask;
288068e7061SPeter Avalos return(1);
289068e7061SPeter Avalos }
290068e7061SPeter Avalos
291068e7061SPeter Avalos int
auth_togdebug(int on)292068e7061SPeter Avalos auth_togdebug(int on)
293068e7061SPeter Avalos {
294068e7061SPeter Avalos if (on < 0)
295068e7061SPeter Avalos auth_debug_mode ^= 1;
296068e7061SPeter Avalos else
297068e7061SPeter Avalos auth_debug_mode = on;
298068e7061SPeter Avalos printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
299068e7061SPeter Avalos return(1);
300068e7061SPeter Avalos }
301068e7061SPeter Avalos
302068e7061SPeter Avalos int
auth_status(void)303068e7061SPeter Avalos auth_status(void)
304068e7061SPeter Avalos {
305068e7061SPeter Avalos Authenticator *ap;
306068e7061SPeter Avalos int i, mask;
307068e7061SPeter Avalos
308068e7061SPeter Avalos if (i_wont_support == -1)
309068e7061SPeter Avalos printf("Authentication disabled\n");
310068e7061SPeter Avalos else
311068e7061SPeter Avalos printf("Authentication enabled\n");
312068e7061SPeter Avalos
313068e7061SPeter Avalos mask = 0;
314068e7061SPeter Avalos for (ap = authenticators; ap->type; ap++) {
315068e7061SPeter Avalos if ((mask & (i = typemask(ap->type))) != 0)
316068e7061SPeter Avalos continue;
317068e7061SPeter Avalos mask |= i;
318068e7061SPeter Avalos printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
319068e7061SPeter Avalos (i_wont_support & typemask(ap->type)) ?
320068e7061SPeter Avalos "disabled" : "enabled");
321068e7061SPeter Avalos }
322068e7061SPeter Avalos return(1);
323068e7061SPeter Avalos }
324068e7061SPeter Avalos
325068e7061SPeter Avalos /*
326068e7061SPeter Avalos * This routine is called by the server to start authentication
327068e7061SPeter Avalos * negotiation.
328068e7061SPeter Avalos */
329068e7061SPeter Avalos void
auth_request(void)330068e7061SPeter Avalos auth_request(void)
331068e7061SPeter Avalos {
332068e7061SPeter Avalos static unsigned char str_request[64] = { IAC, SB,
333068e7061SPeter Avalos TELOPT_AUTHENTICATION,
334068e7061SPeter Avalos TELQUAL_SEND, };
335068e7061SPeter Avalos Authenticator *ap = authenticators;
336068e7061SPeter Avalos unsigned char *e = str_request + 4;
337068e7061SPeter Avalos
338068e7061SPeter Avalos if (!authenticating) {
339068e7061SPeter Avalos authenticating = 1;
340068e7061SPeter Avalos while (ap->type) {
341068e7061SPeter Avalos if (i_support & ~i_wont_support & typemask(ap->type)) {
342068e7061SPeter Avalos if (auth_debug_mode) {
343068e7061SPeter Avalos printf(">>>%s: Sending type %d %d\r\n",
344068e7061SPeter Avalos Name, ap->type, ap->way);
345068e7061SPeter Avalos }
346068e7061SPeter Avalos *e++ = ap->type;
347068e7061SPeter Avalos *e++ = ap->way;
348068e7061SPeter Avalos }
349068e7061SPeter Avalos ++ap;
350068e7061SPeter Avalos }
351068e7061SPeter Avalos *e++ = IAC;
352068e7061SPeter Avalos *e++ = SE;
353068e7061SPeter Avalos net_write(str_request, e - str_request);
354068e7061SPeter Avalos printsub('>', &str_request[2], e - str_request - 2);
355068e7061SPeter Avalos }
356068e7061SPeter Avalos }
357068e7061SPeter Avalos
358068e7061SPeter Avalos /*
359068e7061SPeter Avalos * This is called when an AUTH SEND is received.
360068e7061SPeter Avalos * It should never arrive on the server side (as only the server can
361068e7061SPeter Avalos * send an AUTH SEND).
362068e7061SPeter Avalos * You should probably respond to it if you can...
363068e7061SPeter Avalos *
364068e7061SPeter Avalos * If you want to respond to the types out of order (i.e. even
365068e7061SPeter Avalos * if he sends LOGIN KERBEROS and you support both, you respond
366068e7061SPeter Avalos * with KERBEROS instead of LOGIN (which is against what the
367068e7061SPeter Avalos * protocol says)) you will have to hack this code...
368068e7061SPeter Avalos */
369068e7061SPeter Avalos void
auth_send(unsigned char * data,int cnt)370068e7061SPeter Avalos auth_send(unsigned char *data, int cnt)
371068e7061SPeter Avalos {
372068e7061SPeter Avalos Authenticator *ap;
373068e7061SPeter Avalos static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
374068e7061SPeter Avalos TELQUAL_IS, AUTHTYPE_NULL, 0,
375068e7061SPeter Avalos IAC, SE };
376068e7061SPeter Avalos if (Server) {
377068e7061SPeter Avalos if (auth_debug_mode) {
378068e7061SPeter Avalos printf(">>>%s: auth_send called!\r\n", Name);
379068e7061SPeter Avalos }
380068e7061SPeter Avalos return;
381068e7061SPeter Avalos }
382068e7061SPeter Avalos
383068e7061SPeter Avalos if (auth_debug_mode) {
384068e7061SPeter Avalos printf(">>>%s: auth_send got:", Name);
385068e7061SPeter Avalos printd(data, cnt); printf("\r\n");
386068e7061SPeter Avalos }
387068e7061SPeter Avalos
388068e7061SPeter Avalos /*
389068e7061SPeter Avalos * Save the data, if it is new, so that we can continue looking
390068e7061SPeter Avalos * at it if the authorization we try doesn't work
391068e7061SPeter Avalos */
392068e7061SPeter Avalos if (data < _auth_send_data ||
393068e7061SPeter Avalos data > _auth_send_data + sizeof(_auth_send_data)) {
394068e7061SPeter Avalos auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data)
395068e7061SPeter Avalos ? sizeof(_auth_send_data)
396068e7061SPeter Avalos : cnt;
397068e7061SPeter Avalos memmove((void *)_auth_send_data, (void *)data, auth_send_cnt);
398068e7061SPeter Avalos auth_send_data = _auth_send_data;
399068e7061SPeter Avalos } else {
400068e7061SPeter Avalos /*
401068e7061SPeter Avalos * This is probably a no-op, but we just make sure
402068e7061SPeter Avalos */
403068e7061SPeter Avalos auth_send_data = data;
404068e7061SPeter Avalos auth_send_cnt = cnt;
405068e7061SPeter Avalos }
406068e7061SPeter Avalos while ((auth_send_cnt -= 2) >= 0) {
407068e7061SPeter Avalos if (auth_debug_mode)
408068e7061SPeter Avalos printf(">>>%s: He supports %d\r\n",
409068e7061SPeter Avalos Name, *auth_send_data);
410068e7061SPeter Avalos if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) {
411068e7061SPeter Avalos ap = findauthenticator(auth_send_data[0],
412068e7061SPeter Avalos auth_send_data[1]);
413068e7061SPeter Avalos if (ap && ap->send) {
414068e7061SPeter Avalos if (auth_debug_mode)
415068e7061SPeter Avalos printf(">>>%s: Trying %d %d\r\n",
416068e7061SPeter Avalos Name, auth_send_data[0],
417068e7061SPeter Avalos auth_send_data[1]);
418068e7061SPeter Avalos if ((*ap->send)(ap)) {
419068e7061SPeter Avalos /*
420068e7061SPeter Avalos * Okay, we found one we like
421068e7061SPeter Avalos * and did it.
422068e7061SPeter Avalos * we can go home now.
423068e7061SPeter Avalos */
424068e7061SPeter Avalos if (auth_debug_mode)
425068e7061SPeter Avalos printf(">>>%s: Using type %d\r\n",
426068e7061SPeter Avalos Name, *auth_send_data);
427068e7061SPeter Avalos auth_send_data += 2;
428068e7061SPeter Avalos return;
429068e7061SPeter Avalos }
430068e7061SPeter Avalos }
431068e7061SPeter Avalos /* else
432068e7061SPeter Avalos * just continue on and look for the
433068e7061SPeter Avalos * next one if we didn't do anything.
434068e7061SPeter Avalos */
435068e7061SPeter Avalos }
436068e7061SPeter Avalos auth_send_data += 2;
437068e7061SPeter Avalos }
438068e7061SPeter Avalos net_write(str_none, sizeof(str_none));
439068e7061SPeter Avalos printsub('>', &str_none[2], sizeof(str_none) - 2);
440068e7061SPeter Avalos if (auth_debug_mode)
441068e7061SPeter Avalos printf(">>>%s: Sent failure message\r\n", Name);
442068e7061SPeter Avalos auth_finished(0, AUTH_REJECT);
443068e7061SPeter Avalos }
444068e7061SPeter Avalos
445068e7061SPeter Avalos void
auth_send_retry(void)446068e7061SPeter Avalos auth_send_retry(void)
447068e7061SPeter Avalos {
448068e7061SPeter Avalos /*
449068e7061SPeter Avalos * if auth_send_cnt <= 0 then auth_send will end up rejecting
450068e7061SPeter Avalos * the authentication and informing the other side of this.
451068e7061SPeter Avalos */
452068e7061SPeter Avalos auth_send(auth_send_data, auth_send_cnt);
453068e7061SPeter Avalos }
454068e7061SPeter Avalos
455068e7061SPeter Avalos void
auth_is(unsigned char * data,int cnt)456068e7061SPeter Avalos auth_is(unsigned char *data, int cnt)
457068e7061SPeter Avalos {
458068e7061SPeter Avalos Authenticator *ap;
459068e7061SPeter Avalos
460068e7061SPeter Avalos if (cnt < 2)
461068e7061SPeter Avalos return;
462068e7061SPeter Avalos
463068e7061SPeter Avalos if (data[0] == AUTHTYPE_NULL) {
464068e7061SPeter Avalos auth_finished(0, AUTH_REJECT);
465068e7061SPeter Avalos return;
466068e7061SPeter Avalos }
467068e7061SPeter Avalos
468068e7061SPeter Avalos if ((ap = findauthenticator(data[0], data[1]))) {
469068e7061SPeter Avalos if (ap->is)
470068e7061SPeter Avalos (*ap->is)(ap, data+2, cnt-2);
471068e7061SPeter Avalos } else if (auth_debug_mode)
472068e7061SPeter Avalos printf(">>>%s: Invalid authentication in IS: %d\r\n",
473068e7061SPeter Avalos Name, *data);
474068e7061SPeter Avalos }
475068e7061SPeter Avalos
476068e7061SPeter Avalos void
auth_reply(unsigned char * data,int cnt)477068e7061SPeter Avalos auth_reply(unsigned char *data, int cnt)
478068e7061SPeter Avalos {
479068e7061SPeter Avalos Authenticator *ap;
480068e7061SPeter Avalos
481068e7061SPeter Avalos if (cnt < 2)
482068e7061SPeter Avalos return;
483068e7061SPeter Avalos
484068e7061SPeter Avalos if ((ap = findauthenticator(data[0], data[1]))) {
485068e7061SPeter Avalos if (ap->reply)
486068e7061SPeter Avalos (*ap->reply)(ap, data+2, cnt-2);
487068e7061SPeter Avalos } else if (auth_debug_mode)
488068e7061SPeter Avalos printf(">>>%s: Invalid authentication in SEND: %d\r\n",
489068e7061SPeter Avalos Name, *data);
490068e7061SPeter Avalos }
491068e7061SPeter Avalos
492068e7061SPeter Avalos void
auth_name(unsigned char * data,int cnt)493068e7061SPeter Avalos auth_name(unsigned char *data, int cnt)
494068e7061SPeter Avalos {
495068e7061SPeter Avalos unsigned char savename[256];
496068e7061SPeter Avalos
497068e7061SPeter Avalos if (cnt < 1) {
498068e7061SPeter Avalos if (auth_debug_mode)
499068e7061SPeter Avalos printf(">>>%s: Empty name in NAME\r\n", Name);
500068e7061SPeter Avalos return;
501068e7061SPeter Avalos }
502068e7061SPeter Avalos if ((size_t)cnt > sizeof(savename) - 1) {
503068e7061SPeter Avalos if (auth_debug_mode)
504068e7061SPeter Avalos printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n",
505068e7061SPeter Avalos Name, cnt, (u_int)sizeof(savename)-1);
506068e7061SPeter Avalos return;
507068e7061SPeter Avalos }
508068e7061SPeter Avalos memmove((void *)savename, (void *)data, cnt);
509068e7061SPeter Avalos savename[cnt] = '\0'; /* Null terminate */
510068e7061SPeter Avalos if (auth_debug_mode)
511068e7061SPeter Avalos printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
512068e7061SPeter Avalos auth_encrypt_user(savename);
513068e7061SPeter Avalos }
514068e7061SPeter Avalos
515068e7061SPeter Avalos int
auth_sendname(unsigned char * cp,int len)516068e7061SPeter Avalos auth_sendname(unsigned char *cp, int len)
517068e7061SPeter Avalos {
518068e7061SPeter Avalos static unsigned char str_request[256+6]
519068e7061SPeter Avalos = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
520068e7061SPeter Avalos unsigned char *e = str_request + 4;
521068e7061SPeter Avalos unsigned char *ee = &str_request[sizeof(str_request)-2];
522068e7061SPeter Avalos
523068e7061SPeter Avalos while (--len >= 0) {
524068e7061SPeter Avalos if ((*e++ = *cp++) == IAC)
525068e7061SPeter Avalos *e++ = IAC;
526068e7061SPeter Avalos if (e >= ee)
527068e7061SPeter Avalos return(0);
528068e7061SPeter Avalos }
529068e7061SPeter Avalos *e++ = IAC;
530068e7061SPeter Avalos *e++ = SE;
531068e7061SPeter Avalos net_write(str_request, e - str_request);
532068e7061SPeter Avalos printsub('>', &str_request[2], e - &str_request[2]);
533068e7061SPeter Avalos return(1);
534068e7061SPeter Avalos }
535068e7061SPeter Avalos
536068e7061SPeter Avalos void
auth_finished(Authenticator * ap,int result)537068e7061SPeter Avalos auth_finished(Authenticator *ap, int result)
538068e7061SPeter Avalos {
539068e7061SPeter Avalos if (!(authenticated = ap))
540068e7061SPeter Avalos authenticated = &NoAuth;
541068e7061SPeter Avalos validuser = result;
542068e7061SPeter Avalos }
543068e7061SPeter Avalos
544068e7061SPeter Avalos /* ARGSUSED */
545068e7061SPeter Avalos static void
auth_intr(int sig __unused)546068e7061SPeter Avalos auth_intr(int sig __unused)
547068e7061SPeter Avalos {
548068e7061SPeter Avalos auth_finished(0, AUTH_REJECT);
549068e7061SPeter Avalos }
550068e7061SPeter Avalos
551068e7061SPeter Avalos int
auth_wait(char * name)552068e7061SPeter Avalos auth_wait(char *name)
553068e7061SPeter Avalos {
554068e7061SPeter Avalos if (auth_debug_mode)
555068e7061SPeter Avalos printf(">>>%s: in auth_wait.\r\n", Name);
556068e7061SPeter Avalos
557068e7061SPeter Avalos if (Server && !authenticating)
558068e7061SPeter Avalos return(0);
559068e7061SPeter Avalos
560068e7061SPeter Avalos (void) signal(SIGALRM, auth_intr);
561068e7061SPeter Avalos alarm(30);
562068e7061SPeter Avalos while (!authenticated)
563068e7061SPeter Avalos if (telnet_spin())
564068e7061SPeter Avalos break;
565068e7061SPeter Avalos alarm(0);
566068e7061SPeter Avalos (void) signal(SIGALRM, SIG_DFL);
567068e7061SPeter Avalos
568068e7061SPeter Avalos /*
569068e7061SPeter Avalos * Now check to see if the user is valid or not
570068e7061SPeter Avalos */
571068e7061SPeter Avalos if (!authenticated || authenticated == &NoAuth)
572068e7061SPeter Avalos return(AUTH_REJECT);
573068e7061SPeter Avalos
574068e7061SPeter Avalos if (validuser == AUTH_VALID)
575068e7061SPeter Avalos validuser = AUTH_USER;
576068e7061SPeter Avalos
577068e7061SPeter Avalos if (authenticated->status)
578068e7061SPeter Avalos validuser = (*authenticated->status)(authenticated,
579068e7061SPeter Avalos name, validuser);
580068e7061SPeter Avalos return(validuser);
581068e7061SPeter Avalos }
582068e7061SPeter Avalos
583068e7061SPeter Avalos void
auth_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)584068e7061SPeter Avalos auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
585068e7061SPeter Avalos {
586068e7061SPeter Avalos Authenticator *ap;
587068e7061SPeter Avalos
588068e7061SPeter Avalos if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
589068e7061SPeter Avalos (*ap->printsub)(data, cnt, buf, buflen);
590068e7061SPeter Avalos else
591068e7061SPeter Avalos auth_gen_printsub(data, cnt, buf, buflen);
592068e7061SPeter Avalos }
593068e7061SPeter Avalos
594068e7061SPeter Avalos void
auth_gen_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)595068e7061SPeter Avalos auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
596068e7061SPeter Avalos {
597068e7061SPeter Avalos unsigned char *cp;
598068e7061SPeter Avalos unsigned char tbuf[16];
599068e7061SPeter Avalos
600068e7061SPeter Avalos cnt -= 3;
601068e7061SPeter Avalos data += 3;
602068e7061SPeter Avalos buf[buflen-1] = '\0';
603068e7061SPeter Avalos buf[buflen-2] = '*';
604068e7061SPeter Avalos buflen -= 2;
605068e7061SPeter Avalos for (; cnt > 0; cnt--, data++) {
606068e7061SPeter Avalos sprintf((char *)tbuf, " %d", *data);
607068e7061SPeter Avalos for (cp = tbuf; *cp && buflen > 0; --buflen)
608068e7061SPeter Avalos *buf++ = *cp++;
609068e7061SPeter Avalos if (buflen <= 0)
610068e7061SPeter Avalos return;
611068e7061SPeter Avalos }
612068e7061SPeter Avalos *buf = '\0';
613068e7061SPeter Avalos }
614068e7061SPeter Avalos #endif
615