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

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"
                     27: #include "HTAnchor.h"
2.21      frystyk    28: #include "HTChunk.h"
2.27      frystyk    29: #include "HTReqMan.h"
1.3       timbl      30: #include "HTAlert.h"
2.12      frystyk    31: #include "HTTelnet.h"                                   /* Implemented here */
1.1       timbl      32: 
2.12      frystyk    33: /* ------------------------------------------------------------------------- */
1.1       timbl      34: 
2.11      luotonen   35: /*     make a string secure for passage to the
                     36: **     system() command.  Make it contain only alphanumneric
                     37: **     characters, or the characters '.', '-', '_', '+'.
                     38: **     Also remove leading '-' or '+'.
                     39: **     -----------------------------------------------------
                     40: **     Function taken from Mosaic's HTTelnet.c.
                     41: */
2.28      frystyk    42: PRIVATE void make_system_secure (char * str)
2.11      luotonen   43: {
2.21      frystyk    44:     char *ptr1, *ptr2;
                     45:     if ((str == NULL)||(*str == '\0'))
                     46:        return;
2.11      luotonen   47: 
2.21      frystyk    48:     /*
                     49:      * remove leading '-' or '+' by making it into whitespace that
                     50:      * will be stripped later.
                     51:      */
                     52:     if (*str=='-' || *str=='+')
                     53:        *str = ' ';
                     54:     ptr1 = ptr2 = str;
                     55:     while (*ptr1) {
                     56:        if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
                     57:            (*ptr1 != '.')&&(*ptr1 != '_')&&
                     58:            (*ptr1 != '+')&&(*ptr1 != '-')) {
                     59:            ptr1++;
                     60:        } else {
                     61:            *ptr2 = *ptr1;
                     62:            ptr2++;
                     63:            ptr1++;
2.11      luotonen   64:        }
2.21      frystyk    65:     }
                     66:     *ptr2 = *ptr1;
2.11      luotonen   67: }
                     68: 
