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

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

Webmaster