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

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

Webmaster