/* For best results in visual layout while viewing this file, set tab stops to every 4 columns. */ /* d c p l i b . c DCP system-dependent library Services provided by dcplib.c: - login - UNIX commands simulation Updated: 14May89 - Added system name to login prompt - ahd Added configuration file controlled user id, password Added Kermit server option 17May89 - Redo login processing to time out after five minutes; after all, we have to exit someday. ahd 22Sep89 - Add password file processing ahd 24Sep89 - Modify login() to issue only one wait command for up to 32K seconds; this cuts down LOGFILE clutter. ahd 01Oct89 - Re-do function headers to allow copying for function prototypes in ulib.h ahd 17Jan90 - Filter unprintable characters from logged userid and password to prevent premature end of file. ahd 18Jan90 - Alter processing of alternate shells to directly invoke program instead of using system() call. ahd 6 Sep 90 - Change logging of line data to printable ahd 8 Sep 90 - Split ulib.c into dcplib.c and ulib.c ahd 8 Oct 90 - Break rmail.com and rnews.com out of uuio Add FIXED_SPEED option for no-autobauding ahd 10Nov 90 - Move sleep call into ssleep and rename ahd */ #include #include #include #include #include #include #include #include #include #ifdef __TURBOC__ #include #endif #include "lib.h" #include "arpadate.h" #include "dcp.h" #include "dcplib.h" #include "dcpsys.h" #include "hlib.h" #include "hostable.h" #include "import.h" #include "modem.h" #include "pushpop.h" #include "security.h" #include "ssleep.h" #include "ulib.h" #include "usertabl.h" #include "timestmp.h" /*--------------------------------------------------------------------*/ /* Define current file name for panic() and printerr() */ /*--------------------------------------------------------------------*/ currentfile(); /*--------------------------------------------------------------------*/ /* Internal function prototypes */ /*--------------------------------------------------------------------*/ static void LoginShell( const struct UserTable *userp ); /*--------------------------------------------------------------------*/ /* l o g i n */ /* */ /* Login handler */ /*--------------------------------------------------------------------*/ boolean login(void) { char line[BUFSIZ]; /* Allow for long domain names! */ char user[50]; char pswd[50]; char attempts = 0; /* Allows login tries */ char *token; /* Pointer to returned token */ struct UserTable *userp; /*--------------------------------------------------------------------*/ /* Our modem is now connected. Begin actual login processing */ /* by displaying a banner. */ /*--------------------------------------------------------------------*/ sprintf(line,"\r\n\n%s %d.%02d with %s %s (%s) (%s)\r\n", #ifdef WIN32 "Windows/NT(TM)", _osmajor, #elif defined( __TURBOC__ ) "MS-DOS(R)", _osmajor, #else (_osmode == DOS_MODE) ? "MS-DOS(R)" : "OS/2(R)" , (_osmode == DOS_MODE) ? _osmajor : ((int) _osmajor / 10 ), #endif _osminor, compilep, compilev, E_domain, device); /* Print a hello message */ wmsg(line,0); ddelay(250); /*--------------------------------------------------------------------*/ /* Display a login prompt until we get a printable character or */ /* the login times out */ /*--------------------------------------------------------------------*/ for ( attempts = 0; attempts < 5 ; attempts++ ) { boolean invalid = TRUE; while (invalid) /* Spin for a user id or timeout */ { wmsg("\r\nlogin: ", 0); strcpy(user,""); if (rmsg(user, 2, 30, sizeof user) == TIMEOUT) /* Did the user enter data? */ return FALSE; /* No --> Give up */ if (equal(user,"NO CARRIER")) return FALSE; token = user; while ((*token != '\0') && invalid) /* Ignore empty lines */ invalid = ! isgraph(*token++); } /* while */ printmsg(14, "login: login=%s", user); /*--------------------------------------------------------------------*/ /* We have a user id, now get a password */ /*--------------------------------------------------------------------*/ wmsg("\r\nPassword: ", 0); strcpy(pswd,""); if (rmsg(pswd, 0, 30, sizeof pswd) == TIMEOUT) return FALSE; /*--------------------------------------------------------------------*/ /* Zap unprintable characters before we log the password */ /*--------------------------------------------------------------------*/ printmsg(14, "login: password=%s", pswd); /*--------------------------------------------------------------------*/ /* Validate the user id and passowrd */ /*--------------------------------------------------------------------*/ userp = checkuser(user); /* Locate user id in host table */ if (userp == BADUSER) /* Does user id exist? */ { /* No --> Notify the user */ wmsg("\r\nlogin failed",0); token = user; while (!isalnum( *token ) && (*token != '\0')) token ++; /* Scan for first alpha-numeric */ if (*token != '\0') /* If at least one good char */ printmsg(0,"login: login for user %s failed, bad user id", user); /* Log the error for ourselves */ } else if ( equal(pswd,userp->password)) /* Correct password? */ { /* Yes --> Log the user "in" */ /* . . ..+....1.... +....2....+....3.... + . */ sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n", E_domain, arpadate()); wmsg(line, 0); printmsg(0,"login: login user %s (%s) at %s", userp->uid, userp->realname, arpadate()); if equal(userp->sh,UUCPSHELL) /* Standard uucp shell? */ { securep = userp->hsecure; printmsg(5,"Processing user via %s", UUCPSHELL); return TRUE; /* Yes --> Startup the machine */ } else { /* No --> run special shell */ LoginShell( userp ); return FALSE; /* Hang up phone and exit */ } } else { /* Password was wrong. Report */ wmsg("\r\nlogin failed",0); printmsg(0,"login: login user %s (%s) failed, bad password %s", userp->uid, userp->realname, pswd); } } /* for */ /*-----------------------------------------------------------------*/ /* If we fall through the loop, we have an excessive number of */ /* login attempts; hangup the telephone and try again. */ /*-----------------------------------------------------------------*/ return FALSE; /* Exit processing */ } /*login*/ /*--------------------------------------------------------------------*/ /* l o g i n b y p a s s */ /* */ /* Initialize user setup when login is bypassed */ /*--------------------------------------------------------------------*/ boolean loginbypass(const char *user) { struct UserTable *userp; char line[BUFSIZ]; /* Allow for long domain names! */ printmsg(14, "loginbypass: login=%s", user); /*--------------------------------------------------------------------*/ /* Validate the user id */ /*--------------------------------------------------------------------*/ userp = checkuser(user); /* Locate user id in host table */ if (userp == BADUSER) /* Does user id exist? */ { /* No --> Notify the user */ wmsg("\r\nUUCICO login failed",0); printmsg(0,"loginbypass: login for user %s failed, bad user id", user); /* Log the error for ourselves */ return FALSE; /* Hang up phone and exit */ } else { /* Yes --> Log the user "in" */ /* . . ..+....1.... +....2....+....3.... + . */ sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n", E_domain, arpadate()); wmsg(line, 0); printmsg(0,"loginbypass: login user %s (%s) at %s", userp->uid, userp->realname, arpadate()); if equal(userp->sh,UUCPSHELL) /* Standard uucp shell? */ { securep = userp->hsecure; return TRUE; /* Yes --> Startup the machine */ } /* if equal(userp->sh,UUCPSHELL) */ else { /* No --> run special shell */ LoginShell( userp ); return FALSE; /* Hang up phone and exit */ } /* else */ } /* else */ } /*loginbypass*/ /*--------------------------------------------------------------------*/ /* L o g i n S h e l l */ /* */ /* Execute a non-default remote user shell */ /*--------------------------------------------------------------------*/ static void LoginShell( const struct UserTable *userp ) { char *shellstring; char *path; char *args; int rc; /*--------------------------------------------------------------------*/ /* Get the program to run and its arguments */ /*--------------------------------------------------------------------*/ shellstring = strdup(userp->sh); /* Copy user shell for parsing */ path = strtok(shellstring," \t"); /* Get program name */ args = strtok(NULL,""); /* Get rest of arg string */ printmsg(1,"LoginShell: Invoking %s in directory %s", userp->sh, userp->homedir); ddelay(250); /* Wait for port to stablize */ /*--------------------------------------------------------------------*/ /* Run the requested program in the user's home directory */ /*--------------------------------------------------------------------*/ PushDir(userp->homedir);/* Switch to user's home dir */ if (args == NULL) rc = spawnl(P_WAIT, path, path, NULL); else rc = spawnl(P_WAIT, path, path, args, NULL); PopDir(); /* Return to original directory */ /*--------------------------------------------------------------------*/ /* Report any errors we found */ /*--------------------------------------------------------------------*/ if ( rc < 0 ) /* Error condition? */ { /* Yes --> Report it to the user */ printmsg(0,"LoginShell: Unable to execute user shell"); printerr(path); } else /* No --> Report normal result */ printmsg(rc == 0 ? 4 : 0,"LoginShell: %s return code is %d", path, rc); } /* LoginShell */