Annotation of libwww/Library/src/HTTelnet.c, revision 2.16

2.14      frystyk     1: /*                                                                  HTTelnet.c
                      2: **     TELNET ACCESS, ROLIGIN, etc.
                      3: **
                      4: **     (c) COPYRIGHT CERN 1994.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
1.1       timbl       6: **
                      7: ** Authors
                      8: **     TBL     Tim Berners-Lee timbl@info.cern.ch
                      9: **     JFG     Jean-Francois Groff jgh@next.com
                     10: **     DD      Denis DeLaRoca (310) 825-4580  <CSP1DWD@mvs.oac.ucla.edu>
                     11: ** History
                     12: **       8 Jun 92 Telnet hopping prohibited as telnet is not secure (TBL)
                     13: **     26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. (JFG)
                     14: **      6 Oct 92 Moved HTClientHost and logfile into here. (TBL)
                     15: **     17 Dec 92 Tn3270 added, bug fix. (DD)
                     16: **      2 Feb 93 Split from HTAccess.c. Registration.(TBL)
2.11      luotonen   17: **      2 May 94 Fixed security hole with illegal characters in host
                     18: **               and user names (code from Mosaic/Eric Bina).
1.1       timbl      19: */
                     20: 
2.16    ! frystyk    21: /* Library include files */
        !            22: #include "tcp.h"
        !            23: #include "HTUtils.h"
1.1       timbl      24: #include "HTParse.h"
                     25: #include "HTAnchor.h"
                     26: #include "HTFile.h"
                     27: #include "HTAccess.h"
1.3       timbl      28: #include "HTAlert.h"
2.12      frystyk    29: #include "HTTelnet.h"                                   /* Implemented here */
1.1       timbl      30: 
2.12      frystyk    31: /* ------------------------------------------------------------------------- */
1.1       timbl      32: 
2.11      luotonen   33: /*     make a string secure for passage to the
                     34: **     system() command.  Make it contain only alphanumneric
                     35: **     characters, or the characters '.', '-', '_', '+'.
                     36: **     Also remove leading '-' or '+'.
                     37: **     -----------------------------------------------------
                     38: **     Function taken from Mosaic's HTTelnet.c.
                     39: */
                     40: PRIVATE void make_system_secure ARGS1(char *, str)
                     41: {
                     42:        char *ptr1, *ptr2;
                     43: 
                     44:        if ((str == NULL)||(*str == '\0'))
                     45:        {
                     46:                return;
                     47:        }
                     48: 
                     49:        /*
                     50:         * remove leading '-' or '+' by making it into whitespace that
                     51:         * will be stripped later.
                     52:         */
                     53:        if ((*str == '-')||(*str == '+'))
                     54:        {
                     55:                *str = ' ';
                     56:        }
                     57: 
                     58:        ptr1 = ptr2 = str;
                     59: 
                     60:        while (*ptr1 != '\0')
                     61:        {
                     62:                if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
                     63:                        (*ptr1 != '.')&&(*ptr1 != '_')&&
                     64:                        (*ptr1 != '+')&&(*ptr1 != '-'))
                     65:                {
                     66:                        ptr1++;
                     67:                }
                     68:                else
                     69:                {
                     70:                        *ptr2 = *ptr1;
                     71:                        ptr2++;
                     72:                        ptr1++;
                     73:                }
                     74:        }
                     75:        *ptr2 = *ptr1;
                     76: }
                     77: 
                     78: 
                     79: 