1.1       timbl      69: /*     Telnet or "rlogin" access
                     70: **     -------------------------
2.27      frystyk    71: **     Returns HT_NO_DATA      OK
                     72: **             HT_ERROR        Error
1.1       timbl      73: */
2.28      frystyk    74: PRIVATE int remote_session (HTRequest * request, char * url)
1.1       timbl      75: {
2.21      frystyk    76:     int status = HT_NO_DATA;
                     77:     HTChunk *cmd = HTChunkCreate(64);
                     78:     char *access = HTParse(url, "", PARSE_ACCESS);
                     79:     char *host = HTParse(url, "", PARSE_HOST);
                     80:     char *hostname = strchr(host, '@');
                     81:     char *user = NULL;
                     82:     char *passwd = NULL;
                     83:     char *port = NULL;
                     84: 
2.27      frystyk    85:     /* We must be in interactive mode */
                     86:     if (!HTPrompt_interactive()) {
                     87:        HTAlert(request,"Can't output live session - must be interactive");
                     88:        free(access);
                     89:        free(host);
                     90:        HTChunkFree(cmd);
                     91:        return HT_ERROR;
                     92:     }
                     93: 
2.21      frystyk    94:     /* Look for user name, password, and port number */
                     95:     if (hostname) {
                     96:        *hostname++ = '\0';
                     97:        user = host;
                     98:        if ((passwd = strchr(host, ':')) != NULL) {
                     99:            *passwd++ = '\0';
                    100:            HTUnEscape(passwd);
                    101:        }
                    102:        HTUnEscape(user);                       /* Might have a funny userid */
                    103:     } else {
                    104:        hostname = host;
                    105:     }
                    106:     if ((port = strchr(hostname, ':')) != NULL)
                    107:        *port++ = '\0';
                    108: 
                    109:     /* If the person is already telnetting etc, forbid hopping */
                    110:     if (HTClientHost) {
                    111:        HTChunk *msg = HTChunkCreate(256);
                    112:        HTChunkPuts(msg, "Sorry, but the service you have selected is one ");
                    113:        HTChunkPuts(msg, "to which you have to log in. If you were running ");
                    114:        HTChunkPuts(msg, "locally on your own computer, you would be ");
                    115:        HTChunkPuts(msg, "connected automatically. For security reasons, ");
                    116:        HTChunkPuts(msg, "this is not allowed when you log in to this ");
                    117:        HTChunkPuts(msg, "information service remotely. ");
1.1       timbl     118:        if (hostname) {
2.21      frystyk   119:            HTChunkPuts(msg,"You can manually connect to this service using ");
                    120:            HTChunkPuts(msg, access);
                    121:            HTChunkPuts(msg, " to host ");
                    122:            HTChunkPuts(msg, hostname);
                    123:            if (port) {
                    124:                HTChunkPuts(msg, " using port ");
                    125:                HTChunkPuts(msg, port);
                    126:            }
                    127:            if (user) {
                    128:                HTChunkPuts(msg, " and user name ");
                    129:                HTChunkPuts(msg, user);
                    130:            }
                    131:            if (passwd) {
                    132:                HTChunkPuts(msg, " and passwd ");
                    133:                HTChunkPuts(msg, passwd);
                    134:            }
                    135:        }
2.25      frystyk   136:        HTAlert(request, msg->data);
2.21      frystyk   137:        HTChunkFree(msg);
                    138:        free(access);
                    139:        free(host);
2.27      frystyk   140:        HTChunkFree(cmd);
2.21      frystyk   141:        return HT_NO_DATA;
                    142:     }
                    143: 
                    144:     /*
                    145:     ** Make user and hostname secure by removing leading '-' or '+'.
                    146:     ** and allowing only alphanumeric, '.', '_', '+', and '-'.
                    147:     */
                    148:     make_system_secure(user);
                    149:     make_system_secure(passwd);
                    150:     make_system_secure(hostname);
                    151:     make_system_secure(port);
                    152: 
2.27      frystyk   153:     if (!strcasecomp(access, "telnet")) {
2.21      frystyk   154: #ifdef SIMPLE_TELNET
                    155:        HTChunkPuts(cmd, "TELNET ");
                    156:        HTChunkPuts(cmd, hostname);                       /* Port is ignored */
                    157: #else
2.26      frystyk   158: #ifdef FULL_TELNET                                         /* User and port */
                    159:        HTChunkPuts(cmd, "telnet ");
                    160:        HTChunkPuts(cmd, hostname);
                    161:        if (user) {
                    162:            HTChunkPuts(cmd, " -l ");
                    163:            HTChunkPuts(cmd, user);
                    164:        }
                    165:        if (port) {
                    166:            HTChunkPutc(cmd, ' ');
                    167:            HTChunkPuts(cmd,  port);
                    168:        }
                    169: #else
2.21      frystyk   170: #ifdef MULTINET
                    171:        HTChunkPuts(cmd, "TELNET ");
                    172:        if (port) {
                    173:            HTChunkPuts(cmd, "/PORT=");
                    174:            HTChunkPuts(cmd, port);
                    175:            HTChunkPutc(cmd, ' ');
                    176:        }
                    177:        HTChunkPuts(cmd, hostname);
2.26      frystyk   178: #else                                                    /* User is ignored */
2.21      frystyk   179:        HTChunkPuts(cmd, "telnet ");
                    180:        HTChunkPuts(cmd, hostname);
                    181:        if (port) {
                    182:            HTChunkPutc(cmd, ' ');
                    183:            HTChunkPuts(cmd,  port);
                    184:        }
                    185: #endif /* MULTINET */
2.26      frystyk   186: #endif /* FULL_TELNET */
2.21      frystyk   187: #endif /* SIMPLE_TELNET */
                    188: 
2.27      frystyk   189:     } else if (!strcasecomp(access, "rlogin")) {
2.21      frystyk   190: #ifdef MULTINET
                    191:        HTChunkPuts(cmd, "RLOGIN ");
                    192:        if (user) {
                    193:            HTChunkPuts(cmd, "/USERNAME=");
                    194:            HTChunkPuts(cmd, user);
                    195:            HTChunkPutc(cmd, ' ');
                    196:        }
                    197:        if (port) {
                    198:            HTChunkPuts(cmd, "/PORT=");
                    199:            HTChunkPuts(cmd, port);
                    200:            HTChunkPutc(cmd, ' ');
                    201:        }
                    202:        HTChunkPuts(cmd, hostname);
                    203: #else
                    204: #ifdef RLOGIN_USER                            /* format: "hostname -l user" */
                    205:        HTChunkPuts(cmd, "rlogin ");
                    206:        HTChunkPuts(cmd, hostname);
                    207:        if (user) {
2.22      frystyk   208:            HTChunkPuts(cmd, " -l ");
2.21      frystyk   209:            HTChunkPuts(cmd, user);
                    210:        }
                    211: #else                                         /* format: "-l user hostname" */
                    212:        HTChunkPuts(cmd, "rlogin ");
                    213:        if (user) {
                    214:            HTChunkPuts(cmd, "-l ");
                    215:            HTChunkPuts(cmd, user);
                    216:            HTChunkPutc(cmd, ' ');
                    217:        }
                    218:        HTChunkPuts(cmd, hostname);
                    219: #endif /* RLOGIN_AFTER */
                    220: #endif /* MULTINET */
                    221: 
2.27      frystyk   222:     } else if (!strcasecomp(access, "tn3270")) {
2.21      frystyk   223: #ifdef MULTINET
                    224:        HTChunkPuts(cmd, "TELNET/TN3270 ");
                    225:        if (port) {
                    226:            HTChunkPuts(cmd, "/PORT=");
                    227:            HTChunkPuts(cmd, port);
                    228:            HTChunkPutc(cmd, ' ');
1.1       timbl     229:        }
2.21      frystyk   230:        HTChunkPuts(cmd, hostname);
                    231: #else
                    232:        HTChunkPuts(cmd, "tn3270 ");
                    233:        HTChunkPuts(cmd, hostname);                       /* Port is ignored */
                    234: #endif /* MULTINET */
                    235: 
                    236:     } else {
                    237:        if (PROT_TRACE)
2.29    ! frystyk   238:            TTYPrint(TDEST, "Telnet...... Unknown access method: `%s\'\n",
2.21      frystyk   239:                    access);
                    240:        status = HT_ERROR;
                    241:     }
1.1       timbl     242: 
2.21      frystyk   243:     /* Now we are ready to execute the command */
                    244:     if (PROT_TRACE)
2.29    ! frystyk   245:        TTYPrint(TDEST, "Telnet...... Command is `%s\'\n", cmd->data);
2.21      frystyk   246:     if (user) {
                    247:        HTChunk *msg = HTChunkCreate(128);
                    248:        HTChunkPuts(msg, "When you are connected, log in");
2.27      frystyk   249:        if (strcasecomp(access, "rlogin")) {
2.21      frystyk   250:            HTChunkPuts(msg, "as <");
                    251:            HTChunkPuts(msg, user);
                    252:            HTChunkPutc(msg, '>');
                    253:        }
                    254:        if (passwd) {
                    255:            HTChunkPuts(msg, " using password <");
                    256:            HTChunkPuts(msg, passwd);
                    257:            HTChunkPutc(msg, '>');
1.1       timbl     258:        }
2.25      frystyk   259:        HTAlert(request, msg->data);
2.21      frystyk   260:        HTChunkFree(msg);
                    261:     }
2.29    ! frystyk   262: #ifdef GOT_SYSTEM
2.21      frystyk   263:     system(cmd->data);
2.29    ! frystyk   264: #endif
2.21      frystyk   265:     free(access);
                    266:     free(host);
                    267:     HTChunkFree(cmd);
                    268:     return status;
1.1       timbl     269: 
                    270: }
                    271: 
                    272: /*     "Load a document" -- establishes a session
2.21      frystyk   273: **     ==========================================
1.1       timbl     274: **
                    275: ** On entry,
2.21      frystyk   276: **      request                This is the request structure
1.1       timbl     277: ** On exit,
2.21      frystyk   278: **     returns         HT_ERROR        Error has occured or interrupted
                    279: **                     HT_NO_DATA      if return status 204 No Response
1.1       timbl     280: */
2.28      frystyk   281: PUBLIC int HTLoadTelnet (SOCKET soc, HTRequest * request, SockOps ops)
1.1       timbl     282: {
2.27      frystyk   283:     char *url = HTAnchor_physical(request->anchor);
2.10      luotonen  284: 
2.27      frystyk   285:     /* This is a trick as we don't have any socket! */
                    286:     if (ops == FD_NONE) {
2.29    ! frystyk   287:        if (PROT_TRACE) TTYPrint(TDEST, "Telnet...... Looking for `%s\'\n",url);
2.27      frystyk   288:        HTCleanTelnetString(url);
                    289:        {
                    290:            int status = remote_session(request, url);
                    291:            HTNet_delete(request->net, status);
                    292:        }
                    293:     } else if (ops == FD_CLOSE)                                      /* Interrupted */
                    294:        HTNet_delete(request->net, HT_INTERRUPTED);
                    295:     else
                    296:        HTNet_delete(request->net, HT_ERROR);
                    297:     return HT_OK;
1.1       timbl     298: }
                    299: 
                    300: 

Webmaster