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

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

Webmaster