1.1       timbl      80: /*     Telnet or "rlogin" access
                     81: **     -------------------------
                     82: */
                     83: PRIVATE int remote_session ARGS2(char *, access, char *, host)
                     84: {
                     85:        char * user = host;
                     86:        char * hostname = strchr(host, '@');
                     87:        char * port = strchr(host, ':');
                     88:        char   command[256];
                     89:        enum _login_protocol { telnet, rlogin, tn3270 } login_protocol =
                     90:                strcmp(access, "rlogin") == 0 ? rlogin :
                     91:                strcmp(access, "tn3270") == 0 ? tn3270 : telnet;
                     92:        
                     93:        if (hostname) {
                     94:            *hostname++ = 0;    /* Split */
                     95:        } else {
                     96:            hostname = host;
                     97:            user = 0;           /* No user specified */
                     98:        }
                     99:        if (port) *port++ = 0;  /* Split */
                    100: 
2.11      luotonen  101:        /*
                    102:         * Make user and hostname secure by removing leading '-' or '+'.
                    103:         * and allowing only alphanumeric, '.', '_', '+', and '-'.
                    104:         */
                    105:        make_system_secure(user);
                    106:        make_system_secure(hostname);
1.1       timbl     107: 
                    108: /* If the person is already telnetting etc, forbid hopping */
                    109: /* This is a security precaution, for us and remote site */
                    110: 
2.6       timbl     111:        if (HTSecure) {
1.1       timbl     112: 
                    113: #ifdef TELNETHOPPER_MAIL
                    114:            sprintf(command, 
                    115:              "finger @%s | mail -s \"**telnethopper %s\" tbl@dxcern.cern.ch",
                    116:               HTClientHost, HTClientHost);
                    117:            system(command);
                    118: #endif
                    119:            printf("\n\nSorry, but the service you have selected is one\n");
                    120:            printf("to which you have to log in.  If you were running www\n");
                    121:            printf("on your own computer, you would be automatically connected.\n");
                    122:            printf("For security reasons, this is not allowed when\n");
                    123:            printf("you log in to this information service remotely.\n\n");
                    124: 
                    125:            printf("You can manually connect to this service using %s\n",
                    126:                   access);
                    127:            printf("to host %s", hostname);
                    128:            if (user) printf(", user name %s", user);
                    129:            if (port) printf(", port %s", port);
                    130:            printf(".\n\n");
                    131:            return HT_NO_DATA;
                    132:        }
                    133: 
                    134: /* Not all telnet servers get it even if user name is specified
                    135: ** so we always tell the guy what to log in as
                    136: */
                    137:         if (user) printf("When you are connected, log in as %s\n", user);
2.16    ! frystyk   138:        
        !           139: #ifdef NeXT
        !           140: #define TELNET_MINUS_L
        !           141: #endif
        !           142: #ifdef ultrix
        !           143: #define TELNET_MINUS_L
        !           144: #endif
2.15      roeber    145: 
2.16    ! frystyk   146: #ifdef TELNET_MINUS_L
        !           147:        sprintf(command, "%s%s%s %s %s", access,
        !           148:                user ? " -l " : "",
        !           149:                user ? user : "",
        !           150:                hostname,
        !           151:                port ? port : "");
        !           152: 
        !           153:        if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
        !           154:        system(command);
        !           155:        return HT_NO_DATA;              /* Ok - it was done but no data */
        !           156: #define TELNET_DONE
1.1       timbl     157: #endif
2.15      roeber    158: 
2.16    ! frystyk   159: /* Most unix machines suppport username only with rlogin */
        !           160: #ifdef unix
        !           161: #ifndef TELNET_DONE
        !           162:        if (login_protocol != rlogin) {
        !           163:            sprintf(command, "%s %s %s", access,
        !           164:                hostname,
        !           165:                port ? port : "");
        !           166:        } else {
        !           167:            sprintf(command, "%s%s%s %s %s", access,
        !           168:                user ? " -l " : "",
        !           169:                user ? user : "",
        !           170:                hostname,
        !           171:                port ? port : "");
        !           172:        }
        !           173:        if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
        !           174:        system(command);
        !           175:        return HT_NO_DATA;              /* Ok - it was done but no data */
        !           176: #define TELNET_DONE
        !           177: #endif
1.1       timbl     178: #endif
                    179: 
2.16    ! frystyk   180: #ifdef MULTINET                                /* VMS varieties */
        !           181:        if (login_protocol == telnet) {
        !           182:            sprintf(command, "TELNET %s%s %s",
        !           183:                port ? "/PORT=" : "",
        !           184:                port ? port : "",
        !           185:                hostname);
        !           186:        } else if (login_protocol == tn3270) {
        !           187:            sprintf(command, "TELNET/TN3270 %s%s %s",
        !           188:                port ? "/PORT=" : "",
        !           189:                port ? port : "",
        !           190:                hostname);
        !           191:        } else {
        !           192:            sprintf(command, "RLOGIN%s%s%s%s %s",  /*lm 930713 */
        !           193:                user ? "/USERNAME=" : "",
        !           194:                user ? user : "",
        !           195:                port ? "/PORT=" : "",
        !           196:                port ? port : "",
        !           197:                hostname);
        !           198:        }
        !           199:        if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
        !           200:        system(command);
        !           201:        return HT_NO_DATA;              /* Ok - it was done but no data */
        !           202: #define TELNET_DONE
1.2       timbl     203: #endif
1.1       timbl     204: 
2.16    ! frystyk   205: #ifdef UCX
        !           206: #define SIMPLE_TELNET
        !           207: #endif
        !           208: #ifdef VM
        !           209: #define SIMPLE_TELNET
        !           210: #endif
        !           211: #ifdef SIMPLE_TELNET
        !           212:        if (login_protocol == telnet) {                 /* telnet only */
        !           213:            sprintf(command, "TELNET  %s",      /* @@ Bug: port ignored */
        !           214:                hostname);
        !           215:            if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
        !           216:            system(command);
        !           217:            return HT_NO_DATA;          /* Ok - it was done but no data */
1.1       timbl     218:        }
2.16    ! frystyk   219: #endif
1.1       timbl     220: 
2.16    ! frystyk   221: #ifndef TELNET_DONE
        !           222:        fprintf(TDEST,
        !           223:        "Sorry, this browser was compiled without the %s access option.\n",
        !           224:                access);
        !           225:        fprintf(TDEST,
        !           226:        "\nTo access the information you must %s to %s", access, hostname);
        !           227:        if (port) fprintf(TDEST," (port %s)", port);
        !           228:        if (user) fprintf(TDEST," logging in with username %s", user);
        !           229:        fprintf(TDEST, ".\n");
        !           230:        return -1;
        !           231: #endif
1.1       timbl     232: }
                    233: 
                    234: /*     "Load a document" -- establishes a session
                    235: **     ------------------------------------------
                    236: **
                    237: ** On entry,
                    238: **     addr            must point to the fully qualified hypertext reference.
                    239: **
                    240: ** On exit,
                    241: **     returns         <0      Error has occured.
                    242: **                     >=0     Value of file descriptor or socket to be used
                    243: **                              to read data.
                    244: **     *pFormat        Set to the format of the file, if known.
                    245: **                     (See WWW.h)
                    246: **
                    247: */
