📄 password.c
字号:
/* * password.c: * Code that supports the use of a password in the monitor. * * General notice: * This code is part of a boot-monitor package developed as a generic base * platform for embedded system designs. As such, it is likely to be * distributed to various projects beyond the control of the original * author. Please notify the author of any enhancements made or bugs found * so that all may benefit from the changes. In addition, notification back * to the author will allow the new user to pick up changes that may have * been made by other users after this version of the code was distributed. * * Note1: the majority of this code was edited with 4-space tabs. * Note2: as more and more contributions are accepted, the term "author" * is becoming a mis-representation of credit. * * Original author: Ed Sutter * Email: esutter@lucent.com * Phone: 908-582-2351 */#include "config.h"#include "genlib.h"#include "ether.h"#include "tfs.h"#include "tfsprivate.h"extern char *crypt(char *,char *,char *);/* PASSWORD_FILE: * The name of the file that is used to store passwords. */#define PASSWORD_FILE ".monpswd"#define SALT0 'T'#define SALT1 'J'/* backdoor(): * A mechanism that allows a password to be generated based on the * MAC address of the board... * * Return 1 if the password matches the return of crypt(KEY,SALT). * Where: * KEY is an 8-character string created from the MAC address * stored in the ETHERADD environment variable; * SALT is a 2-character string made up of the first and last * character of the ETHERADD env var; */intbackdoor(char *password){ int i; char *etherstr, salt[3], encryption[32]; unsigned char etherbin[9]; etherstr = getenv("ETHERADD"); if (!etherstr) /* just in case... */ etherstr = "00:00:00:00:00:00"; /* 2 salt characters are the first and last characters of etherstr: */ salt[0] = etherstr[0]; salt[1] = etherstr[strlen(etherstr)-1]; salt[2] = 0; EtherToBin(etherstr,etherbin); etherbin[6] = 'A'; etherbin[7] = 'a'; etherbin[8] = 0; for(i=0;i<6;i++) { while (etherbin[i] > 0x7e) { etherbin[i] -= 0x20; etherbin[6]++; } while (etherbin[i] < 0x20) { etherbin[i] += 0x8; etherbin[7]++; } } crypt(etherbin,salt,encryption); /* Note that the first two characters of the return from crypt() */ /* are not used in the comparison... */ if (!strcmp(password,encryption+2)) return(1); else return(0);}/* validPassword(): * Called with a password and user level. There are a few different ways * in which this can pass... * 1. If there is no PASSWORD_FILE in TFS, return true. * 2. If the password matches the backdoor entry, return true. * 3. If the password matches appropriate entry in the password file, * return true. */intvalidPassword(char *password, int ulvl){ extern void clrTmpMaxUsrLvl(int (*)()); extern int extValidPassword(char *,int); extern void *setTmpMaxUsrLvl(); char line[80]; int (*fptr)(); int tfd, lno, pass, lsize; /* If there is a password file, then use it. * If there is no password file, then call extValidPassword() to * support systems that store the password some other way. * The extValidPassword() function should return 0 if password check * failed, 1 if the check succeeded and -1 if there is no external * password storage hardware. * Finally, if there is no password file, AND there is no external * password storage hardware, then just return 1 to * indicate that ANY password is a valid password. In other words... * the password protection stuff is only enabled if you have a password * stored away somewhere. */ if (!tfsstat(PASSWORD_FILE)) { static int warning; switch(extValidPassword(password,ulvl)) { case 0: /* Password check failed. */ return(0); case 1: /* Password check passed. */ return(1); default: /* No external password check in use. */ break; } if (!warning) { printf("WARNING: no %s file, security inactive.\n",PASSWORD_FILE); warning = 1; } return(1); } /* First check for backdoor entry... */ if (backdoor(password)) return(1); /* Incoming user level must be in valid range... */ if ((ulvl < MINUSRLEVEL) || (ulvl > MAXUSRLEVEL)) return(0); /* If user level is MINUSRLEVEL, there is no need for a password. */ if (ulvl == MINUSRLEVEL) return(1); /* Check for a match in the password file... * The PASSWORD_FILE dedicates one line for each user level. * Line1 is password for user level 1. * Line2 is password for user level 2. * Line3 is password for user level 3. * User level 0 doesn't require a password. */ /* Force the getUsrLvl() function to return MAX: */ fptr = (int(*)())setTmpMaxUsrLvl(); tfd = tfsopen(PASSWORD_FILE,TFS_RDONLY,0); if (tfd < 0) { /* Restore the original getUsrLvl() functionality: */ clrTmpMaxUsrLvl(fptr); printf("%s\n",(char *)tfsctrl(TFS_ERRMSG,tfd,0)); return(0); } lno = 1; pass = 0; while((lsize=tfsgetline(tfd,line,sizeof(line)))) { char encryption[32], salt[3]; if (lno != ulvl) { lno++; continue; } line[lsize-1] = 0; /* Remove the newline */ salt[0] = SALT0; salt[1] = SALT1; salt[2] = 0; crypt(password,salt,encryption); if (!strncmp(line,encryption+2,strlen(line)-2)) pass = 1; break; } tfsclose(tfd,0); /* Restore the original getUsrLvl() functionality: */ clrTmpMaxUsrLvl(fptr); return(pass);}/* newPasswordFile(): * Prompt the user for three passwords. One for each user level. * Then, after retrieving them, make sure the user wants to update * the password file; if yes, do it; else abort. */intnewPasswordFile(void){ int err, i; char salt[3], *epwp, buf[32], epswd[34*3], pswd[16], flags[8]; /* For each of the three levels (1,2&3), get the password, encrypt it * and concatenate newline for storate into the password file. */ epwp = epswd; for(i=1;i<4;i++) { printf("Lvl%d ",i); while(1) { getpass("passwd: ",pswd,sizeof(pswd)-1); if (strlen(pswd) < 8) printf("password must be >= 8 chars.\n"); else break; } salt[0] = SALT0; salt[1] = SALT1; salt[2] = 0; crypt(pswd,salt,buf); sprintf(epwp,"%s\n",&buf[2]); epwp += strlen(epwp); } if (!askuser("Are you sure?")) return(0); err = tfsunlink(PASSWORD_FILE); if ((err != TFS_OKAY) && (err != TFSERR_NOFILE)) { printf("%s\n",(char *)tfsctrl(TFS_ERRMSG,err,0)); return(-1); } sprintf(flags,"u%d",MAXUSRLEVEL); err = tfsadd(PASSWORD_FILE,0, flags, epswd, strlen(epswd)); if (err != TFS_OKAY) { printf("%s\n",(char *)tfsctrl(TFS_ERRMSG,err,0)); return(-1); } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -