1*7348b5c5SDavid van Moolenbroek /* $NetBSD: auth.c,v 1.21 2012/03/21 05:33:27 matt Exp $ */
2*7348b5c5SDavid van Moolenbroek
3*7348b5c5SDavid van Moolenbroek /*-
4*7348b5c5SDavid van Moolenbroek * Copyright (c) 1991, 1993
5*7348b5c5SDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
6*7348b5c5SDavid van Moolenbroek *
7*7348b5c5SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
8*7348b5c5SDavid van Moolenbroek * modification, are permitted provided that the following conditions
9*7348b5c5SDavid van Moolenbroek * are met:
10*7348b5c5SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
11*7348b5c5SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
12*7348b5c5SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
13*7348b5c5SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
14*7348b5c5SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
15*7348b5c5SDavid van Moolenbroek * 3. Neither the name of the University nor the names of its contributors
16*7348b5c5SDavid van Moolenbroek * may be used to endorse or promote products derived from this software
17*7348b5c5SDavid van Moolenbroek * without specific prior written permission.
18*7348b5c5SDavid van Moolenbroek *
19*7348b5c5SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*7348b5c5SDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*7348b5c5SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*7348b5c5SDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*7348b5c5SDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*7348b5c5SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*7348b5c5SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*7348b5c5SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*7348b5c5SDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*7348b5c5SDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*7348b5c5SDavid van Moolenbroek * SUCH DAMAGE.
30*7348b5c5SDavid van Moolenbroek */
31*7348b5c5SDavid van Moolenbroek
32*7348b5c5SDavid van Moolenbroek #include <sys/cdefs.h>
33*7348b5c5SDavid van Moolenbroek #ifndef lint
34*7348b5c5SDavid van Moolenbroek #if 0
35*7348b5c5SDavid van Moolenbroek static char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95"
36*7348b5c5SDavid van Moolenbroek #else
37*7348b5c5SDavid van Moolenbroek __RCSID("$NetBSD: auth.c,v 1.21 2012/03/21 05:33:27 matt Exp $");
38*7348b5c5SDavid van Moolenbroek #endif
39*7348b5c5SDavid van Moolenbroek #endif /* not lint */
40*7348b5c5SDavid van Moolenbroek
41*7348b5c5SDavid van Moolenbroek /*
42*7348b5c5SDavid van Moolenbroek * Copyright (C) 1990 by the Massachusetts Institute of Technology
43*7348b5c5SDavid van Moolenbroek *
44*7348b5c5SDavid van Moolenbroek * Export of this software from the United States of America is assumed
45*7348b5c5SDavid van Moolenbroek * to require a specific license from the United States Government.
46*7348b5c5SDavid van Moolenbroek * It is the responsibility of any person or organization contemplating
47*7348b5c5SDavid van Moolenbroek * export to obtain such a license before exporting.
48*7348b5c5SDavid van Moolenbroek *
49*7348b5c5SDavid van Moolenbroek * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
50*7348b5c5SDavid van Moolenbroek * distribute this software and its documentation for any purpose and
51*7348b5c5SDavid van Moolenbroek * without fee is hereby granted, provided that the above copyright
52*7348b5c5SDavid van Moolenbroek * notice appear in all copies and that both that copyright notice and
53*7348b5c5SDavid van Moolenbroek * this permission notice appear in supporting documentation, and that
54*7348b5c5SDavid van Moolenbroek * the name of M.I.T. not be used in advertising or publicity pertaining
55*7348b5c5SDavid van Moolenbroek * to distribution of the software without specific, written prior
56*7348b5c5SDavid van Moolenbroek * permission. M.I.T. makes no representations about the suitability of
57*7348b5c5SDavid van Moolenbroek * this software for any purpose. It is provided "as is" without express
58*7348b5c5SDavid van Moolenbroek * or implied warranty.
59*7348b5c5SDavid van Moolenbroek */
60*7348b5c5SDavid van Moolenbroek
61*7348b5c5SDavid van Moolenbroek
62*7348b5c5SDavid van Moolenbroek #ifdef AUTHENTICATION
63*7348b5c5SDavid van Moolenbroek #include <stdio.h>
64*7348b5c5SDavid van Moolenbroek #include <sys/types.h>
65*7348b5c5SDavid van Moolenbroek #include <signal.h>
66*7348b5c5SDavid van Moolenbroek #define AUTH_NAMES
67*7348b5c5SDavid van Moolenbroek #include <arpa/telnet.h>
68*7348b5c5SDavid van Moolenbroek #include <stdlib.h>
69*7348b5c5SDavid van Moolenbroek #include <unistd.h>
70*7348b5c5SDavid van Moolenbroek #ifdef NO_STRING_H
71*7348b5c5SDavid van Moolenbroek #include <strings.h>
72*7348b5c5SDavid van Moolenbroek #else
73*7348b5c5SDavid van Moolenbroek #include <string.h>
74*7348b5c5SDavid van Moolenbroek #endif
75*7348b5c5SDavid van Moolenbroek
76*7348b5c5SDavid van Moolenbroek #include "encrypt.h"
77*7348b5c5SDavid van Moolenbroek #include "auth.h"
78*7348b5c5SDavid van Moolenbroek #include "misc-proto.h"
79*7348b5c5SDavid van Moolenbroek #include "auth-proto.h"
80*7348b5c5SDavid van Moolenbroek
81*7348b5c5SDavid van Moolenbroek #define typemask(x) (1<<((x)-1))
82*7348b5c5SDavid van Moolenbroek
83*7348b5c5SDavid van Moolenbroek #ifdef RSA_ENCPWD
84*7348b5c5SDavid van Moolenbroek extern rsaencpwd_init();
85*7348b5c5SDavid van Moolenbroek extern rsaencpwd_send();
86*7348b5c5SDavid van Moolenbroek extern rsaencpwd_is();
87*7348b5c5SDavid van Moolenbroek extern rsaencpwd_reply();
88*7348b5c5SDavid van Moolenbroek extern rsaencpwd_status();
89*7348b5c5SDavid van Moolenbroek extern rsaencpwd_printsub();
90*7348b5c5SDavid van Moolenbroek #endif
91*7348b5c5SDavid van Moolenbroek
92*7348b5c5SDavid van Moolenbroek int auth_debug_mode = 0;
93*7348b5c5SDavid van Moolenbroek static const char *Name = "Noname";
94*7348b5c5SDavid van Moolenbroek static int Server = 0;
95*7348b5c5SDavid van Moolenbroek static Authenticator *authenticated = 0;
96*7348b5c5SDavid van Moolenbroek static int authenticating = 0;
97*7348b5c5SDavid van Moolenbroek static int validuser = 0;
98*7348b5c5SDavid van Moolenbroek static unsigned char _auth_send_data[256];
99*7348b5c5SDavid van Moolenbroek static unsigned char *auth_send_data;
100*7348b5c5SDavid van Moolenbroek static int auth_send_cnt = 0;
101*7348b5c5SDavid van Moolenbroek
102*7348b5c5SDavid van Moolenbroek static void auth_intr(int);
103*7348b5c5SDavid van Moolenbroek
104*7348b5c5SDavid van Moolenbroek /*
105*7348b5c5SDavid van Moolenbroek * Authentication types supported. Plese note that these are stored
106*7348b5c5SDavid van Moolenbroek * in priority order, i.e. try the first one first.
107*7348b5c5SDavid van Moolenbroek */
108*7348b5c5SDavid van Moolenbroek Authenticator authenticators[] = {
109*7348b5c5SDavid van Moolenbroek #ifdef SPX
110*7348b5c5SDavid van Moolenbroek { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
111*7348b5c5SDavid van Moolenbroek spx_init,
112*7348b5c5SDavid van Moolenbroek spx_send,
113*7348b5c5SDavid van Moolenbroek spx_is,
114*7348b5c5SDavid van Moolenbroek spx_reply,
115*7348b5c5SDavid van Moolenbroek spx_status,
116*7348b5c5SDavid van Moolenbroek spx_printsub },
117*7348b5c5SDavid van Moolenbroek { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
118*7348b5c5SDavid van Moolenbroek spx_init,
119*7348b5c5SDavid van Moolenbroek spx_send,
120*7348b5c5SDavid van Moolenbroek spx_is,
121*7348b5c5SDavid van Moolenbroek spx_reply,
122*7348b5c5SDavid van Moolenbroek spx_status,
123*7348b5c5SDavid van Moolenbroek spx_printsub },
124*7348b5c5SDavid van Moolenbroek #endif
125*7348b5c5SDavid van Moolenbroek #ifdef KRB5
126*7348b5c5SDavid van Moolenbroek # ifdef ENCRYPTION
127*7348b5c5SDavid van Moolenbroek { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
128*7348b5c5SDavid van Moolenbroek kerberos5_init,
129*7348b5c5SDavid van Moolenbroek kerberos5_send,
130*7348b5c5SDavid van Moolenbroek kerberos5_is,
131*7348b5c5SDavid van Moolenbroek kerberos5_reply,
132*7348b5c5SDavid van Moolenbroek kerberos5_status,
133*7348b5c5SDavid van Moolenbroek kerberos5_printsub },
134*7348b5c5SDavid van Moolenbroek # endif /* ENCRYPTION */
135*7348b5c5SDavid van Moolenbroek { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
136*7348b5c5SDavid van Moolenbroek kerberos5_init,
137*7348b5c5SDavid van Moolenbroek kerberos5_send,
138*7348b5c5SDavid van Moolenbroek kerberos5_is,
139*7348b5c5SDavid van Moolenbroek kerberos5_reply,
140*7348b5c5SDavid van Moolenbroek kerberos5_status,
141*7348b5c5SDavid van Moolenbroek kerberos5_printsub },
142*7348b5c5SDavid van Moolenbroek #endif
143*7348b5c5SDavid van Moolenbroek #ifdef RSA_ENCPWD
144*7348b5c5SDavid van Moolenbroek { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
145*7348b5c5SDavid van Moolenbroek rsaencpwd_init,
146*7348b5c5SDavid van Moolenbroek rsaencpwd_send,
147*7348b5c5SDavid van Moolenbroek rsaencpwd_is,
148*7348b5c5SDavid van Moolenbroek rsaencpwd_reply,
149*7348b5c5SDavid van Moolenbroek rsaencpwd_status,
150*7348b5c5SDavid van Moolenbroek rsaencpwd_printsub },
151*7348b5c5SDavid van Moolenbroek #endif
152*7348b5c5SDavid van Moolenbroek #ifdef SRA
153*7348b5c5SDavid van Moolenbroek { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
154*7348b5c5SDavid van Moolenbroek sra_init,
155*7348b5c5SDavid van Moolenbroek sra_send,
156*7348b5c5SDavid van Moolenbroek sra_is,
157*7348b5c5SDavid van Moolenbroek sra_reply,
158*7348b5c5SDavid van Moolenbroek sra_status,
159*7348b5c5SDavid van Moolenbroek sra_printsub },
160*7348b5c5SDavid van Moolenbroek
161*7348b5c5SDavid van Moolenbroek #endif
162*7348b5c5SDavid van Moolenbroek { 0, 0, 0, 0, 0, 0, 0, 0 },
163*7348b5c5SDavid van Moolenbroek };
164*7348b5c5SDavid van Moolenbroek
165*7348b5c5SDavid van Moolenbroek static Authenticator NoAuth = { .type = 0 };
166*7348b5c5SDavid van Moolenbroek
167*7348b5c5SDavid van Moolenbroek static int i_support = 0;
168*7348b5c5SDavid van Moolenbroek static int i_wont_support = 0;
169*7348b5c5SDavid van Moolenbroek
170*7348b5c5SDavid van Moolenbroek Authenticator *
findauthenticator(int type,int way)171*7348b5c5SDavid van Moolenbroek findauthenticator(int type, int way)
172*7348b5c5SDavid van Moolenbroek {
173*7348b5c5SDavid van Moolenbroek Authenticator *ap = authenticators;
174*7348b5c5SDavid van Moolenbroek
175*7348b5c5SDavid van Moolenbroek while (ap->type && (ap->type != type || ap->way != way))
176*7348b5c5SDavid van Moolenbroek ++ap;
177*7348b5c5SDavid van Moolenbroek return(ap->type ? ap : 0);
178*7348b5c5SDavid van Moolenbroek }
179*7348b5c5SDavid van Moolenbroek
180*7348b5c5SDavid van Moolenbroek void
auth_init(const char * name,int server)181*7348b5c5SDavid van Moolenbroek auth_init(const char *name, int server)
182*7348b5c5SDavid van Moolenbroek {
183*7348b5c5SDavid van Moolenbroek Authenticator *ap = authenticators;
184*7348b5c5SDavid van Moolenbroek
185*7348b5c5SDavid van Moolenbroek Server = server;
186*7348b5c5SDavid van Moolenbroek Name = name;
187*7348b5c5SDavid van Moolenbroek
188*7348b5c5SDavid van Moolenbroek i_support = 0;
189*7348b5c5SDavid van Moolenbroek authenticated = 0;
190*7348b5c5SDavid van Moolenbroek authenticating = 0;
191*7348b5c5SDavid van Moolenbroek while (ap->type) {
192*7348b5c5SDavid van Moolenbroek if (!ap->init || (*ap->init)(ap, server)) {
193*7348b5c5SDavid van Moolenbroek i_support |= typemask(ap->type);
194*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
195*7348b5c5SDavid van Moolenbroek printf(">>>%s: I support auth type %d %d\r\n",
196*7348b5c5SDavid van Moolenbroek Name,
197*7348b5c5SDavid van Moolenbroek ap->type, ap->way);
198*7348b5c5SDavid van Moolenbroek }
199*7348b5c5SDavid van Moolenbroek else if (auth_debug_mode)
200*7348b5c5SDavid van Moolenbroek printf(">>>%s: Init failed: auth type %d %d\r\n",
201*7348b5c5SDavid van Moolenbroek Name, ap->type, ap->way);
202*7348b5c5SDavid van Moolenbroek ++ap;
203*7348b5c5SDavid van Moolenbroek }
204*7348b5c5SDavid van Moolenbroek }
205*7348b5c5SDavid van Moolenbroek
206*7348b5c5SDavid van Moolenbroek void
auth_disable_name(char * name)207*7348b5c5SDavid van Moolenbroek auth_disable_name(char *name)
208*7348b5c5SDavid van Moolenbroek {
209*7348b5c5SDavid van Moolenbroek int x;
210*7348b5c5SDavid van Moolenbroek for (x = 0; x < AUTHTYPE_CNT; ++x) {
211*7348b5c5SDavid van Moolenbroek if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) {
212*7348b5c5SDavid van Moolenbroek i_wont_support |= typemask(x);
213*7348b5c5SDavid van Moolenbroek break;
214*7348b5c5SDavid van Moolenbroek }
215*7348b5c5SDavid van Moolenbroek }
216*7348b5c5SDavid van Moolenbroek }
217*7348b5c5SDavid van Moolenbroek
218*7348b5c5SDavid van Moolenbroek int
getauthmask(char * type,int * maskp)219*7348b5c5SDavid van Moolenbroek getauthmask(char *type, int *maskp)
220*7348b5c5SDavid van Moolenbroek {
221*7348b5c5SDavid van Moolenbroek register int x;
222*7348b5c5SDavid van Moolenbroek
223*7348b5c5SDavid van Moolenbroek if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) {
224*7348b5c5SDavid van Moolenbroek *maskp = -1;
225*7348b5c5SDavid van Moolenbroek return(1);
226*7348b5c5SDavid van Moolenbroek }
227*7348b5c5SDavid van Moolenbroek
228*7348b5c5SDavid van Moolenbroek for (x = 1; x < AUTHTYPE_CNT; ++x) {
229*7348b5c5SDavid van Moolenbroek if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) {
230*7348b5c5SDavid van Moolenbroek *maskp = typemask(x);
231*7348b5c5SDavid van Moolenbroek return(1);
232*7348b5c5SDavid van Moolenbroek }
233*7348b5c5SDavid van Moolenbroek }
234*7348b5c5SDavid van Moolenbroek return(0);
235*7348b5c5SDavid van Moolenbroek }
236*7348b5c5SDavid van Moolenbroek
237*7348b5c5SDavid van Moolenbroek int
auth_enable(char * type)238*7348b5c5SDavid van Moolenbroek auth_enable(char *type)
239*7348b5c5SDavid van Moolenbroek {
240*7348b5c5SDavid van Moolenbroek return(auth_onoff(type, 1));
241*7348b5c5SDavid van Moolenbroek }
242*7348b5c5SDavid van Moolenbroek
243*7348b5c5SDavid van Moolenbroek int
auth_disable(char * type)244*7348b5c5SDavid van Moolenbroek auth_disable(char *type)
245*7348b5c5SDavid van Moolenbroek {
246*7348b5c5SDavid van Moolenbroek return(auth_onoff(type, 0));
247*7348b5c5SDavid van Moolenbroek }
248*7348b5c5SDavid van Moolenbroek
249*7348b5c5SDavid van Moolenbroek int
auth_onoff(char * type,int on)250*7348b5c5SDavid van Moolenbroek auth_onoff(char *type, int on)
251*7348b5c5SDavid van Moolenbroek {
252*7348b5c5SDavid van Moolenbroek int i, mask = -1;
253*7348b5c5SDavid van Moolenbroek Authenticator *ap;
254*7348b5c5SDavid van Moolenbroek
255*7348b5c5SDavid van Moolenbroek if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
256*7348b5c5SDavid van Moolenbroek printf("auth %s 'type'\n", on ? "enable" : "disable");
257*7348b5c5SDavid van Moolenbroek printf("Where 'type' is one of:\n");
258*7348b5c5SDavid van Moolenbroek printf("\t%s\n", AUTHTYPE_NAME(0));
259*7348b5c5SDavid van Moolenbroek mask = 0;
260*7348b5c5SDavid van Moolenbroek for (ap = authenticators; ap->type; ap++) {
261*7348b5c5SDavid van Moolenbroek if ((mask & (i = typemask(ap->type))) != 0)
262*7348b5c5SDavid van Moolenbroek continue;
263*7348b5c5SDavid van Moolenbroek mask |= i;
264*7348b5c5SDavid van Moolenbroek printf("\t%s\n", AUTHTYPE_NAME(ap->type));
265*7348b5c5SDavid van Moolenbroek }
266*7348b5c5SDavid van Moolenbroek return(0);
267*7348b5c5SDavid van Moolenbroek }
268*7348b5c5SDavid van Moolenbroek
269*7348b5c5SDavid van Moolenbroek if (!getauthmask(type, &mask)) {
270*7348b5c5SDavid van Moolenbroek printf("%s: invalid authentication type\n", type);
271*7348b5c5SDavid van Moolenbroek return(0);
272*7348b5c5SDavid van Moolenbroek }
273*7348b5c5SDavid van Moolenbroek if (on)
274*7348b5c5SDavid van Moolenbroek i_wont_support &= ~mask;
275*7348b5c5SDavid van Moolenbroek else
276*7348b5c5SDavid van Moolenbroek i_wont_support |= mask;
277*7348b5c5SDavid van Moolenbroek return(1);
278*7348b5c5SDavid van Moolenbroek }
279*7348b5c5SDavid van Moolenbroek
280*7348b5c5SDavid van Moolenbroek int
auth_togdebug(int on)281*7348b5c5SDavid van Moolenbroek auth_togdebug(int on)
282*7348b5c5SDavid van Moolenbroek {
283*7348b5c5SDavid van Moolenbroek if (on < 0)
284*7348b5c5SDavid van Moolenbroek auth_debug_mode ^= 1;
285*7348b5c5SDavid van Moolenbroek else
286*7348b5c5SDavid van Moolenbroek auth_debug_mode = on;
287*7348b5c5SDavid van Moolenbroek printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
288*7348b5c5SDavid van Moolenbroek return(1);
289*7348b5c5SDavid van Moolenbroek }
290*7348b5c5SDavid van Moolenbroek
291*7348b5c5SDavid van Moolenbroek int
auth_status(char * s)292*7348b5c5SDavid van Moolenbroek auth_status(char *s)
293*7348b5c5SDavid van Moolenbroek {
294*7348b5c5SDavid van Moolenbroek Authenticator *ap;
295*7348b5c5SDavid van Moolenbroek int i, mask;
296*7348b5c5SDavid van Moolenbroek
297*7348b5c5SDavid van Moolenbroek if (i_wont_support == -1)
298*7348b5c5SDavid van Moolenbroek printf("Authentication disabled\n");
299*7348b5c5SDavid van Moolenbroek else
300*7348b5c5SDavid van Moolenbroek printf("Authentication enabled\n");
301*7348b5c5SDavid van Moolenbroek
302*7348b5c5SDavid van Moolenbroek mask = 0;
303*7348b5c5SDavid van Moolenbroek for (ap = authenticators; ap->type; ap++) {
304*7348b5c5SDavid van Moolenbroek if ((mask & (i = typemask(ap->type))) != 0)
305*7348b5c5SDavid van Moolenbroek continue;
306*7348b5c5SDavid van Moolenbroek mask |= i;
307*7348b5c5SDavid van Moolenbroek printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
308*7348b5c5SDavid van Moolenbroek (i_wont_support & typemask(ap->type)) ?
309*7348b5c5SDavid van Moolenbroek "disabled" : "enabled");
310*7348b5c5SDavid van Moolenbroek }
311*7348b5c5SDavid van Moolenbroek return(1);
312*7348b5c5SDavid van Moolenbroek }
313*7348b5c5SDavid van Moolenbroek
314*7348b5c5SDavid van Moolenbroek /*
315*7348b5c5SDavid van Moolenbroek * This routine is called by the server to start authentication
316*7348b5c5SDavid van Moolenbroek * negotiation.
317*7348b5c5SDavid van Moolenbroek */
318*7348b5c5SDavid van Moolenbroek void
auth_request(void)319*7348b5c5SDavid van Moolenbroek auth_request(void)
320*7348b5c5SDavid van Moolenbroek {
321*7348b5c5SDavid van Moolenbroek static unsigned char str_request[64] = { IAC, SB,
322*7348b5c5SDavid van Moolenbroek TELOPT_AUTHENTICATION,
323*7348b5c5SDavid van Moolenbroek TELQUAL_SEND, };
324*7348b5c5SDavid van Moolenbroek Authenticator *ap = authenticators;
325*7348b5c5SDavid van Moolenbroek unsigned char *e = str_request + 4;
326*7348b5c5SDavid van Moolenbroek
327*7348b5c5SDavid van Moolenbroek if (!authenticating) {
328*7348b5c5SDavid van Moolenbroek authenticating = 1;
329*7348b5c5SDavid van Moolenbroek while (ap->type) {
330*7348b5c5SDavid van Moolenbroek if (i_support & ~i_wont_support & typemask(ap->type)) {
331*7348b5c5SDavid van Moolenbroek if (auth_debug_mode) {
332*7348b5c5SDavid van Moolenbroek printf(">>>%s: Sending type %d %d\r\n",
333*7348b5c5SDavid van Moolenbroek Name, ap->type, ap->way);
334*7348b5c5SDavid van Moolenbroek }
335*7348b5c5SDavid van Moolenbroek *e++ = ap->type;
336*7348b5c5SDavid van Moolenbroek *e++ = ap->way;
337*7348b5c5SDavid van Moolenbroek }
338*7348b5c5SDavid van Moolenbroek ++ap;
339*7348b5c5SDavid van Moolenbroek }
340*7348b5c5SDavid van Moolenbroek *e++ = IAC;
341*7348b5c5SDavid van Moolenbroek *e++ = SE;
342*7348b5c5SDavid van Moolenbroek telnet_net_write(str_request, e - str_request);
343*7348b5c5SDavid van Moolenbroek printsub('>', &str_request[2], e - str_request - 2);
344*7348b5c5SDavid van Moolenbroek }
345*7348b5c5SDavid van Moolenbroek }
346*7348b5c5SDavid van Moolenbroek
347*7348b5c5SDavid van Moolenbroek /*
348*7348b5c5SDavid van Moolenbroek * This is called when an AUTH SEND is received.
349*7348b5c5SDavid van Moolenbroek * It should never arrive on the server side (as only the server can
350*7348b5c5SDavid van Moolenbroek * send an AUTH SEND).
351*7348b5c5SDavid van Moolenbroek * You should probably respond to it if you can...
352*7348b5c5SDavid van Moolenbroek *
353*7348b5c5SDavid van Moolenbroek * If you want to respond to the types out of order (i.e. even
354*7348b5c5SDavid van Moolenbroek * if he sends LOGIN KERBEROS and you support both, you respond
355*7348b5c5SDavid van Moolenbroek * with KERBEROS instead of LOGIN (which is against what the
356*7348b5c5SDavid van Moolenbroek * protocol says)) you will have to hack this code...
357*7348b5c5SDavid van Moolenbroek */
358*7348b5c5SDavid van Moolenbroek void
auth_send(unsigned char * data,int cnt)359*7348b5c5SDavid van Moolenbroek auth_send(unsigned char *data, int cnt)
360*7348b5c5SDavid van Moolenbroek {
361*7348b5c5SDavid van Moolenbroek Authenticator *ap;
362*7348b5c5SDavid van Moolenbroek static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
363*7348b5c5SDavid van Moolenbroek TELQUAL_IS, AUTHTYPE_NULL, 0,
364*7348b5c5SDavid van Moolenbroek IAC, SE };
365*7348b5c5SDavid van Moolenbroek if (Server) {
366*7348b5c5SDavid van Moolenbroek if (auth_debug_mode) {
367*7348b5c5SDavid van Moolenbroek printf(">>>%s: auth_send called!\r\n", Name);
368*7348b5c5SDavid van Moolenbroek }
369*7348b5c5SDavid van Moolenbroek return;
370*7348b5c5SDavid van Moolenbroek }
371*7348b5c5SDavid van Moolenbroek
372*7348b5c5SDavid van Moolenbroek if (auth_debug_mode) {
373*7348b5c5SDavid van Moolenbroek printf(">>>%s: auth_send got:", Name);
374*7348b5c5SDavid van Moolenbroek printd(data, cnt); printf("\r\n");
375*7348b5c5SDavid van Moolenbroek }
376*7348b5c5SDavid van Moolenbroek
377*7348b5c5SDavid van Moolenbroek /*
378*7348b5c5SDavid van Moolenbroek * Save the data, if it is new, so that we can continue looking
379*7348b5c5SDavid van Moolenbroek * at it if the authorization we try doesn't work
380*7348b5c5SDavid van Moolenbroek */
381*7348b5c5SDavid van Moolenbroek if (data < _auth_send_data ||
382*7348b5c5SDavid van Moolenbroek data > _auth_send_data + sizeof(_auth_send_data)) {
383*7348b5c5SDavid van Moolenbroek auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data)
384*7348b5c5SDavid van Moolenbroek ? sizeof(_auth_send_data)
385*7348b5c5SDavid van Moolenbroek : (size_t)cnt;
386*7348b5c5SDavid van Moolenbroek memmove(_auth_send_data, data, auth_send_cnt);
387*7348b5c5SDavid van Moolenbroek auth_send_data = _auth_send_data;
388*7348b5c5SDavid van Moolenbroek } else {
389*7348b5c5SDavid van Moolenbroek /*
390*7348b5c5SDavid van Moolenbroek * This is probably a no-op, but we just make sure
391*7348b5c5SDavid van Moolenbroek */
392*7348b5c5SDavid van Moolenbroek auth_send_data = data;
393*7348b5c5SDavid van Moolenbroek auth_send_cnt = cnt;
394*7348b5c5SDavid van Moolenbroek }
395*7348b5c5SDavid van Moolenbroek while ((auth_send_cnt -= 2) >= 0) {
396*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
397*7348b5c5SDavid van Moolenbroek printf(">>>%s: He supports %d\r\n",
398*7348b5c5SDavid van Moolenbroek Name, *auth_send_data);
399*7348b5c5SDavid van Moolenbroek if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) {
400*7348b5c5SDavid van Moolenbroek ap = findauthenticator(auth_send_data[0],
401*7348b5c5SDavid van Moolenbroek auth_send_data[1]);
402*7348b5c5SDavid van Moolenbroek if (ap && ap->send) {
403*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
404*7348b5c5SDavid van Moolenbroek printf(">>>%s: Trying %d %d\r\n",
405*7348b5c5SDavid van Moolenbroek Name, auth_send_data[0],
406*7348b5c5SDavid van Moolenbroek auth_send_data[1]);
407*7348b5c5SDavid van Moolenbroek if ((*ap->send)(ap)) {
408*7348b5c5SDavid van Moolenbroek /*
409*7348b5c5SDavid van Moolenbroek * Okay, we found one we like
410*7348b5c5SDavid van Moolenbroek * and did it.
411*7348b5c5SDavid van Moolenbroek * we can go home now.
412*7348b5c5SDavid van Moolenbroek */
413*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
414*7348b5c5SDavid van Moolenbroek printf(">>>%s: Using type %d\r\n",
415*7348b5c5SDavid van Moolenbroek Name, *auth_send_data);
416*7348b5c5SDavid van Moolenbroek auth_send_data += 2;
417*7348b5c5SDavid van Moolenbroek return;
418*7348b5c5SDavid van Moolenbroek }
419*7348b5c5SDavid van Moolenbroek }
420*7348b5c5SDavid van Moolenbroek /* else
421*7348b5c5SDavid van Moolenbroek * just continue on and look for the
422*7348b5c5SDavid van Moolenbroek * next one if we didn't do anything.
423*7348b5c5SDavid van Moolenbroek */
424*7348b5c5SDavid van Moolenbroek }
425*7348b5c5SDavid van Moolenbroek auth_send_data += 2;
426*7348b5c5SDavid van Moolenbroek }
427*7348b5c5SDavid van Moolenbroek telnet_net_write(str_none, sizeof(str_none));
428*7348b5c5SDavid van Moolenbroek printsub('>', &str_none[2], sizeof(str_none) - 2);
429*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
430*7348b5c5SDavid van Moolenbroek printf(">>>%s: Sent failure message\r\n", Name);
431*7348b5c5SDavid van Moolenbroek auth_finished(0, AUTH_REJECT);
432*7348b5c5SDavid van Moolenbroek #ifdef KANNAN
433*7348b5c5SDavid van Moolenbroek /*
434*7348b5c5SDavid van Moolenbroek * We requested strong authentication, however no mechanisms worked.
435*7348b5c5SDavid van Moolenbroek * Therefore, exit on client end.
436*7348b5c5SDavid van Moolenbroek */
437*7348b5c5SDavid van Moolenbroek printf("Unable to securely authenticate user ... exit\n");
438*7348b5c5SDavid van Moolenbroek exit(0);
439*7348b5c5SDavid van Moolenbroek #endif /* KANNAN */
440*7348b5c5SDavid van Moolenbroek }
441*7348b5c5SDavid van Moolenbroek
442*7348b5c5SDavid van Moolenbroek void
auth_send_retry(void)443*7348b5c5SDavid van Moolenbroek auth_send_retry(void)
444*7348b5c5SDavid van Moolenbroek {
445*7348b5c5SDavid van Moolenbroek /*
446*7348b5c5SDavid van Moolenbroek * if auth_send_cnt <= 0 then auth_send will end up rejecting
447*7348b5c5SDavid van Moolenbroek * the authentication and informing the other side of this.
448*7348b5c5SDavid van Moolenbroek */
449*7348b5c5SDavid van Moolenbroek auth_send(auth_send_data, auth_send_cnt);
450*7348b5c5SDavid van Moolenbroek }
451*7348b5c5SDavid van Moolenbroek
452*7348b5c5SDavid van Moolenbroek void
auth_is(unsigned char * data,int cnt)453*7348b5c5SDavid van Moolenbroek auth_is(unsigned char *data, int cnt)
454*7348b5c5SDavid van Moolenbroek {
455*7348b5c5SDavid van Moolenbroek Authenticator *ap;
456*7348b5c5SDavid van Moolenbroek
457*7348b5c5SDavid van Moolenbroek if (cnt < 2)
458*7348b5c5SDavid van Moolenbroek return;
459*7348b5c5SDavid van Moolenbroek
460*7348b5c5SDavid van Moolenbroek if (data[0] == AUTHTYPE_NULL) {
461*7348b5c5SDavid van Moolenbroek auth_finished(0, AUTH_REJECT);
462*7348b5c5SDavid van Moolenbroek return;
463*7348b5c5SDavid van Moolenbroek }
464*7348b5c5SDavid van Moolenbroek
465*7348b5c5SDavid van Moolenbroek if ((ap = findauthenticator(data[0], data[1])) != NULL) {
466*7348b5c5SDavid van Moolenbroek if (ap->is)
467*7348b5c5SDavid van Moolenbroek (*ap->is)(ap, data+2, cnt-2);
468*7348b5c5SDavid van Moolenbroek } else if (auth_debug_mode)
469*7348b5c5SDavid van Moolenbroek printf(">>>%s: Invalid authentication in IS: %d\r\n",
470*7348b5c5SDavid van Moolenbroek Name, *data);
471*7348b5c5SDavid van Moolenbroek }
472*7348b5c5SDavid van Moolenbroek
473*7348b5c5SDavid van Moolenbroek void
auth_reply(unsigned char * data,int cnt)474*7348b5c5SDavid van Moolenbroek auth_reply(unsigned char *data, int cnt)
475*7348b5c5SDavid van Moolenbroek {
476*7348b5c5SDavid van Moolenbroek Authenticator *ap;
477*7348b5c5SDavid van Moolenbroek
478*7348b5c5SDavid van Moolenbroek if (cnt < 2)
479*7348b5c5SDavid van Moolenbroek return;
480*7348b5c5SDavid van Moolenbroek
481*7348b5c5SDavid van Moolenbroek if ((ap = findauthenticator(data[0], data[1])) != NULL) {
482*7348b5c5SDavid van Moolenbroek if (ap->reply)
483*7348b5c5SDavid van Moolenbroek (*ap->reply)(ap, data+2, cnt-2);
484*7348b5c5SDavid van Moolenbroek } else if (auth_debug_mode)
485*7348b5c5SDavid van Moolenbroek printf(">>>%s: Invalid authentication in SEND: %d\r\n",
486*7348b5c5SDavid van Moolenbroek Name, *data);
487*7348b5c5SDavid van Moolenbroek }
488*7348b5c5SDavid van Moolenbroek
489*7348b5c5SDavid van Moolenbroek void
auth_name(unsigned char * data,int cnt)490*7348b5c5SDavid van Moolenbroek auth_name(unsigned char *data, int cnt)
491*7348b5c5SDavid van Moolenbroek {
492*7348b5c5SDavid van Moolenbroek unsigned char savename[256];
493*7348b5c5SDavid van Moolenbroek
494*7348b5c5SDavid van Moolenbroek if (cnt < 1) {
495*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
496*7348b5c5SDavid van Moolenbroek printf(">>>%s: Empty name in NAME\r\n", Name);
497*7348b5c5SDavid van Moolenbroek return;
498*7348b5c5SDavid van Moolenbroek }
499*7348b5c5SDavid van Moolenbroek if ((size_t)cnt > sizeof(savename) - 1) {
500*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
501*7348b5c5SDavid van Moolenbroek printf(">>>%s: Name in NAME (%d) exceeds %ld length\r\n",
502*7348b5c5SDavid van Moolenbroek Name, cnt, (long)sizeof(savename)-1);
503*7348b5c5SDavid van Moolenbroek return;
504*7348b5c5SDavid van Moolenbroek }
505*7348b5c5SDavid van Moolenbroek memmove((void *)savename, (void *)data, cnt);
506*7348b5c5SDavid van Moolenbroek savename[cnt] = '\0'; /* Null terminate */
507*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
508*7348b5c5SDavid van Moolenbroek printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
509*7348b5c5SDavid van Moolenbroek auth_encrypt_user(savename);
510*7348b5c5SDavid van Moolenbroek }
511*7348b5c5SDavid van Moolenbroek
512*7348b5c5SDavid van Moolenbroek int
auth_sendname(unsigned char * cp,int len)513*7348b5c5SDavid van Moolenbroek auth_sendname(unsigned char *cp, int len)
514*7348b5c5SDavid van Moolenbroek {
515*7348b5c5SDavid van Moolenbroek static unsigned char str_request[256+6]
516*7348b5c5SDavid van Moolenbroek = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
517*7348b5c5SDavid van Moolenbroek register unsigned char *e = str_request + 4;
518*7348b5c5SDavid van Moolenbroek register unsigned char *ee = &str_request[sizeof(str_request)-2];
519*7348b5c5SDavid van Moolenbroek
520*7348b5c5SDavid van Moolenbroek while (--len >= 0) {
521*7348b5c5SDavid van Moolenbroek if ((*e++ = *cp++) == IAC)
522*7348b5c5SDavid van Moolenbroek *e++ = IAC;
523*7348b5c5SDavid van Moolenbroek if (e >= ee)
524*7348b5c5SDavid van Moolenbroek return(0);
525*7348b5c5SDavid van Moolenbroek }
526*7348b5c5SDavid van Moolenbroek *e++ = IAC;
527*7348b5c5SDavid van Moolenbroek *e++ = SE;
528*7348b5c5SDavid van Moolenbroek telnet_net_write(str_request, e - str_request);
529*7348b5c5SDavid van Moolenbroek printsub('>', &str_request[2], e - &str_request[2]);
530*7348b5c5SDavid van Moolenbroek return(1);
531*7348b5c5SDavid van Moolenbroek }
532*7348b5c5SDavid van Moolenbroek
533*7348b5c5SDavid van Moolenbroek void
auth_finished(Authenticator * ap,int result)534*7348b5c5SDavid van Moolenbroek auth_finished(Authenticator *ap, int result)
535*7348b5c5SDavid van Moolenbroek {
536*7348b5c5SDavid van Moolenbroek if (!(authenticated = ap))
537*7348b5c5SDavid van Moolenbroek authenticated = &NoAuth;
538*7348b5c5SDavid van Moolenbroek validuser = result;
539*7348b5c5SDavid van Moolenbroek }
540*7348b5c5SDavid van Moolenbroek
541*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
542*7348b5c5SDavid van Moolenbroek static void
auth_intr(int sig)543*7348b5c5SDavid van Moolenbroek auth_intr(int sig)
544*7348b5c5SDavid van Moolenbroek {
545*7348b5c5SDavid van Moolenbroek auth_finished(0, AUTH_REJECT);
546*7348b5c5SDavid van Moolenbroek }
547*7348b5c5SDavid van Moolenbroek
548*7348b5c5SDavid van Moolenbroek int
auth_wait(char * name,size_t l)549*7348b5c5SDavid van Moolenbroek auth_wait(char *name, size_t l)
550*7348b5c5SDavid van Moolenbroek {
551*7348b5c5SDavid van Moolenbroek if (auth_debug_mode)
552*7348b5c5SDavid van Moolenbroek printf(">>>%s: in auth_wait.\r\n", Name);
553*7348b5c5SDavid van Moolenbroek
554*7348b5c5SDavid van Moolenbroek if (Server && !authenticating)
555*7348b5c5SDavid van Moolenbroek return(0);
556*7348b5c5SDavid van Moolenbroek
557*7348b5c5SDavid van Moolenbroek (void) signal(SIGALRM, auth_intr);
558*7348b5c5SDavid van Moolenbroek alarm(30);
559*7348b5c5SDavid van Moolenbroek while (!authenticated)
560*7348b5c5SDavid van Moolenbroek if (telnet_spin())
561*7348b5c5SDavid van Moolenbroek break;
562*7348b5c5SDavid van Moolenbroek alarm(0);
563*7348b5c5SDavid van Moolenbroek (void) signal(SIGALRM, SIG_DFL);
564*7348b5c5SDavid van Moolenbroek
565*7348b5c5SDavid van Moolenbroek /*
566*7348b5c5SDavid van Moolenbroek * Now check to see if the user is valid or not
567*7348b5c5SDavid van Moolenbroek */
568*7348b5c5SDavid van Moolenbroek if (!authenticated || authenticated == &NoAuth)
569*7348b5c5SDavid van Moolenbroek return(AUTH_REJECT);
570*7348b5c5SDavid van Moolenbroek
571*7348b5c5SDavid van Moolenbroek if (validuser == AUTH_VALID)
572*7348b5c5SDavid van Moolenbroek validuser = AUTH_USER;
573*7348b5c5SDavid van Moolenbroek
574*7348b5c5SDavid van Moolenbroek if (authenticated->status)
575*7348b5c5SDavid van Moolenbroek validuser = (*authenticated->status)(authenticated,
576*7348b5c5SDavid van Moolenbroek name, l, validuser);
577*7348b5c5SDavid van Moolenbroek return(validuser);
578*7348b5c5SDavid van Moolenbroek }
579*7348b5c5SDavid van Moolenbroek
580*7348b5c5SDavid van Moolenbroek void
auth_debug(int mode)581*7348b5c5SDavid van Moolenbroek auth_debug(int mode)
582*7348b5c5SDavid van Moolenbroek {
583*7348b5c5SDavid van Moolenbroek auth_debug_mode = mode;
584*7348b5c5SDavid van Moolenbroek }
585*7348b5c5SDavid van Moolenbroek
586*7348b5c5SDavid van Moolenbroek void
auth_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)587*7348b5c5SDavid van Moolenbroek auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
588*7348b5c5SDavid van Moolenbroek {
589*7348b5c5SDavid van Moolenbroek Authenticator *ap;
590*7348b5c5SDavid van Moolenbroek
591*7348b5c5SDavid van Moolenbroek if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
592*7348b5c5SDavid van Moolenbroek (*ap->printsub)(data, cnt, buf, buflen);
593*7348b5c5SDavid van Moolenbroek else
594*7348b5c5SDavid van Moolenbroek auth_gen_printsub(data, cnt, buf, buflen);
595*7348b5c5SDavid van Moolenbroek }
596*7348b5c5SDavid van Moolenbroek
597*7348b5c5SDavid van Moolenbroek void
auth_gen_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)598*7348b5c5SDavid van Moolenbroek auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
599*7348b5c5SDavid van Moolenbroek {
600*7348b5c5SDavid van Moolenbroek register unsigned char *cp;
601*7348b5c5SDavid van Moolenbroek unsigned char tbuf[16];
602*7348b5c5SDavid van Moolenbroek
603*7348b5c5SDavid van Moolenbroek cnt -= 3;
604*7348b5c5SDavid van Moolenbroek data += 3;
605*7348b5c5SDavid van Moolenbroek buf[buflen-1] = '\0';
606*7348b5c5SDavid van Moolenbroek buf[buflen-2] = '*';
607*7348b5c5SDavid van Moolenbroek buflen -= 2;
608*7348b5c5SDavid van Moolenbroek for (; cnt > 0; cnt--, data++) {
609*7348b5c5SDavid van Moolenbroek snprintf((char *)tbuf, sizeof(tbuf), " %d", *data);
610*7348b5c5SDavid van Moolenbroek for (cp = tbuf; *cp && buflen > 0; --buflen)
611*7348b5c5SDavid van Moolenbroek *buf++ = *cp++;
612*7348b5c5SDavid van Moolenbroek if (buflen <= 0)
613*7348b5c5SDavid van Moolenbroek return;
614*7348b5c5SDavid van Moolenbroek }
615*7348b5c5SDavid van Moolenbroek *buf = '\0';
616*7348b5c5SDavid van Moolenbroek }
617*7348b5c5SDavid van Moolenbroek #endif
618