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

2.14      frystyk     1: /*                                                                  HTTelnet.c
                      2: **     TELNET ACCESS, ROLIGIN, etc.
                      3: **
2.17      frystyk     4: **     (c) COPYRIGHT MIT 1995.
2.14      frystyk     5: **     Please first read the full copyright statement in the file COPYRIGH.
1.1       timbl       6: **
                      7: ** Authors
2.20      frystyk     8: **     TBL     Tim Berners-Lee timbl@w3.org
1.1       timbl       9: **     JFG     Jean-Francois Groff jgh@next.com
                     10: **     DD      Denis DeLaRoca (310) 825-4580  <CSP1DWD@mvs.oac.ucla.edu>
2.21      frystyk    11: **     HFN     Henrik Frystyk
1.1       timbl      12: ** History
                     13: **       8 Jun 92 Telnet hopping prohibited as telnet is not secure (TBL)
                     14: **     26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. (JFG)
                     15: **      6 Oct 92 Moved HTClientHost and logfile into here. (TBL)
                     16: **     17 Dec 92 Tn3270 added, bug fix. (DD)
                     17: **      2 Feb 93 Split from HTAccess.c. Registration.(TBL)
2.11      luotonen   18: **      2 May 94 Fixed security hole with illegal characters in host
                     19: **               and user names (code from Mosaic/Eric Bina).
1.1       timbl      20: */
                     21: 
2.16      frystyk    22: /* Library include files */
                     23: #include "tcp.h"
                     24: #include "HTUtils.h"
2.27      frystyk    25: #include "HTString.h"
1.1       timbl      26: #include "HTParse.h"
2.30      frystyk    27: #include "HTAccess.h"
1.1       timbl      28: #include "HTAnchor.h"
2.21      frystyk    29: #include "HTChunk.h"
2.27      frystyk    30: #include "HTReqMan.h"
1.3       timbl      31: #include "HTAlert.h"
2.12      frystyk    32: #include "HTTelnet.h"                                   /* Implemented here */
1.1       timbl      33: 
2.12      frystyk    34: /* ------------------------------------------------------------------------- */
1.1       timbl      35: 
2.11      luotonen   36: /*     make a string secure for passage to the
                     37: **     system() command.  Make it contain only alphanumneric
                     38: **     characters, or the characters '.', '-', '_', '+'.
                     39: **     Also remove leading '-' or '+'.
                     40: **     -----------------------------------------------------
                     41: **     Function taken from Mosaic's HTTelnet.c.
                     42: */
2.28      frystyk    43: PRIVATE void make_system_secure (char * str)
2.11      luotonen   44: {
2.21      frystyk    45:     char *ptr1, *ptr2;
                     46:     if ((str == NULL)||(*str == '\0'))
                     47:        return;
2.11      luotonen   48: 
2.21      frystyk    49:     /*
                     50:      * remove leading '-' or '+' by making it into whitespace that
                     51:      * will be stripped later.
                     52:      */
                     53:     if (*str=='-' || *str=='+')
                     54:        *str = ' ';
                     55:     ptr1 = ptr2 = str;
                     56:     while (*ptr1) {
                     57:        if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
                     58:            (*ptr1 != '.')&&(*ptr1 != '_')&&
                     59:            (*ptr1 != '+')&&(*ptr1 != '-')) {
                     60:            ptr1++;
                     61:        } else {
                     62:            *ptr2 = *ptr1;
                     63:            ptr2++;
                     64:            ptr1++;
2.11      luotonen   65:        }
2.21      frystyk    66:     }
                     67:     *ptr2 = *ptr1;
2.11      luotonen   68: }
                     69: 
