1 #ifdef SRA 2 #include <sys/types.h> 3 #include <arpa/telnet.h> 4 #include <stdio.h> 5 #ifdef __STDC__ 6 #include <stdlib.h> 7 #endif 8 #ifdef NO_STRING_H 9 #include <strings.h> 10 #else 11 #include <string.h> 12 #endif 13 14 #include "auth.h" 15 #include "misc.h" 16 #include "encrypt.h" 17 #include "pk.h" 18 19 char pka[HEXKEYBYTES+1], ska[HEXKEYBYTES+1], pkb[HEXKEYBYTES+1]; 20 char *user,*pass,*xuser,*xpass; 21 DesData ck; 22 IdeaData ik; 23 24 extern int auth_debug_mode; 25 static sra_valid = 0; 26 static passwd_sent = 0; 27 28 static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, 29 AUTHTYPE_SRA, }; 30 31 #define SRA_KEY 0 32 #define SRA_USER 1 33 #define SRA_CONTINUE 2 34 #define SRA_PASS 3 35 #define SRA_ACCEPT 4 36 #define SRA_REJECT 5 37 38 /* support routine to send out authentication message */ 39 static int Data(ap, type, d, c) 40 Authenticator *ap; 41 int type; 42 void *d; 43 int c; 44 { 45 unsigned char *p = str_data + 4; 46 unsigned char *cd = (unsigned char *)d; 47 48 if (c == -1) 49 c = strlen((char *)cd); 50 51 if (auth_debug_mode) { 52 printf("%s:%d: [%d] (%d)", 53 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", 54 str_data[3], 55 type, c); 56 printd(d, c); 57 printf("\r\n"); 58 } 59 *p++ = ap->type; 60 *p++ = ap->way; 61 *p++ = type; 62 while (c-- > 0) { 63 if ((*p++ = *cd++) == IAC) 64 *p++ = IAC; 65 } 66 *p++ = IAC; 67 *p++ = SE; 68 if (str_data[3] == TELQUAL_IS) 69 printsub('>', &str_data[2], p - (&str_data[2])); 70 return(net_write(str_data, p - str_data)); 71 } 72 73 int sra_init(ap, server) 74 Authenticator *ap; 75 int server; 76 { 77 if (server) 78 str_data[3] = TELQUAL_REPLY; 79 else 80 str_data[3] = TELQUAL_IS; 81 82 user = (char *)malloc(256); 83 xuser = (char *)malloc(512); 84 pass = (char *)malloc(256); 85 xpass = (char *)malloc(512); 86 passwd_sent = 0; 87 88 genkeys(pka,ska); 89 return(1); 90 } 91 92 /* client received a go-ahead for sra */ 93 int sra_send(ap) 94 Authenticator *ap; 95 { 96 /* send PKA */ 97 98 if (auth_debug_mode) 99 printf("Sent PKA to server.\r\n" ); 100 printf("Trying SRA secure login:\r\n"); 101 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) { 102 if (auth_debug_mode) 103 printf("Not enough room for authentication data\r\n"); 104 return(0); 105 } 106 107 return(1); 108 } 109 110 /* server received an IS -- could be SRA KEY, USER, or PASS */ 111 void sra_is(ap, data, cnt) 112 Authenticator *ap; 113 unsigned char *data; 114 int cnt; 115 { 116 int valid; 117 Session_Key skey; 118 119 if (cnt-- < 1) 120 return; 121 switch (*data++) { 122 123 case SRA_KEY: 124 if (cnt < HEXKEYBYTES) { 125 Data(ap, SRA_REJECT, (void *)0, 0); 126 auth_finished(ap, AUTH_USER); 127 if (auth_debug_mode) { 128 printf("SRA user rejected for bad PKB\r\n"); 129 } 130 return; 131 } 132 if (auth_debug_mode) 133 printf("Sent pka\r\n"); 134 if (!Data(ap, SRA_KEY, (void *)pka, HEXKEYBYTES)) { 135 if (auth_debug_mode) 136 printf("Not enough room\r\n"); 137 return; 138 } 139 memcpy(pkb,data,HEXKEYBYTES); 140 pkb[HEXKEYBYTES] = '\0'; 141 common_key(ska,pkb,&ik,&ck); 142 break; 143 144 case SRA_USER: 145 /* decode KAB(u) */ 146 memcpy(xuser,data,cnt); 147 xuser[cnt] = '\0'; 148 pk_decode(xuser,user,&ck); 149 auth_encrypt_user(user); 150 Data(ap, SRA_CONTINUE, (void *)0, 0); 151 152 break; 153 154 case SRA_PASS: 155 /* decode KAB(P) */ 156 memcpy(xpass,data,cnt); 157 xpass[cnt] = '\0'; 158 pk_decode(xpass,pass,&ck); 159 160 /* check user's password */ 161 valid = check_user(user,pass); 162 163 if(valid) { 164 Data(ap, SRA_ACCEPT, (void *)0, 0); 165 #ifdef DES_ENCRYPTION 166 skey.data = ck; 167 skey.type = SK_DES; 168 skey.length = 8; 169 encrypt_session_key(&skey, 1); 170 #endif 171 172 sra_valid = 1; 173 auth_finished(ap, AUTH_VALID); 174 if (auth_debug_mode) { 175 printf("SRA user accepted\r\n"); 176 } 177 } 178 else { 179 Data(ap, SRA_CONTINUE, (void *)0, 0); 180 /* 181 Data(ap, SRA_REJECT, (void *)0, 0); 182 sra_valid = 0; 183 auth_finished(ap, AUTH_REJECT); 184 */ 185 if (auth_debug_mode) { 186 printf("SRA user failed\r\n"); 187 } 188 } 189 break; 190 191 default: 192 if (auth_debug_mode) 193 printf("Unknown SRA option %d\r\n", data[-1]); 194 Data(ap, SRA_REJECT, 0, 0); 195 sra_valid = 0; 196 auth_finished(ap, AUTH_REJECT); 197 break; 198 } 199 } 200 201 extern char *getpass(); 202 203 /* client received REPLY -- could be SRA KEY, CONTINUE, ACCEPT, or REJECT */ 204 void sra_reply(ap, data, cnt) 205 Authenticator *ap; 206 unsigned char *data; 207 int cnt; 208 { 209 extern char *telnet_gets(); 210 char uprompt[256],tuser[256]; 211 Session_Key skey; 212 int i; 213 214 if (cnt-- < 1) 215 return; 216 switch (*data++) { 217 218 case SRA_KEY: 219 /* calculate common key */ 220 if (cnt < HEXKEYBYTES) { 221 if (auth_debug_mode) { 222 printf("SRA user rejected for bad PKB\r\n"); 223 } 224 return; 225 } 226 memcpy(pkb,data,HEXKEYBYTES); 227 pkb[HEXKEYBYTES] = '\0'; 228 229 common_key(ska,pkb,&ik,&ck); 230 231 enc_user: 232 233 /* encode user */ 234 memset(tuser,0,sizeof(tuser)); 235 sprintf(uprompt,"User (%s): ",UserNameRequested); 236 telnet_gets(uprompt,tuser,255,1); 237 if (tuser[0] == '\n' || tuser[0] == '\r' ) 238 strcpy(user,UserNameRequested); 239 else { 240 /* telnet_gets leaves the newline on */ 241 for(i=0;i<sizeof(tuser);i++) { 242 if (tuser[i] == '\n') { 243 tuser[i] = '\0'; 244 break; 245 } 246 } 247 strcpy(user,tuser); 248 } 249 pk_encode(user,xuser,&ck); 250 251 /* send it off */ 252 if (auth_debug_mode) 253 printf("Sent KAB(U)\r\n"); 254 if (!Data(ap, SRA_USER, (void *)xuser, strlen(xuser))) { 255 if (auth_debug_mode) 256 printf("Not enough room\r\n"); 257 return; 258 } 259 break; 260 261 case SRA_CONTINUE: 262 if (passwd_sent) { 263 passwd_sent = 0; 264 printf("[ SRA login failed ]\r\n"); 265 goto enc_user; 266 } 267 /* encode password */ 268 memset(pass,0,sizeof(pass)); 269 telnet_gets("Password: ",pass,255,0); 270 pk_encode(pass,xpass,&ck); 271 /* send it off */ 272 if (auth_debug_mode) 273 printf("Sent KAB(P)\r\n"); 274 if (!Data(ap, SRA_PASS, (void *)xpass, strlen(xpass))) { 275 if (auth_debug_mode) 276 printf("Not enough room\r\n"); 277 return; 278 } 279 passwd_sent = 1; 280 break; 281 282 case SRA_REJECT: 283 printf("[ SRA refuses authentication ]\r\n"); 284 printf("Trying plaintext login:\r\n"); 285 auth_finished(0,AUTH_REJECT); 286 return; 287 288 case SRA_ACCEPT: 289 printf("[ SRA accepts you ]\r\n"); 290 #ifdef DES_ENCRYPTION 291 skey.data = ck; 292 skey.type = SK_DES; 293 skey.length = 8; 294 encrypt_session_key(&skey, 0); 295 #endif 296 297 auth_finished(ap, AUTH_VALID); 298 return; 299 default: 300 if (auth_debug_mode) 301 printf("Unknown SRA option %d\r\n", data[-1]); 302 return; 303 } 304 } 305 306 int sra_status(ap, name, level) 307 Authenticator *ap; 308 char *name; 309 int level; 310 { 311 if (level < AUTH_USER) 312 return(level); 313 if (UserNameRequested && sra_valid) { 314 strcpy(name, UserNameRequested); 315 return(AUTH_VALID); 316 } else 317 return(AUTH_USER); 318 } 319 320 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} 321 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} 322 323 void sra_printsub(data, cnt, buf, buflen) 324 unsigned char *data, *buf; 325 int cnt, buflen; 326 { 327 char lbuf[32]; 328 register int i; 329 330 buf[buflen-1] = '\0'; /* make sure its NULL terminated */ 331 buflen -= 1; 332 333 switch(data[3]) { 334 335 case SRA_CONTINUE: 336 strncpy((char *)buf, " CONTINUE ", buflen); 337 goto common; 338 339 case SRA_REJECT: /* Rejected (reason might follow) */ 340 strncpy((char *)buf, " REJECT ", buflen); 341 goto common; 342 343 case SRA_ACCEPT: /* Accepted (name might follow) */ 344 strncpy((char *)buf, " ACCEPT ", buflen); 345 346 common: 347 BUMP(buf, buflen); 348 if (cnt <= 4) 349 break; 350 ADDC(buf, buflen, '"'); 351 for (i = 4; i < cnt; i++) 352 ADDC(buf, buflen, data[i]); 353 ADDC(buf, buflen, '"'); 354 ADDC(buf, buflen, '\0'); 355 break; 356 357 case SRA_KEY: /* Authentication data follows */ 358 strncpy((char *)buf, " KEY ", buflen); 359 goto common2; 360 361 case SRA_USER: 362 strncpy((char *)buf, " USER ", buflen); 363 goto common2; 364 365 case SRA_PASS: 366 strncpy((char *)buf, " PASS ", buflen); 367 goto common2; 368 369 default: 370 sprintf(lbuf, " %d (unknown)", data[3]); 371 strncpy((char *)buf, lbuf, buflen); 372 common2: 373 BUMP(buf, buflen); 374 for (i = 4; i < cnt; i++) { 375 sprintf(lbuf, " %d", data[i]); 376 strncpy((char *)buf, lbuf, buflen); 377 BUMP(buf, buflen); 378 } 379 break; 380 } 381 } 382 383 struct passwd *pw; 384 385 /* 386 * Helper function for sgetpwnam(). 387 */ 388 char * 389 sgetsave(s) 390 char *s; 391 { 392 char *new = malloc((unsigned) strlen(s) + 1); 393 394 if (new == NULL) { 395 return(NULL); 396 } 397 (void) strcpy(new, s); 398 return (new); 399 } 400 401 #include <pwd.h> 402 #include <syslog.h> 403 #ifdef USE_SHADOW 404 #include <shadow.h> 405 #endif 406 407 408 struct passwd * 409 sgetpwnam(name) 410 char *name; 411 { 412 static struct passwd save; 413 register struct passwd *p; 414 char *sgetsave(); 415 416 if ((p = getpwnam(name)) == NULL) 417 return (p); 418 if (save.pw_name) { 419 free(save.pw_name); 420 free(save.pw_passwd); 421 free(save.pw_gecos); 422 free(save.pw_dir); 423 free(save.pw_shell); 424 } 425 save = *p; 426 save.pw_name = sgetsave(p->pw_name); 427 save.pw_passwd = sgetsave(p->pw_passwd); 428 save.pw_gecos = sgetsave(p->pw_gecos); 429 save.pw_dir = sgetsave(p->pw_dir); 430 save.pw_shell = sgetsave(p->pw_shell); 431 #if 0 432 syslog(LOG_WARNING,"%s\n",save.pw_name); 433 syslog(LOG_WARNING,"%s\n",save.pw_passwd); 434 syslog(LOG_WARNING,"%s\n",save.pw_gecos); 435 syslog(LOG_WARNING,"%s\n",save.pw_dir); 436 #endif 437 #ifdef USE_SHADOW 438 { 439 struct spwd *sp; 440 sp = getspnam(name); 441 free(save.pw_passwd); 442 save.pw_passwd = sgetsave(sp->sp_pwdp); 443 } 444 #endif 445 return (&save); 446 } 447 448 char *crypt(); 449 450 int check_user(name, pass) 451 char *name; 452 char *pass; 453 { 454 register char *cp; 455 char *xpasswd, *salt; 456 457 if (pw = sgetpwnam(name)) { 458 if (pw->pw_shell == NULL) { 459 pw = (struct passwd *) NULL; 460 return(0); 461 } 462 463 salt = pw->pw_passwd; 464 xpasswd = crypt(pass, salt); 465 /* The strcmp does not catch null passwords! */ 466 if (pw == NULL || *pw->pw_passwd == '\0' || 467 strcmp(xpasswd, pw->pw_passwd)) { 468 pw = (struct passwd *) NULL; 469 return(0); 470 } 471 return(1); 472 } 473 return(0); 474 } 475 476 477 #endif 478 479