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

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

Webmaster