Deleted Added
full compact
sra.c (76751) sra.c (81965)
1/* $FreeBSD: head/contrib/telnet/libtelnet/sra.c 76751 2001-05-17 16:28:11Z nsayer $ */
1/* $FreeBSD: head/contrib/telnet/libtelnet/sra.c 81965 2001-08-20 12:28:40Z markm $ */
2
3#ifdef SRA
4#include <sys/types.h>
5#include <arpa/telnet.h>
6#include <stdio.h>
7#ifdef __STDC__
8#include <stdlib.h>
9#endif
10#ifdef NO_STRING_H
11#include <strings.h>
12#else
13#include <string.h>
14#endif
15
16#if !defined(NOPAM)
17#include <security/pam_appl.h>
2
3#ifdef SRA
4#include <sys/types.h>
5#include <arpa/telnet.h>
6#include <stdio.h>
7#ifdef __STDC__
8#include <stdlib.h>
9#endif
10#ifdef NO_STRING_H
11#include <strings.h>
12#else
13#include <string.h>
14#endif
15
16#if !defined(NOPAM)
17#include <security/pam_appl.h>
18#else
19#include <unistd.h>
18#endif
19
20#endif
21
22#include <pwd.h>
23#include <syslog.h>
20#include <ttyent.h>
21
22#include "auth.h"
23#include "misc.h"
24#include "encrypt.h"
25#include "pk.h"
26
27char pka[HEXKEYBYTES+1], ska[HEXKEYBYTES+1], pkb[HEXKEYBYTES+1];
28char *user,*pass,*xuser,*xpass;
29DesData ck;
30IdeaData ik;
31
32extern int auth_debug_mode;
33extern char *line;
34
24#include <ttyent.h>
25
26#include "auth.h"
27#include "misc.h"
28#include "encrypt.h"
29#include "pk.h"
30
31char pka[HEXKEYBYTES+1], ska[HEXKEYBYTES+1], pkb[HEXKEYBYTES+1];
32char *user,*pass,*xuser,*xpass;
33DesData ck;
34IdeaData ik;
35
36extern int auth_debug_mode;
37extern char *line;
38
35static sra_valid = 0;
36static passwd_sent = 0;
39static int sra_valid = 0;
40static int passwd_sent = 0;
37
38static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
39 AUTHTYPE_SRA, };
40
41#define SRA_KEY 0
42#define SRA_USER 1
43#define SRA_CONTINUE 2
44#define SRA_PASS 3
45#define SRA_ACCEPT 4
46#define SRA_REJECT 5
47
41
42static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
43 AUTHTYPE_SRA, };
44
45#define SRA_KEY 0
46#define SRA_USER 1
47#define SRA_CONTINUE 2
48#define SRA_PASS 3
49#define SRA_ACCEPT 4
50#define SRA_REJECT 5
51
52static int check_user(const char *, const char *);
53
48/* support routine to send out authentication message */
54/* support routine to send out authentication message */
49static int Data(ap, type, d, c)
50Authenticator *ap;
51int type;
52void *d;
53int c;
55static int
56Data(Authenticator *ap, int type, void *d, int c)
54{
55 unsigned char *p = str_data + 4;
56 unsigned char *cd = (unsigned char *)d;
57
58 if (c == -1)
59 c = strlen((char *)cd);
60
61 if (auth_debug_mode) {
62 printf("%s:%d: [%d] (%d)",
63 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
64 str_data[3],
65 type, c);
66 printd(d, c);
67 printf("\r\n");
68 }
69 *p++ = ap->type;
70 *p++ = ap->way;
71 *p++ = type;
72 while (c-- > 0) {
73 if ((*p++ = *cd++) == IAC)
74 *p++ = IAC;
75 }
76 *p++ = IAC;
77 *p++ = SE;
78 if (str_data[3] == TELQUAL_IS)
79 printsub('>', &str_data[2], p - (&str_data[2]));
80 return(net_write(str_data, p - str_data));
81}
82
57{
58 unsigned char *p = str_data + 4;
59 unsigned char *cd = (unsigned char *)d;
60
61 if (c == -1)
62 c = strlen((char *)cd);
63
64 if (auth_debug_mode) {
65 printf("%s:%d: [%d] (%d)",
66 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
67 str_data[3],
68 type, c);
69 printd(d, c);
70 printf("\r\n");
71 }
72 *p++ = ap->type;
73 *p++ = ap->way;
74 *p++ = type;
75 while (c-- > 0) {
76 if ((*p++ = *cd++) == IAC)
77 *p++ = IAC;
78 }
79 *p++ = IAC;
80 *p++ = SE;
81 if (str_data[3] == TELQUAL_IS)
82 printsub('>', &str_data[2], p - (&str_data[2]));
83 return(net_write(str_data, p - str_data));
84}
85
83int sra_init(ap, server)
84Authenticator *ap;
85int server;
86int
87sra_init(Authenticator *ap, int server)
86{
87 if (server)
88 str_data[3] = TELQUAL_REPLY;
89 else
90 str_data[3] = TELQUAL_IS;
91
92 user = (char *)malloc(256);
93 xuser = (char *)malloc(513);
94 pass = (char *)malloc(256);
95 xpass = (char *)malloc(513);
96
97 if (user == NULL || xuser == NULL || pass == NULL || xpass ==
98 NULL)
99 return 0; /* malloc failed */
100
101 passwd_sent = 0;
102
103 genkeys(pka,ska);
104 return(1);
105}
106
107/* client received a go-ahead for sra */
88{
89 if (server)
90 str_data[3] = TELQUAL_REPLY;
91 else
92 str_data[3] = TELQUAL_IS;
93
94 user = (char *)malloc(256);
95 xuser = (char *)malloc(513);
96 pass = (char *)malloc(256);
97 xpass = (char *)malloc(513);
98
99 if (user == NULL || xuser == NULL || pass == NULL || xpass ==
100 NULL)
101 return 0; /* malloc failed */
102
103 passwd_sent = 0;
104
105 genkeys(pka,ska);
106 return(1);
107}
108
109/* client received a go-ahead for sra */
108int sra_send(ap)
109Authenticator *ap;
110int
111sra_send(Authenticator *ap)
110{
111 /* send PKA */
112
113 if (auth_debug_mode)
114 printf("Sent PKA to server.\r\n" );
115 printf("Trying SRA secure login:\r\n");
116 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
117 if (auth_debug_mode)
118 printf("Not enough room for authentication data\r\n");
119 return(0);
120 }
121
122 return(1);
123}
124
125/* server received an IS -- could be SRA KEY, USER, or PASS */
112{
113 /* send PKA */
114
115 if (auth_debug_mode)
116 printf("Sent PKA to server.\r\n" );
117 printf("Trying SRA secure login:\r\n");
118 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
119 if (auth_debug_mode)
120 printf("Not enough room for authentication data\r\n");
121 return(0);
122 }
123
124 return(1);
125}
126
127/* server received an IS -- could be SRA KEY, USER, or PASS */
126void sra_is(ap, data, cnt)
127Authenticator *ap;
128unsigned char *data;
129int cnt;
128void
129sra_is(Authenticator *ap, unsigned char *data, int cnt)
130{
131 int valid;
132 Session_Key skey;
133
134 if (cnt-- < 1)
135 goto bad;
136 switch (*data++) {
137
138 case SRA_KEY:
139 if (cnt < HEXKEYBYTES) {
140 Data(ap, SRA_REJECT, (void *)0, 0);
141 auth_finished(ap, AUTH_USER);
142 if (auth_debug_mode) {
143 printf("SRA user rejected for bad PKB\r\n");
144 }
145 return;
146 }
147 if (auth_debug_mode)
148 printf("Sent pka\r\n");
149 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
150 if (auth_debug_mode)
151 printf("Not enough room\r\n");
152 return;
153 }
154 memcpy(pkb,data,HEXKEYBYTES);
155 pkb[HEXKEYBYTES] = '\0';
156 common_key(ska,pkb,&ik,&ck);
157 return;
158
159 case SRA_USER:
160 /* decode KAB(u) */
161 if (cnt > 512) /* Attempted buffer overflow */
162 break;
163 memcpy(xuser,data,cnt);
164 xuser[cnt] = '\0';
165 pk_decode(xuser,user,&ck);
166 auth_encrypt_user(user);
167 Data(ap, SRA_CONTINUE, (void *)0, 0);
168
169 return;
170
171 case SRA_PASS:
172 if (cnt > 512) /* Attempted buffer overflow */
173 break;
174 /* decode KAB(P) */
175 memcpy(xpass,data,cnt);
176 xpass[cnt] = '\0';
177 pk_decode(xpass,pass,&ck);
178
179 /* check user's password */
180 valid = check_user(user,pass);
181
182 if(valid) {
183 Data(ap, SRA_ACCEPT, (void *)0, 0);
184#ifdef DES_ENCRYPTION
185 skey.data = ck;
186 skey.type = SK_DES;
187 skey.length = 8;
188 encrypt_session_key(&skey, 1);
189#endif
190
191 sra_valid = 1;
192 auth_finished(ap, AUTH_VALID);
193 if (auth_debug_mode) {
194 printf("SRA user accepted\r\n");
195 }
196 }
197 else {
198 Data(ap, SRA_CONTINUE, (void *)0, 0);
199/*
200 Data(ap, SRA_REJECT, (void *)0, 0);
201 sra_valid = 0;
202 auth_finished(ap, AUTH_REJECT);
203*/
204 if (auth_debug_mode) {
205 printf("SRA user failed\r\n");
206 }
207 }
208 return;
209
210 default:
211 if (auth_debug_mode)
212 printf("Unknown SRA option %d\r\n", data[-1]);
213 }
214bad:
215 Data(ap, SRA_REJECT, 0, 0);
216 sra_valid = 0;
217 auth_finished(ap, AUTH_REJECT);
218}
219
130{
131 int valid;
132 Session_Key skey;
133
134 if (cnt-- < 1)
135 goto bad;
136 switch (*data++) {
137
138 case SRA_KEY:
139 if (cnt < HEXKEYBYTES) {
140 Data(ap, SRA_REJECT, (void *)0, 0);
141 auth_finished(ap, AUTH_USER);
142 if (auth_debug_mode) {
143 printf("SRA user rejected for bad PKB\r\n");
144 }
145 return;
146 }
147 if (auth_debug_mode)
148 printf("Sent pka\r\n");
149 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) {
150 if (auth_debug_mode)
151 printf("Not enough room\r\n");
152 return;
153 }
154 memcpy(pkb,data,HEXKEYBYTES);
155 pkb[HEXKEYBYTES] = '\0';
156 common_key(ska,pkb,&ik,&ck);
157 return;
158
159 case SRA_USER:
160 /* decode KAB(u) */
161 if (cnt > 512) /* Attempted buffer overflow */
162 break;
163 memcpy(xuser,data,cnt);
164 xuser[cnt] = '\0';
165 pk_decode(xuser,user,&ck);
166 auth_encrypt_user(user);
167 Data(ap, SRA_CONTINUE, (void *)0, 0);
168
169 return;
170
171 case SRA_PASS:
172 if (cnt > 512) /* Attempted buffer overflow */
173 break;
174 /* decode KAB(P) */
175 memcpy(xpass,data,cnt);
176 xpass[cnt] = '\0';
177 pk_decode(xpass,pass,&ck);
178
179 /* check user's password */
180 valid = check_user(user,pass);
181
182 if(valid) {
183 Data(ap, SRA_ACCEPT, (void *)0, 0);
184#ifdef DES_ENCRYPTION
185 skey.data = ck;
186 skey.type = SK_DES;
187 skey.length = 8;
188 encrypt_session_key(&skey, 1);
189#endif
190
191 sra_valid = 1;
192 auth_finished(ap, AUTH_VALID);
193 if (auth_debug_mode) {
194 printf("SRA user accepted\r\n");
195 }
196 }
197 else {
198 Data(ap, SRA_CONTINUE, (void *)0, 0);
199/*
200 Data(ap, SRA_REJECT, (void *)0, 0);
201 sra_valid = 0;
202 auth_finished(ap, AUTH_REJECT);
203*/
204 if (auth_debug_mode) {
205 printf("SRA user failed\r\n");
206 }
207 }
208 return;
209
210 default:
211 if (auth_debug_mode)
212 printf("Unknown SRA option %d\r\n", data[-1]);
213 }
214bad:
215 Data(ap, SRA_REJECT, 0, 0);
216 sra_valid = 0;
217 auth_finished(ap, AUTH_REJECT);
218}
219
220extern char *getpass();
221
222/* client received REPLY -- could be SRA KEY, CONTINUE, ACCEPT, or REJECT */
220/* client received REPLY -- could be SRA KEY, CONTINUE, ACCEPT, or REJECT */
223void sra_reply(ap, data, cnt)
224Authenticator *ap;
225unsigned char *data;
226int cnt;
221void
222sra_reply(Authenticator *ap, unsigned char *data, int cnt)
227{
228 extern char *telnet_gets();
229 char uprompt[256],tuser[256];
230 Session_Key skey;
231 int i;
232
233 if (cnt-- < 1)
234 return;
235 switch (*data++) {
236
237 case SRA_KEY:
238 /* calculate common key */
239 if (cnt < HEXKEYBYTES) {
240 if (auth_debug_mode) {
241 printf("SRA user rejected for bad PKB\r\n");
242 }
243 return;
244 }
245 memcpy(pkb,data,HEXKEYBYTES);
246 pkb[HEXKEYBYTES] = '\0';
247
248 common_key(ska,pkb,&ik,&ck);
249
250 enc_user:
251
252 /* encode user */
253 memset(tuser,0,sizeof(tuser));
254 sprintf(uprompt,"User (%s): ",UserNameRequested);
255 telnet_gets(uprompt,tuser,255,1);
256 if (tuser[0] == '\n' || tuser[0] == '\r' )
257 strcpy(user,UserNameRequested);
258 else {
259 /* telnet_gets leaves the newline on */
260 for(i=0;i<sizeof(tuser);i++) {
261 if (tuser[i] == '\n') {
262 tuser[i] = '\0';
263 break;
264 }
265 }
266 strcpy(user,tuser);
267 }
268 pk_encode(user,xuser,&ck);
269
270 /* send it off */
271 if (auth_debug_mode)
272 printf("Sent KAB(U)\r\n");
273 if (!Data(ap, SRA_USER, (void *)xuser, strlen(xuser))) {
274 if (auth_debug_mode)
275 printf("Not enough room\r\n");
276 return;
277 }
278 break;
279
280 case SRA_CONTINUE:
281 if (passwd_sent) {
282 passwd_sent = 0;
283 printf("[ SRA login failed ]\r\n");
284 goto enc_user;
285 }
286 /* encode password */
287 memset(pass,0,sizeof(pass));
288 telnet_gets("Password: ",pass,255,0);
289 pk_encode(pass,xpass,&ck);
290 /* send it off */
291 if (auth_debug_mode)
292 printf("Sent KAB(P)\r\n");
293 if (!Data(ap, SRA_PASS, (void *)xpass, strlen(xpass))) {
294 if (auth_debug_mode)
295 printf("Not enough room\r\n");
296 return;
297 }
298 passwd_sent = 1;
299 break;
300
301 case SRA_REJECT:
302 printf("[ SRA refuses authentication ]\r\n");
303 printf("Trying plaintext login:\r\n");
304 auth_finished(0,AUTH_REJECT);
305 return;
306
307 case SRA_ACCEPT:
308 printf("[ SRA accepts you ]\r\n");
309#ifdef DES_ENCRYPTION
310 skey.data = ck;
311 skey.type = SK_DES;
312 skey.length = 8;
313 encrypt_session_key(&skey, 0);
314#endif
315
316 auth_finished(ap, AUTH_VALID);
317 return;
318 default:
319 if (auth_debug_mode)
320 printf("Unknown SRA option %d\r\n", data[-1]);
321 return;
322 }
323}
324
223{
224 extern char *telnet_gets();
225 char uprompt[256],tuser[256];
226 Session_Key skey;
227 int i;
228
229 if (cnt-- < 1)
230 return;
231 switch (*data++) {
232
233 case SRA_KEY:
234 /* calculate common key */
235 if (cnt < HEXKEYBYTES) {
236 if (auth_debug_mode) {
237 printf("SRA user rejected for bad PKB\r\n");
238 }
239 return;
240 }
241 memcpy(pkb,data,HEXKEYBYTES);
242 pkb[HEXKEYBYTES] = '\0';
243
244 common_key(ska,pkb,&ik,&ck);
245
246 enc_user:
247
248 /* encode user */
249 memset(tuser,0,sizeof(tuser));
250 sprintf(uprompt,"User (%s): ",UserNameRequested);
251 telnet_gets(uprompt,tuser,255,1);
252 if (tuser[0] == '\n' || tuser[0] == '\r' )
253 strcpy(user,UserNameRequested);
254 else {
255 /* telnet_gets leaves the newline on */
256 for(i=0;i<sizeof(tuser);i++) {
257 if (tuser[i] == '\n') {
258 tuser[i] = '\0';
259 break;
260 }
261 }
262 strcpy(user,tuser);
263 }
264 pk_encode(user,xuser,&ck);
265
266 /* send it off */
267 if (auth_debug_mode)
268 printf("Sent KAB(U)\r\n");
269 if (!Data(ap, SRA_USER, (void *)xuser, strlen(xuser))) {
270 if (auth_debug_mode)
271 printf("Not enough room\r\n");
272 return;
273 }
274 break;
275
276 case SRA_CONTINUE:
277 if (passwd_sent) {
278 passwd_sent = 0;
279 printf("[ SRA login failed ]\r\n");
280 goto enc_user;
281 }
282 /* encode password */
283 memset(pass,0,sizeof(pass));
284 telnet_gets("Password: ",pass,255,0);
285 pk_encode(pass,xpass,&ck);
286 /* send it off */
287 if (auth_debug_mode)
288 printf("Sent KAB(P)\r\n");
289 if (!Data(ap, SRA_PASS, (void *)xpass, strlen(xpass))) {
290 if (auth_debug_mode)
291 printf("Not enough room\r\n");
292 return;
293 }
294 passwd_sent = 1;
295 break;
296
297 case SRA_REJECT:
298 printf("[ SRA refuses authentication ]\r\n");
299 printf("Trying plaintext login:\r\n");
300 auth_finished(0,AUTH_REJECT);
301 return;
302
303 case SRA_ACCEPT:
304 printf("[ SRA accepts you ]\r\n");
305#ifdef DES_ENCRYPTION
306 skey.data = ck;
307 skey.type = SK_DES;
308 skey.length = 8;
309 encrypt_session_key(&skey, 0);
310#endif
311
312 auth_finished(ap, AUTH_VALID);
313 return;
314 default:
315 if (auth_debug_mode)
316 printf("Unknown SRA option %d\r\n", data[-1]);
317 return;
318 }
319}
320
325int sra_status(ap, name, level)
326Authenticator *ap;
327char *name;
328int level;
321int
322sra_status(Authenticator *ap, char *name, int level)
329{
330 if (level < AUTH_USER)
331 return(level);
332 if (UserNameRequested && sra_valid) {
333 strcpy(name, UserNameRequested);
334 return(AUTH_VALID);
335 } else
336 return(AUTH_USER);
337}
338
339#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
340#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
341
323{
324 if (level < AUTH_USER)
325 return(level);
326 if (UserNameRequested && sra_valid) {
327 strcpy(name, UserNameRequested);
328 return(AUTH_VALID);
329 } else
330 return(AUTH_USER);
331}
332
333#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
334#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
335
342void sra_printsub(data, cnt, buf, buflen)
343unsigned char *data, *buf;
344int cnt, buflen;
336void
337sra_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
345{
346 char lbuf[32];
347 register int i;
348
349 buf[buflen-1] = '\0'; /* make sure its NULL terminated */
350 buflen -= 1;
351
352 switch(data[3]) {
353
354 case SRA_CONTINUE:
355 strncpy((char *)buf, " CONTINUE ", buflen);
356 goto common;
357
358 case SRA_REJECT: /* Rejected (reason might follow) */
359 strncpy((char *)buf, " REJECT ", buflen);
360 goto common;
361
362 case SRA_ACCEPT: /* Accepted (name might follow) */
363 strncpy((char *)buf, " ACCEPT ", buflen);
364
365 common:
366 BUMP(buf, buflen);
367 if (cnt <= 4)
368 break;
369 ADDC(buf, buflen, '"');
370 for (i = 4; i < cnt; i++)
371 ADDC(buf, buflen, data[i]);
372 ADDC(buf, buflen, '"');
373 ADDC(buf, buflen, '\0');
374 break;
375
376 case SRA_KEY: /* Authentication data follows */
377 strncpy((char *)buf, " KEY ", buflen);
378 goto common2;
379
380 case SRA_USER:
381 strncpy((char *)buf, " USER ", buflen);
382 goto common2;
383
384 case SRA_PASS:
385 strncpy((char *)buf, " PASS ", buflen);
386 goto common2;
387
388 default:
389 sprintf(lbuf, " %d (unknown)", data[3]);
390 strncpy((char *)buf, lbuf, buflen);
391 common2:
392 BUMP(buf, buflen);
393 for (i = 4; i < cnt; i++) {
394 sprintf(lbuf, " %d", data[i]);
395 strncpy((char *)buf, lbuf, buflen);
396 BUMP(buf, buflen);
397 }
398 break;
399 }
400}
401
402struct passwd *pw;
403
404/*
405 * Helper function for sgetpwnam().
406 */
407char *
338{
339 char lbuf[32];
340 register int i;
341
342 buf[buflen-1] = '\0'; /* make sure its NULL terminated */
343 buflen -= 1;
344
345 switch(data[3]) {
346
347 case SRA_CONTINUE:
348 strncpy((char *)buf, " CONTINUE ", buflen);
349 goto common;
350
351 case SRA_REJECT: /* Rejected (reason might follow) */
352 strncpy((char *)buf, " REJECT ", buflen);
353 goto common;
354
355 case SRA_ACCEPT: /* Accepted (name might follow) */
356 strncpy((char *)buf, " ACCEPT ", buflen);
357
358 common:
359 BUMP(buf, buflen);
360 if (cnt <= 4)
361 break;
362 ADDC(buf, buflen, '"');
363 for (i = 4; i < cnt; i++)
364 ADDC(buf, buflen, data[i]);
365 ADDC(buf, buflen, '"');
366 ADDC(buf, buflen, '\0');
367 break;
368
369 case SRA_KEY: /* Authentication data follows */
370 strncpy((char *)buf, " KEY ", buflen);
371 goto common2;
372
373 case SRA_USER:
374 strncpy((char *)buf, " USER ", buflen);
375 goto common2;
376
377 case SRA_PASS:
378 strncpy((char *)buf, " PASS ", buflen);
379 goto common2;
380
381 default:
382 sprintf(lbuf, " %d (unknown)", data[3]);
383 strncpy((char *)buf, lbuf, buflen);
384 common2:
385 BUMP(buf, buflen);
386 for (i = 4; i < cnt; i++) {
387 sprintf(lbuf, " %d", data[i]);
388 strncpy((char *)buf, lbuf, buflen);
389 BUMP(buf, buflen);
390 }
391 break;
392 }
393}
394
395struct passwd *pw;
396
397/*
398 * Helper function for sgetpwnam().
399 */
400char *
408sgetsave(s)
409 char *s;
401sgetsave(char *s)
410{
411 char *new = malloc((unsigned) strlen(s) + 1);
412
413 if (new == NULL) {
414 return(NULL);
415 }
416 (void) strcpy(new, s);
417 return (new);
418}
419
402{
403 char *new = malloc((unsigned) strlen(s) + 1);
404
405 if (new == NULL) {
406 return(NULL);
407 }
408 (void) strcpy(new, s);
409 return (new);
410}
411
420#include <pwd.h>
421#include <syslog.h>
422#ifdef USE_SHADOW
423#include <shadow.h>
424#endif
425
426
427struct passwd *
412struct passwd *
428sgetpwnam(name)
429 char *name;
413sgetpwnam(char *name)
430{
431 static struct passwd save;
432 register struct passwd *p;
433 char *sgetsave();
434
435 if ((p = getpwnam(name)) == NULL)
436 return (p);
437 if (save.pw_name) {
438 free(save.pw_name);
439 free(save.pw_passwd);
440 free(save.pw_gecos);
441 free(save.pw_dir);
442 free(save.pw_shell);
443 }
444 save = *p;
445 save.pw_name = sgetsave(p->pw_name);
446 save.pw_passwd = sgetsave(p->pw_passwd);
447 save.pw_gecos = sgetsave(p->pw_gecos);
448 save.pw_dir = sgetsave(p->pw_dir);
449 save.pw_shell = sgetsave(p->pw_shell);
450#if 0
451syslog(LOG_WARNING,"%s\n",save.pw_name);
452syslog(LOG_WARNING,"%s\n",save.pw_passwd);
453syslog(LOG_WARNING,"%s\n",save.pw_gecos);
454syslog(LOG_WARNING,"%s\n",save.pw_dir);
455#endif
456#ifdef USE_SHADOW
457 {
458 struct spwd *sp;
459 sp = getspnam(name);
460 free(save.pw_passwd);
461 save.pw_passwd = sgetsave(sp->sp_pwdp);
462 }
463#endif
464 return (&save);
465}
466
467static int
414{
415 static struct passwd save;
416 register struct passwd *p;
417 char *sgetsave();
418
419 if ((p = getpwnam(name)) == NULL)
420 return (p);
421 if (save.pw_name) {
422 free(save.pw_name);
423 free(save.pw_passwd);
424 free(save.pw_gecos);
425 free(save.pw_dir);
426 free(save.pw_shell);
427 }
428 save = *p;
429 save.pw_name = sgetsave(p->pw_name);
430 save.pw_passwd = sgetsave(p->pw_passwd);
431 save.pw_gecos = sgetsave(p->pw_gecos);
432 save.pw_dir = sgetsave(p->pw_dir);
433 save.pw_shell = sgetsave(p->pw_shell);
434#if 0
435syslog(LOG_WARNING,"%s\n",save.pw_name);
436syslog(LOG_WARNING,"%s\n",save.pw_passwd);
437syslog(LOG_WARNING,"%s\n",save.pw_gecos);
438syslog(LOG_WARNING,"%s\n",save.pw_dir);
439#endif
440#ifdef USE_SHADOW
441 {
442 struct spwd *sp;
443 sp = getspnam(name);
444 free(save.pw_passwd);
445 save.pw_passwd = sgetsave(sp->sp_pwdp);
446 }
447#endif
448 return (&save);
449}
450
451static int
468isroot(user)
469char *user;
452isroot(const char *user)
470{
471 struct passwd *pw;
472
473 if ((pw=getpwnam(user))==NULL)
474 return 0;
475 return (!pw->pw_uid);
476}
477
478static int
453{
454 struct passwd *pw;
455
456 if ((pw=getpwnam(user))==NULL)
457 return 0;
458 return (!pw->pw_uid);
459}
460
461static int
479rootterm(ttyn)
480char *ttyn;
462rootterm(char *ttyn)
481{
482 struct ttyent *t;
483
484 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
485}
486
487#ifdef NOPAM
463{
464 struct ttyent *t;
465
466 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
467}
468
469#ifdef NOPAM
488char *crypt();
489
490int check_user(name, pass)
491char *name;
492char *pass;
470static int
471check_user(const char *name, const char *pass)
493{
494 register char *cp;
495 char *xpasswd, *salt;
496
497 if (isroot(name) && !rootterm(line))
498 {
499 crypt("AA","*"); /* Waste some time to simulate success */
500 return(0);
501 }
502
503 if (pw = sgetpwnam(name)) {
504 if (pw->pw_shell == NULL) {
505 pw = (struct passwd *) NULL;
506 return(0);
507 }
508
509 salt = pw->pw_passwd;
510 xpasswd = crypt(pass, salt);
511 /* The strcmp does not catch null passwords! */
512 if (pw == NULL || *pw->pw_passwd == '\0' ||
513 strcmp(xpasswd, pw->pw_passwd)) {
514 pw = (struct passwd *) NULL;
515 return(0);
516 }
517 return(1);
518 }
519 return(0);
520}
521#else
522
523/*
524 * The following is stolen from ftpd, which stole it from the imap-uw
525 * PAM module and login.c. It is needed because we can't really
526 * "converse" with the user, having already gone to the trouble of
527 * getting their username and password through an encrypted channel.
528 */
529
530#define COPY_STRING(s) (s ? strdup(s):NULL)
531
532struct cred_t {
533 const char *uname;
534 const char *pass;
535};
536typedef struct cred_t cred_t;
537
472{
473 register char *cp;
474 char *xpasswd, *salt;
475
476 if (isroot(name) && !rootterm(line))
477 {
478 crypt("AA","*"); /* Waste some time to simulate success */
479 return(0);
480 }
481
482 if (pw = sgetpwnam(name)) {
483 if (pw->pw_shell == NULL) {
484 pw = (struct passwd *) NULL;
485 return(0);
486 }
487
488 salt = pw->pw_passwd;
489 xpasswd = crypt(pass, salt);
490 /* The strcmp does not catch null passwords! */
491 if (pw == NULL || *pw->pw_passwd == '\0' ||
492 strcmp(xpasswd, pw->pw_passwd)) {
493 pw = (struct passwd *) NULL;
494 return(0);
495 }
496 return(1);
497 }
498 return(0);
499}
500#else
501
502/*
503 * The following is stolen from ftpd, which stole it from the imap-uw
504 * PAM module and login.c. It is needed because we can't really
505 * "converse" with the user, having already gone to the trouble of
506 * getting their username and password through an encrypted channel.
507 */
508
509#define COPY_STRING(s) (s ? strdup(s):NULL)
510
511struct cred_t {
512 const char *uname;
513 const char *pass;
514};
515typedef struct cred_t cred_t;
516
517int
538auth_conv(int num_msg, const struct pam_message **msg,
539 struct pam_response **resp, void *appdata)
540{
541 int i;
542 cred_t *cred = (cred_t *) appdata;
543 struct pam_response *reply =
544 malloc(sizeof(struct pam_response) * num_msg);
545
546 if (reply == NULL)
547 return PAM_BUF_ERR;
548
549 for (i = 0; i < num_msg; i++) {
550 switch (msg[i]->msg_style) {
551 case PAM_PROMPT_ECHO_ON: /* assume want user name */
552 reply[i].resp_retcode = PAM_SUCCESS;
553 reply[i].resp = COPY_STRING(cred->uname);
554 /* PAM frees resp. */
555 break;
556 case PAM_PROMPT_ECHO_OFF: /* assume want password */
557 reply[i].resp_retcode = PAM_SUCCESS;
558 reply[i].resp = COPY_STRING(cred->pass);
559 /* PAM frees resp. */
560 break;
561 case PAM_TEXT_INFO:
562 case PAM_ERROR_MSG:
563 reply[i].resp_retcode = PAM_SUCCESS;
564 reply[i].resp = NULL;
565 break;
566 default: /* unknown message style */
567 free(reply);
568 return PAM_CONV_ERR;
569 }
570 }
571
572 *resp = reply;
573 return PAM_SUCCESS;
574}
575
576/*
577 * The PAM version as a side effect may put a new username in *name.
578 */
518auth_conv(int num_msg, const struct pam_message **msg,
519 struct pam_response **resp, void *appdata)
520{
521 int i;
522 cred_t *cred = (cred_t *) appdata;
523 struct pam_response *reply =
524 malloc(sizeof(struct pam_response) * num_msg);
525
526 if (reply == NULL)
527 return PAM_BUF_ERR;
528
529 for (i = 0; i < num_msg; i++) {
530 switch (msg[i]->msg_style) {
531 case PAM_PROMPT_ECHO_ON: /* assume want user name */
532 reply[i].resp_retcode = PAM_SUCCESS;
533 reply[i].resp = COPY_STRING(cred->uname);
534 /* PAM frees resp. */
535 break;
536 case PAM_PROMPT_ECHO_OFF: /* assume want password */
537 reply[i].resp_retcode = PAM_SUCCESS;
538 reply[i].resp = COPY_STRING(cred->pass);
539 /* PAM frees resp. */
540 break;
541 case PAM_TEXT_INFO:
542 case PAM_ERROR_MSG:
543 reply[i].resp_retcode = PAM_SUCCESS;
544 reply[i].resp = NULL;
545 break;
546 default: /* unknown message style */
547 free(reply);
548 return PAM_CONV_ERR;
549 }
550 }
551
552 *resp = reply;
553 return PAM_SUCCESS;
554}
555
556/*
557 * The PAM version as a side effect may put a new username in *name.
558 */
579int check_user(const char *name, const char *pass)
559static int
560check_user(const char *name, const char *pass)
580{
581 pam_handle_t *pamh = NULL;
561{
562 pam_handle_t *pamh = NULL;
582 const char *tmpl_user;
583 const void *item;
584 int rval;
585 int e;
586 cred_t auth_cred = { name, pass };
587 struct pam_conv conv = { &auth_conv, &auth_cred };
588
589 e = pam_start("telnetd", name, &conv, &pamh);
590 if (e != PAM_SUCCESS) {
591 syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
592 return 0;
593 }
594
595#if 0 /* Where can we find this value? */
596 e = pam_set_item(pamh, PAM_RHOST, remotehost);
597 if (e != PAM_SUCCESS) {
598 syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
599 pam_strerror(pamh, e));
600 return 0;
601 }
602#endif
603
604 e = pam_authenticate(pamh, 0);
605 switch (e) {
606 case PAM_SUCCESS:
607 /*
608 * With PAM we support the concept of a "template"
609 * user. The user enters a login name which is
610 * authenticated by PAM, usually via a remote service
611 * such as RADIUS or TACACS+. If authentication
612 * succeeds, a different but related "template" name
613 * is used for setting the credentials, shell, and
614 * home directory. The name the user enters need only
615 * exist on the remote authentication server, but the
616 * template name must be present in the local password
617 * database.
618 *
619 * This is supported by two various mechanisms in the
620 * individual modules. However, from the application's
621 * point of view, the template user is always passed
622 * back as a changed value of the PAM_USER item.
623 */
624 if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
625 PAM_SUCCESS) {
563 const void *item;
564 int rval;
565 int e;
566 cred_t auth_cred = { name, pass };
567 struct pam_conv conv = { &auth_conv, &auth_cred };
568
569 e = pam_start("telnetd", name, &conv, &pamh);
570 if (e != PAM_SUCCESS) {
571 syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
572 return 0;
573 }
574
575#if 0 /* Where can we find this value? */
576 e = pam_set_item(pamh, PAM_RHOST, remotehost);
577 if (e != PAM_SUCCESS) {
578 syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
579 pam_strerror(pamh, e));
580 return 0;
581 }
582#endif
583
584 e = pam_authenticate(pamh, 0);
585 switch (e) {
586 case PAM_SUCCESS:
587 /*
588 * With PAM we support the concept of a "template"
589 * user. The user enters a login name which is
590 * authenticated by PAM, usually via a remote service
591 * such as RADIUS or TACACS+. If authentication
592 * succeeds, a different but related "template" name
593 * is used for setting the credentials, shell, and
594 * home directory. The name the user enters need only
595 * exist on the remote authentication server, but the
596 * template name must be present in the local password
597 * database.
598 *
599 * This is supported by two various mechanisms in the
600 * individual modules. However, from the application's
601 * point of view, the template user is always passed
602 * back as a changed value of the PAM_USER item.
603 */
604 if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
605 PAM_SUCCESS) {
626 strcpy(name, (const char *) item);
606 strcpy((char *) name, (const char *) item);
627 } else
628 syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
629 pam_strerror(pamh, e));
630 if (isroot(name) && !rootterm(line))
631 rval = 0;
632 else
633 rval = 1;
634 break;
635
636 case PAM_AUTH_ERR:
637 case PAM_USER_UNKNOWN:
638 case PAM_MAXTRIES:
639 rval = 0;
640 break;
641
642 default:
643 syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
644 rval = 0;
645 break;
646 }
647
648 if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
649 syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
650 rval = 0;
651 }
652 return rval;
653}
654
655#endif
656
657#endif
658
607 } else
608 syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
609 pam_strerror(pamh, e));
610 if (isroot(name) && !rootterm(line))
611 rval = 0;
612 else
613 rval = 1;
614 break;
615
616 case PAM_AUTH_ERR:
617 case PAM_USER_UNKNOWN:
618 case PAM_MAXTRIES:
619 rval = 0;
620 break;
621
622 default:
623 syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
624 rval = 0;
625 break;
626 }
627
628 if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
629 syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
630 rval = 0;
631 }
632 return rval;
633}
634
635#endif
636
637#endif
638