/* paswrd.c */ /* * Includes */ #include #include #include "fmtdat.h" #include "vt1xx.h" #include "kbdutl.h" #include "suspnd.h" #include "termio.h" #include "usrblk.h" /* * Screen Options */ #define OPTION1 1 #define OPTION2 2 #define OPTION3 3 #define OPTION4 4 #define OPTION5 5 #define OPTION6 6 #define OPTION7 7 #define OPTION8 8 #define OPTION9 9 #define OPTION10 10 #define OPTION11 11 #define OPTION12 12 #define OPTION13 13 #define OPTION14 14 #define OPTION15 15 #define OPTION16 16 #define OPTION17 17 #define OPTION18 18 #define OPTION19 19 #define OPTION20 20 #define OPTION21 21 #define OPTION22 22 #define OPTION23 23 #define OPTION24 24 int options[25]; struct userlist { struct userlist *next; struct userblock user; }; struct userlist *ulp = NULL; struct userlist *sulp = NULL; routine[] = { &scrn0, &scrn1, &scrnexit, &scrnquit }; char pswdfile[80]; FILE *pfl; extern struct userblock user; /* * Internal Routines */ extern VOID scrn0(); extern VOID scrn1(); extern VOID scrnexit(); extern VOID scrnquit(); extern int scrnuser(); extern int scrndir(); extern int chngdir(); extern int query(); extern char *newentry(); extern int initoptions(); extern int position(); extern VOID encdpass(); extern VOID strlwr(); main(argc,argv) int argc; char *argv[]; { int (*r) (); int c,sel; struct userlist *u; if(argc<2) { kb_puts("Usage: paswrd filename\r\n"); exit(0); } strcpy(pswdfile,argv[1]); if((pfl = fopen(pswdfile,"rn")) != NULL) { do { u = (struct userlist *) newentry(); c = fread(&u->user,1,sizeof(struct userblock),pfl); if(c==sizeof(struct userblock)) { if(ulp == NULL) { ulp = u; } else { sulp->next = u; } sulp = u; } else { free(u); c = 0; } } while(c); fclose(pfl); } kb_init(0x03); outekp(); outclr(); fmtrow = SCRNBT-SCRNTP; fmtcol = 0; outpos(0,SCRNBT-SCRNTP); fmtclr(); sel = -1; do { if(sel) { sel = 0; outclr(); fmtclr(); r = routine[sel]; (*r) (); outscan(); } while((c = syscin()) == 0 && !fndbrk) { suspnd(0); } if('1'<=c && c<='3') { sel = c - '0'; r = routine[sel]; (*r) (); } else if(c==CTRLW) { sel = -1; } } while(!fndbrk); outclr(); outdkp(); exit(0); } VOID scrn0() { int row; fmtplc("Password file editor for TSX-Plus TCPIP-11",0); row = 4; fmtplc("Note: This encryption of passwords is to hide",row++); fmtplc(" clear text from casual viewing, not to",row++); fmtplc(" protect them from decryption. You must",row++); fmtplc(" assume that anyone with access to the",row++); fmtplc(" password file can decrypt the passwords.",row++); row += 3; fmtplc(" 1 - Users List",row++); row += 2; fmtplc(" 2 - Exit saving updated Users List",row++); row += 2; fmtplc(" 3 - Quit discarding updates",row++); } VOID scrn1() { int c,cnt,i,row; char s[80],t[USERPASSLEN+1]; do { cnt = 0; sulp = ulp; do { if(!cnt) { outclr(); fmtclr(); fmtplc( "Password file editor for TSX-Plus TCPIP-11",0); fmtplc( "Users: (CR / ENTER - (+# to select / 0 to add / -# to delete)",2); fmtplc( " (GOLD - to exit screen)",3); } row = 6; for(i=0; i<10; i++,row++) { fmtplc("",row); if(sulp!=NULL) { cnt++; strncpy(t,sulp->user.username,USERPASSLEN); t[USERPASSLEN] = '\0'; sprintf(s," #%d %s", cnt,t); fmtplc(s,row); sulp = sulp->next; } } if(sulp==NULL) { cnt = 0; sulp = ulp; fmtplc("",22); } else { fmtplc("... MORE ... (use space key)",22); } outscan(); do { while((c = syscin()) == 0 && !fndbrk) { suspnd(0); } if(c==CR || c==ENTER) { c = query("Enter user number -->> ",s,80,1); if(c==CR || c==ENTER) { if(sscanf(s,"%d",&c)==1) { scrnuser(c); } } c = CTRLW; } } while(c!=GOLD && !fndbrk && c!=CTRLW && c!=SPACEKEY); } while(c!=GOLD && !fndbrk && c!=CTRLW); } while(c!=GOLD && !fndbrk); } /* * Write password file and exit */ VOID scrnexit() { if(ulp!=NULL && (pfl = fopen(pswdfile,"wn")) != NULL) { sulp = ulp; do { fwrite(&sulp->user,sizeof(struct userblock),1,pfl); } while((sulp = sulp->next) != NULL); fclose(pfl); } fndbrk = 1; } /* * Just exit */ VOID scrnquit() { fndbrk = 1; } /* * User Directory List Screen */ int scrnuser(n) int n; { struct userlist *dulp; struct userblock *u; int c,i,j,pos,row; char s[80],t[80]; char *st; /* * Check for add */ if(!n) { /* * Add a new entry */ if((dulp = (struct userlist *) newentry()) == NULL) return; /* * Link new entry to end of user list */ if(ulp==NULL) { n = 1; ulp = dulp; } else { n = 2; sulp = ulp; while(sulp->next!=NULL) { n++; sulp = sulp->next; } sulp->next = dulp; } /* * Create a new user entry */ sulp = dulp; strcpy(sulp->user.username,"newusername"); strcpy(sulp->user.password,"emanresuwen"); strcpy(&sulp->user.defdir,"dk:"); } /* * Must have at least 1 user */ if(ulp==NULL) return(0); /* * Check for a deletion */ if(n<0){ n = -n; sprintf(t,"Delete user #%d (Y/N) ? ", n); query(t,s,80,1); if(tolower(*s)!='y') { return; } if(n==1) { if(ulp!=NULL) { sulp = ulp->next; free(ulp); ulp = sulp; } } else { n -= 2; for(i=0,sulp=ulp; inext; } if(i==n && sulp!=NULL && sulp->next!=NULL) { dulp = sulp->next; sulp->next = dulp->next; free(dulp); } } return(0); } /* * Scan to the correct entry */ for(i=0,sulp=ulp; iuser; sulp = sulp->next; } if(i!=n) return(0); /* * Position cursor initially at OPTION1 */ pos = 4; /* * Clear screen */ outclr(); fmtclr(); do { /* * Initialize the options list */ initoptions(pos); /* * Write the whole screen */ fmtplc("Password file editor for TSX-Plus TCPIP-11",0); fmtplc("Modify Directory Options: (UP / DOWN arrows, CR / ENTER)",1); fmtplc(" (GOLD - to exit screen)",2); row = 4; strncpy(t,u->username,USERPASSLEN); t[USERPASSLEN] = '\0'; sprintf(s," Username: %s", t); options[row] = OPTION1; fmtplc(s,row++); sprintf(s," Local Priveleges: "); i = u->userflag[1]; j = 0; if(i & LTELNET_PRIV) { strcat(s,"TELNET"); j++; } if(i & LCNCT_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"CNCT"); } if(i & LFTP_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"FTP"); } if(i & LSMTP_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"MAIL"); } options[row] = OPTION2; fmtplc(s,row++); sprintf(s," Remote Privileges: "); i = u->userflag[1]; j = 0; if(i & RTELNET_PRIV) { strcat(s,"TELNET"); j++; } if(i & RCNCT_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"CNCT"); } if(i & RFTP_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"FTP"); } if(i & RSMTP_PRIV) { if(j++) { strcat(s," / "); } strcat(s,"MAIL"); } options[row] = OPTION2; fmtplc(s,row++); if(u->userflag[1] & DIRUNRESTRICTED) { sprintf(s, " Remote FTP is restricted only by the specified access rights"); } else { sprintf(s, " Remote FTP may access only the specified directories / subdirectories"); } options[row] = OPTION3; fmtplc(s,row++); strncpy(t,u->msgfil.path,DIRPATHLEN); t[DIRPATHLEN] = '\0'; sprintf(s," Remote FTP message file: %s", t); options[row] = OPTION4; fmtplc(s,row++); strncpy(t,u->mailbox.path,DIRPATHLEN); t[DIRPATHLEN] = '\0'; sprintf(s," Mailbox Directory: %s", t); options[row] = OPTION5; fmtplc(s,row++); strncpy(t,u->defdir.path,DIRPATHLEN); t[DIRPATHLEN] = '\0'; sprintf(s," Default Directory %s", t); options[row] = OPTION6; fmtplc(s,row++); options[row] = OPTION7; for(i=0; idirlst[i].path; strncpy(t,st,DIRPATHLEN); t[DIRPATHLEN] = '\0'; if(*t) { sprintf(s," Access Directory %s", t); options[row] = OPTION7 + i; if(i!=DIRLSTSIZE-1) { options[row+1] = OPTION7 + i + 1; } } else { sprintf(s," _._._._"); } fmtplc(s,row); } outscan(); outpos(0,pos); do { while((c = syscin()) == 0 && !fndbrk) { suspnd(0); } i = position(c); if(pos != i) { pos = i; outpos(0,pos); } if(c==CTRLW) { outclr(); fmtclr(); } if(c==CR || c==ENTER) { if(scrndir(u)) { outclr(); fmtclr(); } c = CTRLW; } } while(c!=CTRLW && c!=GOLD && !fndbrk); } while(c!=GOLD && !fndbrk); return(1); } /* * Directory Options Screen */ int scrndir(u) struct userblock *u; { struct entry *en; int c,i,opt,pos,row; char s[80],t[80]; opt = options[options[24]]; if(!opt) return(0); /* * username */ if(opt==OPTION1) { query("Change user name ? (Y/N) -->> ",s,80,1); if(tolower(*s)=='y') { query("Enter new user name -->> ",s,80,1); if(*s) { strlwr(s); strncpy(u->username,s,USERPASSLEN); } } query("Change password ? (Y/N) -->> ",s,80,1); if(tolower(*s)=='y') { i = 0; do { if(!i) { query("Enter new password -->> ",s,80,0); query("Verify new password -->> ",t,80,0); } else { query("Re-Enter new password -->> ",s,80,0); query("Re-Verify new password -->> ",t,80,0); } } while(i = strcmp(s,t)); /* * Encode password */ strlwr(t); encdpass(s,t); strncpy(u->password,s,USERPASSLEN); if(*t) { u->userflag[0] &= ~PASSNOTREQUIRED; } else { u->userflag[0] |= PASSNOTREQUIRED; } } return(0); } else if(opt==OPTION2) { /* * Position cursor initially at OPTION1 */ pos = 6; /* * Clear screen */ outclr(); fmtclr(); do { /* * Initialize the options list */ initoptions(pos); /* * Write the whole screen */ fmtplc("Password file editor for TSX-Plus TCPIP-11",0); fmtplc("Modify Access Options: (UP / DOWN arrows, CR / ENTER)",2); fmtplc(" (GOLD - to exit screen)",3); /* * Get access rights */ i = u->userflag[1]; row = 6; sprintf(s," Local TELNET access allowed . . . . . %s", i<ELNET_PRIV ? "yes" : "no"); options[row] = OPTION1; fmtplc(s,row++); row += 1; sprintf(s," Local CNCT access allowed . . . . . . %s", i&LCNCT_PRIV ? "yes" : "no"); options[row] = OPTION2; fmtplc(s,row++); row += 1; sprintf(s," Local FTP access allowed . . . . . . %s", i&LFTP_PRIV ? "yes" : "no"); options[row] = OPTION3; fmtplc(s,row++); row += 1; sprintf(s," Local SMTP [MAIL] access allowed . . %s", i&LSMTP_PRIV ? "yes" : "no"); options[row] = OPTION4; fmtplc(s,row++); row += 1; sprintf(s," Remote TELNET access allowed . . . . . %s", i&RTELNET_PRIV ? "yes" : "no"); options[row] = OPTION5; fmtplc(s,row++); row += 1; sprintf(s," Remote CNCT access allowed . . . . . . %s", i&RCNCT_PRIV ? "yes" : "no"); options[row] = OPTION6; fmtplc(s,row++); row += 1; sprintf(s," Remote FTP access allowed . . . . . . %s", i&RFTP_PRIV ? "yes" : "no"); options[row] = OPTION7; fmtplc(s,row++); row += 1; sprintf(s," Remote SMTP [MAIL] access allowed . . %s", i&RSMTP_PRIV ? "yes" : "no"); options[row] = OPTION8; fmtplc(s,row++); outscan(); outpos(0,pos); do { while((c = syscin()) == 0 && !fndbrk) { suspnd(0); } i = position(c); if(pos != i) { pos = i; outpos(0,pos); } if(c==CTRLW) { outclr(); fmtclr(); } if(c==CR || c==ENTER) { if(chngaccess(u)) { c = GOLD; } else { c = CTRLW; } } } while(c!=CTRLW && c!=GOLD && !fndbrk); } while(c!=GOLD && !fndbrk); return(1); } else /* * access rights */ if(opt==OPTION3) { u->userflag[1] ^= DIRUNRESTRICTED; return(0); } else /* * message file */ if(opt==OPTION4) { query("Change message file ? (Y/N) -->> ",s,80,1); if(tolower(*s)=='y') { query("Enter message file name -->> ",s,80,1); strlwr(s); strncpy(u->msgfil.path,s,DIRPATHLEN); } return(0); } else /* * mailbox directory */ if(opt==OPTION5) { query("Change mailbox directory ? (Y/N) -->> ",s,80,1); if(tolower(*s)=='y') { query("Enter mailbox directory path -->> ",s,80,1); strlwr(s); strncpy(u->mailbox.path,s,DIRPATHLEN); } return(0); } else /* * Default Directory / Specified Directories */ if(opt==OPTION6) { en = &u->defdir; } else { en = &u->dirlst[opt-OPTION7]; } /* * Position cursor initially at OPTION1 */ pos = 7; /* * Clear screen */ outclr(); fmtclr(); do { /* * Initialize the options list */ initoptions(pos); /* * Write the whole screen */ fmtplc("Password file editor for TSX-Plus TCPIP-11",0); fmtplc("Modify Directory Options: (UP / DOWN arrows, CR / ENTER)",2); fmtplc(" (GOLD - to exit screen)",3); row = 7; strncpy(t,en->path,DIRPATHLEN); t[DIRPATHLEN] = '\0'; if(opt==OPTION6) { sprintf(s," Default Directory %s", t); } else { sprintf(s," Access Directory %s", t); } options[row] = OPTION1; fmtplc(s,row++); row += 2; fmtplc(" Directory Access Rights:",row++); /* * Get access rights */ i = en->flags; row += 1; sprintf(s," access allowed . . . . . . %s", i&ACCESSABLE ? "yes" : "no"); options[row] = OPTION2; fmtplc(s,row++); sprintf(s," rename file allowed . . . %s", i&FILERENAME ? "yes" : "no"); options[row] = OPTION3; fmtplc(s,row++); sprintf(s," set file protect . . . %s", i&FILEPROTECT ? "yes" : "no"); options[row] = OPTION4; fmtplc(s,row++); sprintf(s," clear file protect . . . %s", i&FILEUNPROTECT ? "yes" : "no"); options[row] = OPTION5; fmtplc(s,row++); sprintf(s," create files . . . . . . . %s", i&FILECREATE ? "yes" : "no"); options[row] = OPTION6; fmtplc(s,row++); sprintf(s," delete files . . . . . . . %s", i&FILEDELETE ? "yes" : "no"); options[row] = OPTION7; fmtplc(s,row++); sprintf(s," create directories . . . . %s", i&DIRCREATE ? "yes" : "no"); options[row] = OPTION8; fmtplc(s,row++); sprintf(s," delete directories . . . . %s", i&DIRDELETE ? "yes" : "no"); options[row] = OPTION9; fmtplc(s,row++); outscan(); outpos(0,pos); do { while((c = syscin()) == 0 && !fndbrk) { suspnd(0); } i = position(c); if(pos != i) { pos = i; outpos(0,pos); } if(c==CTRLW) { outclr(); fmtclr(); } if(c==CR || c==ENTER) { if(chngdir(u,en)) { c = GOLD; } else { c = CTRLW; } } } while(c!=CTRLW && c!=GOLD && !fndbrk); } while(c!=GOLD && !fndbrk); return(1); } /* * Change Access Options */ int chngaccess(u) struct userblock *u; { int opt; opt = options[options[24]]; if(!opt) return(0); switch(opt) { case OPTION1: /* Local Telnet */ u->userflag[1] ^= LTELNET_PRIV; break; case OPTION2: /* Local CNCT */ u->userflag[1] ^= LCNCT_PRIV; break; case OPTION3: /* Local FTP */ u->userflag[1] ^= LFTP_PRIV; break; case OPTION4: /* Local SMTP [MAIL] */ u->userflag[1] ^= LSMTP_PRIV; break; case OPTION5: /* Remote Telnet */ u->userflag[1] ^= RTELNET_PRIV; break; case OPTION6: /* Remote CNCT */ u->userflag[1] ^= RCNCT_PRIV; break; case OPTION7: /* Remote FTP */ u->userflag[1] ^= RFTP_PRIV; break; case OPTION8: /* Remote SMTP [MAIL] */ u->userflag[1] ^= RSMTP_PRIV; break; default: break; } return(0); } /* * Change Directory Options */ int chngdir(u,en) struct userblock *u; struct entry *en; { int i,j,k,opt; char *p,*q; char s[80]; opt = options[options[24]]; if(!opt) return(0); switch(opt) { case OPTION1: /* Directory specification */ if(en!=&u->defdir && en->path[0]!='\0') { /* * Deletions only for access directories */ query("Delete directory specification ? (Y/N) -->> ",s,80,1); if(tolower(*s)=='y') { /* * Delete directory entry */ en->path[0] = '\0'; /* * Shuffle directories */ p = (char *) &u->dirlst[0]; for(i=0,k=0; idirlst[i].path[0]!='\0') { q = (char *) &u->dirlst[i]; for(j=0; jpath[0]!='\0') { query("Change directory specification ? (Y/N) -->> ",s,80,1); if(tolower(*s)!='y') { break; } } /* * Else, just ask for a new directory */ query("Enter new directory -->> ",s,80,1); if(*s) { strlwr(s); strncpy(en->path,s,DIRPATHLEN); } break; case OPTION2: /* accessable */ en->flags ^= ACCESSABLE; break; case OPTION3: /* file rename */ en->flags ^= FILERENAME; break; case OPTION4: /* file protect */ en->flags ^= FILEPROTECT; break; case OPTION5: /* file unprotect */ en->flags ^= FILEUNPROTECT; break; case OPTION6: /* file create */ en->flags ^= FILECREATE; break; case OPTION7: /* file delete */ en->flags ^= FILEDELETE; break; case OPTION8: /* directory create */ en->flags ^= DIRCREATE; break; case OPTION9: /* directory delete */ en->flags ^= DIRDELETE; break; default: break; } return(0); } /* * General Query Routine */ int query(prompt,s,len,echo) char *prompt,*s; int len,echo; { char c; outpos(0,SCRNBT-SCRNTP); outdeol(); outpos(0,SCRNBT-SCRNTP-1); outdeol(); tt_puts(prompt); s[0] = '\0'; do { suspnd(0); c = tt_gets(s,len,echo); } while((c!=CR) & (c!=ENTER) & !fndbrk); outpos(0,SCRNBT-SCRNTP-1); outdeol(); outpos(0,SCRNBT-SCRNTP); outdeol(); return(c); } /* * tt_gets() * * This routine will continually add to a string that is re-submitted * until a special character is hit. It never blocks. * * As long as editing characters (bksp, delete, Ctrl-U) and printable * characters are pressed, this routine will update the string. * When any other special character is hit, that character is discarded. */ int tt_gets(s,lim,echo) register char *s; char echo; int lim; { register int c,count; int i; char *save; count = strlen(s); save = s; s += count; while((c = syscin()) != 0) { /* allow certain editing chars */ switch (c) { case 8: /* backspace */ case 127: /* delete */ if(count) { if (echo) { tt_out(8); tt_out(' '); tt_out(8); } /* one less character */ count--; /* move pointer backward */ s--; } break; case 9: /* HT */ *s++ = ' '; break; case 13: /* CR */ case ENTER: /* ENTER */ /* terminate the string */ *s = '\0'; return(c); case 21: /* ^U */ if (echo) for(i=0; i31 && c<127) { if (echo) tt_out(c); /* add to string */ *s++ = (char)c; /* length of string */ count++; } break; } } /* terminate the string */ *s = '\0'; return(c); } /* * Create a new User Block */ char *newentry() { char *p,*q; int i; p = q = (char *) malloc(sizeof(struct userlist)); if(p == NULL) { return(NULL); } else { for(i=0; i