2.9       timbl     248: PRIVATE int HTLoadTelnet ARGS1(HTRequest *, request)
1.1       timbl     249: {
1.2       timbl     250:     char * access;
2.9       timbl     251:     CONST char * addr = HTAnchor_physical(request->anchor);
1.2       timbl     252:     char * host;
                    253:     int status;
2.10      luotonen  254: 
2.9       timbl     255:     if (request->output_stream) {
1.2       timbl     256:         HTAlert("Can't output a live session -- it has to be interactive");
                    257:        return HT_NO_ACCESS;
                    258:     }
                    259:     access =  HTParse(addr, "file:", PARSE_ACCESS);
1.1       timbl     260:     
1.2       timbl     261:     host = HTParse(addr, "", PARSE_HOST);
2.10      luotonen  262: 
                    263:     /*
                    264:      * Fix a security hole with telnet: URLs that contain semicolon
                    265:      * after the machine name.  This would cause system commands to
                    266:      * be executed after the telnet session is finished, e.g.
                    267:      *
                    268:      *         telnet://some.host; rm some_important_file
                    269:      *
                    270:      * or even more destructive:
                    271:      *
                    272:      *         telnet://some.host; rm -fr *    (don't try this!!)
                    273:      */
                    274:     {
                    275:        char * semi = strchr(host,';');
                    276:        if (semi) *semi = 0;
                    277:     }
                    278: 
1.2       timbl     279:     status = remote_session(access, host);
1.1       timbl     280: 
                    281:     free(host);        
                    282:     free(access);
                    283:     return status;
                    284: }
                    285: 
                    286: 
2.13      frystyk   287: GLOBALDEF PUBLIC HTProtocol HTTelnet = {
                    288:     "telnet", SOC_BLOCK, HTLoadTelnet, NULL, NULL
                    289: };
                    290: 
                    291: GLOBALDEF PUBLIC HTProtocol HTRlogin = {
                    292:     "rlogin", SOC_BLOCK, HTLoadTelnet, NULL, NULL
                    293: };
                    294: 
                    295: GLOBALDEF PUBLIC HTProtocol HTTn3270 = {
                    296:     "tn3270", SOC_BLOCK, HTLoadTelnet, NULL, NULL
                    297: };
1.1       timbl     298: 
                    299: 

Webmaster