📄 radlogin.c
字号:
/* * Secure packet radio login command. The system first prompts for the * user's name. It then generates and sends a unique "challenge" (a 64-bit * hexadecimal integer) based on the time of day. The user encrypts * this value using the Data Encryption Standard and his private key and * type it back to the system. The system also encrypts the challenge * with the user's key and compares the two. If they match, he's in. * * 18 December 1986 Phil Karn, KA9Q * * mods: * 870318 Bdale, N3EUA Add code to run user's .login commands. * 870317 Bdale, N3EUA Hacked to remove putenv() by calling execle() * instead of execl(). */#include <stdio.h>#include <strings.h>#include <pwd.h>#include <utmp.h>#define KEYFILE "/etc/rkeys" /* This file must be read-protected */main(argc,argv)int argc;char *argv[];{ struct passwd *pp,*getpwnam(); unsigned long t; FILE *fp; char name[64]; char key[8]; char work[8]; char answer[8]; char fbuf[64]; char ibuf[64]; char home[64]; char login[64]; char shell[64]; char user[64]; char *keyp; char *cp,*tty,*ttyname(); int i,ikey[8]; struct utmp utmp; char *ep[5]; /* we'll build an environment here */ if((fp = fopen(KEYFILE,"r")) == NULL){ printf("Can't open key file\n"); exit(1); } /* Get user's name and look it up in the database */ printf("Secure login: "); fgets(ibuf,sizeof(ibuf),stdin); if((cp = index(ibuf,'\n')) != NULL) *cp = '\0'; strncpy(name,ibuf,sizeof(name)); for(;;){ fgets(fbuf,sizeof(fbuf),fp); if(feof(fp)){ printf("No key for login name\n"); exit(2); } if((cp = index(fbuf,'\n')) != NULL) *cp = '\0'; if(strncmp(name,fbuf,strlen(name)) == 0) break; } fclose(fp); /* Find the user's DES key */ if((keyp = index(fbuf,' ')) == NULL){ printf("Missing key field\n"); exit(3); } keyp++; /* Initialize DES with the user's key */ sscanf(keyp,"%2x%2x%2x%2x%2x%2x%2x%2x", &ikey[0], &ikey[1], &ikey[2], &ikey[3], &ikey[4], &ikey[5], &ikey[6], &ikey[7]); for(i=0;i<8;i++) key[i] = ikey[i]; desinit(0); setkey(key); /* Generate and send the challenge */ time(&t); printf("Challenge: %016x\n",t); /* Encrypt it locally... */ for(i=0;i<4;i++) work[i] = 0; work[4] = t >> 24; work[5] = t >> 16; work[6] = t >> 8; work[7] = t; endes(work); /* ...and see if the user can do the same */ printf("Response: "); for(i=0;i<8;i++){ scanf("%2x",&t); answer[i] = t; } printf("\n"); /* I like it better with a blank line here - bdale */ /* Compare the ciphertexts. If they match, he's in */ for(i=0; i < 8; i++){ if(work[i] != answer[i]){ printf("Wrong response\n"); exit(4); } } if((pp = getpwnam(name)) == NULL){ printf("Login name \"%s\" not in /etc/passwd\n",name); exit(4); } if((fp = fopen(UTMP_FILE,"r+")) == NULL){ printf("Can't open utmp!\n"); exit(4); } tty = ttyname(0); if((cp = rindex(tty,'/')) != NULL) tty = cp + 1; while(fread((char *)&utmp,sizeof(struct utmp),1,fp),!feof(fp)){ if(strncmp(utmp.ut_line,tty,8) == 0){ strncpy(utmp.ut_name,name,8); fseek(fp,(long)-sizeof(struct utmp),1); fwrite((char *)&utmp,sizeof(struct utmp),1,fp); break; } } fclose(fp); chdir(pp->pw_dir); setregid(pp->pw_gid,pp->pw_gid); setreuid(pp->pw_uid,pp->pw_uid); if(pp->pw_shell == NULL || *pp->pw_shell == '\0') pp->pw_shell = "/bin/csh"; sprintf(home,"HOME=%s",pp->pw_dir); sprintf(shell,"SHELL=%s",pp->pw_shell); sprintf(user,"USER=%s",name); sprintf(login,"%s/.login",pp->pw_dir); ep[0] = home; ep[1] = shell; ep[2] = user; ep[3] = (char *) NULL; execle(pp->pw_shell,"-",0,ep); printf("Exec failed\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -