home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES2.ZIP / UUCICO / dcplib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-20  |  19.3 KB  |  518 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    d c p l i b . c                                                 */
  3. /*                                                                    */
  4. /*    DCP system-dependent library                                    */
  5. /*                                                                    */
  6. /*    Services provided by dcplib.c:                                  */
  7. /*                                                                    */
  8. /*    - login                                                         */
  9. /*    - UNIX commands simulation                                      */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. /*--------------------------------------------------------------------*/
  13. /*    Changes Copyright (c) 1989-1993 by Kendra Electronic            */
  14. /*    Wonderworks.                                                    */
  15. /*                                                                    */
  16. /*    All rights reserved except those explicitly granted by the      */
  17. /*    UUPC/extended license agreement.                                */
  18. /*--------------------------------------------------------------------*/
  19.  
  20. /*--------------------------------------------------------------------*/
  21. /*    Copyright (c) Richard H. Lamb 1985, 1986, 1987                  */
  22. /*    Changes Copyright (c) Stuart Lynne 1987                         */
  23. /*--------------------------------------------------------------------*/
  24.  
  25. /*
  26.  *    $Id: dcplib.c 1.10 1993/11/20 14:48:53 ahd Exp $
  27.  *
  28.  *    $Log: dcplib.c $
  29.  * Revision 1.10  1993/11/20  14:48:53  ahd
  30.  * Add support for passing port name/port handle/port speed/user id to child
  31.  *
  32.  * Revision 1.9  1993/10/28  12:19:01  ahd
  33.  * Cosmetic time formatting twiddles and clean ups
  34.  *
  35.  * Revision 1.8  1993/10/12  01:33:59  ahd
  36.  * Normalize comments to PL/I style
  37.  *
  38.  * Revision 1.7  1993/09/29  04:52:03  ahd
  39.  * Make device name use standard modem file configuration prefix
  40.  *
  41.  * Revision 1.6  1993/09/20  04:48:25  ahd
  42.  * TCP/IP support from Dave Watt
  43.  * 't' protocol support
  44.  * OS/2 2.x support (BC++ 1.0 for OS/2)
  45.  *
  46.  * Revision 1.5  1993/07/24  03:40:55  ahd
  47.  * Correct #ifif to #ifel
  48.  *
  49.  * Revision 1.4  1993/07/22  23:22:27  ahd
  50.  * First pass at changes for Robert Denny's Windows 3.1 support
  51.  *
  52.  * Revision 1.3  1993/05/30  00:01:47  ahd
  53.  * Multiple commuications drivers support
  54.  *
  55.  *
  56.  * Updated:
  57.  *
  58.  *    14May89  - Added system name to login prompt - ahd
  59.  *               Added configuration file controlled user id, password
  60.  *               Added Kermit server option
  61.  *    17May89  - Redo login processing to time out after five minutes;
  62.  *               after all, we have to exit someday.                    ahd
  63.  *    22Sep89  - Add password file processing                           ahd
  64.  *    24Sep89  - Modify login() to issue only one wait command for up
  65.  *               to 32K seconds; this cuts down LOGFILE clutter.        ahd
  66.  *    01Oct89  - Re-do function headers to allow copying for function
  67.  *               prototypes in ulib.h                                   ahd
  68.  *    17Jan90  - Filter unprintable characters from logged userid and
  69.  *               password to prevent premature end of file.             ahd
  70.  *    18Jan90  - Alter processing of alternate shells to directly
  71.  *               invoke program instead of using system() call.         ahd
  72.  * 6  Sep 90   - Change logging of line data to printable               ahd
  73.  *    8 Sep 90 - Split ulib.c into dcplib.c and ulib.c                  ahd
  74.  *    8 Oct 90 - Break rmail.com and rnews.com out of uuio
  75.  *               Add FIXED_SPEED option for no-autobauding              ahd
  76.  *    10Nov 90 - Move sleep call into ssleep and rename                 ahd
  77.  */
  78.  
  79. /*--------------------------------------------------------------------*/
  80. /*                        System include files                        */
  81. /*--------------------------------------------------------------------*/
  82.  
  83. #include <ctype.h>
  84. #include <direct.h>
  85. #include <dos.h>
  86. #include <stdio.h>
  87. #include <stdlib.h>
  88. #include <string.h>
  89. #include <sys/types.h>
  90. #include <time.h>
  91.  
  92. #ifdef __TURBOC__
  93. #include <sys/timeb.h>
  94. #endif
  95.  
  96. #if defined(_Windows)
  97. #include <windows.h>
  98. #endif
  99.  
  100. /*--------------------------------------------------------------------*/
  101. /*                    UUPC/extended include files                     */
  102. /*--------------------------------------------------------------------*/
  103.  
  104. #include "lib.h"
  105. #include "arpadate.h"
  106. #include "dcp.h"
  107. #include "dcplib.h"
  108. #include "dcpsys.h"
  109. #include "hlib.h"
  110. #include "execute.h"
  111. #include "hostable.h"
  112. #include "import.h"
  113. #include "modem.h"
  114. #include "pushpop.h"
  115. #include "security.h"
  116. #include "ssleep.h"
  117. #include "commlib.h"
  118. #include "usertabl.h"
  119. #include "timestmp.h"
  120.  
  121. /*--------------------------------------------------------------------*/
  122. /*        Define current file name for panic() and printerr()         */
  123. /*--------------------------------------------------------------------*/
  124.  
  125. #if !defined(_Windows)
  126. currentfile();
  127. #endif
  128.  
  129. /*--------------------------------------------------------------------*/
  130. /*                    Internal function prototypes                    */
  131. /*--------------------------------------------------------------------*/
  132.  
  133. static void LoginShell( const   struct UserTable *userp );
  134.  
  135. void motd( const char *fname, char *buf, const int bufsiz );
  136.  
  137. /*--------------------------------------------------------------------*/
  138. /*    l o g i n                                                       */
  139. /*                                                                    */
  140. /*    Login handler                                                   */
  141. /*--------------------------------------------------------------------*/
  142.  
  143. boolean login(void)
  144. {
  145.    char line[BUFSIZ];                  /* Allow for long domain names! */
  146.    char user[50];
  147.    char pswd[50];
  148.    char attempts = 0;                  /* Allows login tries         */
  149.    char *token;                        /* Pointer to returned token  */
  150.    struct UserTable *userp;
  151.  
  152. #if defined(_Windows)
  153.    WORD wVersion;
  154. #endif
  155.  
  156.    if ( E_banner != NULL )
  157.       motd( E_banner, line, sizeof line );
  158.  
  159. /*--------------------------------------------------------------------*/
  160. /*    Our modem is now connected.  Begin actual login processing      */
  161. /*    by displaying a banner.                                         */
  162. /*--------------------------------------------------------------------*/
  163.  
  164. #if defined(_Windows)
  165.     wVersion = LOWORD(GetVersion());
  166.     sprintf(line, "\r\n\nMS-Windows(TM) %d.%02d with %s %s (%s) (%s)\r\n",
  167.          (WORD)(LOBYTE(wVersion)),
  168.          (WORD)(HIBYTE(wVersion)),
  169.           compilep,
  170.           compilev,
  171.          E_domain,
  172.          M_device);           /* Print a hello message                 */
  173.  
  174. #else /* not Windows */
  175.  
  176.    sprintf(line,"\r\n\n%s %d.%02d with %s %s (%s) (%s)\r\n",
  177. #ifdef WIN32
  178.             "Windows NT(TM)",
  179.             _winmajor,
  180.             _winminor,
  181. #elif defined(__OS2__)
  182.             "OS/2(R)",
  183.             (int) _osmajor / 10,
  184.             _osminor,
  185. #elif defined( __TURBOC__ )
  186.             "MS-DOS(R)",
  187.             _osmajor,
  188.             _osminor,
  189. #else
  190.             (_osmode == DOS_MODE) ? "DOS" : "OS/2(R)" ,
  191.             (_osmode == DOS_MODE) ? (int) _osmajor : ((int) _osmajor / 10 ),
  192.             _osminor,
  193. #endif
  194.             compilep,
  195.             compilev,
  196.             E_domain,
  197.             M_device); /* Print a hello message            */
  198. #endif
  199.  
  200.    wmsg(line,0);
  201.  
  202. /*--------------------------------------------------------------------*/
  203. /*    Display a login prompt until we get a printable character or    */
  204. /*    the login times out                                             */
  205. /*--------------------------------------------------------------------*/
  206.  
  207.    for ( attempts = 0; attempts < 5 ; attempts++ )
  208.    {
  209.       boolean invalid = TRUE;
  210.       while (invalid)         /* Spin for a user id or timeout       */
  211.       {
  212.          wmsg("\r\nlogin: ", 0);
  213.          strcpy(user,"");
  214.          if (rmsg(user, 2, 30, sizeof user) == TIMEOUT)
  215.                                     /* Did the user enter data?  */
  216.             return FALSE;   /* No --> Give up                */
  217.  
  218.          if (equal(user,"NO CARRIER"))
  219.             return FALSE;
  220.  
  221.          token = user;
  222.          while ((*token != '\0') && invalid) /* Ignore empty lines   */
  223.             invalid = ! isgraph(*token++);
  224.       } /* while */
  225.  
  226.       printmsg(14, "login: login=%s", user);
  227.  
  228. /*--------------------------------------------------------------------*/
  229. /*               We have a user id, now get a password                */
  230. /*--------------------------------------------------------------------*/
  231.  
  232.       wmsg("\r\nPassword: ", 0);
  233.       strcpy(pswd,"");
  234.       if (rmsg(pswd, 0, 30, sizeof pswd) == TIMEOUT)
  235.          return FALSE;
  236.  
  237. /*--------------------------------------------------------------------*/
  238. /*       Zap unprintable characters before we log the password        */
  239. /*--------------------------------------------------------------------*/
  240.  
  241.       printmsg(14, "login: password=%s", pswd);
  242.  
  243. /*--------------------------------------------------------------------*/
  244. /*                 Validate the user id and passowrd                  */
  245. /*--------------------------------------------------------------------*/
  246.  
  247.       userp = checkuser(user);         /* Locate user id in host table */
  248.  
  249.       if (userp == BADUSER)            /* Does user id exist?          */
  250.       {                                /* No --> Notify the user       */
  251.          wmsg("\r\nlogin failed",0);
  252.  
  253.          token = user;
  254.          while (!isalnum( *token ) && (*token !=  '\0'))
  255.             token ++;                  /* Scan for first alpha-numeric */
  256.  
  257.          if (*token != '\0')           /* If at least one good char    */
  258.             printmsg(0,"login: login for user %s failed, bad user id",
  259.                   user);               /* Log the error for ourselves  */
  260.       }
  261.       else if ( equal(pswd,userp->password))   /* Correct password?    */
  262.       {                                /* Yes --> Log the user "in"    */
  263.          time_t now;
  264.                    /*   . . ..+....1....  +....2....+....3....  + .   */
  265.          sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n",
  266.                   E_domain, arpadate());
  267.          wmsg(line, 0);
  268.  
  269.          time( &now );
  270.          printmsg(0,"login: login user %s (%s) at %.24s",
  271.                      userp->uid, userp->realname, ctime( &now ));
  272.  
  273.          if equal(userp->sh,UUCPSHELL) /* Standard uucp shell?       */
  274.          {
  275.             securep = userp->hsecure;
  276.             printmsg(5,"Processing user via %s", UUCPSHELL);
  277.             return TRUE;            /* Yes --> Startup the machine   */
  278.          }
  279.          else {                     /* No --> run special shell      */
  280.  
  281.             if ( E_motd != NULL )
  282.                motd( E_motd, line, sizeof line );
  283.             LoginShell( userp );
  284.             return FALSE;   /* Hang up phone and exit        */
  285.          }
  286.       }
  287.       else {                        /* Password was wrong.  Report   */
  288.          wmsg("\r\nlogin failed",0);
  289.          printmsg(0,"login: login user %s (%s) failed, bad password %s",
  290.                   userp->uid, userp->realname, pswd);
  291.       }
  292.    }  /* for */
  293.  
  294. /*-----------------------------------------------------------------*/
  295. /*    If we fall through the loop, we have an excessive number of  */
  296. /*    login attempts; hangup the telephone and try again.          */
  297. /*-----------------------------------------------------------------*/
  298.  
  299.    return FALSE;                    /* Exit processing            */
  300.  
  301. } /*login*/
  302.  
  303. /*--------------------------------------------------------------------*/
  304. /*    l o g i n b y p a s s                                           */
  305. /*                                                                    */
  306. /*    Initialize user setup when login is bypassed                    */
  307. /*--------------------------------------------------------------------*/
  308.  
  309. boolean loginbypass(const char *user)
  310. {
  311.    struct UserTable *userp;
  312.    char line[BUFSIZ];                  /* Allow for long domain names! */
  313.  
  314.    printmsg(14, "loginbypass: login=%s", user);
  315.  
  316. /*--------------------------------------------------------------------*/
  317. /*                 Validate the user id                               */
  318. /*--------------------------------------------------------------------*/
  319.  
  320.    userp = checkuser(user);         /* Locate user id in host table  */
  321.  
  322.    if (userp == BADUSER)            /* Does user id exist?           */
  323.    {                                /* No --> Notify the user        */
  324.       wmsg("\r\nUUCICO login failed",0);
  325.  
  326.       printmsg(0,"loginbypass: login for user %s failed, bad user id",
  327.                user);               /* Log the error for ourselves   */
  328.       return FALSE;                 /* Hang up phone and exit        */
  329.    }
  330.    else {
  331.                                     /* Yes --> Log the user "in"     */
  332.                 /*   . . ..+....1....  +....2....+....3....  + .   */
  333.       sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n",
  334.                E_domain, arpadate());
  335.       wmsg(line, 0);
  336.       printmsg(0,"loginbypass: login user %s (%s) at %s",
  337.                   userp->uid, userp->realname, arpadate());
  338.  
  339.       if equal(userp->sh,UUCPSHELL) /* Standard uucp shell?       */
  340.       {
  341.          securep = userp->hsecure;
  342.          return TRUE;            /* Yes --> Startup the machine   */
  343.       } /* if equal(userp->sh,UUCPSHELL) */
  344.       else {                     /* No --> run special shell      */
  345.          LoginShell( userp );
  346.          return FALSE;           /* Hang up phone and exit        */
  347.       } /* else */
  348.    } /* else */
  349.  
  350. } /*loginbypass*/
  351.  
  352. /*--------------------------------------------------------------------*/
  353. /*    L o g i n S h e l l                                             */
  354. /*                                                                    */
  355. /*    Execute a non-default remote user shell                         */
  356. /*--------------------------------------------------------------------*/
  357.  
  358. static void LoginShell( const   struct UserTable *userp )
  359. {
  360.  
  361.    char line[128];
  362.  
  363. #if defined(_Windows)
  364.  
  365. /*--------------------------------------------------------------------*/
  366. /*           No special shell support under Windows, sorry!           */
  367. /*--------------------------------------------------------------------*/
  368.  
  369.    sprintf(line,
  370.           "LoginShell: special shell %s not supported. Goodbye.\r\n",
  371.            userp->sh);
  372.    wmsg(line, 0);
  373.    printmsg(0, "Login with special shell %s, not supported.", userp->sh);
  374.    return;
  375.  
  376. #else
  377.  
  378.    char *shellstring;
  379.    char *path;
  380.    char *args;
  381.    int   rc;
  382.    char argstring[255];
  383.    char *s = argstring;
  384.  
  385. /*--------------------------------------------------------------------*/
  386. /*              Get the program to run and its arguments              */
  387. /*--------------------------------------------------------------------*/
  388.  
  389.    shellstring = strdup(userp->sh);
  390.                               /* Copy user shell for parsing   */
  391.    checkref(shellstring);
  392.    path = strtok(shellstring,WHITESPACE);   /* Get program name  */
  393.  
  394.    args = strtok(NULL,"");    /* Get rest of arg string     */
  395.  
  396.    if ( args == NULL )
  397.       *argstring = '\0';
  398.    else {
  399.       strncpy( argstring, args, sizeof argstring - 1 );
  400.       argstring[ sizeof argstring - 1 ] = '\0';
  401.    }
  402.  
  403.    path = newstr(path);
  404.    free( shellstring );
  405.  
  406. /*--------------------------------------------------------------------*/
  407. /*                 Perform command line substitution                  */
  408. /*--------------------------------------------------------------------*/
  409.  
  410.    printmsg(4,"LoginShell: command %s, parameters %s",
  411.             path, argstring );
  412.  
  413.    if ( args != NULL )
  414.    while( (s = strchr( s, '%')) != NULL ) /* Get next percent on line */
  415.    {
  416.       char *insert;
  417.       int len;
  418.  
  419.       switch( s[1] )                /* Look at next character        */
  420.       {
  421.          case '%':
  422.             insert = "%";           /* Literal percent size          */
  423.             break;
  424.  
  425.          case 'l':                  /* Com port handle               */
  426.             sprintf(line,"%d", GetComHandle());
  427.             insert = line;
  428.             break;
  429.  
  430.          case 'u':                  /* User id                       */
  431.             insert = (char *) userp->uid;
  432.             break;
  433.  
  434.          case 'p':
  435.             insert = M_device;      /* Port name                     */
  436.             break;
  437.  
  438.          case 's':
  439.             sprintf( line,"%lu", (long unsigned) GetSpeed());
  440.             insert = line;
  441.             break;                  /* Current line speed            */
  442.  
  443.          default:
  444.             printmsg(0,"LoginShell: Unknown substitution character %c",
  445.                      s[1] );
  446.             line[0] = s[1];
  447.             line[1] = '\0';
  448.             insert = line;
  449.             break;
  450.  
  451.       } /* switch */
  452.  
  453.       len = strlen( insert );
  454.       printmsg(4,"Inserting %s into %s",
  455.                  insert,
  456.                  argstring );
  457.       if ( len != 2 )               /* Make room for new string      */
  458.          memmove( s + len, s + 2, strlen(s + 2));
  459.  
  460.       memcpy( s, insert, len );     /* Move in the string            */
  461.  
  462.       s += len;                     /* Step past the string          */
  463.  
  464.    } /* while */
  465.  
  466. /*--------------------------------------------------------------------*/
  467. /*       Run the requested program in the user's home directory       */
  468. /*--------------------------------------------------------------------*/
  469.  
  470.    PushDir(userp->homedir);         /* Switch to user's home dir     */
  471.  
  472.  
  473.    printmsg(1,"LoginShell: Invoking %s %s in directory %s",
  474.          path, argstring, userp->homedir);
  475.    rc = execute( path, args ? argstring : NULL, NULL, NULL, TRUE, FALSE );
  476.  
  477.    PopDir();               /* Return to original directory  */
  478.  
  479. /*--------------------------------------------------------------------*/
  480. /*                     Report any errors we found                     */
  481. /*--------------------------------------------------------------------*/
  482.  
  483.    if ( rc > 0 )              /* Error condition?              */
  484.       printmsg(rc == 0 ? 4 : 0,"LoginShell: %s return code is %d",
  485.                path,
  486.                rc);
  487.  
  488. #endif
  489.  
  490. } /* LoginShell */
  491.  
  492. /*--------------------------------------------------------------------*/
  493. /*    m o t d                                                         */
  494. /*                                                                    */
  495. /*    Display a message of the day to the remote login                */
  496. /*--------------------------------------------------------------------*/
  497.  
  498. void motd( const char *fname, char *buf, const int bufsiz )
  499. {
  500.    FILE *stream = FOPEN( fname, "r", BINARY_MODE );  /* Leave CRLF in data */
  501.  
  502.    if ( stream == NULL )
  503.    {
  504.       perror( fname );
  505.       wmsg( fname,0 );
  506.       wmsg( ": ", 0);
  507.       wmsg( strerror( errno ),0);
  508.       wmsg( "\n\r",0);
  509.       return;
  510.    } /* if ( stream == NULL ) */
  511.  
  512.    while( fgets( buf, bufsiz, stream ) != NULL )
  513.       wmsg( buf, 0 );
  514.  
  515.    fclose( stream );
  516.  
  517. } /* motd */
  518.