1.1       timbl      70: /*     Telnet or "rlogin" access
                     71: **     -------------------------
2.27      frystyk    72: **     Returns HT_NO_DATA      OK
                     73: **             HT_ERROR        Error
1.1       timbl      74: */
2.28      frystyk    75: PRIVATE int remote_session (HTRequest * request, char * url)
1.1       timbl      76: {
2.21      frystyk    77:     int status = HT_NO_DATA;
2.32      frystyk    78:     HTChunk *cmd = HTChunk_new(64);
2.21      frystyk    79:     char *access = HTParse(url, "", PARSE_ACCESS);
                     80:     char *host = HTParse(url, "", PARSE_HOST);
                     81:     char *hostname = strchr(host, '@');
                     82:     char *user = NULL;
                     83:     char *passwd = NULL;
                     84:     char *port = NULL;
                     85: 
2.27      frystyk    86:     /* We must be in interactive mode */
2.31      frystyk    87:     if (!HTAlert_interactive()) {
                     88:        if (PROT_TRACE) TTYPrint(TDEST, "Telnet...... Not interactive\n");
2.33    ! frystyk    89:        HT_FREE(access);
        !            90:        HT_FREE(host);
2.32      frystyk    91:        HTChunk_delete(cmd);
2.27      frystyk    92:        return HT_ERROR;
                     93:     }
                     94: 
2.21      frystyk    95:     /* Look for user name, password, and port number */
                     96:     if (hostname) {
                     97:        *hostname++ = '\0';
                     98:        user = host;
                     99:        if ((passwd = strchr(host, ':')) != NULL) {
                    100:            *passwd++ = '\0';
                    101:            HTUnEscape(passwd);
                    102:        }
                    103:        HTUnEscape(user);                       /* Might have a funny userid */
                    104:     } else {
                    105:        hostname = host;
                    106:     }
                    107:     if ((port = strchr(hostname, ':')) != NULL)
                    108:        *port++ = '\0';
                    109: 
                    110:     /* If the person is already telnetting etc, forbid hopping */
2.30      frystyk   111:     if (HTLib_secure()) {
2.31      frystyk   112:        HTRequest_addError(request, ERR_FATAL, NO,
                    113:                           HTERR_ACCESS, NULL, 0, "HTLoadTelnet");
2.33    ! frystyk   114:        HT_FREE(access);
        !           115:        HT_FREE(host);
2.32      frystyk   116:        HTChunk_delete(cmd);
2.21      frystyk   117:        return HT_NO_DATA;
                    118:     }
                    119: 
                    120:     /*
                    121:     ** Make user and hostname secure by removing leading '-' or '+'.
                    122:     ** and allowing only alphanumeric, '.', '_', '+', and '-'.
                    123:     */
                    124:     make_system_secure(user);
                    125:     make_system_secure(passwd);
                    126:     make_system_secure(hostname);
                    127:     make_system_secure(port);
                    128: 
2.27      frystyk   129:     if (!strcasecomp(access, "telnet")) {
2.21      frystyk   130: #ifdef SIMPLE_TELNET
2.32      frystyk   131:        HTChunk_puts(cmd, "TELNET ");
                    132:        HTChunk_puts(cmd, hostname);                      /* Port is ignored */
2.21      frystyk   133: #else
2.26      frystyk   134: #ifdef FULL_TELNET                                         /* User and port */
2.32      frystyk   135:        HTChunk_puts(cmd, "telnet ");
                    136:        HTChunk_puts(cmd, hostname);
2.26      frystyk   137:        if (user) {
2.32      frystyk   138:            HTChunk_puts(cmd, " -l ");
                    139:            HTChunk_puts(cmd, user);
2.26      frystyk   140:        }
                    141:        if (port) {
2.32      frystyk   142:            HTChunk_putc(cmd, ' ');
                    143:            HTChunk_puts(cmd,  port);
2.26      frystyk   144:        }
                    145: #else
2.21      frystyk   146: #ifdef MULTINET
2.32      frystyk   147:        HTChunk_puts(cmd, "TELNET ");
2.21      frystyk   148:        if (port) {
2.32      frystyk   149:            HTChunk_puts(cmd, "/PORT=");
                    150:            HTChunk_puts(cmd, port);
                    151:            HTChunk_putc(cmd, ' ');
2.21      frystyk   152:        }
2.32      frystyk   153:        HTChunk_puts(cmd, hostname);
2.26      frystyk   154: #else                                                    /* User is ignored */
2.32      frystyk   155:        HTChunk_puts(cmd, "telnet ");
                    156:        HTChunk_puts(cmd, hostname);
2.21      frystyk   157:        if (port) {
2.32      frystyk   158:            HTChunk_putc(cmd, ' ');
                    159:            HTChunk_puts(cmd,  port);
2.21      frystyk   160:        }
                    161: #endif /* MULTINET */
2.26      frystyk   162: #endif /* FULL_TELNET */
2.21      frystyk   163: #endif /* SIMPLE_TELNET */
                    164: 
2.27      frystyk   165:     } else if (!strcasecomp(access, "rlogin")) {
2.21      frystyk   166: #ifdef MULTINET
2.32      frystyk   167:        HTChunk_puts(cmd, "RLOGIN ");
2.21      frystyk   168:        if (user) {
2.32      frystyk   169:            HTChunk_puts(cmd, "/USERNAME=");
                    170:            HTChunk_puts(cmd, user);
                    171:            HTChunk_putc(cmd, ' ');
2.21      frystyk   172:        }
                    173:        if (port) {
2.32      frystyk   174:            HTChunk_puts(cmd, "/PORT=");
                    175:            HTChunk_puts(cmd, port);
                    176:            HTChunk_putc(cmd, ' ');
2.21      frystyk   177:        }
2.32      frystyk   178:        HTChunk_puts(cmd, hostname);
2.21      frystyk   179: #else
                    180: #ifdef RLOGIN_USER                            /* format: "hostname -l user" */
2.32      frystyk   181:        HTChunk_puts(cmd, "rlogin ");
                    182:        HTChunk_puts(cmd, hostname);
2.21      frystyk   183:        if (user) {
2.32      frystyk   184:            HTChunk_puts(cmd, " -l ");
                    185:            HTChunk_puts(cmd, user);
2.21      frystyk   186:        }
                    187: #else                                         /* format: "-l user hostname" */
2.32      frystyk   188:        HTChunk_puts(cmd, "rlogin ");
2.21      frystyk   189:        if (user) {
2.32      frystyk   190:            HTChunk_puts(cmd, "-l ");
                    191:            HTChunk_puts(cmd, user);
                    192:            HTChunk_putc(cmd, ' ');
2.21      frystyk   193:        }
2.32      frystyk   194:        HTChunk_puts(cmd, hostname);
2.21      frystyk   195: #endif /* RLOGIN_AFTER */
                    196: #endif /* MULTINET */
                    197: 
2.27      frystyk   198:     } else if (!strcasecomp(access, "tn3270")) {
2.21      frystyk   199: #ifdef MULTINET
2.32      frystyk   200:        HTChunk_puts(cmd, "TELNET/TN3270 ");
2.21      frystyk   201:        if (port) {
2.32      frystyk   202:            HTChunk_puts(cmd, "/PORT=");
                    203:            HTChunk_puts(cmd, port);
                    204:            HTChunk_putc(cmd, ' ');
1.1       timbl     205:        }
2.32      frystyk   206:        HTChunk_puts(cmd, hostname);
2.21      frystyk   207: #else
2.32      frystyk   208:        HTChunk_puts(cmd, "tn3270 ");
                    209:        HTChunk_puts(cmd, hostname);                      /* Port is ignored */
2.21      frystyk   210: #endif /* MULTINET */
                    211: 
                    212:     } else {
                    213:        if (PROT_TRACE)
2.29      frystyk   214:            TTYPrint(TDEST, "Telnet...... Unknown access method: `%s\'\n",
2.21      frystyk   215:                    access);
                    216:        status = HT_ERROR;
                    217:     }
1.1       timbl     218: 
2.21      frystyk   219:     /* Now we are ready to execute the command */
                    220:     if (PROT_TRACE)
2.29      frystyk   221:        TTYPrint(TDEST, "Telnet...... Command is `%s\'\n", cmd->data);
2.21      frystyk   222:     if (user) {
2.32      frystyk   223:        HTChunk *msg = HTChunk_new(128);
2.27      frystyk   224:        if (strcasecomp(access, "rlogin")) {
2.32      frystyk   225:            HTChunk_puts(msg, "user <");
                    226:            HTChunk_puts(msg, user);
                    227:            HTChunk_putc(msg, '>');
2.21      frystyk   228:        }
                    229:        if (passwd) {
2.32      frystyk   230:            HTChunk_puts(msg, " and password <");
                    231:            HTChunk_puts(msg, passwd);
                    232:            HTChunk_putc(msg, '>');
1.1       timbl     233:        }
2.31      frystyk   234:        HTRequest_addError(request, ERR_INFO, NO,
2.32      frystyk   235:                           HTERR_LOGIN, HTChunk_data(msg), HTChunk_size(msg),
2.31      frystyk   236:                           "HTLoadTelnet");
2.32      frystyk   237:        HTChunk_delete(msg);
2.21      frystyk   238:     }
2.29      frystyk   239: #ifdef GOT_SYSTEM
2.21      frystyk   240:     system(cmd->data);
2.29      frystyk   241: #endif
2.33    ! frystyk   242:     HT_FREE(access);
        !           243:     HT_FREE(host);
2.32      frystyk   244:     HTChunk_delete(cmd);
2.21      frystyk   245:     return status;
1.1       timbl     246: 
                    247: }
                    248: 
                    249: /*     "Load a document" -- establishes a session
2.21      frystyk   250: **     ==========================================
1.1       timbl     251: **
                    252: ** On entry,
2.21      frystyk   253: **      request                This is the request structure
1.1       timbl     254: ** On exit,
2.21      frystyk   255: **     returns         HT_ERROR        Error has occured or interrupted
                    256: **                     HT_NO_DATA      if return status 204 No Response
1.1       timbl     257: */
2.28      frystyk   258: PUBLIC int HTLoadTelnet (SOCKET soc, HTRequest * request, SockOps ops)
1.1       timbl     259: {
2.27      frystyk   260:     char *url = HTAnchor_physical(request->anchor);
2.10      luotonen  261: 
2.27      frystyk   262:     /* This is a trick as we don't have any socket! */
                    263:     if (ops == FD_NONE) {
2.29      frystyk   264:        if (PROT_TRACE) TTYPrint(TDEST, "Telnet...... Looking for `%s\'\n",url);
2.27      frystyk   265:        HTCleanTelnetString(url);
                    266:        {
                    267:            int status = remote_session(request, url);
                    268:            HTNet_delete(request->net, status);
                    269:        }
                    270:     } else if (ops == FD_CLOSE)                                      /* Interrupted */
                    271:        HTNet_delete(request->net, HT_INTERRUPTED);
                    272:     else
                    273:        HTNet_delete(request->net, HT_ERROR);
                    274:     return HT_OK;
1.1       timbl     275: }
                    276: 
                    277: 

Webmaster