ckctel.c
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:158k
源码类别:

通讯/手机编程

开发平台:

Windows_Unix

  1.                             switch (sb[1]) {
  2.                               case 5:   /* SRP */
  3.                                 s[3] = "FORWARD";
  4.                                 break;
  5.                               case 2:   /* KERBEROS_V5 */
  6.                                 s[3] = "FORWARD_ACCEPT";
  7.                                 break;
  8.                             }
  9.                             break;
  10.                           case 6:
  11.                             switch (sb[1]) {
  12.                               case 5:   /* SRP */
  13.                                 s[3] = "FORWARD_ACCEPT";
  14.                                 break;
  15.                               case 2: /* KERBEROS_V5 */
  16.                                 s[3] = "FORWARD_REJECT";
  17.                                 break;
  18.                             }
  19.                             break;
  20.                           case 7:
  21.                             switch (sb[1]) {
  22.                               case 5:   /* SRP */
  23.                                 s[3] = "FORWARD_REJECT";
  24.                                 break;
  25.                             }
  26.                             break;
  27.                           case 8:
  28.                             switch (sb[1]) {
  29.                               case 5: /* SRP */
  30.                                 s[3] = "EXP";
  31.                                 break;
  32.                             }
  33.                             break;
  34.                           case 9:
  35.                             switch (sb[1]) {
  36.                               case 5: /* SRP */
  37.                                 s[3] = "PARAMS";
  38.                                 break;
  39.                             }
  40.                             break;
  41.                         }
  42.                     }
  43.                 }
  44.                 break;
  45.               case 1:
  46.                 switch (opt) {
  47.                   case TELOPT_FORWARD_X:
  48.                     s[0] = "OPEN";
  49.                     break;
  50.                   case TELOPT_LFLOW:
  51.                     s[0] = "ON";
  52.                     break;
  53.                   case TELOPT_KERMIT:
  54.                     s[0] = "STOP";
  55.                     break;
  56.                   case TELOPT_AUTHENTICATION:
  57.                     s[0] = "SEND";
  58.                     hexbuf[0] = '';
  59.                     for (; i < n-2; i += 2) {
  60.                         sprintf(tn_msg,
  61.                                 "%s %s ",
  62.                                 authtype_names[sb[i]],
  63.                                 authmode_names[sb[i+1]]
  64.                                 );
  65.                         strcat(hexbuf,tn_msg);
  66.                     }
  67.                     s[1] = hexbuf;
  68.                     break;
  69.                   case TELOPT_ENCRYPTION:
  70.                     s[0] = "SUPPORT";
  71.                     while (i < n-2) {
  72.                         s[i] = enctype_names[sb[i]];
  73.                         i++;
  74.                     }
  75.                     break;
  76.                   case TELOPT_START_TLS:
  77.                     s[0] = "FOLLOWS";
  78.                     break;
  79.                   default:
  80.                     s[0] = "SEND";
  81.                 }
  82.                 break;
  83.               case 2:
  84.                 switch (opt) {
  85.                 case TELOPT_FORWARD_X:
  86.                     s[0] = "CLOSE";
  87.                     break;
  88.                   case TELOPT_LFLOW:
  89.                     s[0] = "RESTART-ANY";
  90.                     break;
  91.                   case TELOPT_KERMIT:
  92.                     s[0] = "REQ-START";
  93.                     break;
  94.                   case TELOPT_NEWENVIRON:
  95.                     s[0] = "INFO";
  96.                     break;
  97.                   case TELOPT_AUTHENTICATION:
  98.                     s[0] = "REPLY";
  99.                     i=4;
  100.                     s[1] = authtype_names[sb[1]];
  101.                     s[2] = authmode_names[sb[2]];
  102.                     switch (sb[3]) {
  103.                       case 0:
  104.                         switch (sb[1]) {
  105.                           case AUTHTYPE_NTLM:
  106.                             s[3] = "NTLM_AUTH";
  107.                             break;
  108.                           default:
  109.                             s[3] = "AUTH";
  110.                         }
  111.                         break;
  112.                       case 1:
  113.                         switch (sb[1]) {
  114.                           case AUTHTYPE_NTLM:
  115.                             s[3] = "NTLM_CHALLENGE";
  116.                             break;
  117.                           default:
  118.                             s[3] = "REJECT";
  119.                         }
  120.                         break;
  121.                       case 2:
  122.                         switch (sb[1]) {
  123.                           case AUTHTYPE_NTLM:
  124.                             s[3] = "NTLM_RESPONSE";
  125.                             break;
  126.                           default:
  127.                             s[3] = "ACCEPT";
  128.                         }
  129.                         break;
  130.                       case 3:
  131.                         switch (sb[1]) {
  132.                           case AUTHTYPE_NTLM:
  133.                             s[3] = "NTLM_ACCEPT";
  134.                             break;
  135.                           case AUTHTYPE_KERBEROS_V4:
  136.                           case AUTHTYPE_SRP:
  137.                             s[3] = "CHALLENGE";
  138.                             break;
  139.                           case AUTHTYPE_KERBEROS_V5:
  140.                             s[3] = "RESPONSE";
  141.                             break;
  142.                         }
  143.                         break;
  144.                       case 4:
  145.                         switch (sb[1]) {
  146.                           case AUTHTYPE_NTLM:
  147.                             s[3] = "NTLM_REJECT";
  148.                             break;
  149.                           case AUTHTYPE_KERBEROS_V4:
  150.                           case AUTHTYPE_SRP:
  151.                             s[3] = "RESPONSE";
  152.                             break;
  153.                           case AUTHTYPE_KERBEROS_V5:
  154.                             s[3] = "FORWARD";
  155.                             break;
  156.                         }
  157.                         break;
  158.                       case 5:
  159.                         switch (sb[1]) {
  160.                           case AUTHTYPE_SRP:
  161.                             s[3] = "FORWARD";
  162.                             break;
  163.                           case AUTHTYPE_KERBEROS_V5:
  164.                             s[3] = "FORWARD_ACCEPT";
  165.                             break;
  166.                         }
  167.                         break;
  168.                       case 6:
  169.                         switch (sb[1]) {
  170.                           case AUTHTYPE_SRP:
  171.                             s[3] = "FORWARD_ACCEPT";
  172.                             break;
  173.                           case AUTHTYPE_KERBEROS_V5:
  174.                             s[3] = "FORWARD_REJECT";
  175.                             break;
  176.                         }
  177.                         break;
  178.                       case 7:
  179.                         switch (sb[1]) {
  180.                           case AUTHTYPE_SRP:
  181.                             s[3] = "FORWARD_REJECT";
  182.                             break;
  183.                         }
  184.                         break;
  185.                       case 8:
  186.                         switch (sb[1]) {
  187.                           case AUTHTYPE_SRP:
  188.                             s[3] = "EXP";
  189.                             break;
  190.                         }
  191.                         break;
  192.                       case 9:
  193.                         switch (sb[1]) {
  194.                           case AUTHTYPE_SRP:
  195.                             s[3] = "PARAMS";
  196.                             break;
  197.                         }
  198.                         break;
  199.                     }
  200.                     break;
  201.                   case TELOPT_ENCRYPTION:
  202.                     s[0] = "REPLY";
  203.                     s[1] = enctype_names[sb[1]];
  204.                     i++;
  205.                     switch (sb[2]) {
  206.                       case 1:
  207.                         i++;
  208.                         s[2] = "FB64_IV";
  209.                         break;
  210.                       case 2:
  211.                         i++;
  212.                         s[2] = "FB64_IV_OK";
  213.                         break;
  214.                       case 3:
  215.                         i++;
  216.                         s[2] = "FB64_IV_BAD";
  217.                         break;
  218.                       case 4:
  219.                         i++;
  220.                         s[2] = "FB64_CHALLENGE";
  221.                         break;
  222.                       case 5:
  223.                         i++;
  224.                         s[2] = "FB64_RESPONSE";
  225.                         break;
  226.                     }
  227.                     break;
  228.                 }
  229.                 break;
  230.               case 3:
  231.                 switch (opt) {
  232.                   case TELOPT_FORWARD_X:
  233.                     s[0] = "DATA";
  234.                     break;
  235.                   case TELOPT_LFLOW:
  236.                     s[0] = "RESTART-XON";
  237.                     break;
  238.                   case TELOPT_KERMIT:
  239.                     s[0] = "REQ-STOP";
  240.                     break;
  241.                   case TELOPT_AUTHENTICATION:
  242.                     s[0] = "NAME";
  243.                     break;
  244.                   case TELOPT_ENCRYPTION:
  245.                     s[0] = "START";
  246.                     break;
  247.                 }
  248.                 break;
  249.               case 4:
  250.                 switch (opt) {
  251.                   case TELOPT_KERMIT:
  252.                     s[0] = "SOP";
  253.                     break;
  254.                   case TELOPT_ENCRYPTION:
  255.                     s[0] = "END";
  256.                     break;
  257.                 }
  258.                 break;
  259.               case 5:
  260.                 switch (opt) {
  261.                 case TELOPT_ENCRYPTION:
  262.                     s[0] = "REQUEST-START";
  263.                     break;
  264.                 }
  265.                 break;
  266.               case 6:
  267.                 switch (opt) {
  268.                   case TELOPT_ENCRYPTION:
  269.                     s[0] = "REQUEST-END";
  270.                     break;
  271.                 }
  272.                 break;
  273.               case 7:
  274.                 switch (opt) {
  275.                   case TELOPT_ENCRYPTION:
  276.                     s[0] = "ENC-KEYID";
  277.                     break;
  278.                 }
  279.                 break;
  280.               case 8:
  281.                 switch (opt) {
  282.                   case TELOPT_KERMIT:
  283.                     s[0] = "RESP-START";
  284.                     break;
  285.                   case TELOPT_ENCRYPTION:
  286.                     s[0] = "DEC-KEYID";
  287.                     break;
  288.                 }
  289.                 break;
  290.               case 9:
  291.                 switch (opt) {
  292.                   case TELOPT_KERMIT:
  293.                     s[0] = "RESP-STOP";
  294.                     break;
  295.                 }
  296.                 break;
  297.             }
  298.         }
  299. #ifdef M_XENIX
  300.         {
  301.           int len, param, param_len;
  302.           sprintf(tn_msg,
  303.                 "TELNET RCVD SB %s ",
  304.                 TELOPT(opt));
  305.           len = strlen(tn_msg);
  306.           for (param = 0; param <= 15; param++) {
  307.             param_len = strlen(s[param]);
  308.             if (param_len > 0) {
  309.               strcpy(&tn_msg[len], s[param]);
  310.               len += param_len;
  311.               tn_msg[len++] = ' ';
  312.             }
  313.           }
  314.           tn_msg[len] = '';
  315.         }
  316. #else
  317.         sprintf(tn_msg,
  318.                 "TELNET RCVD SB 
  319. %s %s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  320.                 TELOPT(opt),s[0],
  321.                  s[ 1], s[ 1][0]?" ":"",
  322.                  s[ 2], s[ 2][0]?" ":"",
  323.                  s[ 3], s[ 3][0]?" ":"",
  324.                  s[ 4], s[ 4][0]?" ":"",
  325.                  s[ 5], s[ 5][0]?" ":"",
  326.                  s[ 6], s[ 6][0]?" ":"",
  327.                  s[ 7], s[ 7][0]?" ":"",
  328.                  s[ 8], s[ 8][0]?" ":"",
  329.                  s[ 9], s[ 9][0]?" ":"",
  330.                  s[10], s[10][0]?" ":"",
  331.                  s[11], s[11][0]?" ":"",
  332.                  s[12], s[12][0]?" ":"",
  333.                  s[13], s[13][0]?" ":"",
  334.                  s[14], s[14][0]?" ":"",
  335.                  s[15], s[15][0]?" ":"");
  336. #endif /* M_XENIX */
  337. #ifdef HEXDISP
  338.         {
  339.             int was_hex = 1;
  340.             for (; i < n-2; i++) {
  341.                 if (sb[i] < 32 || sb[i] >= 127) {
  342.                     sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",sb[i]);
  343.                     was_hex = 1;
  344.                 } else {
  345.                     sprintf(hexbuf,"%s%c",was_hex?""":"",sb[i]);
  346.                     was_hex = 0;
  347.                 }
  348.                 strcat(tn_msg,hexbuf);
  349.             }
  350.             if (!was_hex)
  351.               strcat(tn_msg,"" ");
  352.         }
  353. #else /* HEXDISP */
  354.         memcpy(hexbuf,&sb[i],n-i-2);
  355.         hexbuf[n-i-2] = ' ';
  356.         hexbuf[n-i-1] = '';
  357.         strcat(tn_msg,hexbuf);
  358. #endif /* HEXDISP */
  359.         if (flag == 2)
  360.           strcat(tn_msg,"SE");
  361.         else if (flag == 3)
  362.           strcat(tn_msg," IAC DONT");
  363.         else
  364.           strcat(tn_msg," IAC SE");
  365.         debug(F100,tn_msg,"",0);
  366.         if (tn_deb || debses)
  367.           tn_debug(tn_msg);
  368.     }
  369.     *len = n;           /* return length */
  370.     return(1);          /* success */
  371. }
  372. static char rows_buf[16] = { 0, 0 }; /* LINES Environment variable */
  373. static char cols_buf[16] = { 0, 0 }; /* COLUMNS Enviornment variable */
  374. static char term_buf[64] = { 0, 0 }; /* TERM Environment variable */
  375. #ifdef CK_CURSES
  376. #ifndef VMS
  377. #ifndef COHERENT
  378. _PROTOTYP(int tgetent,(char *, char *));
  379. #endif /* COHERENT */
  380. #else
  381. #ifdef __DECC
  382. _PROTOTYP(int tgetent,(char *, char *));
  383. #endif /* __DECC */
  384. #endif /* VMS */
  385. extern char * trmbuf;                   /* Real curses */
  386. #endif /* CK_CURSES */
  387. #ifdef CK_ENCRYPTION
  388. static int
  389. tn_no_encrypt()
  390. {
  391.     /* Prevent Encryption from being negotiated */
  392.     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  393.     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  394.     /* Cancel any negotiation that might have started */
  395.     ck_tn_enc_stop();
  396.     if (TELOPT_ME(TELOPT_ENCRYPTION) ||
  397.          TELOPT_UNANSWERED_WILL(TELOPT_ENCRYPTION)) {
  398.         TELOPT_ME(TELOPT_ENCRYPTION) = 0;
  399.         if (tn_sopt(WONT,TELOPT_ENCRYPTION) < 0)
  400.             return(-1);
  401.         TELOPT_UNANSWERED_WONT(TELOPT_ENCRYPTION) = 1;
  402.     }
  403.     if (TELOPT_U(TELOPT_ENCRYPTION) ||
  404.          TELOPT_UNANSWERED_DO(TELOPT_ENCRYPTION)) {
  405.         TELOPT_U(TELOPT_ENCRYPTION) = 0;
  406.         if (tn_sopt(DONT,TELOPT_ENCRYPTION) < 0)
  407.             return(-1);
  408.         TELOPT_UNANSWERED_DONT(TELOPT_ENCRYPTION) = 1;
  409.     }
  410.     return(0);
  411. }
  412. #endif /* CK_ENCRYPTION */
  413. /* The following note came from the old SGA negotiation code.  This should */
  414. /* no longer be necessary with the New Telnet negotiation state machine.   */
  415. /*
  416.   Note: The following is proper behavior, and required for talking to the
  417.   Apertus interface to the NOTIS library system, e.g. at Iowa State U:
  418.   scholar.iastate.edu.  Without this reply, the server hangs forever.  This
  419.   code should not be loop-inducing, since C-Kermit never sends WILL SGA as
  420.   an initial bid, so if DO SGA comes, it is never an ACK.
  421. */
  422. /*
  423.   Return values:
  424.   -1 = Telnet Opton negotiation error
  425.   -2 = Connection closed by peer
  426.   -3 = Connection closed by us
  427.   0  = Success
  428.   1  = Echoing on
  429.   2  = Echoing off
  430.   3  = Quoted IAC
  431.   4  = IKS Event
  432.   5  = (unassigned)
  433.   6  = Logout
  434. */
  435. int
  436. #ifdef CK_ANSIC                         /* TELNET DO OPTION */
  437. tn_doop(CHAR z, int echo, int (*fn)(int))
  438. #else
  439. tn_doop(z, echo, fn) CHAR z; int echo; int (*fn)();
  440. #endif /* CK_ANSIC */
  441. /* tn_doop */ {
  442.     int c, x, y, n, m, flag;
  443. #ifdef IKS_OPTION
  444.     extern int server;
  445.     extern int local;
  446. #ifdef NOICP
  447.     extern int autodl;
  448.     int inautodl = 0, cmdadl = 1;
  449. #else
  450. #ifdef CK_AUTODL
  451.     extern int autodl, inautodl, cmdadl;
  452. #endif /* CK_AUTODL */
  453. #endif /* NOICP */
  454. #endif /* IKS_OPTION */
  455.     if (z != (CHAR) IAC) {
  456.         debug(F101,"tn_doop bad call","",z);
  457.         return(-1);
  458.     }
  459.     if (ttnet != NET_TCPB)              /* Check network type */
  460.       return(0);
  461.     if (ttnproto != NP_TELNET &&
  462.          ttnproto != NP_NONE)           /* Check protocol */
  463.       return(0);
  464. /* Have IAC, read command character. */
  465.     while ((c = (*fn)(0)) == -1);       /* Read command character */
  466.     if (c < 0)
  467.       return(c);
  468.     c &= 0xFF;                          /* Strip high bits */
  469.     if (!TELCMD_OK(c)) {
  470.         sprintf(tn_msg,"TELNET RCVD UNKNOWN (%d)",c);
  471.         debug(F101,tn_msg,"",c);
  472.         if (tn_deb || debses) tn_debug(tn_msg);
  473.         return(0);
  474.     }
  475.     if (ttnproto == NP_NONE) {
  476.         debug(F100,"tn_doop discovered a Telnet command",
  477.               "ttnproto = NP_TELNET",0);
  478.         ttnproto = NP_TELNET;
  479.     }
  480.     if (seslog && sessft == XYFT_D) {   /* Copy to session log, if any. */
  481.         logchar((char)z);
  482.         logchar((char)c);
  483.     }
  484.     if (c == (CHAR) IAC)                /* Quoted IAC */
  485.       return(3);
  486.     if (c < SB) {                       /* Other command with no arguments. */
  487.         if (deblog || tn_deb || debses) {
  488.             sprintf(tn_msg,"TELNET RCVD %s",TELCMD(c));
  489.             debug(F101,tn_msg,"",c);
  490.             if (tn_deb || debses) tn_debug(tn_msg);
  491.         }
  492.         switch (c) {                    /* What we would like to do here    */
  493.           case TN_GA:                   /* Is substitute ASCII characters   */
  494.             break;                      /* for the Telnet Command so that   */
  495.           case TN_EL:                   /* the command may be processed by  */
  496.             break;                      /* either the internal emulator or  */
  497.           case TN_EC:                   /* by the superior process or shell */
  498.             break;
  499.           case TN_AYT:
  500.             ttol((CHAR *)"[Yes]1512",7);
  501.             break;
  502.           case TN_AO:
  503. #ifdef BETATEST
  504.             bleep(BP_NOTE);
  505. #endif /* BETATEST */
  506.             break;
  507.           case TN_IP:
  508.             break;
  509.           case BREAK:
  510.             break;
  511.           case TN_DM:
  512.             break;
  513.           case TN_NOP:
  514.             break;
  515.           case SE:
  516.             break;
  517.           case TN_EOR:
  518.             break;
  519.           case TN_ABORT:
  520.             break;
  521.           case TN_SUSP:
  522.             break;
  523.           case TN_EOF:
  524.             break;
  525.           case TN_SAK:
  526.             break;
  527.         }
  528.         return(0);
  529.     }
  530. /* SB, WILL, WONT, DO, or DONT need more bytes... */
  531.     if ((x = (*fn)(0)) < 0)             /* Get the option. */
  532.       return(x);
  533.     x &= 0xff;                          /* Trim to 8 bits. */
  534.     if (seslog && sessft == XYFT_D) {   /* Session log */
  535.         logchar((char) x);
  536.     }
  537.     if ((deblog || tn_deb || debses) && c != SB) {
  538.         sprintf(tn_msg,"TELNET RCVD %s %s",TELCMD(c),TELOPT(x));
  539.         debug(F101,tn_msg,"",x);
  540.         if (tn_deb || debses) tn_debug(tn_msg);
  541.     }
  542.     /* Now handle the command */
  543.     switch (c) {
  544.       case WILL:
  545. #ifdef CK_SSL
  546.         if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  547.             return(0);
  548. #endif /* CK_SSL */
  549.         if (!TELOPT_OK(x) || TELOPT_U_MODE(x) == TN_NG_RF) {
  550.             if (tn_sopt(DONT,x) < 0)
  551.               return(-1);
  552.             if (TELOPT_UNANSWERED_DO(x))
  553.                 TELOPT_UNANSWERED_DO(x) = 0;
  554.         } else if (!TELOPT_U(x)) {
  555.             if (!TELOPT_UNANSWERED_DO(x)) {
  556.                 if (tn_sopt(DO,x) < 0)
  557.                   return -1;
  558.             }
  559.             if (TELOPT_UNANSWERED_DO(x))
  560.                 TELOPT_UNANSWERED_DO(x) = 0;
  561.             TELOPT_U(x) = 1;
  562.             switch (x) {
  563. #ifdef CK_SSL
  564.               case TELOPT_START_TLS:
  565.                 /*
  566.                    If my proposal is accepted, at this point the Telnet
  567.                    protocol is turned off and a TLS negotiation takes
  568.                    place.
  569.                    Start by sending SB START_TLS FOLLOWS  to signal
  570.                    we are ready.  Wait for the peer to send the same
  571.                    and then start the TLS negotiation.
  572.                    If the TLS negotiation succeeds we call tn_ini()
  573.                    again to reset the telnet state machine and restart
  574.                    the negotiation process over the now secure link.
  575.                    If the TLS negotiation fails, we call ttclos()
  576.                    to terminate the connection.
  577.                    Only the server should receive a WILL START_TLS
  578.                  */
  579.                 tn_ssbopt(TELOPT_START_TLS,1,NULL,0);
  580.                 TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 1;
  581.                 break;
  582. #endif /* CK_SSL */
  583. #ifdef CK_AUTHENTICATION
  584.               case TELOPT_AUTHENTICATION: {
  585.                   /* We now have to perform a SB SEND to identify the  */
  586.                   /* supported authentication types to the other side. */
  587.                   extern int authentication_version;
  588.                   authentication_version = AUTHTYPE_AUTO;
  589.                   ck_tn_auth_request();
  590.                   break;
  591.               }
  592. #endif /* CK_AUTHENTICATION */
  593. #ifdef CK_ENCRYPTION
  594.               case TELOPT_ENCRYPTION:
  595.                 if (!(TELOPT_ME(TELOPT_AUTHENTICATION) ||
  596.                       TELOPT_U(TELOPT_AUTHENTICATION))
  597.                     ) {
  598.                     if (tn_sopt(DONT,x) < 0)
  599.                       return(-1);
  600.                     TELOPT_U(x) = 0;
  601.                 } else {
  602.                     if (ck_tn_auth_in_progress()) {
  603.                         TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send = 1;
  604.                     } else {
  605.                         /* Perform subnegotiation */
  606.                         ck_encrypt_send_support();
  607.                     }
  608.                     if (!(TELOPT_ME(x) || TELOPT_UNANSWERED_WILL(x))
  609.                         && TELOPT_ME_MODE(x) != TN_NG_RF) {
  610.                         if (tn_sopt(WILL, x) < 0)
  611.                           return(-1);
  612.                         TELOPT_UNANSWERED_WILL(x) = 1;
  613.                     }
  614.                 }
  615.                 break;
  616. #endif /* CK_ENCRYPTION */
  617. #ifdef IKS_OPTION
  618.               case TELOPT_KERMIT:
  619.                 if (!TELOPT_ME(x)) {
  620.                     /* Tell the other side what Start of Packet Character */
  621.                     tn_siks(KERMIT_SOP); /* SOP */
  622.                     if (!TELOPT_UNANSWERED_WILL(x) &&
  623.                         TELOPT_ME_MODE(x) != TN_NG_RF) {
  624.                         if (tn_sopt(WILL, x) < 0)
  625.                           return(-1);
  626.                         TELOPT_UNANSWERED_WILL(x) = 1;
  627.                     }
  628.                 }
  629.                 break;
  630. #endif /* IKS_OPTION */
  631.               case TELOPT_BINARY:
  632.                 if (!TELOPT_ME(x)) {
  633.                     if (!TELOPT_UNANSWERED_WILL(x) &&
  634.                         TELOPT_ME_MODE(x) >= TN_NG_RQ) {
  635.                         if (tn_sopt(WILL, x) < 0)
  636.                           return(-1);
  637.                         TELOPT_UNANSWERED_WILL(x) = 1;
  638.                     }
  639.                 }
  640.                 break;
  641.               case TELOPT_ECHO:
  642.                 if (echo) {
  643.                     if (TELOPT_UNANSWERED_DO(x))
  644.                       TELOPT_UNANSWERED_DO(x) = 0;
  645.                     return(2);
  646.                 }
  647.                 break;
  648.               case TELOPT_TTYPE:
  649.                 /* SB TTYPE SEND */
  650.                 tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
  651.                 TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
  652.                 break;
  653. #ifdef CK_ENVIRONMENT
  654.               case TELOPT_NEWENVIRON:   /* SB NEW-ENVIRON SEND */
  655. #ifdef CK_AUTHENTICATION
  656.                 if (ck_tn_auth_valid() != AUTH_VALID)
  657. #endif /* CK_AUTHENTICATION */
  658. {
  659.                   char request[6];      /* request it */
  660.                   sprintf(request,"%cUSER",TEL_ENV_VAR);
  661.                   tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_SEND,request,5);
  662.                   TELOPT_UNANSWERED_SB(TELOPT_NEWENVIRON)=1;
  663.                 }
  664.                 break;
  665. #endif /* CK_ENVIRONMENT */
  666. #ifdef CK_FORWARD_X
  667.                case TELOPT_FORWARD_X:
  668.                   if ( !tn_outst(0) || tn_init ) {
  669.                       if (tn_sndfwdx() < 0) {
  670.                           if (tn_sopt(DONT,x) < 0)
  671.                               return(-1);
  672.                           TELOPT_UNANSWERED_DONT(x) = 1;
  673.                       }
  674.                   } else {
  675.                       TELOPT_SB(TELOPT_FORWARD_X).forward_x.need_to_send = 1;
  676.                   }
  677.                   break;
  678. #endif /* CK_FORWARD_X */
  679.             } /* switch */
  680.         } else {
  681.             if (TELOPT_UNANSWERED_DO(x))
  682.                 TELOPT_UNANSWERED_DO(x) = 0;
  683.         }
  684.         break;
  685.       case WONT:
  686. #ifdef CK_SSL
  687.         if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  688.             return(0);
  689. #endif /* CK_SSL */
  690.         if (!TELOPT_OK(x) || TELOPT_U(x) || TELOPT_UNANSWERED_DO(x)) {
  691.             /* David Borman says we should not respond DONT when */
  692.             /* the WONT is a response to a DO that we sent.   */
  693.             if (!(TELOPT_UNANSWERED_DO(x) || TELOPT_UNANSWERED_DONT(x)))
  694.               if (tn_sopt(DONT,x) < 0)
  695.                 return(-1);
  696.             if (TELOPT_UNANSWERED_DONT(x))
  697.                 TELOPT_UNANSWERED_DONT(x) = 0;
  698.             if (TELOPT_UNANSWERED_DO(x))
  699.                 TELOPT_UNANSWERED_DO(x) = 0;
  700.             if (TELOPT_U(x)) {
  701.                 TELOPT_U(x) = 0;
  702.             }
  703.             switch(x) {
  704. #ifdef CK_SSL
  705.             case TELOPT_START_TLS:
  706.                 if (sstelnet && TELOPT_U_MODE(x) == TN_NG_MU) {
  707.                     printf("Telnet Start-TLS refused.n");
  708.                     ttclos(0);
  709.                     whyclosed = WC_TELOPT;
  710.                     return(-3);
  711.                 }
  712.                 break;
  713. #endif /* CK_SSL */
  714. #ifdef CK_AUTHENTICATION
  715.               case TELOPT_AUTHENTICATION:
  716.                 if (sstelnet && TELOPT_U_MODE(x) == TN_NG_MU) {
  717.                     printf("Telnet authentication refused.n");
  718.                     ttclos(0);
  719.                     whyclosed = WC_TELOPT;
  720.                     return(-3);
  721.                 } else if (TELOPT_U_MODE(x) == TN_NG_RQ) {
  722.                     TELOPT_U_MODE(x) = TN_NG_AC;
  723.                 }
  724.                 if (ck_tn_auth_in_progress())
  725.                   printf("Telnet authentication refused.n");
  726. #ifdef CK_ENCRYPTION
  727.                 if (sstelnet) {
  728.                     if (tn_no_encrypt()<0)
  729.                         return(-1);
  730.                 }
  731. #endif /* CK_ENCRYPTION */
  732.                 break;
  733. #endif /* CK_AUTHENTICATION */
  734. #ifdef CK_ENCRYPTION
  735.               case TELOPT_ENCRYPTION:
  736.                 ck_tn_enc_stop();
  737.                 break;
  738. #endif /* CK_ENCRYPTION */
  739. #ifdef IKS_OPTION
  740.               case TELOPT_KERMIT:
  741.                 TELOPT_SB(x).kermit.u_start = 0;
  742.                 TELOPT_SB(x).kermit.me_req_start = 0;
  743.                 TELOPT_SB(x).kermit.me_req_stop = 0;
  744.                 break;
  745. #endif /* IKS_OPTION */
  746.               case TELOPT_NAWS: {
  747.                   /* The client does not support NAWS. */
  748.                   /* Assume a height of 24 and a width of 80 */
  749.                   if (sstelnet
  750. #ifdef IKSD
  751.                    || inserver
  752. #endif /* IKSD */
  753.                    ) {
  754.                       int w = 80, h = 24;
  755.                       if (tcp_incoming) {
  756. #ifdef OS2
  757.                           tt_cols[VTERM] = w;
  758.                           tt_rows[VTERM] = h;
  759.                           VscrnSetWidth(VTERM, w);
  760.                           VscrnSetHeight(VTERM, h+(tt_status?1:0));
  761. #else /* OS2 */
  762.                           tt_cols = w;
  763.                           tt_rows = h;
  764. #endif /* OS2 */
  765.                       } else {
  766. #ifdef OS2
  767.                           tt_cols[VCMD] = w;
  768.                           tt_rows[VCMD] = h;
  769.                           VscrnSetWidth(VCMD, w);
  770.                           VscrnSetHeight(VCMD, h);
  771. #endif /* OS2 */
  772.                           cmd_cols = w;
  773.                           cmd_rows = h;
  774.                       }
  775.                       /* Add LINES and COLUMNS to the environment */
  776.                       sprintf((char *)rows_buf,"LINES=%d",h);
  777.                       sprintf((char *)cols_buf,"COLUMNS=%d",w);
  778. #ifdef OS2ORUNIX
  779. #ifndef NOPUTENV
  780.                       putenv(rows_buf);
  781.                       putenv(cols_buf);
  782. #endif /* NOPUTENV */
  783. #endif /* OS2ORUNIX */
  784.                   }
  785.                   break;
  786.               }
  787.               case TELOPT_ECHO:
  788.                 if (!echo) {
  789.                     if (TELOPT_UNANSWERED_DO(x))
  790.                       TELOPT_UNANSWERED_DO(x) = 0;
  791.                     return(1);
  792.                 }
  793.                 break;
  794.             }
  795.         } else {
  796.             if (TELOPT_UNANSWERED_DONT(x))
  797.                 TELOPT_UNANSWERED_DONT(x) = 0;
  798.             if (TELOPT_UNANSWERED_DO(x))
  799.                 TELOPT_UNANSWERED_DO(x) = 0;
  800.         }
  801.         if (TELOPT_U_MODE(x) == TN_NG_MU) {
  802.             sprintf(tn_msg,
  803.             "Peer refuses TELNET DO %s negotiations - terminating connection",
  804.                     TELOPT(x)
  805.                     );
  806.             debug(F100,tn_msg,"",0);
  807.             if (tn_deb || debses) tn_debug(tn_msg);
  808.             printf("%sn",tn_msg);
  809.             ttclos(0);
  810.             whyclosed = WC_TELOPT;
  811.             return(-3);
  812.         }
  813. #ifdef COMMENT
  814.         if (x == TELOPT_ECHO && !echo) /* Special handling for echo */
  815.           return(1);                   /* because we allow 'duplex' */
  816. #endif /* COMMENT */
  817.         break;
  818.       case DO:
  819. #ifdef CK_SSL
  820.         if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  821.             return(0);
  822. #endif /* CK_SSL */
  823.         if (!TELOPT_OK(x) || TELOPT_ME_MODE(x) == TN_NG_RF) {
  824.             if (tn_sopt(WONT,x) < 0)
  825.               return(-1);
  826.             if (TELOPT_UNANSWERED_WILL(x))
  827.                 TELOPT_UNANSWERED_WILL(x) = 0;
  828.         } else if (!TELOPT_ME(x)) {
  829.             if (!TELOPT_UNANSWERED_WILL(x)) {
  830.                 if (tn_sopt(WILL,x) < 0)
  831.                   return(-1);
  832.             }
  833.             if (TELOPT_UNANSWERED_WILL(x))
  834.                 TELOPT_UNANSWERED_WILL(x) = 0;
  835.             TELOPT_ME(x) = 1;
  836.             switch (x) {
  837. #ifdef CK_SSL
  838.               case TELOPT_START_TLS:
  839.                 /*
  840.                    If my proposal is accepted at this point the Telnet
  841.                    protocol is turned off and a TLS negotiation takes
  842.                    place.
  843.                    Start by sending SB START_TLS FOLLOWS  to signal
  844.                    we are ready.  Wait for the peer to send the same
  845.                    and then start the TLS negotiation.
  846.                    If the TLS negotiation succeeds we call tn_ini()
  847.                    again to reset the telnet state machine and restart
  848.                    the negotiation process over the now secure link.
  849.                    If the TLS negotiation fails, we call ttclos()
  850.                    to terminate the connection.  Then we set the
  851.                    U_MODE and ME_MODE for TELOPT_START_TLS to REFUSE
  852.                    and then call ttopen() to create a new connection
  853.                    to the same host but this time do not attempt
  854.                    TLS security.
  855.                    Only the client should receive DO START_TLS.
  856.                 */
  857.                 tn_ssbopt(TELOPT_START_TLS,1,NULL,0);
  858.                 TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows = 1;
  859.                 break;
  860. #endif /* CK_SSL */
  861. #ifdef CK_AUTHENTICATION
  862.               case TELOPT_AUTHENTICATION: {
  863.                   /* We don't know what authentication we are using yet */
  864.                   /* but it is not NULL until a failure is detected so */
  865.                   /* use AUTO in the meantime. */
  866.                   extern int authentication_version;
  867.                   authentication_version = AUTHTYPE_AUTO;
  868.                   break;
  869.               }
  870. #endif /* CK_AUTHENTICATION */
  871. #ifdef CK_ENCRYPTION
  872.               case TELOPT_ENCRYPTION:
  873.                 if (!(TELOPT_ME(TELOPT_AUTHENTICATION) ||
  874.                       TELOPT_U(TELOPT_AUTHENTICATION))
  875.                     ) {
  876.                     if (tn_sopt(WONT,x) < 0)
  877.                       return(-1);
  878.                     TELOPT_ME(x) = 0;
  879.                 } else {
  880.                     if (!(TELOPT_U(x) || TELOPT_UNANSWERED_DO(x))
  881.                         && TELOPT_U_MODE(x) != TN_NG_RF) {
  882.                         if (tn_sopt(DO, x) < 0)
  883.                           return(-1);
  884.                         TELOPT_UNANSWERED_DO(x) = 1;
  885.                     }
  886.                 }
  887.                 break;
  888. #endif /* CK_ENCRYPTION */
  889. #ifdef IKS_OPTION
  890.               case TELOPT_KERMIT:
  891. /* If currently processing Kermit server packets, must tell the other side */
  892.                 debug(F111,"tn_doop","what",what);
  893.                 debug(F111,"tn_doop","server",server);
  894. #ifdef CK_AUTODL
  895.                 debug(F111,"tn_doop","autodl",autodl);
  896.                 debug(F111,"tn_doop","inautodl",inautodl);
  897.                 debug(F111,"tn_doop","cmdadl",cmdadl);
  898. #endif /* CK_AUTODL */
  899.                 if (server
  900. #ifdef CK_AUTODL
  901.                     || (local && ((what == W_CONNECT && autodl) ||
  902.                                   (what != W_CONNECT && inautodl)))
  903.                     || (!local && cmdadl)
  904. #endif /* CK_AUTODL */
  905.                     ) {
  906.                     tn_siks(KERMIT_START);      /* START */
  907.                 }
  908.                 if (!TELOPT_U(x)) {
  909.                     /* Tell the other side what Start of Packet Character */
  910.                     tn_siks(KERMIT_SOP);             /* SOP */
  911.                     if (!TELOPT_UNANSWERED_DO(x) &&
  912.                         TELOPT_U_MODE(x) != TN_NG_RF) {
  913.                         if (tn_sopt(DO, x) < 0)
  914.                           return(-1);
  915.                         TELOPT_UNANSWERED_DO(x) = 1;
  916.                     }
  917.                 }
  918.                 break;
  919. #endif /* IKS_OPTION */
  920.               case TELOPT_BINARY:
  921.                 if (!TELOPT_U(x)) {
  922.                     if (!TELOPT_UNANSWERED_DO(x) &&
  923.                         TELOPT_U_MODE(x) >= TN_NG_RQ) {
  924.                         if (tn_sopt(DO, x) < 0)
  925.                           return(-1);
  926.                         TELOPT_UNANSWERED_DO(x) = 1;
  927.                     }
  928.                 }
  929.                 break;
  930.               case TELOPT_NAWS:
  931. #ifndef NOSIGWINCH
  932. #ifdef SIGWINCH
  933. #ifdef UNIX
  934.                 if (sw_armed++ < 1) {   /* Catch window-size changes. */
  935.                     debug(F100,"tn_doop arming SIGWINCH","",0);
  936.                     signal(SIGWINCH,winchh);
  937.                 }
  938. #else
  939.                 debug(F100,"SIGWINCH defined but not used","",0);
  940. #endif /* UNIX */
  941. #else  /* SIGWINCH */
  942.                 debug(F100,"SIGWINCH not defined","",0);
  943. #endif /* SIGWINCH */
  944. #else  /* NOSIGWINCH */
  945.                 debug(F100,"NOSIGWINCH defined","",0);
  946. #endif /* NOSIGWINCH */
  947. #ifdef CK_NAWS
  948.                 if ( !tn_outst(0) || tn_init ) {
  949.                     if (tn_snaws() < 0)
  950.                         return(-1);
  951.                 } else {
  952.                     TELOPT_SB(TELOPT_NAWS).naws.need_to_send = 1;
  953.                 }
  954. #endif /* CK_NAWS */
  955.                 break;
  956.               case TELOPT_LOGOUT:
  957.                 ttclos(0);              /* And then hangup */
  958.                 whyclosed = WC_TELOPT;
  959. #ifdef IKSD
  960.                 if (inserver
  961. #ifndef NOLOCAL
  962.                     && !local
  963. #endif /* NOLOCAL */
  964.                     )
  965.                   doexit(GOOD_EXIT,0);
  966. #endif /* IKSD */
  967.                 if (TELOPT_UNANSWERED_WILL(x))
  968.                   TELOPT_UNANSWERED_WILL(x) = 0;
  969.                 return(6);
  970. #ifdef CK_SNDLOC
  971.                case TELOPT_SNDLOC:
  972.                   if ( !tn_outst(0) || tn_init ) {
  973.                       if (tn_sndloc() < 0)
  974.                           return(-1);
  975.                   } else {
  976.                       TELOPT_SB(TELOPT_SNDLOC).sndloc.need_to_send = 1;
  977.                   }
  978.                   break;
  979. #endif /* CK_SNDLOC */
  980.             } /* switch */
  981.         } else {
  982.           if (TELOPT_UNANSWERED_WILL(x))
  983.             TELOPT_UNANSWERED_WILL(x) = 0;
  984.         }
  985.         break;
  986.       case DONT:
  987. #ifdef CK_SSL
  988.         if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  989.             return(0);
  990. #endif /* CK_SSL */
  991.         if (!TELOPT_OK(x) || TELOPT_ME(x) || TELOPT_UNANSWERED_WILL(x)) {
  992.             /* David Borman says we should not respond DONT when */
  993.             /* the WONT is a response to a WILL that we sent. */
  994.             if (!(TELOPT_UNANSWERED_WILL(x) || TELOPT_UNANSWERED_WONT(x)))
  995.               if (tn_sopt(WONT,x) < 0)
  996.                 return(-1);
  997.             if (TELOPT_UNANSWERED_WILL(x))
  998.                 TELOPT_UNANSWERED_WILL(x) = 0;
  999.             if (TELOPT_UNANSWERED_WONT(x))
  1000.                 TELOPT_UNANSWERED_WONT(x) = 0;
  1001.             if (TELOPT_ME(x))
  1002.               TELOPT_ME(x) = 0;
  1003.             switch (x) {
  1004. #ifdef CK_SSL
  1005.             case TELOPT_START_TLS:
  1006.                 if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
  1007.                     printf("Telnet Start-TLS refused.n");
  1008.                     ttclos(0);
  1009.                     whyclosed = WC_TELOPT;
  1010.                     return(-3);
  1011.                 }
  1012.                 break;
  1013. #endif /* CK_SSL */
  1014. #ifdef CK_AUTHENTICATION
  1015.               case TELOPT_AUTHENTICATION:
  1016.                 if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
  1017.                     printf("Telnet authentication refused.n");
  1018.                     ttclos(0);
  1019.                     whyclosed = WC_TELOPT;
  1020.                     return(-3);
  1021.                 } else if (TELOPT_ME_MODE(x) == TN_NG_RQ) {
  1022.                     TELOPT_ME_MODE(x) = TN_NG_AC;
  1023.                 }
  1024.                 if (ck_tn_auth_in_progress())
  1025.                   printf("Telnet authentication refused.n");
  1026. #ifdef CK_ENCRYPTION
  1027.                 if (!sstelnet) {
  1028.                     if (tn_no_encrypt()<0)
  1029.                         return(-1);
  1030.                 }
  1031. #endif /* CK_ENCRYPTION */
  1032.                 break;
  1033. #endif /* CK_AUTHENTICATION */
  1034.               case TELOPT_ENCRYPTION:
  1035. #ifdef CK_ENCRYPTION
  1036.                 ck_tn_enc_stop();
  1037. #endif /* CK_ENCRYPTION */
  1038.                 break;
  1039.               case TELOPT_KERMIT:
  1040. #ifdef IKS_OPTION
  1041.                 TELOPT_SB(x).kermit.me_start = 0;
  1042. #endif /* IKS_OPTION */
  1043.                 break;
  1044.               default:
  1045.                 break;
  1046.             } /* switch */
  1047.         } else {
  1048.           if (TELOPT_UNANSWERED_WILL(x))
  1049.               TELOPT_UNANSWERED_WILL(x) = 0;
  1050.           if (TELOPT_UNANSWERED_WONT(x))
  1051.               TELOPT_UNANSWERED_WONT(x) = 0;
  1052.         }
  1053.         if (TELOPT_ME_MODE(x) == TN_NG_MU) {
  1054.             sprintf(tn_msg,
  1055.            "Peer refuses TELNET WILL %s negotiations - terminating connection",
  1056.                     TELOPT(x)
  1057.                     );
  1058.             debug(F100,tn_msg,"",0);
  1059.             if (tn_deb || debses) tn_debug(tn_msg);
  1060.             printf("%sn",tn_msg);
  1061.             ttclos(0);
  1062.             whyclosed = WC_TELOPT;
  1063.             return(-3);
  1064.         }
  1065.         break;
  1066.       case SB:
  1067.         if ((y = tn_sb(x,&n,fn)) <= 0)
  1068.           return(y);
  1069. #ifdef CK_SSL
  1070.         /* Do not process subnegotiations other than START_TLS after we */
  1071.         /* have agreed to begin the TLS negotiation sequence.           */
  1072.         if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows &&
  1073.              x != TELOPT_START_TLS)
  1074.             break;
  1075. #endif /* CK_SSL */
  1076.         if (!TELOPT_OK(x)) {
  1077.             hexdump("unknown telnet subnegotiation",sb,n);
  1078.             break;
  1079.         } else if ( !(TELOPT_ME(x) || TELOPT_U(x)) ) {
  1080.             hexdump("telnet option not negotiated",sb,n);
  1081.             if (!tn_sb_bug)
  1082.                 break;
  1083.             if (TELOPT_UNANSWERED_WILL(x)) {
  1084.                 TELOPT_UNANSWERED_WILL(x) = 0;
  1085.                 TELOPT_U(x) = 1;
  1086.                 sprintf(tn_msg,
  1087.          "TELNET DO %s (implied by receipt of SB - protocol error ignored)",
  1088.                          TELOPT(x)
  1089.                          );
  1090.                 debug(F100,tn_msg,"",0);
  1091.                 if (tn_deb || debses) tn_debug(tn_msg);
  1092.             }
  1093.             if (TELOPT_UNANSWERED_DO(x)) {
  1094.                 TELOPT_UNANSWERED_DO(x) = 0;
  1095.                 TELOPT_ME(x) = 1;
  1096.                 sprintf(tn_msg,
  1097.          "TELNET WILL %s (implied by receipt of SB - protocol error ignored)",
  1098.                          TELOPT(x)
  1099.                          );
  1100.                 debug(F100,tn_msg,"",0);
  1101.                 if (tn_deb || debses) tn_debug(tn_msg);
  1102.              }
  1103.         }
  1104.         TELOPT_UNANSWERED_SB(x)=0;
  1105.         switch (x) {
  1106. #ifdef CK_FORWARD_X
  1107.           case TELOPT_FORWARD_X:
  1108.             return(fwdx_tn_sb(sb, n));
  1109. #endif /* CK_FORWARD_X */
  1110. #ifdef CK_SSL
  1111.           case TELOPT_START_TLS: {
  1112.               /*
  1113.                  the other side is saying SB START_TLS FOLLOWS
  1114.                  the incoming channel is now ready for starting the
  1115.                  TLS negotiation.
  1116.                  */
  1117.               int def_tls_u_mode, def_tls_me_mode;
  1118.               int def_enc_u_mode, def_enc_me_mode;
  1119.               int rc = 0;
  1120.               TELOPT_SB(TELOPT_START_TLS).start_tls.u_follows = 1;
  1121.               /* Preserve the default modes and make sure we will */
  1122.               /* refuse START_TLS when we retry. */
  1123.               if (sstelnet) {
  1124.                   def_tls_u_mode = TELOPT_DEF_S_U_MODE(TELOPT_START_TLS);
  1125.                   def_tls_me_mode = TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS);
  1126.                   TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  1127.                   TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS)= TN_NG_RF;
  1128. #ifdef CK_ENCRYPTION
  1129.                   def_enc_u_mode = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
  1130.                   def_enc_me_mode = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
  1131.                   TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1132.                   TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION)= TN_NG_RF;
  1133. #endif /* CK_ENCRYPTION */
  1134.               } else {
  1135.                   def_tls_u_mode = TELOPT_DEF_C_U_MODE(TELOPT_START_TLS);
  1136.                   def_tls_me_mode = TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS);
  1137.                   TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF;
  1138.                   TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS)= TN_NG_RF;
  1139. #ifdef CK_ENCRYPTION
  1140.                   def_enc_u_mode = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
  1141.                   def_enc_me_mode = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
  1142.                   TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1143.                   TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION)= TN_NG_RF;
  1144. #endif /* CK_ENCRYPTION */
  1145.               }
  1146.               /* Negotiate TLS */
  1147.               ttnproto = NP_TLS;
  1148.               tn_init = 0;
  1149.               if (ck_tn_tls_negotiate()<0) {
  1150.                   /* we failed.  disconnect and if we are the client */
  1151.                   /* then reconnect and try without START_TLS.       */
  1152.                   extern char * line;
  1153.                   int x = -1;
  1154.                   extern int mdmtyp;
  1155.                   if (sstelnet) {
  1156.                       printf("TLS failed:  Disconnecting.n");
  1157.                       TELOPT_DEF_S_U_MODE(TELOPT_START_TLS)  = def_tls_u_mode;
  1158.                       TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
  1159. #ifdef CK_ENCRYPTION
  1160.                      TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION)  = def_enc_u_mode;
  1161.                      TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
  1162. #endif /* CK_ENCRYPTION */
  1163.                       ttclos(0);
  1164.                       whyclosed = WC_TELOPT;
  1165.                       ttnproto = NP_TELNET;
  1166.                       rc = -3;
  1167.                   } else {
  1168.                       extern tls_norestore;
  1169.                       printf("TLS failed:  Disconnecting...n");
  1170. #ifdef CK_ENCRYPTION
  1171.                      TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION)  = def_enc_u_mode;
  1172.                      TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
  1173. #endif /* CK_ENCRYPTION */
  1174.                       /* if START_TLS is not REQUIRED, then retry without it */
  1175.                       if ( def_tls_me_mode != TN_NG_MU ) {
  1176.                           tls_norestore = 1;
  1177.                           ttclos(0);
  1178.                           whyclosed = WC_TELOPT;
  1179.                           tls_norestore = 0;
  1180.                           ttnproto = NP_TELNET;
  1181.                           printf("Reconnecting without TLS.n");
  1182.                           sleep(2);
  1183.                           if (ttopen(line,&x,mdmtyp,0)<0)
  1184.                               rc = -3;
  1185.                       } else {
  1186.                           TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) =
  1187.                             def_tls_u_mode;
  1188.                           TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) =
  1189.                             def_tls_me_mode;
  1190.                           ttclos(0);
  1191.                           whyclosed = WC_TELOPT;
  1192.                           ttnproto = NP_TELNET;
  1193.                           rc = -3;
  1194.                       }
  1195.                   }
  1196.               } else {
  1197.                   /* we succeeded.  restart telnet negotiations from */
  1198.                   /* the beginning.  However, if we have received a  */
  1199.                   /* client certificate and we are a server, then do */
  1200.                   /* not offer TELOPT_AUTH */
  1201.                   if ( ck_tn_auth_valid() == AUTH_VALID ) {
  1202.                       TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  1203.                       TELOPT_DEF_S_ME_MODE(TELOPT_AUTHENTICATION)= TN_NG_RF;
  1204.                   }
  1205.                   ttnproto = NP_TELNET;
  1206.                   if (tn_ini() < 0)
  1207.                     if (ttchk() < 0)
  1208.                       rc = -1;
  1209.               }
  1210.               /* Restore the default modes */
  1211.               if (sstelnet) {
  1212.                   TELOPT_DEF_S_U_MODE(TELOPT_START_TLS)  = def_tls_u_mode;
  1213.                   TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
  1214. #ifdef CK_ENCRYPTION
  1215.                   TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION)  = def_enc_u_mode;
  1216.                   TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
  1217. #endif /* CK_ENCRYPTION */
  1218.               } else {
  1219.                   TELOPT_DEF_C_U_MODE(TELOPT_START_TLS)  = def_tls_u_mode;
  1220.                   TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = def_tls_me_mode;
  1221. #ifdef CK_ENCRYPTION
  1222.                   TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION)  = def_enc_u_mode;
  1223.                   TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = def_enc_me_mode;
  1224. #endif /* CK_ENCRYPTION */
  1225.               }
  1226.               return(rc);
  1227.           }
  1228. #endif /* CK_SSL */
  1229. #ifdef CK_AUTHENTICATION
  1230.           case TELOPT_AUTHENTICATION:
  1231.             if (ck_tn_sb_auth(sb,n) < 0) {
  1232.                 if (sstelnet && TELOPT_U_MODE(x) == TN_NG_MU) {
  1233.                     ttclos(0);
  1234.                     whyclosed = WC_TELOPT;
  1235.                     return(-3);
  1236.                 } else if (!sstelnet && TELOPT_ME_MODE(x) == TN_NG_MU) {
  1237.                     ttclos(0);
  1238.                     whyclosed = WC_TELOPT;
  1239.                     return(-3);
  1240.                 } else {
  1241.                     if (TELOPT_ME_MODE(x) == TN_NG_RQ)
  1242.                       TELOPT_ME_MODE(x) = TN_NG_AC;
  1243.                     if (TELOPT_U_MODE(x) == TN_NG_RQ)
  1244.                       TELOPT_U_MODE(x) = TN_NG_AC;
  1245.                 }
  1246.                 if (TELOPT_ME(x)) {
  1247.                     TELOPT_ME(x) = 0;
  1248.                     if (tn_sopt(WONT,x) < 0)
  1249.                       return(-1);
  1250.                 }
  1251.                 if (TELOPT_U(x)) {
  1252.                     TELOPT_U(x) = 0;
  1253.                     if (tn_sopt(DONT,x) < 0)
  1254.                       return(-1);
  1255.                 }
  1256. #ifdef CK_ENCRYPTION
  1257.                 if (tn_no_encrypt()<0)
  1258.                     return(-1);
  1259. #endif /* CK_ENCRYPTION */
  1260.             } else {
  1261. #ifdef CK_ENCRYPTION
  1262.                 if (!ck_tn_auth_in_progress()) { /* we are finished */
  1263.                     if (ck_tn_authenticated() == AUTHTYPE_SSL) {
  1264.                         /* TLS was successful.  Disable ENCRYPTION */
  1265.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1266.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1267.                     }
  1268.                     if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send) {
  1269.                         ck_encrypt_send_support();
  1270.                         TELOPT_SB(TELOPT_ENCRYPTION).encrypt.need_to_send = 0;
  1271.                     }
  1272.                 }
  1273. #endif /* CK_ENCRYPTION */
  1274.             }
  1275.             break;
  1276. #endif /* CK_AUTHENTICATION */
  1277. #ifdef CK_ENCRYPTION
  1278.           case TELOPT_ENCRYPTION:
  1279.             if (ck_tn_sb_encrypt(sb, n) < 0) {
  1280.                 if (TELOPT_U_MODE(x) == TN_NG_MU ||
  1281.                     TELOPT_ME_MODE(x) == TN_NG_MU)
  1282.                   {
  1283.                       ttclos(0);
  1284.                       whyclosed = WC_TELOPT;
  1285.                       return(-3);
  1286.                 } else {
  1287.                     if (TELOPT_ME_MODE(x) == TN_NG_RQ)
  1288.                       TELOPT_ME_MODE(x) = TN_NG_AC;
  1289.                     if (TELOPT_U_MODE(x) == TN_NG_RQ)
  1290.                       TELOPT_U_MODE(x) = TN_NG_AC;
  1291.                 }
  1292.                 if (TELOPT_ME(x)) {
  1293.                     TELOPT_ME(x) = 0;
  1294.                     if (tn_sopt(WONT,x) < 0)
  1295.                       return(-1);
  1296.                 }
  1297.                 if (TELOPT_U(x)) {
  1298.                     TELOPT_U(x) = 0;
  1299.                     if (tn_sopt(DONT,x) < 0)
  1300.                       return(-1);
  1301.                 }
  1302.             }
  1303.             break;
  1304. #endif /* CK_ENCRYPTION */
  1305. #ifdef IKS_OPTION
  1306.           case TELOPT_KERMIT:
  1307.             return(iks_tn_sb((char *)sb, n));
  1308. #endif /* IKS_OPTION */
  1309.           case TELOPT_TTYPE:
  1310.             switch (sb[0]) {
  1311.               case TELQUAL_SEND:        /* SEND terminal type? */
  1312.                 if ( !tn_outst(0) || tn_init ) {
  1313.                     if (tn_sttyp() < 0) /* Yes, so send it. */
  1314.                         return(-1);
  1315.                 } else {
  1316.                     TELOPT_SB(TELOPT_TTYPE).term.need_to_send = 1;
  1317.                 }
  1318.                 break;
  1319.               case TELQUAL_IS: {        /* IS terminal type? */
  1320.                   /* IS terminal type -- remote gave us its current type */
  1321.                   int i = 0;
  1322. #ifndef OS2
  1323.                   CHAR oldterm[64], *p;
  1324. #endif /* OS2 */
  1325.                   /* Isolate the specified terminal type string */
  1326.                   while (sb[i++] != IAC) {
  1327.                       if (i == 40 ||    /* max len of term string - RFC */
  1328.                           sb[i] == IAC) {
  1329.                           sb[i] = '';
  1330.                           break;
  1331.                       }
  1332.                   }
  1333. #ifdef OS2
  1334.                   strupr(&(sb[1]));     /* Upper case it */
  1335.                   for (i = 0; i <= max_tt; i++) { /* find it in our list */
  1336.                       if (!strcmp(&(sb[1]),tt_info[i].x_name)
  1337.                           && i != TT_VTNT) /* can't support VTNT as server */
  1338.                         {
  1339.                           /* Set terminal type to the one chosen */
  1340.                           if (i != tt_type)
  1341.                             settermtype(i,0);
  1342.                           break;
  1343.                       }
  1344.                   }
  1345.                   if (i > max_tt &&
  1346.                       strcmp(&(sb[1]),TELOPT_SB(TELOPT_TTYPE).term.type)) {
  1347.                       /* Couldn't find the specified term type */
  1348.                       sb[40] = '';
  1349.                       strcpy(TELOPT_SB(TELOPT_TTYPE).term.type,&(sb[1]));
  1350.                       /* SB TTYPE SEND */
  1351.                       tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
  1352.                       TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
  1353.                   }
  1354. #else /* OS2 */
  1355.                   p = (CHAR *) getenv("TERM");
  1356.                   if (p)
  1357.                     ckstrncpy((char *)oldterm,(char *)p,63);
  1358.                   else
  1359.                     oldterm[0] = '';
  1360.                   cklower((char *)&(sb[1])); /* Lower case new term */
  1361.                   sprintf(term_buf,"TERM=%s",&(sb[1]));
  1362. #ifdef OS2ORUNIX
  1363. #ifndef NOPUTENV
  1364.                   putenv(term_buf);
  1365. #endif /* NOPUTENV */
  1366. #endif /* OS2ORUNIX */
  1367. #ifdef CK_CURSES
  1368. #ifndef MYCURSES
  1369. #ifndef COHERENT
  1370.                   if (trmbuf) {
  1371.                       if (tgetent(trmbuf,(char *)&sb[1]) < 1) {
  1372.                           /* Unsupported terminal.  If new and old terminal */
  1373.                           /* types do not match, ask for another type. */
  1374.                           if (strcmp((char *)oldterm,(char *)&sb[1])) {
  1375.                               /* SB TTYPE SEND */
  1376.                               tn_ssbopt(TELOPT_TTYPE,TELQUAL_SEND,NULL,0);
  1377.                               TELOPT_UNANSWERED_SB(TELOPT_TTYPE)=1;
  1378.                           }
  1379.                       }
  1380.                   }
  1381. #endif /* COHERENT */
  1382. #endif /* MYCURSES */
  1383. #endif /* CK_CURSES */
  1384. #endif /* OS2 */
  1385.               }
  1386.             }
  1387.             break;
  1388. #ifdef CK_ENVIRONMENT
  1389. #ifdef CK_XDISPLOC
  1390.           case TELOPT_XDISPLOC:         /* Send X-Display Location */
  1391.             if (sb[0] == TELQUAL_SEND) {/* SEND X-Display Loc? */
  1392.                 if ( !tn_outst(0) || tn_init ) {
  1393.                     if (tn_sxdisploc() < 0)     /* Yes, so send it. */
  1394.                         return(-1);
  1395.                 } else {
  1396.                     TELOPT_SB(TELOPT_XDISPLOC).xdisp.need_to_send = 1;
  1397.                 }
  1398.             }
  1399.             /* IS -- X Display Location (not supported) */
  1400.             else if (sb[0] == TELQUAL_IS) {
  1401.                 int i = 0;
  1402.                 /* Isolate the specified X-display string */
  1403.                 while (sb[i++] != IAC) {
  1404.                     if (i >= TSBUFSIZ)
  1405.                       return (-1);
  1406.                     if (sb[i] == IAC) {
  1407.                         sb[i] = '';
  1408.                         break;
  1409.                     }
  1410.                 }
  1411.                 debug(F110,"TELNET SB XDISPLOC IS",&sb[1],0);
  1412.             }
  1413.             break;
  1414. #endif /* CK_XDISPLOC */
  1415. #endif /* CK_ENVIRONMENT */
  1416.           case TELOPT_NAWS:
  1417.               if (sstelnet
  1418. #ifdef IKSD
  1419.                    || inserver
  1420. #endif /* IKSD */
  1421.                    ) {
  1422.                   int w = 0, h = 0;
  1423.                   int i = 0;
  1424.                   /* At this point sb[] should contain width and height */
  1425.                   if (sb[i] == IAC) i++;
  1426.                   w = (sb[i++] << 8);   /* save upper height */
  1427.                   if (sb[i] == IAC) i++;
  1428.                   w += sb[i++];         /* save the width */
  1429.                   if (sb[i] == IAC) i++;
  1430.                   h = (sb[i++] << 8);   /* save upper height */
  1431.                   if (sb[i] == IAC) i++;
  1432.                   h += sb[i++];
  1433.                   debug(F111,"tn_doop NAWS SB","width",w);
  1434.                   debug(F111,"tn_doop NAWS SB","height",h);
  1435.                   if (w == 0)
  1436.                     w = 80;
  1437.                   if (h == 0)
  1438.                     h = 24;
  1439.                   if (tcp_incoming) {
  1440. #ifdef OS2
  1441.                       tt_cols[VTERM] = w;
  1442.                       tt_rows[VTERM] = h;
  1443.                       VscrnSetWidth(VTERM, w);
  1444.                       VscrnSetHeight(VTERM, h+(tt_status?1:0));
  1445. #ifdef IKSD
  1446.                       if (inserver) {
  1447.                           cmd_cols = tt_cols[VCMD] = w;
  1448.                           cmd_rows = tt_rows[VCMD] = h;
  1449.                           VscrnSetWidth(VCMD, w);
  1450.                           VscrnSetHeight(VCMD, h);
  1451.                       }
  1452. #endif /* IKSD */
  1453. #else /* OS2 */
  1454.                       tt_cols = w;
  1455.                       tt_rows = h;
  1456. #endif /* OS2 */
  1457.                   } else {
  1458. #ifdef OS2
  1459.                       tt_cols[VCMD] = w;
  1460.                       tt_rows[VCMD] = h;
  1461.                       VscrnSetWidth(VCMD, w);
  1462.                       VscrnSetHeight(VCMD, h);
  1463. #endif /* OS2 */
  1464.                       cmd_cols = w;
  1465.                       cmd_rows = h;
  1466.                   }
  1467.                   /* Add LINES and COLUMNS to the environment */
  1468.                   sprintf((char *)rows_buf,"LINES=%d",h);
  1469.                   sprintf((char *)cols_buf,"COLUMNS=%d",w);
  1470. #ifdef OS2ORUNIX
  1471. #ifndef NOPUTENV
  1472.                   putenv(rows_buf);
  1473.                   putenv(cols_buf);
  1474. #endif /* NOPUTENV */
  1475. #endif /* OS2ORUNIX */
  1476.               }
  1477.               break;
  1478. #ifdef CK_ENVIRONMENT
  1479.           case TELOPT_NEWENVIRON:
  1480.             switch (sb[0]) {
  1481.               case TELQUAL_IS:                  /* IS */
  1482.               case TELQUAL_INFO:                /* INFO */
  1483.                 if (sb[0] == TELQUAL_IS)
  1484.                   debug(F101,"tn_doop NEW-ENV SB IS","",n-3);
  1485.                 else
  1486.                   debug(F101,"tn_doop NEW-ENV SB INFO","",n-3);
  1487.                 if (sstelnet || inserver) { /* Yes, receive it. */
  1488.                     if (tn_rnenv((CHAR *)&sb[1],n-3) < 0)
  1489.                       return(-1);
  1490.                 }
  1491.                 break;
  1492.               case TELQUAL_SEND:        /* SEND */
  1493.                 if ( sstelnet || inserver )         /* ignore if server */
  1494.                     break;
  1495.                 /* We need to take the sb[] and build a structure */
  1496.                 /* containing all of the variables and types that */
  1497.                 /* we are supposed to keep track of and send to   */
  1498.                 /* the host, then call tn_snenv().                  */
  1499.                 /* Or we can punt ...                               */
  1500.                 if ( !tn_outst(0) || tn_init ) {
  1501.                   if (tn_snenv((CHAR *)&sb[1],n-3) < 0) /* Yes, send it. */
  1502.                      return(-1);
  1503.                 } else {
  1504. #ifndef VMS
  1505.                   CHAR * xxx;
  1506.                   xxx = (CHAR *) malloc(n-1);
  1507. #else
  1508.                   unsigned char * xxx;
  1509.                   xxx = (unsigned char *) malloc(n-1);
  1510. #endif /* VMS */
  1511.                   /* Postpone sending until end of tn_ini() */
  1512.                   TELOPT_SB(TELOPT_NEWENVIRON).env.str = xxx;
  1513.                   if (TELOPT_SB(TELOPT_NEWENVIRON).env.str) {
  1514.                   ckmemcpy((char *)TELOPT_SB(TELOPT_NEWENVIRON).env.str,
  1515.                             (char *)&sb[1],n-3);
  1516.                   TELOPT_SB(TELOPT_NEWENVIRON).env.str[n-3] = IAC;
  1517.                   TELOPT_SB(TELOPT_NEWENVIRON).env.str[n-2] = '';
  1518.                   TELOPT_SB(TELOPT_NEWENVIRON).env.len = n-3;
  1519.                   TELOPT_SB(TELOPT_NEWENVIRON).env.need_to_send = 1;
  1520.                   }
  1521.                 }
  1522.                 break;
  1523.               }
  1524.               break;
  1525. #endif /* CK_ENVIRONMENT */
  1526. #ifdef CK_SNDLOC
  1527.           case TELOPT_SNDLOC: {
  1528.               if ( deblog ) {
  1529.                   sb[n-2] = '';
  1530.                   debug(F110,"TELNET Send-Location",sb,0);
  1531.               }
  1532.               break;
  1533.           }
  1534. #endif /* CK_SNDLOC */
  1535.           } /* switch */
  1536.         break;
  1537.     }
  1538.     return(0);
  1539. }
  1540. #ifdef CK_ENVIRONMENT
  1541. /* Telnet receive new environment */
  1542. /* Returns -1 on error, 0 if nothing happens, 1 on success */
  1543. /* In order for this code to work, sb[len] == IAC          */
  1544. /* We currently only support the USER environment variable */
  1545. int
  1546. #ifdef CK_ANSIC
  1547. tn_rnenv(CHAR * sb, int len)
  1548. #else
  1549. tn_rnenv(sb, len) CHAR * sb; int len;
  1550. #endif /* CK_ANSIC */
  1551. /* tn_rnenv */ {                        /* Receive new environment */
  1552.     char varname[17];
  1553.     char value[65];
  1554.     char * reply = 0, * s = 0;
  1555.     int i,j,k,n;                                /* Worker. */
  1556.     int type = 0; /* 0 for NONE, 1 for VAR, 2 for USERVAR, */
  1557.                   /* 3 for VALUE in progress */
  1558.     if (ttnet != NET_TCPB) return(0);
  1559.     if (ttnproto != NP_TELNET) return(0);
  1560.     if (sb == NULL) return(-1);
  1561.     if (len == 0) return(1);
  1562.     /*
  1563.     Pairs of <type> [VAR=0, VALUE=1, ESC=2, USERVAR=3] <value> "unterminated"
  1564.     follow here until done...
  1565.     */
  1566.     for (i = 0, j = 0, k = 0, type = 0, varname[0]= ''; i <= len; i++) {
  1567.         switch (sb[i]) {
  1568.         case TEL_ENV_VAR:               /* VAR */
  1569.         case TEL_ENV_USERVAR:           /* USERVAR */
  1570.         case IAC:                       /* End of the list */
  1571.             switch (type) {
  1572.       case 0: /* Nothing in progress */
  1573.                 /* If we get IAC only, then that means there were */
  1574.                 /* no environment variables to send.  we are done */
  1575.                 if (j == 0 && sb[i] == IAC)
  1576.                     return(1);
  1577.       case 1: /* VAR in progress */
  1578.       case 2: /* USERVAR in progress */
  1579.       case 3: /* VALUE in progress */
  1580.                 value[k] = '';
  1581.                 varname[j] = '';
  1582.                 debug(F111,"tn_rnenv varname",varname,type);
  1583.                 debug(F111,"tn_rnenv value",value,type);
  1584.                 if (!strcmp(varname,"USER")) {
  1585. #ifdef CK_AUTHENTICATION
  1586.                     if (ck_tn_auth_valid() != AUTH_VALID) {
  1587.                         extern char szUserNameRequested[];
  1588.                         debug(F100,"tn_rnenv != AUTH_VALID","",0);
  1589.                         ckstrncpy(szUserNameRequested,value,UIDBUFLEN);
  1590.                         ckstrncpy(uidbuf,value,UIDBUFLEN);
  1591. #ifdef CK_SSL
  1592.                         if (ssl_active_flag) {
  1593.                             if ( tls_is_user_valid(ssl_con, uidbuf) ) {
  1594.                                 extern char szUserNameAuthenticated[];
  1595.                                 ckstrncpy(szUserNameAuthenticated,uidbuf,
  1596.                                            UIDBUFLEN);
  1597.                                 auth_finished(AUTH_VALID);
  1598.                             }
  1599.                         } else if (tls_active_flag) {
  1600.                             if ( tls_is_user_valid(tls_con, uidbuf) ) {
  1601.                                 extern char szUserNameAuthenticated[];
  1602.                                 ckstrncpy(szUserNameAuthenticated,uidbuf,
  1603.                                            UIDBUFLEN);
  1604.                                 auth_finished(AUTH_VALID);
  1605.                             }
  1606.                         }
  1607. #endif /* CK_SSL */
  1608.                     } else {    /* AUTH_VALID */
  1609.                         debug(F110,"tn_rnenv AUTH_VALID uidbuf",uidbuf,0);
  1610.                         if ( strcmp(value,uidbuf) ) {
  1611.                             extern char szUserNameRequested[];
  1612.                             ckstrncpy(uidbuf,value,UIDBUFLEN);
  1613.                             ckstrncpy(szUserNameRequested,value,UIDBUFLEN);
  1614.                             auth_finished(AUTH_USER);
  1615. #ifdef CK_SSL
  1616.                             if (ssl_active_flag || tls_active_flag) {
  1617.                                 if ( tls_is_user_valid(ssl_con, uidbuf) )
  1618.                                     auth_finished(AUTH_VALID);
  1619.                             }
  1620. #endif /* CK_SSL */
  1621.                         }
  1622.                     }
  1623. #else /* CK_AUTHENTICATION */
  1624.                     ckstrncpy(uidbuf,value,UIDBUFLEN);
  1625. #endif /* CK_AUTHENTICATION */
  1626.                 }
  1627.                 break;
  1628.             }
  1629.             varname[0] = '';
  1630.             value[0] = '';
  1631.             j = 0;
  1632.             k = 0;
  1633.             type = (sb[i] == TEL_ENV_USERVAR ? 2 :      /* USERVAR */
  1634.                     sb[i] == TEL_ENV_VAR ? 1 :  /* VAR */
  1635.                      0
  1636.                      );
  1637.             break;
  1638.         case TEL_ENV_VALUE: /* VALUE */
  1639.             if ( type == 1 || type == 2 )
  1640.                 type = 3;
  1641.             break;
  1642.         case TEL_ENV_ESC:       /* ESC */
  1643.             /* Take next character literally */
  1644.             if ( ++i >= len )
  1645.                 break;
  1646.             /* otherwise, fallthrough so byte will be added to string. */
  1647.         default:
  1648.             switch (type) {
  1649.             case 1:     /* VAR in progress */
  1650.             case 2:     /* USERVAR in progress */
  1651.                 if ( j < 16 )
  1652.                     varname[j++] = sb[i];
  1653.                 break;
  1654.             case 3:
  1655.                 if ( k < 64 )
  1656.                     value[k++] = sb[i];
  1657.                 break;
  1658.             }
  1659.         }
  1660.     }
  1661.     return(0);
  1662. }
  1663. /* Telnet send new environment */
  1664. /* Returns -1 on error, 0 if nothing happens, 1 on success */
  1665. /* In order for this code to work, sb[len] == IAC          */
  1666. int
  1667. #ifdef CK_ANSIC
  1668. tn_snenv(CHAR * sb, int len)
  1669. #else
  1670. tn_snenv(sb, len) CHAR * sb; int len;
  1671. #endif /* CK_ANSIC */
  1672. /* tn_snenv */ {                        /* Send new environment */
  1673.     char varname[16];
  1674.     char * reply = 0, * s = 0;
  1675.     int i,j,n;                          /* Worker. */
  1676.     int type = 0;       /* 0 for NONE, 1 for VAR, 2 for USERVAR in progress */
  1677.     extern int ck_lcname;
  1678.     char localuidbuf[UIDBUFLEN];
  1679.     char * uu = uidbuf;
  1680.     char * disp = NULL, tmploc[256];
  1681.     if (ttnet != NET_TCPB) return(0);
  1682.     if (ttnproto != NP_TELNET) return(0);
  1683.     if (!sb) return(-1);
  1684. #ifdef CK_SSL
  1685.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1686.         return(0);
  1687.     }
  1688. #endif /* CK_SSL */
  1689.     /* Must compute the DISPLAY string we are going to send to the host */
  1690.     /* If one is not assigned, do not send a string unless the user has */
  1691.     /* explicitedly requested we try to send one via X-Display Location */
  1692.     if (tn_env_disp[0]) {
  1693.         int colon = ckindex(":",tn_env_disp,0,0,1);
  1694.         if ( !colon ) {
  1695.             sprintf(tmploc,"%s:%s",myipaddr,tn_env_disp);
  1696.             disp = tmploc;
  1697.         } else if ( ckindex("localhost:",tn_env_disp,0,0,0) ||
  1698.                     ckindex("127.0.0.1:",tn_env_disp,0,0,0) ||
  1699.                     ckindex("0:",tn_env_disp,0,0,0) ) {
  1700.             sprintf(tmploc,"%s:%s",myipaddr,&tn_env_disp[colon]);
  1701.             disp = tmploc;
  1702.         } else
  1703.             disp = tn_env_disp;
  1704.     }
  1705.     else if (TELOPT_ME_MODE(TELOPT_XDISPLOC)) {
  1706.         sprintf(tmploc,"%s:0.0",myipaddr);
  1707.         disp = tmploc;
  1708.     }
  1709.     if (ck_lcname) {
  1710.         ckstrncpy(localuidbuf,uidbuf,UIDBUFLEN);
  1711.         cklower(localuidbuf);
  1712.         uu = localuidbuf;
  1713.     }
  1714.     hexdump((CHAR *)"tn_snenv sb[]",sb,len);
  1715.     debug(F110,"tn_snenv uidbuf",uidbuf,0);
  1716.     debug(F110,"tn_snenv localuidbuf",localuidbuf,0);
  1717.     debug(F110,"tn_snenv tn_env_sys",tn_env_sys,0);
  1718.     debug(F110,"tn_snenv tn_env_disp",tn_env_disp,0);
  1719.     debug(F110,"tn_snenv disp",disp,0);
  1720.     /* First determine the size of the buffer we will need */
  1721.     for (i = 0, j = 0, n = 0, type = 0, varname[0]= ''; i <= len; i++) {
  1722.         switch (sb[i]) {
  1723.           case TEL_ENV_VAR:             /* VAR */
  1724.           case TEL_ENV_USERVAR:         /* USERVAR */
  1725.           case IAC:                     /* End of the list */
  1726.             switch (type) {
  1727.               case 0:                   /* Nothing in progress */
  1728.                 /* If we get IAC only, then that means send all */
  1729.                 /* VAR and USERVAR.  But since we don't support */
  1730.                 /* USERVAR yet, we can just pass through        */
  1731.                 if (!(j == 0 && sb[i] == IAC))
  1732.                   break;
  1733.               case 1:                   /* VAR in progress */
  1734.                 varname[j] = '' ;
  1735.                 if (!varname[0]) {      /* Send All */
  1736.                     if (uu[0])
  1737.                       n += strlen(uu) + 4 + 2;
  1738.                     if (tn_env_job[0])
  1739.                       n += strlen(tn_env_job) + 3 + 2;
  1740.                     if (tn_env_acct[0])
  1741.                       n += strlen(tn_env_acct) + 4 + 2;
  1742.                     if (tn_env_prnt[0])
  1743.                       n += strlen(tn_env_prnt) + 7 + 2;
  1744.                     if (tn_env_sys[0])
  1745.                       n += strlen(tn_env_sys) + 10 + 2;
  1746.                     if (tn_env_disp[0])
  1747.                       n += strlen(tn_env_disp) + 7 + 2;
  1748.                 } else if (!strcmp(varname,"USER") && uu[0])
  1749.                   n += strlen(uu) + 4 + 2;
  1750.                 else if (!strcmp(varname,"JOB") && tn_env_job[0])
  1751.                   n += strlen(tn_env_job) + 3 + 2;
  1752.                 else if (!strcmp(varname,"ACCT") && tn_env_acct[0])
  1753.                   n += strlen(tn_env_acct) + 4 + 2;
  1754.                 else if (!strcmp(varname,"PRINTER") && tn_env_prnt[0])
  1755.                   n += strlen(tn_env_prnt) + 7 + 2;
  1756.                 else if (!strcmp(varname,"SYSTEMTYPE") && tn_env_sys[0])
  1757.                   n += strlen(tn_env_sys) + 10 + 2;
  1758.                 else if (!strcmp(varname,"DISPLAY") && disp)
  1759.                   n += strlen(disp) + 7 + 2;
  1760.                 break;
  1761.               case 2:                   /* USERVAR in progress */
  1762.                 break;                  /* We don't support this yet */
  1763.             }
  1764.             varname[0] = '';
  1765.             j = 0;
  1766.             type = (sb[i] == TEL_ENV_USERVAR ? 2 :      /* USERVAR */
  1767.                     sb[i] == TEL_ENV_VAR ? 1 :          /* VAR */
  1768.                     0
  1769.                    );
  1770.             break;
  1771.           case TEL_ENV_VALUE:           /* VALUE */
  1772.             /* Protocol Error */
  1773.             debug(F100, "TELNET Subnegotiation error - VALUE in SEND", "",0);
  1774.             if (tn_deb || debses)
  1775.               tn_debug("TELNET Subnegotiation error - VALUE in SEND");
  1776.             return(0);
  1777.           case TEL_ENV_ESC:     /* ESC */
  1778.             if (++i >= len)
  1779.               break;
  1780.           default:
  1781.             if (j < 16 )
  1782.               varname[j++] = sb[i];
  1783.         }
  1784.     }
  1785.     reply = malloc(n + 16);              /* Leave room for IAC stuff */
  1786.     if (!reply) {
  1787.         debug(F100, "TELNET Subnegotiation error - malloc failed", "",0);
  1788.         if (tn_deb || debses)
  1789.           tn_debug("TELNET Subnegotiation error - malloc failed");
  1790.         /* Send a return packet with no variables so that the host */
  1791.         /* may continue with additional negotiations               */
  1792.         if (tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_IS,"",0) < 0)
  1793.           return(-1);
  1794.         return(0);
  1795.     }
  1796.     /* Now construct the real reply */
  1797.     n = 0;                              /* Start at beginning of buffer */
  1798. /*
  1799.   Pairs of <type> [VAR=0, VALUE=1, ESC=2, USERVAR=3] <value> "unterminated"
  1800.   follow here until done...
  1801. */
  1802.     for (i = 0, j = 0, type = 0, varname[0]= ''; i <= len; i++) {
  1803.         switch (sb[i]) {
  1804.           case TEL_ENV_VAR:             /* VAR */
  1805.           case TEL_ENV_USERVAR:         /* USERVAR */
  1806.           case IAC:                     /* End of the list */
  1807.             switch (type) {
  1808.               case 0:                   /* Nothing in progress */
  1809.                 /* If we get IAC only, then that means send all */
  1810.                 /* VAR and USERVAR.  But since we don't support */
  1811.                 /* USERVAR yet, we can just pass through        */
  1812.                 if (!(j == 0 && sb[i] == IAC))
  1813.                   break;
  1814.               case 1:                   /* VAR in progress */
  1815.                 varname[j] = '';
  1816.                 if (!varname[0]) {
  1817.                     /* Send All */
  1818.                     if (uu[0]) {
  1819.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1820.                         strcpy(&reply[n+1],"USER");
  1821.                         reply[n+5] = TEL_ENV_VALUE;             /* VALUE */
  1822.                         strcpy(&reply[n+6],uu);
  1823.                         n += strlen(uu) + 4 + 2;
  1824.                     }
  1825.                     if (tn_env_job[0]) {
  1826.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1827.                         strcpy(&reply[n+1],"JOB");
  1828.                         reply[n+4] = TEL_ENV_VALUE;     /* VALUE */
  1829.                         strcpy(&reply[n+5],tn_env_job);
  1830.                         n += strlen(tn_env_job) + 3 + 2;
  1831.                     }
  1832.                     if (tn_env_acct[0]) {
  1833.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1834.                         strcpy(&reply[n+1],"ACCT");
  1835.                         reply[n+5] = TEL_ENV_VALUE;     /* VALUE */
  1836.                         strcpy(&reply[n+6],tn_env_acct);
  1837.                         n += strlen(tn_env_acct) + 4 + 2;
  1838.                     }
  1839.                     if (tn_env_prnt[0]) {
  1840.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1841.                         strcpy(&reply[n+1],"PRINTER");
  1842.                         reply[n+8] = TEL_ENV_VALUE;     /* VALUE */
  1843.                         strcpy(&reply[n+9],tn_env_prnt);
  1844.                         n += strlen(tn_env_prnt) + 7 + 2;
  1845.                     }
  1846.                     if (tn_env_sys[0]) {
  1847.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1848.                         strcpy(&reply[n+1],"SYSTEMTYPE");
  1849.                         reply[n+11] = TEL_ENV_VALUE; /* VALUE */
  1850.                         strcpy(&reply[n+12],tn_env_sys);
  1851.                         n += strlen(tn_env_sys) + 10 + 2;
  1852.                     }
  1853.                     if (disp) {
  1854.                         reply[n] = TEL_ENV_VAR; /* VAR */
  1855.                         strcpy(&reply[n+1],"DISPLAY");
  1856.                         reply[n+8] = TEL_ENV_VALUE;     /* VALUE */
  1857.                         strcpy(&reply[n+9],disp);
  1858.                         n += strlen(disp) + 7 + 2;
  1859.                     }
  1860.                 } else if (!strcmp(varname,"USER") && uu[0]) {
  1861.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1862.                     strcpy(&reply[n+1],"USER");
  1863.                     reply[n+5] = TEL_ENV_VALUE; /* VALUE */
  1864.                     strcpy(&reply[n+6],uu);
  1865.                     n += strlen(uu) + 4 + 2;
  1866.                 } else if (!strcmp(varname,"JOB") && tn_env_job[0]) {
  1867.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1868.                     strcpy(&reply[n+1],"JOB");
  1869.                     reply[n+4] = TEL_ENV_VALUE; /* VALUE */
  1870.                     strcpy(&reply[n+5],tn_env_job);
  1871.                     n += strlen(tn_env_job) + 3 + 2;
  1872.                 } else if (!strcmp(varname,"ACCT") && tn_env_acct[0]) {
  1873.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1874.                     strcpy(&reply[n+1],"ACCT");
  1875.                     reply[n+5] = TEL_ENV_VALUE; /* VALUE */
  1876.                     strcpy(&reply[n+6],tn_env_acct);
  1877.                     n += strlen(tn_env_acct) + 4 + 2;
  1878.                 } else if (!strcmp(varname,"PRINTER") && tn_env_prnt[0]) {
  1879.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1880.                     strcpy(&reply[n+1],"PRINTER");
  1881.                     reply[n+8] = TEL_ENV_VALUE; /* VALUE */
  1882.                     strcpy(&reply[n+9],tn_env_prnt);
  1883.                     n += strlen(tn_env_prnt) + 7 + 2;
  1884.                 } else if (!strcmp(varname,"SYSTEMTYPE") && tn_env_sys[0]) {
  1885.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1886.                     strcpy(&reply[n+1],"SYSTEMTYPE");
  1887.                     reply[n+11] = TEL_ENV_VALUE;        /* VALUE */
  1888.                     strcpy(&reply[n+12],tn_env_sys);
  1889.                     n += strlen(tn_env_sys) + 10 + 2;
  1890.                 } else if (!strcmp(varname,"DISPLAY") && disp) {
  1891.                     reply[n] = TEL_ENV_VAR;     /* VAR */
  1892.                     strcpy(&reply[n+1],"DISPLAY");
  1893.                     reply[n+8] = TEL_ENV_VALUE; /* VALUE */
  1894.                     strcpy(&reply[n+9],disp);
  1895.                     n += strlen(disp) + 7 + 2;
  1896.                 }
  1897.                 break;
  1898.             case 2:     /* USERVAR in progress */
  1899.                 /* we don't support this yet */
  1900.                 break;
  1901.             }
  1902.             varname[0] = '';
  1903.             j = 0;
  1904.             type = (sb[i] == TEL_ENV_USERVAR ? 2 :      /* USERVAR */
  1905.                     sb[i] == TEL_ENV_VAR ? 1 :  /* VAR */
  1906.                     0
  1907.                    );
  1908.             break;
  1909.           case TEL_ENV_VALUE: /* VALUE */
  1910.             /* Protocol Error */
  1911.             debug(F100, "TELNET Subnegotiation error - VALUE in SEND", "",0);
  1912.             if (tn_deb || debses)
  1913.               tn_debug("TELNET Subnegotiation error - VALUE in SEND");
  1914.             return(0);  /* Was -1 but that would be taken as */
  1915.                         /* an I/O error, so absorb it and go on. */
  1916.           case TEL_ENV_ESC:     /* ESC */
  1917.             /* Not sure what this for.  Quote next character? */
  1918.             break;
  1919.           default:
  1920.             varname[j++] = sb[i];
  1921.         }
  1922.     }
  1923.     if (tn_ssbopt(TELOPT_NEWENVIRON,TELQUAL_IS,reply,n) < 0) {
  1924.         free(reply);
  1925.         return(-1);
  1926.     }
  1927.     free(reply);
  1928.     return(1);
  1929. }
  1930. #endif /* CK_ENVIRONMENT */
  1931. /* Telnet send terminal type */
  1932. /* Returns -1 on error, 0 if nothing happens, 1 if type sent successfully */
  1933. int
  1934. tn_sttyp() {                            /* Send telnet terminal type. */
  1935.     char *ttn;                          /* Name of terminal type. */
  1936. #ifdef OS2
  1937.     static int alias = -1;              /* which alias are we using ? */
  1938. #endif /* OS2 */
  1939.     int i;                              /* Worker. */
  1940.     int tntermflg = 0;
  1941.     int settype = 0;
  1942.     if (ttnet != NET_TCPB) return(0);
  1943.     if (ttnproto != NP_TELNET) return(0);
  1944.     if (!TELOPT_ME(TELOPT_TTYPE)) return(0);
  1945. #ifdef CK_SSL
  1946.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1947.         return(0);
  1948.     }
  1949. #endif /* CK_SSL */
  1950.     ttn = NULL;
  1951. #ifdef OS2
  1952.     if (!tn_term) {
  1953.         if (ttnum == -1) {
  1954.             ttnum = tt_type;
  1955.             settype = 0;
  1956.             alias = -1;
  1957.         } else if (ttnumend) {
  1958.             ttnumend = 0;
  1959.             settype = 0;
  1960.         } else {
  1961.             if (tt_info[tt_type].x_aliases[++alias] == NULL)  {
  1962.                 if (--tt_type < 0)
  1963.                   tt_type = max_tt;
  1964.                 if (ttnum == tt_type)
  1965.                   ttnumend = 1;
  1966.                 settype = 1;
  1967.                 alias = -1;
  1968.             }
  1969.         }
  1970.         if (tt_type >= 0 && tt_type <= max_tt) {
  1971.             if (alias == -1)
  1972.               ttn = tt_info[tt_type].x_name;
  1973.             else
  1974.               ttn = tt_info[tt_type].x_aliases[alias];
  1975.         } else
  1976.           ttn = NULL;
  1977.     }
  1978.     else settype = 0;
  1979. #endif /* OS2 */
  1980.     if (tn_term) {                      /* Terminal type override? */
  1981.         debug(F110,"tn_sttyp",tn_term,0);
  1982.         if (*tn_term) {
  1983.             ttn = tn_term;
  1984.             tntermflg = 1;
  1985.         }
  1986.     } else debug(F100,"tn_sttyp no term override","",0);
  1987. #ifndef datageneral
  1988.     if (!ttn) {                         /* If no override, */
  1989.         ttn = getenv("TERM");           /* get it from the environment. */
  1990.     }
  1991. #endif /* datageneral */
  1992.     if ((ttn == ((char *)0)) || ((int)strlen(ttn) >= TSBUFSIZ))
  1993.       ttn = "UNKNOWN";
  1994.     sb[0] = (CHAR) IAC;                 /* I Am a Command */
  1995.     sb[1] = (CHAR) SB;                  /* Subnegotiation */
  1996.     sb[2] = TELOPT_TTYPE;               /* Terminal Type */
  1997.     sb[3] = (CHAR) 0;                   /* Is... */
  1998.     for (i = 4; *ttn; ttn++,i++) {      /* Copy and uppercase it */
  1999. #ifdef VMS
  2000.         if (!tntermflg && *ttn == '-' &&
  2001.             (!strcmp(ttn,"-80") || !strcmp(ttn,"-132")))
  2002.           break;
  2003.         else
  2004. #endif /* VMS */
  2005.         sb[i] = (char) ((!tntermflg && islower(*ttn)) ? toupper(*ttn) : *ttn);
  2006.     }
  2007.     ttn = (char *)sb;                   /* Point back to beginning */
  2008.     if (deblog || tn_deb || debses) {
  2009.         sb[i] = '';                   /* For debugging */
  2010.         sprintf(tn_msg,"TELNET SENT SB %s IS %s IAC SE",
  2011.                  TELOPT(TELOPT_TTYPE),sb+4);
  2012.         debug(F100,tn_msg,"",0);
  2013.         if (tn_deb || debses) tn_debug(tn_msg);
  2014.     }
  2015.     sb[i++] = (CHAR) IAC;               /* End of Subnegotiation */
  2016.     sb[i++] = (CHAR) SE;                /* marked by IAC SE */
  2017.     if (ttol((CHAR *)sb,i) < 0)         /* Send it. */
  2018.       return(-1);
  2019. #ifdef OS2
  2020.     if (settype)
  2021.         settermtype(tt_type,0);
  2022.     else {
  2023.         ipadl25();
  2024.         VscrnIsDirty(VTERM);
  2025.     }
  2026. #endif /* OS2 */
  2027.     return(1);
  2028. }
  2029. #ifdef CK_ENVIRONMENT
  2030. #ifdef CK_XDISPLOC
  2031. /* Telnet send xdisplay location */
  2032. /* Returns -1 on error, 0 if nothing happens, 1 if type sent successfully */
  2033. int
  2034. tn_sxdisploc() {                        /* Send telnet X display location. */
  2035.     char * disp=NULL;
  2036.     char tmploc[256];
  2037.     int i;
  2038.     tmploc[0] = '';
  2039.     if (ttnet != NET_TCPB) return(0);
  2040.     if (ttnproto != NP_TELNET) return(0);
  2041.     if (!TELOPT_ME(TELOPT_XDISPLOC)) return(0);
  2042. #ifdef CK_SSL
  2043.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  2044.         return(0);
  2045.     }
  2046. #endif /* CK_SSL */
  2047.     if (tn_env_disp[0]) {
  2048.         int colon = ckindex(":",tn_env_disp,0,0,1);
  2049.         if ( !colon ) {
  2050.             sprintf(tmploc,"%s:%s",myipaddr,tn_env_disp);
  2051.             disp = tmploc;
  2052.         } else if ( ckindex("localhost:",tn_env_disp,0,0,0) ||
  2053.                     ckindex("127.0.0.1:",tn_env_disp,0,0,0) ||
  2054.                     ckindex("0:",tn_env_disp,0,0,0) ) {
  2055.             sprintf(tmploc,"%s:%s",myipaddr,&tn_env_disp[colon]);
  2056.             disp = tmploc;
  2057.         } else
  2058.             disp = tn_env_disp;
  2059.     } else {
  2060.         sprintf(tmploc,"%s:0.0",myipaddr);
  2061.         disp = tmploc;
  2062.     }
  2063.     debug(F110,"tn_sxdisploc",disp,0);
  2064.     sb[0] = (CHAR) IAC;                 /* I Am a Command */
  2065.     sb[1] = (CHAR) SB;                  /* Subnegotiation */
  2066.     sb[2] = TELOPT_XDISPLOC;            /* X-Display Location */
  2067.     sb[3] = (CHAR) 0;                   /* Is... */
  2068.     for (i = 4; *disp; disp++,i++) {      /* Copy and uppercase it */
  2069.         sb[i] = (char) *disp;
  2070.     }
  2071.     if (deblog || tn_deb || debses) {
  2072.         sb[i] = '';                   /* For debugging */
  2073.         sprintf(tn_msg,
  2074.                 "TELNET SENT SB %s IS %s IAC SE",
  2075.                 TELOPT(TELOPT_XDISPLOC),sb+4);
  2076.         debug(F100,tn_msg,"",0);
  2077.         if (tn_deb || debses) tn_debug(tn_msg);
  2078.     }
  2079.     sb[i++] = (CHAR) IAC;               /* End of Subnegotiation */
  2080.     sb[i++] = (CHAR) SE;                /* marked by IAC SE */
  2081.     if (ttol((CHAR *)sb,i) < 0)         /* Send it. */
  2082.       return(-1);
  2083.     return(1);
  2084. }
  2085. #endif /* CK_XDISPLOC */
  2086. #endif /* CK_ENVIRONMENT */
  2087. #ifdef CK_FORWARD_X
  2088. int
  2089. tn_sndfwdx() {                          /* Send Fwd X Screen number to host */
  2090.     unsigned char screen = 0;
  2091.     if (!TELOPT_U(TELOPT_FORWARD_X)) return(0);
  2092. #ifdef CK_SSL
  2093.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  2094.         return(0);
  2095.     }
  2096. #endif /* CK_SSL */
  2097.     /*
  2098.      * The format of the DISPLAY variable is [<host>:]<display>[.<screen>]
  2099.      * where <host> is an optional DNS name or ip address with a default of
  2100.      * the localhost; the screen defaults to 0
  2101.      */
  2102.     if (tn_env_disp[0]) {
  2103.         int colon,dot;
  2104.         colon = ckindex(":",tn_env_disp,0,0,1);
  2105.         dot   = ckindex(".",&tn_env_disp[colon],0,0,1);
  2106.         if ( dot ) {
  2107.             screen = atoi(&tn_env_disp[colon+dot]);
  2108.         }
  2109.     } else {
  2110.         return(-1);
  2111.     }
  2112.     sb[0] = (CHAR) IAC;                 /* I Am a Command */
  2113.     sb[1] = (CHAR) SB;                  /* Subnegotiation */
  2114.     sb[2] = TELOPT_FORWARD_X;           /* Forward X */
  2115.     sb[3] = FWDX_SCREEN;                /* Screen */
  2116.     sb[4] = screen;
  2117.     sb[5] = (CHAR) IAC;                 /* End of Subnegotiation */
  2118.     sb[6] = (CHAR) SE;                  /* marked by IAC SE */
  2119.     if (ttol((CHAR *)sb,7) < 0)         /* Send it. */
  2120.       return(-1);
  2121. #ifdef DEBUG
  2122.     if (deblog || tn_deb || debses) {
  2123.         sprintf(tn_msg,"TELNET SENT SB %s SCREEN %02x IAC SE",
  2124.         TELOPT(TELOPT_FORWARD_X),screen);
  2125.         debug(F100,tn_msg,"",0);
  2126.         if (tn_deb || debses) tn_debug(tn_msg);
  2127.     }
  2128. #endif /* DEBUG */
  2129.     return(0);
  2130. }
  2131. #endif /* CK_FORWARD_X */
  2132. #ifdef CK_SNDLOC
  2133. int
  2134. tn_sndloc() {                           /* Send location. */
  2135.     int i;                              /* Worker. */
  2136.     char *ttloc;
  2137.     if (!TELOPT_ME(TELOPT_SNDLOC)) return(0);
  2138. #ifdef CK_SSL
  2139.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  2140.         return(0);
  2141.     }
  2142. #endif /* CK_SSL */
  2143.     ttloc = (tn_loc ? tn_loc : "");     /* In case we are being called even */
  2144.                                         /* though there is no location. */
  2145.     sb[0] = (CHAR) IAC;                 /* I Am a Command */
  2146.     sb[1] = (CHAR) SB;                  /* Subnegotiation */
  2147.     sb[2] = TELOPT_SNDLOC;              /* Location */
  2148.     for (i = 3; *ttloc && i < TSBUFSIZ; ttloc++,i++) /* Copy it */
  2149.       sb[i] = (char) *ttloc;
  2150.     sb[i++] = (CHAR) IAC;               /* End of Subnegotiation */
  2151.     sb[i++] = (CHAR) SE;                /* marked by IAC SE */
  2152.     if (ttol((CHAR *)sb,i) < 0)         /* Send it. */
  2153.       return(-1);
  2154.     sb[i-2] = '';                     /* For debugging */
  2155. #ifdef DEBUG
  2156.     if (deblog || tn_deb || debses) {
  2157.         sprintf(tn_msg,"TELNET SENT SB %s %s IAC SE",
  2158.         TELOPT(TELOPT_SNDLOC),sb+3);
  2159.         debug(F100,tn_msg,"",0);
  2160.         if (tn_deb || debses) tn_debug(tn_msg);
  2161.     }
  2162. #endif /* DEBUG */
  2163.     return(0);
  2164. }
  2165. #endif /* CK_SNDLOC */
  2166. #ifdef CK_NAWS                  /*  NAWS = Negotiate About Window Size  */
  2167. int
  2168. tn_snaws() {                    /*  Send terminal width and height, RFC 1073 */
  2169.     int i = 0;
  2170. #ifdef OS2
  2171.     int x = VscrnGetWidth(VTERM),
  2172.     y = VscrnGetHeight(VTERM) - (tt_status ? 1 : 0);
  2173. #else /* OS2 */
  2174.     int x = tt_cols, y = tt_rows;
  2175. #endif /* OS2 */
  2176.     if (ttnet != NET_TCPB) return(0);
  2177.     if (ttnproto != NP_TELNET) return(0);
  2178.     if (!TELOPT_ME(TELOPT_NAWS)) return(0);
  2179. #ifdef CK_SSL
  2180.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  2181.         return(0);
  2182.     }
  2183. #endif /* CK_SSL */
  2184.     if (x < 0) x = 0;
  2185.     if (y < 0) y = 0;
  2186.     if (x == TELOPT_SB(TELOPT_NAWS).naws.x && /* Only send if changed */
  2187.         y == TELOPT_SB(TELOPT_NAWS).naws.y
  2188.         )
  2189.       return(0);
  2190.     TELOPT_SB(TELOPT_NAWS).naws.x = x;  /* Remember the size     */
  2191.     TELOPT_SB(TELOPT_NAWS).naws.y = y;
  2192.     sb[i++] = (CHAR) IAC;               /* Send the subnegotiation */
  2193.     sb[i++] = (CHAR) SB;
  2194.     sb[i++] = TELOPT_NAWS;
  2195.     sb[i++] = (CHAR) (x >> 8) & 0xff;
  2196.     if ((CHAR) sb[i-1] == (CHAR) IAC)   /* IAC in data must be doubled */
  2197.       sb[i++] = (CHAR) IAC;
  2198.     sb[i++] = (CHAR) (x & 0xff);
  2199.     if ((CHAR) sb[i-1] == (CHAR) IAC)
  2200.       sb[i++] = (CHAR) IAC;
  2201.     sb[i++] = (CHAR) (y >> 8) & 0xff;
  2202.     if ((CHAR) sb[i-1] == (CHAR) IAC)
  2203.       sb[i++] = (CHAR) IAC;
  2204.     sb[i++] = (CHAR) (y & 0xff);
  2205.     if ((CHAR) sb[i-1] == (CHAR) IAC)
  2206.       sb[i++] = (CHAR) IAC;
  2207.     sb[i++] = (CHAR) IAC;
  2208.     sb[i++] = (CHAR) SE;
  2209.     if (deblog || tn_deb || debses) {
  2210.         sprintf(tn_msg,"TELNET SENT SB NAWS %d %d IAC SE",x,y);
  2211.         debug(F100,tn_msg,"",0);
  2212.         if (tn_deb || debses) tn_debug(tn_msg);
  2213.     }
  2214.     if (ttol((CHAR *)sb,i) < 0)         /* Send it. */
  2215.       return(-1);
  2216.     return (0);
  2217. }
  2218. #endif /* CK_NAWS */
  2219. #endif /* TNCODE */