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

通讯/手机编程

开发平台:

Windows_Unix

  1. char *ckathv = "Authentication, 7.0.141, 19 Dec 1999";
  2. /*
  3.   C K U A T H . C  --  Authentication for C-Kermit
  4.   Copyright (C) 1999, 2000,
  5.     Trustees of Columbia University in the City of New York.
  6.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  7.     copyright text in the ckcmai.c module for disclaimer and permissions.
  8.   Author:  Jeffrey E Altman (jaltman@columbia.edu)
  9. */
  10. /*
  11.  * Based on a concatenation of all necessary source files distributed with the
  12.  * Kerberos 5 NT Alpha 2 Telnet package from MIT with significant changes.
  13.  * Additional copyrights included with affected code.
  14.  */
  15. /*
  16.  * Implements Kerberos 4/5, SRP, SSL, NTLM authentication and START_TLS
  17.  */
  18. #include "ckcdeb.h"
  19. #ifdef CK_AUTHENTICATION
  20. #include "ckcker.h"
  21. #include "ckucmd.h"                             /* For struct keytab */
  22. #include "ckcnet.h"
  23. #ifdef CRYPT_DLL
  24. #ifndef LIBDES
  25. #define LIBDES
  26. #endif /* LIBDES */
  27. #ifdef OS2
  28. #ifdef NT
  29. #include <windows.h>
  30. #else /* NT */
  31. #define INCL_DOSMODULEMGR
  32. #include <os2.h>
  33. #endif /* NT */
  34. #endif /* OS2 */
  35. #endif /* CRYPT_DLL */
  36. #ifdef NT
  37. #define KRB5_AUTOCONF__
  38. #define NTLM
  39. #endif /* NT */
  40. #ifdef CK_KERBEROS
  41. #define KINIT
  42. #define KLIST
  43. #define KDESTROY
  44. #define CHECKADDRS
  45. #else /* CK_KERBEROS */
  46. #ifdef KRB4
  47. #undef KRB4
  48. #endif /* KRB4 */
  49. #ifdef KRB5
  50. #undef KRB5
  51. #endif /* KRB5 */
  52. #ifdef KRB524
  53. #undef KRB524
  54. #endif /* KRB524 */
  55. #endif /* CK_KERBEROS */
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <stdio.h>
  59. #include <time.h>
  60. #include <fcntl.h>
  61. #include <malloc.h>
  62. #ifdef OS2
  63. #include <io.h>
  64. #endif /* OS2 */
  65. #ifdef KRB5
  66. #include "krb5.h"
  67. #include "com_err.h"
  68. #ifdef HAVE_PWD_H
  69. #include <pwd.h>
  70. #endif
  71. #ifdef UNIX
  72. #define krb5_free_unparsed_name(con,val) free((char FAR *)(val))
  73. #endif /* UNIX */
  74. #endif /* KRB5 */
  75. #ifdef KRB4
  76. #define  des_cblock Block
  77. #define  des_key_schedule Schedule
  78. #ifdef NT
  79. #define _WINDOWS
  80. #include "kerberosIV/krb.h"
  81. #else /* NT */
  82. #ifdef KRB524
  83. #include "kerberosIV/krb.h"
  84. _PROTOTYP(const char * krb_get_err_text_entry, (int));
  85. #else /* KRB524 */
  86. #ifdef SOLARIS
  87. #ifndef sun
  88. /* for some reason the Makefile entries for the Solaris systems have -Usun */
  89. #define sun
  90. #endif /* sun */
  91. #endif /* SOLARIS */
  92. #include "krb.h"
  93. #define krb_get_err_text_entry krb_get_err_text
  94. #endif /* KRB524 */
  95. #endif /* NT */
  96. #else /* KRB4 */
  97. #ifdef CK_SSL
  98. #define  des_cblock Block
  99. #define  des_key_schedule Schedule
  100. #endif /* CK_SSL */
  101. #endif /* KRB4 */
  102. #include "ckuath.h"
  103. #ifdef CK_KERBEROS
  104. #ifndef KRB5
  105. #define NOBLOCKDEF
  106. #endif /* KRB5 */
  107. #ifdef KRB524
  108. #define NOBLOCKDEF
  109. #endif /* KRB524 */
  110. #endif /* CK_KERBEROS */
  111. #include "ckuat2.h"
  112. #ifdef CK_SSL
  113. #ifdef LIBDES
  114. #ifndef HEADER_DES_H
  115. #define HEADER_DES_H
  116. #endif /* HEADER_DES_H */
  117. #endif /* LIBDES */
  118. #include "ck_ssl.h"
  119. #endif /* SSL */
  120. #define PWD_SZ 128
  121. #ifndef LIBDES
  122. #ifdef UNIX
  123. #define des_set_random_generator_seed(x) des_init_random_number_generator(x)
  124. #endif /* UNIX */
  125. #endif /* LIBDES */
  126. /*
  127.  * Globals
  128.  */
  129. int authentication_version = AUTHTYPE_NULL;
  130. int auth_type_user[AUTHTYPLSTSZ]      = {AUTHTYPE_AUTO, AUTHTYPE_NULL};
  131. static int auth_how=0;
  132. static int auth_crypt=0;
  133. static int auth_fwd=0;
  134. /* These are state completion variables */
  135. int accept_complete = 0;
  136. static int mutual_complete = 0;
  137. #ifdef KRB4
  138. #ifdef OS2
  139. /* The Leash implementation of Kerberos 4 used by Kermit 95 */
  140. /* has an extended Credentials structure that includes the  */
  141. /* ip address of the ticket in readable form.               */
  142. #ifdef KRB4
  143. #ifndef ADDR_SZ
  144. #define ADDR_SZ 40      /* From Leash krb.h */
  145. #endif /* ADDR_SZ */
  146. struct leash_credentials {
  147.     char    service[ANAME_SZ];  /* Service name */
  148.     char    instance[INST_SZ];  /* Instance */
  149.     char    realm[REALM_SZ];    /* Auth domain */
  150.     C_Block session;            /* Session key */
  151.     int     lifetime;           /* Lifetime */
  152.     int     kvno;               /* Key version number */
  153.     KTEXT_ST ticket_st;         /* The ticket itself */
  154.     long    issue_date;         /* The issue time */
  155.     char    pname[ANAME_SZ];    /* Principal's name */
  156.     char    pinst[INST_SZ];     /* Principal's instance */
  157.     char    address[ADDR_SZ];   /* IP Address in ticket */
  158. };
  159. typedef struct leash_credentials LEASH_CREDENTIALS;
  160. #endif /* KRB4 */
  161. static LEASH_CREDENTIALS cred;
  162. #else /* OS2 */
  163. static CREDENTIALS cred;
  164. #endif /* OS2 */
  165. static KTEXT_ST k4_auth;
  166. static char     k4_name[ANAME_SZ];
  167. static AUTH_DAT k4_adat  = { 0 };
  168. static char *   k4_keyfile = "/etc/srvtab";
  169. static MSG_DAT  k4_msg_data;
  170. #ifdef CK_ENCRYPTION
  171. static Block    k4_session_key     = { 0 };
  172. static Schedule k4_sched;
  173. static Block    k4_challenge       = { 0 };
  174. #ifdef MIT_CURRENT
  175. static krb5_keyblock k4_krbkey;
  176. #endif /* MIT_CURRENT */
  177. #endif /* ENCRYPTION */
  178. #define KRB4_SERVICE_NAME    "rcmd"
  179. _PROTOTYP(static int k4_auth_send,(VOID));
  180. _PROTOTYP(static int k4_auth_reply,(unsigned char *, int));
  181. _PROTOTYP(static int k4_auth_is,(unsigned char *, int));
  182. #endif /* KRB4 */
  183. #ifdef KRB5
  184. static krb5_data          k5_auth;
  185. static krb5_auth_context  auth_context;
  186. static krb5_keyblock     *k5_session_key = NULL;
  187. #ifdef FORWARD
  188. _PROTOTYP(void kerberos5_forward,(VOID));
  189. #endif /* FORWARD */
  190. #define KRB5_SERVICE_NAME    "host"
  191. _PROTOTYP(static int k5_auth_send,(int,int,int));
  192. _PROTOTYP(static int k5_auth_reply,(int, unsigned char *, int));
  193. _PROTOTYP(static int k5_auth_is,(int,unsigned char *, int));
  194. _PROTOTYP(static int SendK5AuthSB,(int, void *, int));
  195. #endif /* KRB5 */
  196. #ifdef CK_SRP
  197. _PROTOTYP(static int srp_reply,(int, unsigned char *, int));
  198. _PROTOTYP(static int srp_is,(int, unsigned char *, int));
  199. #endif /* SRP */
  200. _PROTOTYP(void auth_finished, (int));
  201. #ifdef CK_ENCRYPTION
  202. static int encrypt_flag = 1;
  203. #endif
  204. #ifdef FORWARD
  205. int forward_flag = 0;           /* forward tickets? */
  206. int forwardable_flag = 1;       /* get forwardable tickets to forward? */
  207. int forwarded_tickets = 0;         /* were tickets forwarded? */
  208. #endif
  209. static unsigned char str_data[4096] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  210.    AUTHTYPE_KERBEROS_V5, };
  211. #define AUTHTMPBL 2048
  212. static char strTmp[AUTHTMPBL+1];
  213.        char szUserNameRequested[UIDBUFLEN+1];    /* for incoming connections */
  214.        char szUserNameAuthenticated[UIDBUFLEN+1];/* for incoming connections */
  215.        char szHostName[UIDBUFLEN+1];
  216. static char szLocalHostName[UIDBUFLEN+1];
  217. static char szIP[16];
  218. static char szUserName[UIDBUFLEN+1];
  219. static int  validUser = AUTH_REJECT;    /* User starts out invalid */
  220. static struct kstream_crypt_ctl_block ctl;
  221. static kstream g_kstream=NULL;
  222. #ifdef KRB5
  223. static krb5_context k5_context=NULL;
  224. static krb5_creds * ret_cred=NULL;
  225. static krb5_context telnet_context=NULL;
  226. static char * telnet_srvtab = NULL;
  227. static char * telnet_krb5_realm = NULL;
  228. static krb5_ticket * k5_ticket = NULL;
  229. #endif /* KRB5 */
  230. #ifdef CK_SRP
  231. #include <t_pwd.h>
  232. #include <t_client.h>
  233. #include <t_server.h>
  234. static struct t_server * ts = NULL;
  235. static struct t_client * tc = NULL;
  236. #ifdef PRE_SRP_1_4_4
  237. #ifndef PRE_SRP_1_4_5
  238. #define PRE_SRP_1_4_5
  239. #endif /* PRE_SRP_1_4_5 */
  240. static struct t_pw * tpw = NULL;
  241. static struct t_conf * tconf = NULL;
  242. #endif /* PRE_SRP_1_4_4 */
  243. static int srp_waitresp = 0; /* Flag to indicate readiness for response */
  244. static struct t_num * B; /* Holder for B */
  245. static char srp_passwd[PWD_SZ];
  246. #endif /* CK_SRP */
  247. #ifdef CK_KERBEROS
  248. #ifdef RLOGCODE
  249. #define OPTS_FORWARD_CREDS           0x00000002
  250. #define OPTS_FORWARDABLE_CREDS       0x00000001
  251. #define RLOGIN_BUFSIZ 5120
  252. char des_inbuf[2*RLOGIN_BUFSIZ];       /* needs to be > largest read size */
  253. char des_outpkt[2*RLOGIN_BUFSIZ+4];    /* needs to be > largest write size */
  254. #ifdef KRB5
  255. krb5_data desinbuf,desoutbuf;
  256. krb5_encrypt_block eblock;             /* eblock for encrypt/decrypt */
  257. #endif /* KRB5 */
  258. static char storage[2*RLOGIN_BUFSIZ];  /* storage for the decryption */
  259. static int nstored = 0;
  260. static char *store_ptr = storage;
  261. static int rlog_encrypt = 0;
  262. #endif /* RLOGCODE */
  263. extern char * krb5_d_principal; /* Default principal */
  264. extern char * krb5_d_instance;          /* Default instance */
  265. extern char * krb5_d_realm; /* Default realm */
  266. extern char * krb5_d_cc; /* Default credentials cache */
  267. extern char * krb5_d_srv;               /* Default service name */
  268. extern int    krb5_d_lifetime;          /* Default lifetime */
  269. extern int    krb5_d_forwardable;
  270. extern int    krb5_d_proxiable;
  271. extern int    krb5_d_renewable;
  272. extern int    krb5_autoget;
  273. extern int    krb5_checkaddrs;
  274. extern int    krb5_d_getk4;
  275. extern int    krb5_errno;
  276. extern char * krb5_errmsg;
  277. extern char * krb4_d_principal; /* Default principal */
  278. extern char * krb4_d_realm; /* Default realm */
  279. extern char * krb4_d_srv;               /* Default service name */
  280. extern int    krb4_d_lifetime;          /* Default lifetime */
  281. extern int    krb4_d_preauth;
  282. extern char * krb4_d_instance;
  283. extern int    krb4_autoget;
  284. extern int    krb4_checkaddrs;
  285. extern int    krb4_errno;
  286. extern char * krb4_errmsg;
  287. #endif /* CK_KERBEROS */
  288. extern char tn_msg[], hexbuf[];         /* from ckcnet.c */
  289. extern char pwbuf[];
  290. extern int  pwflg, pwcrypt;
  291. extern int deblog, debses, tn_deb;
  292. extern int sstelnet, inserver;
  293. #ifdef CK_LOGIN
  294. extern int ckxanon;
  295. #endif /* CK_LOGIN */
  296. extern int tn_auth_how;
  297. extern int tn_auth_enc;
  298. #ifdef CK_ENCRYPTION
  299. extern int cx_type;
  300. #endif /* CK_ENCRYPTION */
  301. #ifdef OS2
  302. #include "ckoath.c"
  303. #endif /* OS2 */
  304. int
  305. ck_krb5_is_installed()
  306. {
  307. #ifdef KRB5
  308. #ifdef OS2
  309.     return(hKRB5_32 != NULL);
  310. #else /* OS2 */
  311.     return(1);
  312. #endif /* OS2 */
  313. #else /* KRB5 */
  314.     return(0);
  315. #endif /* KRB5 */
  316. }
  317. int
  318. ck_krb4_is_installed()
  319. {
  320. #ifdef KRB4
  321. #ifdef OS2
  322.     return(hKRB4_32 != NULL);
  323. #else /* OS2 */
  324.     return(1);
  325. #endif /* OS2 */
  326. #else /* KRB4 */
  327.     return(0);
  328. #endif /* KRB4 */
  329. }
  330. int
  331. ck_srp_is_installed()
  332. {
  333. #ifdef CK_SRP
  334. #ifdef SRPDLL
  335.     return(hSRP != NULL);
  336. #else /* SRPDLL */
  337.     return(1);
  338. #endif /* SRPDLL */
  339. #else /* SRP */
  340.     return(0);
  341. #endif /* SRP */
  342. }
  343. int
  344. ck_crypt_is_installed()
  345. {
  346. #ifdef CK_ENCRYPTION
  347. #ifdef CRYPT_DLL
  348.     return(hCRYPT != NULL);
  349. #else /* CRYPT_DLL */
  350.     return(1);
  351. #endif /* CRYPT_DLL */
  352. #else /* ENCRYPTION */
  353.     return(0);
  354. #endif /* ENCRYPTION */
  355. }
  356. int
  357. ck_ntlm_is_installed()
  358. {
  359. #ifdef NT
  360.     return(hSSPI != NULL);
  361. #else /* NT */
  362.     return(0);
  363. #endif /* NT */
  364. }
  365. /* C K _ K R B _ I N I T
  366.  * Initialize the Kerberos system for a pending connection
  367.  *   hostname - a reverse DNS lookup of the hostname when possible
  368.  *   ipaddr   - the ip address of the host
  369.  *   username - the name the user wants to connect under not necessarily
  370.  *              the same as principal
  371.  *   socket   - the socket handle (ttyfd in Kermit speak)
  372.  *
  373.  * Returns: 1 on success and 0 on failure
  374.  */
  375. int
  376. #ifdef CK_ANSIC
  377. ck_auth_init( char * hostname, char * ipaddr, char * username, int socket )
  378. #else /* CK_ANSIC */
  379. ck_auth_init( hostname, ipaddr, username, socket )
  380.     char * hostname; char * ipaddr; char *username; int socket;
  381. #endif /* CK_ANSIC */
  382. {
  383. #ifdef OS2
  384.     if ( !ck_auth_loaddll() ) {
  385.         TELOPT_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  386.         TELOPT_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  387.         return(0);
  388.     }
  389. #endif /* OS2 */
  390.     if ( !!ck_crypt_is_installed() ) {
  391.         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  392.         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  393.     }
  394.     if (!hostname) hostname = "";
  395.     if (!ipaddr) ipaddr = "";
  396.     if (!username) username = "";
  397.     ckstrncpy( szUserName, username, UIDBUFLEN );
  398.     ckstrncpy( szHostName, hostname, UIDBUFLEN );
  399.     ckstrncpy( szIP, ipaddr, 16 );
  400.     szUserNameRequested[0] = '';
  401.     szUserNameAuthenticated[0] = '';
  402.     validUser = AUTH_REJECT;
  403.     if ( sstelnet )
  404.         str_data[3] = TELQUAL_REPLY;
  405.     else
  406.         str_data[3] = TELQUAL_IS;
  407.     debug(F110,"ck_auth_init Username",username,0);
  408.     debug(F110,"ck_auth_init Hostname",hostname,0);
  409.     debug(F110,"ck_auth_init Ipaddr",ipaddr,0);
  410. #ifdef KRB5
  411.     /* free previous ret_cred  */
  412.     if ( ret_cred ) {
  413.         krb5_free_creds(k5_context, ret_cred);
  414.         ret_cred = NULL;
  415.     }
  416.     /* and context */
  417.     if ( k5_context ) {
  418.         krb5_free_context(k5_context);
  419.         k5_context = NULL;
  420.     }
  421.     /* create k5_context */
  422.     krb5_init_context(&k5_context);
  423. #ifndef MIT_CURRENT
  424.     krb5_init_ets(k5_context);
  425. #endif /* MIT_CURRENT */
  426.     memset(&k5_auth,0,sizeof(k5_auth));
  427.     if (auth_context) {
  428.         krb5_auth_con_free(k5_context, auth_context);
  429.         auth_context = 0;
  430.     }
  431. #ifdef CK_ENCRYPTION
  432.     if (k5_session_key) {
  433.         krb5_free_keyblock(k5_context, k5_session_key);
  434.         k5_session_key = 0;
  435.     }
  436. #endif /* ENCRYPTION */
  437. #endif /* KRB5 */
  438. #ifdef KRB4
  439. #ifdef CK_ENCRYPTION
  440.     /* Initialize buffers used for authentication */
  441.     memset(&k4_session_key, 0, sizeof(k4_session_key));
  442.     memset(&k4_challenge, 0, sizeof(k4_challenge));
  443. #endif /* ENCRYPTION */
  444. #endif /* KRB4 */
  445.     kstream_destroy();
  446.     auth_how = 0;
  447.     auth_crypt = 0;
  448.     auth_fwd = 0;
  449.     accept_complete = 0;
  450.     mutual_complete = 0;
  451.     authentication_version = AUTHTYPE_NULL;
  452. #ifdef CK_KERBEROS
  453. #ifdef RLOGCODE
  454.     rlog_encrypt = 0;
  455.     nstored = 0;
  456.     store_ptr = storage;
  457.     memset(storage,0,sizeof(storage));
  458. #endif /* RLOGCODE */
  459. #endif /* CK_KERBEROS */
  460. #ifdef CK_SRP
  461.     srp_waitresp = 0;
  462. #endif /* SRP */
  463.     /* create kstream from socket */
  464.     /* a kstream is simply a structure containing the socket handle */
  465.     /* and pointers to the appropriate functions for encryption,    */
  466.     /* decryption, and the like.                                    */
  467.     ctl.encrypt = auth_encrypt;
  468.     ctl.decrypt = auth_decrypt;
  469.     ctl.init = auth_init;
  470.     ctl.destroy = auth_destroy;
  471.     if (!kstream_create_from_fd(socket, &ctl, NULL))
  472.         return(0);
  473.     return(1);
  474. }
  475. int
  476. ck_tn_auth_valid()
  477. {
  478.     return(validUser);
  479. }
  480. /* C K _ K R B _ A U T H _ I N _ P R O G R E S S
  481.  *
  482.  * Is an authentication negotiation still in progress?
  483.  *
  484.  */
  485. int
  486. #ifdef CK_ANSIC
  487. ck_tn_auth_in_progress(void)
  488. #else
  489. ck_tn_auth_in_progress()
  490. #endif
  491. {
  492.     switch (authentication_version) {
  493.     case AUTHTYPE_AUTO:
  494.         return(1);
  495.     case AUTHTYPE_NULL:
  496.         return(0);
  497. #ifdef KRB4
  498.     case AUTHTYPE_KERBEROS_V4:
  499.         if (!accept_complete) {
  500.     debug(F100,"ck_auth_in_progress() Kerberos 4 !accept_complete",
  501.    "",0);
  502.             return(1);
  503. }
  504.         else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
  505.     debug(F100,"ck_auth_in_progress() Kerberos 4 !mutual_complete",
  506.    "",0);
  507.             return(1);
  508. }
  509.         else
  510.             return(0);
  511. #endif /* KRB4 */
  512. #ifdef KRB5
  513.     case AUTHTYPE_KERBEROS_V5:
  514.         if (!accept_complete) {
  515.     debug(F100,"ck_auth_in_progress() Kerberos 5 !accept_complete",
  516.    "",0);
  517.             return(1);
  518. }
  519.         else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
  520.     debug(F100,"ck_auth_in_progress() Kerberos 5 !mutual_complete",
  521.    "",0);
  522.             return(1);
  523. }
  524.         else
  525.             return(0);
  526. #endif /* KRB5 */
  527. #ifdef CK_SRP
  528.     case AUTHTYPE_SRP:
  529.         if (!accept_complete || srp_waitresp)
  530.             return(1);
  531.         else
  532.             return(0);
  533. #endif /* CK_SRP */
  534. #ifdef NTLM
  535.     case AUTHTYPE_NTLM:
  536.         if (!accept_complete) {
  537.     debug(F100,"ck_auth_in_progress() NTLM !accept_complete",
  538.    "",0);
  539.             return(1);
  540. }
  541.         else
  542.             return(0);
  543. #endif /* NTLM */
  544.     case AUTHTYPE_SSL:
  545.         if (!accept_complete) {
  546.     debug(F100,"ck_auth_in_progress() SSL !accept_complete",
  547.    "",0);
  548.             return(1);
  549. }
  550.         else
  551.             return(0);
  552.     default:
  553.         return(0);
  554.     }
  555.     return(0);
  556. }
  557. /*  C K _ K R B _ T N _ A U T H _ R E Q U E S T
  558.  *
  559.  *  Builds a Telnet Authentication Send Negotiation providing the
  560.  *  list of supported authentication methods.  To be used only
  561.  *  when accepting incoming connections as only the server (DO) side of the
  562.  *  Telnet negotiation is allowed to send an AUTH SEND.
  563.  *
  564.  *  Returns: 0 on success and -1 on failure
  565.  */
  566. int
  567. #ifdef CK_ANSIC
  568. ck_tn_auth_request(void)
  569. #else
  570. ck_tn_auth_request()
  571. #endif
  572. {
  573.     static unsigned char str_request[64] = { IAC, SB,
  574.                                                  TELOPT_AUTHENTICATION,
  575.                                                  TELQUAL_SEND };
  576.     int i = 4, rc = -1;
  577. #ifdef CK_SSL
  578.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  579. return(0);
  580.     }
  581. #endif /* CK_SSL */
  582.     if ( deblog || tn_deb || debses )
  583.         strcpy(tn_msg,"TELNET SENT SB AUTHENTICATION SEND ");
  584.     /* Create a list of acceptable Authentication types to send to */
  585.     /* the client and let it choose find one that we support       */
  586.     /* For those authentication methods that support Encryption or */
  587.     /* Credentials Forwarding we must send all of the appropriate  */
  588.     /* combinations based upon the state of                        */
  589.     /* TELOPT_x_MODE(TELOPT_ENCRYPTION) and forward_flag.          */
  590.     if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
  591.         /* Microsoft's Telnet client won't perform authentication if */
  592.         /* NTLM is not first.                                        */
  593. #ifdef NTLM
  594.         if ( ck_ntlm_is_valid() ) {
  595.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  596.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  597.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  598.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  599.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  600.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  601.             {
  602.                 str_request[i++] = AUTHTYPE_NTLM;
  603.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  604.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  605.                 if ( deblog || tn_deb || debses )
  606.                     strcat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ");
  607.                 i++;
  608.             }
  609.         }
  610. #endif /* NTLM */
  611. #ifdef KRB5
  612.         if (1
  613. #ifdef OS2
  614.              && hKRB5_32
  615. #endif /* OS2 */
  616.              ) {
  617. #ifdef CK_ENCRYPTION
  618. #ifdef USE_INI_CRED_FWD
  619.             if ( forward_flag &&
  620.  (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  621.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  622.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  623.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  624.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  625.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) )
  626.             {
  627.                 str_request[i++] = AUTHTYPE_KERBEROS_V5;
  628.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  629.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  630.                 str_request[i] |= INI_CRED_FWD_ON;
  631.                 if ( deblog || tn_deb || debses )
  632.  strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  633.                 i++;
  634.             }
  635. #endif /* USE_INI_CRED_FWD */
  636.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  637.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  638.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  639.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  640.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  641.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  642.                 str_request[i++] = AUTHTYPE_KERBEROS_V5;
  643.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  644.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  645.                 if ( deblog || tn_deb || debses )
  646.  strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  647.                 i++;
  648.             }
  649. #endif /* CK_ENCRYPTION */
  650.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  651.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  652.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  653.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  654.             {
  655. #ifdef CK_ENCRYPTION
  656.                 /* Can't perform mutual authentication without encryption */
  657.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  658.                      tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  659.                     str_request[i++] = AUTHTYPE_KERBEROS_V5;
  660.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  661.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  662.                     if ( deblog || tn_deb || debses )
  663.                         strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ");
  664.                     i++;
  665.                 }
  666. #endif /* CK_ENCRYPTION */
  667.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  668.                      tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  669.                     str_request[i++] = AUTHTYPE_KERBEROS_V5;
  670.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  671.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  672.                     if ( deblog || tn_deb || debses )
  673.                         strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ");
  674.                     i++;
  675.                 }
  676.             }
  677.         }
  678. #endif /* KRB5 */
  679. #ifdef KRB4
  680.         if (1
  681. #ifdef OS2
  682.              && hKRB4_32
  683. #endif /* OS2 */
  684.              ) {
  685. #ifdef CK_ENCRYPTION
  686.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  687.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  688.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  689.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  690.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  691.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) )
  692.             {
  693.                 str_request[i++] = AUTHTYPE_KERBEROS_V4;
  694.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  695.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  696.                 if ( deblog || tn_deb || debses )
  697.  strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  698.                 i++;
  699.             }
  700. #endif /* CK_ENCRYPTION */
  701.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  702.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  703.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  704.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  705.             {
  706. #ifdef CK_ENCRYPTION
  707.                 /* Can't perform mutual authentication without encryption */
  708.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  709.                      tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  710.                     str_request[i++] = AUTHTYPE_KERBEROS_V4;
  711.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  712.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  713.                     if ( deblog || tn_deb || debses )
  714.                         strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ");
  715.                     i++;
  716.                 }
  717. #endif /* CK_ENCRYPTION */
  718.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  719.                      tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  720.                     str_request[i++] = AUTHTYPE_KERBEROS_V4;
  721.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  722.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  723.                     if ( deblog || tn_deb || debses )
  724.                         strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ");
  725.                     i++;
  726.                 }
  727.             }
  728.         }
  729. #endif /* KRB4 */
  730. #ifdef CK_SRP
  731.         if ( 1
  732. #ifdef SRPDLL
  733.              && hSRP
  734. #endif /* SRPDLL */
  735.              ) {
  736. #ifndef PRE_SRP_1_4_5
  737.           /* Dont' do this yet.  SRP when it uses the ENCRYPT_USING_TELOPT   */
  738.           /* flag it must perform a checksum of the auth-type-pair but there */
  739.           /* is no mechansim to do that yet.                                 */
  740. #ifdef CK_ENCRYPTION
  741.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  742.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  743.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  744.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  745.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  746.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  747.                 str_request[i++] = AUTHTYPE_SRP;
  748.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  749.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  750.                 if ( deblog || tn_deb || debses )
  751.                     strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT ");
  752.                 i++;
  753.             }
  754. #endif /* CK_ENCRYPTION */
  755. #endif /* PRE_SRP_1_4_5 */
  756.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  757.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  758.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  759.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  760.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  761.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  762.             {
  763.                 str_request[i++] = AUTHTYPE_SRP;
  764.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  765.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  766.                 if ( deblog || tn_deb || debses )
  767.                     strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ");
  768.                 i++;
  769.             }
  770.         }
  771. #endif /* SRP */
  772. #ifdef CK_SSL
  773.         if ( 1
  774. #ifdef SSLDLL
  775.              && ck_ssleay_is_installed()
  776. #endif /* SSLDLL */
  777.              && !tls_active_flag && !ssl_active_flag && ssl_initialized
  778.              ) {
  779.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  780.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  781.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  782.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  783.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  784.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  785.             {
  786.                 str_request[i++] = AUTHTYPE_SSL;
  787.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  788.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  789.                 if ( deblog || tn_deb || debses )
  790.                     strcat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ");
  791.                 i++;
  792.             }
  793.         }
  794. #endif /* CK_SSL */
  795.     } else {
  796.         int j;
  797.         for ( j=0;
  798.               j<AUTHTYPLSTSZ && auth_type_user[j] != AUTHTYPE_NULL;
  799.               j++) {
  800. #ifdef NTLM
  801.         if (auth_type_user[j] == AUTHTYPE_NTLM &&
  802. ck_ntlm_is_valid()) {
  803.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  804.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  805.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  806.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  807.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  808.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  809.             {
  810.                 str_request[i++] = AUTHTYPE_NTLM;
  811.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  812.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  813.                 if ( deblog || tn_deb || debses )
  814.                     strcat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ");
  815.                 i++;
  816.             }
  817.         }
  818. #endif /* NTLM */
  819. #ifdef CK_SSL
  820.         if ( auth_type_user[j] == AUTHTYPE_SSL
  821. #ifdef SSLDLL
  822.              && ck_ssleay_is_installed()
  823. #endif /* SSLDLL */
  824.              && !tls_active_flag && !ssl_active_flag && ssl_initialized
  825.              )
  826.         {
  827.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  828.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  829.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  830.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  831.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  832.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  833.             {
  834.                 str_request[i++] = AUTHTYPE_SSL;
  835.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  836.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  837.                 if ( deblog || tn_deb || debses )
  838.                     strcat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ");
  839.                 i++;
  840.             }
  841.         }
  842. #endif /* CK_SSL */
  843. #ifdef CK_SRP
  844.         if ( auth_type_user[j] == AUTHTYPE_SRP
  845. #ifdef SRPDLL
  846.              && hSRP
  847. #endif /* SRPDLL */
  848.              )
  849.         {
  850. #ifndef PRE_SRP_1_4_5
  851.           /* Dont' do this yet.  SRP when it uses the ENCRYPT_USING_TELOPT   */
  852.           /* flag it must perform a checksum of the auth-type-pair but there */
  853.           /* is no mechansim to do that yet.                                 */
  854. #ifdef CK_ENCRYPTION
  855.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  856.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  857.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  858.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  859.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  860.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  861.                 str_request[i++] = AUTHTYPE_SRP;
  862.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  863.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  864.                 if ( deblog || tn_deb || debses )
  865.                     strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT ");
  866.                 i++;
  867.             }
  868. #endif /* CK_ENCRYPTION */
  869. #endif /* PRE_SRP_1_4_5 */
  870.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  871.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  872.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  873.                    tn_auth_how == TN_AUTH_HOW_ONE_WAY)  &&
  874.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  875.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  876.             {
  877.                 str_request[i++] = AUTHTYPE_SRP;
  878.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  879.                 str_request[i] |= AUTH_ENCRYPT_OFF;
  880.                 if ( deblog || tn_deb || debses )
  881.                     strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ");
  882.                 i++;
  883.             }
  884.         }
  885. #endif /* SRP */
  886. #ifdef KRB5
  887.         if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V5
  888. #ifdef OS2
  889.              && hKRB5_32
  890. #endif /* OS2 */
  891.              )
  892.         {
  893. #ifdef CK_ENCRYPTION
  894. #ifdef USE_INI_CRED_FWD
  895.             if ( forward_flag &&
  896.  (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  897.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  898.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  899.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  900.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  901.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  902.                 str_request[i++] = AUTHTYPE_KERBEROS_V5;
  903.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  904.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  905.                 str_request[i] |= INI_CRED_FWD_ON;
  906.                 if ( deblog || tn_deb || debses )
  907.  strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  908.                 i++;
  909.             }
  910. #endif /* USE_INI_CRED_FWD */
  911.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  912.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  913.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  914.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  915.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  916.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  917.                 str_request[i++] = AUTHTYPE_KERBEROS_V5;
  918.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  919.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  920.                 if ( deblog || tn_deb || debses )
  921.  strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  922.                 i++;
  923.             }
  924. #endif /* CK_ENCRYPTION */
  925.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  926.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  927.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  928.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  929.             {
  930. #ifdef CK_ENCRYPTION
  931.                 /* Can't perform mutual authentication without encryption */
  932.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  933.                      tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  934.                     str_request[i++] = AUTHTYPE_KERBEROS_V5;
  935.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  936.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  937.                     if ( deblog || tn_deb || debses )
  938.                         strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ");
  939.                     i++;
  940.                 }
  941. #endif /* CK_ENCRYPTION */
  942.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  943.                      tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  944.                     str_request[i++] = AUTHTYPE_KERBEROS_V5;
  945.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  946.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  947.                     if ( deblog || tn_deb || debses )
  948.                         strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ");
  949.                     i++;
  950.                 }
  951.             }
  952.         }
  953. #endif /* KRB5 */
  954. #ifdef KRB4
  955.         if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V4
  956. #ifdef OS2
  957.              && hKRB4_32
  958. #endif /* OS2 */
  959.              )
  960.         {
  961. #ifdef CK_ENCRYPTION
  962.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  963.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
  964.                  (tn_auth_how == TN_AUTH_HOW_ANY ||
  965.                    tn_auth_how == TN_AUTH_HOW_MUTUAL)  &&
  966.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  967.                    tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  968.                 str_request[i++] = AUTHTYPE_KERBEROS_V4;
  969.                 str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  970.                 str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  971.                 if ( deblog || tn_deb || debses )
  972.  strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
  973.                 i++;
  974.             }
  975. #endif /* CK_ENCRYPTION */
  976.             if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  977.                   TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
  978.                  (tn_auth_enc == TN_AUTH_ENC_ANY ||
  979.                    tn_auth_enc == TN_AUTH_ENC_NONE) )
  980.             {
  981. #ifdef CK_ENCRYPTION
  982.                 /* Can't perform mutual authentication without encryption */
  983.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  984.                      tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  985.                     str_request[i++] = AUTHTYPE_KERBEROS_V4;
  986.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  987.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  988.                     if ( deblog || tn_deb || debses )
  989.                         strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ");
  990.                     i++;
  991.                 }
  992. #endif /* CK_ENCRYPTION */
  993.                 if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  994.                      tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  995.                     str_request[i++] = AUTHTYPE_KERBEROS_V4;
  996.                     str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  997.                     str_request[i] |= AUTH_ENCRYPT_OFF;
  998.                     if ( deblog || tn_deb || debses )
  999.                         strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ");
  1000.                     i++;
  1001.                 }
  1002.             }
  1003.         }
  1004. #endif /* KRB4 */
  1005.         }
  1006.     }
  1007.     str_request[i++] = IAC;
  1008.     str_request[i++] = SE;
  1009.     if ( deblog || tn_deb || debses ) {
  1010.         strcat(tn_msg,"IAC SE");
  1011. debug(F100,tn_msg,"",0);
  1012. if (tn_deb || debses) tn_debug(tn_msg);
  1013.     }
  1014.     /* Send data */
  1015.     rc = ttol((CHAR *)str_request, i);
  1016.     if ( rc == i )
  1017.         return(0);
  1018.     else
  1019.         return(-1);
  1020. }
  1021. #ifdef CK_ENCRYPTION
  1022. VOID
  1023. ck_tn_enc_start()
  1024. {
  1025.     if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
  1026.         return;
  1027.     if (!TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop &&
  1028.  (!encrypt_is_decrypting() || !encrypt_is_encrypting())) {
  1029. debug(F110,"ck_tn_enc_start","nothing to do",0);
  1030.         return;
  1031.     }
  1032.     TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
  1033.     if (TELOPT_ME(TELOPT_ENCRYPTION) && !encrypt_is_encrypting()) {
  1034. debug(F110,"ck_tn_enc_start","encrypt_request_start",0);
  1035.         encrypt_request_start();
  1036.     }
  1037.     if (TELOPT_U(TELOPT_ENCRYPTION) && !encrypt_is_decrypting()) {
  1038. debug(F110,"ck_tn_enc_start","encrypt_send_request_start",0);
  1039.         encrypt_send_request_start();
  1040.     }
  1041.     tn_wait("encrypt start");
  1042.     tn_push();
  1043. }
  1044. VOID
  1045. ck_tn_enc_stop()
  1046. {
  1047.     if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
  1048.         return;
  1049.     if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop ||
  1050.  !(encrypt_is_decrypting() || encrypt_is_encrypting())) {
  1051. debug(F110,"ck_tn_enc_stop","nothing to do",0);
  1052.       return;
  1053.     }
  1054.     TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
  1055.     if (TELOPT_U(TELOPT_ENCRYPTION) && encrypt_is_decrypting()) {
  1056. debug(F110,"ck_tn_enc_stop","encrypt_send_request_end",0);
  1057.         encrypt_send_request_end();
  1058.     }
  1059.     if (TELOPT_ME(TELOPT_ENCRYPTION) && encrypt_is_encrypting()) {
  1060. debug(F110,"ck_tn_enc_stop","encrypt_send_end",0);
  1061.         encrypt_send_end();
  1062.     }
  1063.     tn_wait("encrypt stop");
  1064.     tn_push();
  1065. }
  1066. #endif /* CK_ENCRYPTION */
  1067. /*  C K _ K R B _ T N _ S B _ A U T H
  1068.  *  An interface between the C-Kermit Telnet Command Parser and the Authent-
  1069.  *  ication option parser implemented in the Kerberos Telnet client.
  1070.  *
  1071.  *  sb   - the subnegotiation as calculated in ckcnet.c
  1072.  *  len  - the length of the buffer
  1073.  *
  1074.  *  Returns: 0 on success and -1 on failure
  1075.  */
  1076. int
  1077. #ifdef CK_ANSIC
  1078. ck_tn_sb_auth(char * sb, int len)
  1079. #else /* CK_ANSIC */
  1080. ck_tn_sb_auth(sb,len) char * sb; int len;
  1081. #endif /* CK_ANSIC */
  1082. {
  1083.     /* auth_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
  1084.     /* and it wants the length to exclude the IAC SE bytes                  */
  1085.     char buf[1024];
  1086.     int rc = -1;
  1087.     buf[0] = SB;
  1088.     memcpy( &buf[1], sb, len );
  1089.     buf[len+1] = '';
  1090.     rc = auth_parse(buf,len+1-2);
  1091.     debug(F111,"ck_tn_sb_auth","rc",rc);
  1092.     if (rc == AUTH_FAILURE) {
  1093.         authentication_version = AUTHTYPE_NULL;
  1094. #ifdef OS2
  1095.         ipadl25();
  1096. #endif /* OS2 */
  1097.         return(-1);
  1098.     }
  1099. #ifdef OS2
  1100.     ipadl25();
  1101. #endif /* OS2 */
  1102.     return(0);
  1103. }
  1104. /*  C K _ K R B _ T N _ S B _ E N C R Y P T
  1105.  *  An interface between the C-Kermit Telnet Command Parser and the Encryption
  1106.  *  option parser implemented in the Kerberos Telnet client.
  1107.  *
  1108.  *  sb   - the subnegotiation as calculated in ckcnet.c
  1109.  *  len  - the length of the buffer
  1110.  *
  1111.  *  Returns: Always returns 0 for success since encrypt_parse is void
  1112.  */
  1113. int
  1114. #ifdef CK_ANSIC
  1115. ck_tn_sb_encrypt(char * sb, int len)
  1116. #else
  1117. ck_tn_sb_encrypt(sb,len) char * sb; int len;
  1118. #endif /* CK_ANSIC */
  1119. {
  1120.     /* encrypt_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
  1121.     /* and it wants the length to exclude the IAC SE bytes                  */
  1122. #ifdef CK_ENCRYPTION
  1123.     char buf[1024];
  1124.     buf[0] = SB;
  1125.     memcpy( &buf[1], sb, len );
  1126.     buf[len+1] = '';
  1127.     if (encrypt_parse(buf,len+1-2) < 0)
  1128. return(-1);
  1129.     /* This is a hack.  It does not belong here but should really be in */
  1130.     /* encrypt_parse() but in K95 the encrypt_parse() routine does not  */
  1131.     /* have access to the telopt_states array.                          */
  1132.     if ( buf[1] == ENCRYPT_REQEND )
  1133.         TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
  1134.     else if ( buf[1] == ENCRYPT_REQSTART )
  1135.         TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
  1136. #ifdef OS2
  1137.     ipadl25();
  1138. #endif /* OS2 */
  1139. #endif /* ENCRYPTION */
  1140.     return(0);
  1141. }
  1142. /*  C K _ K R B _ E N C R Y P T I N G
  1143.  *  Returns 1 if we are encrypting and 0 if we are not
  1144.  */
  1145. int
  1146. #ifdef CK_ANSIC
  1147. ck_tn_encrypting(VOID)
  1148. #else /* CK_ANSIC */
  1149. ck_tn_encrypting()
  1150. #endif /* CK_ANSIC */
  1151. {
  1152. #ifdef CK_ENCRYPTION
  1153.     if ( g_kstream == NULL )
  1154.         return(0);
  1155.     if ( g_kstream->encrypt && encrypt_is_encrypting()) {
  1156. debug(F111,"ck_tn_encrypting","encrypting",
  1157.        g_kstream->encrypt_type);
  1158.         return(g_kstream->encrypt_type);
  1159.     }
  1160. #endif /* CK_ENCRYPTION */
  1161.     debug(F110,"ck_tn_encrypting","not encrypting",0);
  1162.     return(0);
  1163. }
  1164. /*  C K _ K R B _ D E C R Y P T I N G
  1165.  *  Returns 1 if we are decrypting and 0 if we are not
  1166.  */
  1167. int
  1168. #ifdef CK_ANSIC
  1169. ck_tn_decrypting(VOID)
  1170. #else
  1171. ck_tn_decrypting()
  1172. #endif /* CK_ANSIC */
  1173. {
  1174. #ifdef CK_ENCRYPTION
  1175.     if ( g_kstream == NULL )
  1176.         return(0);
  1177.     if ( g_kstream->decrypt && encrypt_is_decrypting()) {
  1178. debug(F111,"ck_tn_decrypting","decrypting",
  1179.        g_kstream->decrypt_type);
  1180.         return(g_kstream->decrypt_type);
  1181.     }
  1182. #endif /* CK_ENCRYPTION */
  1183.     debug(F110,"ck_tn_decrypting","not decrypting",0);
  1184.     return(0);
  1185. }
  1186. /*  C K _ K R B _ A U T H E N T I C A T E D
  1187.  *  Returns the authentication type: AUTHTYPE_NULL, AUTHTYPE_KERBEROS4,
  1188.  *  or AUTHTYPE_KERBEROS5, AUTHTYPE_SRP, ... (see ckctel.h)
  1189.  */
  1190. int
  1191. #ifdef CK_ANSIC
  1192. ck_tn_authenticated(VOID)
  1193. #else
  1194. ck_tn_authenticated()
  1195. #endif
  1196. {
  1197.     return(authentication_version);
  1198. }
  1199. /*  C K _ K R B _ E N C R Y P T
  1200.  *  encrypts n characters in s if we are encrypting
  1201.  */
  1202. VOID
  1203. #ifdef CK_ANSIC
  1204. ck_tn_encrypt( char * s, int n )
  1205. #else
  1206. ck_tn_encrypt( s,n ) char * s; int n;
  1207. #endif
  1208. {
  1209. #ifdef CK_ENCRYPTION
  1210.     struct kstream_data_block i;
  1211.     if (g_kstream->encrypt && encrypt_is_encrypting()) {
  1212. #ifdef DEBUG
  1213.       hexdump("from plaintext", s, n);
  1214. #endif
  1215.         i.ptr = s;
  1216.         i.length = n;
  1217.         g_kstream->encrypt(&i, NULL);
  1218. #ifdef DEBUG
  1219.         hexdump("to cyphertext", s, n);
  1220. #endif
  1221.     }
  1222.     else debug(F101,"ck_tn_encrypt not encrypting","",n);
  1223. #endif /* ENCRYPTION */
  1224. }
  1225. /*  C K _ K R B _ D E C R Y P T
  1226.  *  decrypts n characters in s if we are decrypting
  1227.  */
  1228. VOID
  1229. #ifdef CK_ANSIC
  1230. ck_tn_decrypt( char * s, int n )
  1231. #else
  1232. ck_tn_decrypt( s,n ) char * s; int n;
  1233. #endif
  1234. {
  1235. #ifdef CK_ENCRYPTION
  1236.     struct kstream_data_block i;
  1237.     if (g_kstream->decrypt && encrypt_is_decrypting()) {
  1238. #ifdef DEBUG
  1239.         hexdump("from cyphertext", s, n);
  1240. #endif
  1241.         i.ptr = s;
  1242.         i.length = n;
  1243.         g_kstream->decrypt(&i, NULL);
  1244. #ifdef DEBUG
  1245.         hexdump("to plaintext", s, n);
  1246. #endif
  1247.     }
  1248.     else debug(F101,"ck_tn_decrypt not decrypting","",n);
  1249. #endif /* ENCRYPTION */
  1250. }
  1251. /*  S E N D K 5 A U T H S B
  1252.  *  Send a Kerberos 5 Authentication Subnegotiation to host and
  1253.  *  output appropriate Telnet Debug messages
  1254.  *
  1255.  *  type - Sub Negotiation type
  1256.  *  data - ptr to buffer containing data
  1257.  *  len  - len of buffer if not NUL terminated
  1258.  *
  1259.  *  returns number of characters sent or error value
  1260.  */
  1261. static int
  1262. #ifdef CK_ANSIC
  1263. SendK5AuthSB(int type, void *data, int len)
  1264. #else
  1265. SendK5AuthSB(type,data,len) int type; void *data; int len;
  1266. #endif
  1267. {
  1268.     int rc;
  1269.     unsigned char *p = str_data + 3;
  1270.     unsigned char *cd = (unsigned char *)data;
  1271.     extern int sstelnet;
  1272. #ifdef CK_SSL
  1273.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1274.         if (ttchk() < 0)
  1275.   return(0);
  1276.         else
  1277.   return(1);
  1278.     }
  1279. #endif /* CK_SSL */
  1280.     if ( type < 0 || type > 6 )         /* Check for invalid values */
  1281.         return(0);
  1282.     if (!cd) {
  1283.         cd = (unsigned char *)"";
  1284.         len = 0;
  1285.     }
  1286.     if (len == -1)                        /* Use strlen() for len */
  1287.         len = strlen((char *)cd);
  1288.     /* Construct Message */
  1289.     *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1290.     *p++ = AUTHTYPE_KERBEROS_V5;
  1291.     *p = AUTH_CLIENT_TO_SERVER;
  1292.     *p |= auth_how;
  1293. #ifdef CK_ENCRYPTION
  1294.     *p |= auth_crypt;
  1295. #endif
  1296. #ifdef USE_INI_CRED_FWD
  1297.     if (auth_fwd)
  1298.         *p |= INI_CRED_FWD_ON;
  1299. #endif /* USE_INI_CRED_FWD */
  1300.     p++;
  1301.     *p++ = type;
  1302.     while (len-- > 0) {
  1303.         if ((*p++ = *cd++) == IAC)
  1304.             *p++ = IAC;
  1305.     }
  1306.     *p++ = IAC;
  1307.     *p++ = SE;
  1308.     /* Handle Telnet Debugging Messages */
  1309.     if (deblog || tn_deb || debses) {
  1310.         int i;
  1311.         int deblen=p-str_data-2;
  1312.         char *s=NULL;
  1313.         int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1314.             (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF)
  1315. #ifdef USE_INI_CRED_FWD
  1316.               | (auth_fwd?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
  1317. #endif /* USE_INI_CRED_FWD */
  1318.                     ;
  1319.         switch (type) {
  1320.         case 0:
  1321.             s = "AUTH";
  1322.             break;
  1323.         case 1:
  1324.             s = "REJECT";
  1325.             break;
  1326.         case 2:
  1327.             s = "ACCEPT";
  1328.             break;
  1329.         case 3:
  1330.             s = "RESPONSE";
  1331.             break;
  1332.         case 4:
  1333.             s = "FORWARD";
  1334.             break;
  1335.         case 5:
  1336.             s = "FORWARD_ACCEPT";
  1337.             break;
  1338.         case 6:
  1339.             s = "FORWARD_REJECT";
  1340.             break;
  1341.         }
  1342. sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
  1343.                  TELOPT(TELOPT_AUTHENTICATION),
  1344.                  str_data[3] == TELQUAL_IS ? "IS" :
  1345.                  str_data[3] == TELQUAL_REPLY ? "REPLY" : "???",
  1346.                  authtype_names[authentication_version],
  1347.                  authmode_names[mode],
  1348.                  s);
  1349. #ifdef HEXDISP
  1350.         {
  1351.             int was_hex = 1;
  1352.             for ( i=7;i<deblen;i++ ) {
  1353.                 if ( str_data[i] < 32 || str_data[i] >= 127) {
  1354.                     sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
  1355.                     was_hex = 1;
  1356.                 } else {
  1357.                     sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
  1358.                     was_hex = 0;
  1359.                 }
  1360.                 strcat(tn_msg,hexbuf);
  1361.             }
  1362.             if ( !was_hex )
  1363.                 strcat(tn_msg,"" ");
  1364.         }
  1365. #else /* HEXDISP */
  1366.         memcpy(hexbuf,&str_data[7],deblen-7);
  1367.         hexbuf[deblen-7] = ' ';
  1368.         hexbuf[deblen-6] = '';
  1369.         strcat(tn_msg,hexbuf);
  1370. #endif /* HEXDISP */
  1371.         strcat(tn_msg,"IAC SE");
  1372. debug(F100,tn_msg,"",0);
  1373. if (tn_deb || debses) tn_debug(tn_msg);
  1374.     }
  1375.     /* Send data */
  1376.     rc = ttol((CHAR *)str_data, p - str_data);
  1377.     debug(F111,"SendK5AuthSB","ttol()",rc);
  1378.     return(rc);
  1379. }
  1380. /*  S E N D K 4 A U T H S B
  1381.  *  Send a Kerberos 4 Authentication Subnegotiation to host and
  1382.  *  output appropriate Telnet Debug messages
  1383.  *
  1384.  *  type - Sub Negotiation type
  1385.  *  data - ptr to buffer containing data
  1386.  *  len  - len of buffer if not NUL terminated
  1387.  *
  1388.  *  returns number of characters sent or error value
  1389.  */
  1390. static int
  1391. #ifdef CK_ANSIC
  1392. SendK4AuthSB(int type, void *data, int len)
  1393. #else
  1394. SendK4AuthSB(type,data,len) int type; void *data; int len;
  1395. #endif
  1396. {
  1397.     int rc;
  1398.     unsigned char *p = str_data + 3;
  1399.     unsigned char *cd = (unsigned char *)data;
  1400.     extern int sstelnet;
  1401.     int mode = (auth_how & AUTH_HOW_MASK) |
  1402.         (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF) ;
  1403.     if ( type < 0 || type > 4 )         /* Check for invalid values */
  1404.         return(0);
  1405. #ifdef CK_SSL
  1406.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1407.         if (ttchk() < 0)
  1408.   return(0);
  1409.         else
  1410.   return(1);
  1411.     }
  1412. #endif /* CK_SSL */
  1413.     if (!cd) {
  1414.         cd = (unsigned char *)"";
  1415.         len = 0;
  1416.     }
  1417.     if (len == -1)                        /* Use strlen() for len */
  1418.         len = strlen((char *)cd);
  1419.     /* Construct Message */
  1420.     *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1421.     *p++ = AUTHTYPE_KERBEROS_V4;
  1422.     *p = AUTH_CLIENT_TO_SERVER;
  1423.     *p |= mode;
  1424.     p++;
  1425.     *p++ = type;
  1426.     while (len-- > 0) {
  1427.         if ((*p++ = *cd++) == IAC)
  1428.             *p++ = IAC;
  1429.         }
  1430.     *p++ = IAC;
  1431.     *p++ = SE;
  1432.     /* Handle Telnet Debugging Messages */
  1433.     if (deblog || tn_deb || debses) {
  1434.         int i;
  1435.         int deblen=p-str_data-2;
  1436.         char *s=NULL;
  1437.         switch (type) {
  1438.         case 0:
  1439.             s = "AUTH";
  1440.             break;
  1441.         case 1:
  1442.             s = "REJECT";
  1443.             break;
  1444.         case 2:
  1445.             s = "ACCEPT";
  1446.             break;
  1447.         case 3:
  1448.             s = "CHALLENGE";
  1449.             break;
  1450.         case 4:
  1451.             s = "RESPONSE";
  1452.             break;
  1453.         }
  1454. sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
  1455.                  TELOPT(TELOPT_AUTHENTICATION),
  1456.                  str_data[3] == TELQUAL_IS ? "IS" :
  1457.                  (str_data[3] == TELQUAL_REPLY ? "REPLY" : "???"),
  1458.                  authtype_names[authentication_version],
  1459.                  authmode_names[mode],
  1460.                  s);
  1461. #ifdef HEXDISP
  1462.         {
  1463.             int was_hex = 1;
  1464.             for ( i=7;i<deblen;i++ ) {
  1465.                 if ( str_data[i] < 32 || str_data[i] >= 127) {
  1466.                     sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
  1467.                     was_hex = 1;
  1468.                 } else {
  1469.                     sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
  1470.                     was_hex = 0;
  1471.                 }
  1472.                 strcat(tn_msg,hexbuf);
  1473.             }
  1474.             if ( !was_hex )
  1475.                 strcat(tn_msg,"" ");
  1476.         }
  1477. #else /* HEXDISP */
  1478.         memcpy(hexbuf,&str_data[7],deblen-7);
  1479.         hexbuf[deblen-7] = ' ';
  1480.         hexbuf[deblen-6] = '';
  1481.         strcat(tn_msg,hexbuf);
  1482. #endif /* HEXDISP */
  1483.         strcat(tn_msg,"IAC SE");
  1484. debug(F100,tn_msg,"",0);
  1485. if (tn_deb || debses) tn_debug(tn_msg);
  1486.     }
  1487.     /* Send data */
  1488.     rc = ttol((CHAR *)str_data, p - str_data);
  1489.     debug(F111,"SendK4AuthSB","ttol()",rc);
  1490.     return(rc);
  1491. }
  1492. /*  S E N D S R P A U T H S B
  1493.  *  Send a SRP Authentication Subnegotiation to host and
  1494.  *  output appropriate Telnet Debug messages
  1495.  *
  1496.  *  type - Sub Negotiation type
  1497.  *  data - ptr to buffer containing data
  1498.  *  len  - len of buffer if not NUL terminated
  1499.  *
  1500.  *  returns number of characters sent or error value
  1501.  */
  1502. static int
  1503. #ifdef CK_ANSIC
  1504. SendSRPAuthSB(int type, void *data, int len)
  1505. #else
  1506. SendSRPAuthSB(type,data,len) int type; void *data; int len;
  1507. #endif
  1508. {
  1509.     int rc;
  1510.     unsigned char *p = str_data + 3;
  1511.     unsigned char *cd = (unsigned char *)data;
  1512.     extern int sstelnet;
  1513.     /* Check for invalid values */
  1514.     if ( type != SRP_EXP && type != SRP_RESPONSE &&
  1515.          type != SRP_REJECT && type != SRP_ACCEPT &&
  1516.          type != SRP_CHALLENGE && type != SRP_PARAMS &&
  1517.          type != SRP_AUTH)
  1518.         return(0);
  1519.     if (len == -1)                        /* Use strlen() for len */
  1520.         len = strlen((char *)cd);
  1521.     /* Construct Message */
  1522.     *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1523.     *p++ = AUTHTYPE_SRP;
  1524.     *p = AUTH_CLIENT_TO_SERVER;
  1525.     *p |= auth_how;
  1526. #ifdef CK_ENCRYPTION
  1527.     *p |= auth_crypt;
  1528. #endif
  1529.     p++;
  1530.     *p++ = type;
  1531.     while (len-- > 0) {
  1532.         if ((*p++ = *cd++) == IAC)
  1533.             *p++ = IAC;
  1534.         }
  1535.     *p++ = IAC;
  1536.     *p++ = SE;
  1537.     /* Handle Telnet Debugging Messages */
  1538.     if (deblog || tn_deb || debses) {
  1539.         int i;
  1540.         int deblen=p-str_data-2;
  1541.         char *s=NULL;
  1542.         int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1543.             (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
  1544.         switch (type) {
  1545.         case 0:
  1546.             s = "AUTH";
  1547.             break;
  1548.         case 1:
  1549.             s = "REJECT";
  1550.             break;
  1551.         case 2:
  1552.             s = "ACCEPT";
  1553.             break;
  1554.         case 3:
  1555.             s = "CHALLENGE";
  1556.             break;
  1557.         case 4:
  1558.             s = "RESPONSE";
  1559.             break;
  1560.         case 5:
  1561.             s = "FORWARD";
  1562.             break;
  1563.         case 6:
  1564.             s = "FORWARD_ACCEPT";
  1565.             break;
  1566.         case 7:
  1567.             s = "FORWARD_REJECT";
  1568.             break;
  1569.         case 8:
  1570.             s = "EXP";
  1571.             break;
  1572.         case 9:
  1573.             s = "PARAMS";
  1574.             break;
  1575.         }
  1576. sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
  1577.                  TELOPT(TELOPT_AUTHENTICATION),
  1578.                  str_data[3] == TELQUAL_REPLY ? "REPLY" :
  1579.                  str_data[3] == TELQUAL_IS ? "IS" : "???",
  1580.                  authtype_names[authentication_version],
  1581.                  authmode_names[mode],
  1582.                  s);
  1583. #ifdef HEXDISP
  1584.         {
  1585.             int was_hex = 1;
  1586.             for ( i=7;i<deblen;i++ ) {
  1587.                 if ( str_data[i] < 32 || str_data[i] >= 127) {
  1588.                     sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
  1589.                     was_hex = 1;
  1590.                 } else {
  1591.                     sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
  1592.                     was_hex = 0;
  1593.                 }
  1594.                 strcat(tn_msg,hexbuf);
  1595.             }
  1596.             if ( !was_hex )
  1597.                 strcat(tn_msg,"" ");
  1598.         }
  1599. #else /* HEXDISP */
  1600.         memcpy(hexbuf,&str_data[7],deblen-7);
  1601.         hexbuf[deblen-7] = ' ';
  1602.         hexbuf[deblen-6] = '';
  1603.         strcat(tn_msg,hexbuf);
  1604. #endif /* HEXDISP */
  1605.         strcat(tn_msg,"IAC SE");
  1606. debug(F100,tn_msg,"",0);
  1607. if (tn_deb || debses) tn_debug(tn_msg);
  1608.     }
  1609.     /* Send data */
  1610.     rc = ttol((CHAR *)str_data, p - str_data);
  1611.     return(rc);
  1612. }
  1613. #ifdef CK_ENCRYPTION
  1614. /*
  1615.  * Function: Enable or disable the encryption process.
  1616.  *
  1617.  * Parameters:
  1618.  * enable - TRUE to enable, FALSE to disable.
  1619.  */
  1620. static VOID
  1621. #ifdef CK_ANSIC
  1622. auth_encrypt_enable(BOOL enable)
  1623. #else
  1624. auth_encrypt_enable(enable) BOOL enable;
  1625. #endif
  1626. {
  1627.   encrypt_flag = enable;
  1628. }
  1629. #endif
  1630. /*
  1631.  * Function: Abort the authentication process
  1632.  *
  1633.  * Parameters:
  1634.  */
  1635. static VOID
  1636. #ifdef CK_ANSIC
  1637. auth_abort(char *errmsg, long r)
  1638. #else
  1639. auth_abort(errmsg,r) char *errmsg; long r;
  1640. #endif
  1641. {
  1642.     char buf[9];
  1643.     extern int sstelnet;
  1644. #ifdef CK_SSL
  1645.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1646. return;
  1647.     }
  1648. #endif /* CK_SSL */
  1649.     debug(F111,"auth_abort",errmsg,r);
  1650.     /* Construct Telnet Debugging messages */
  1651.     if (deblog || tn_deb || debses) {
  1652. sprintf(tn_msg,"TELNET SENT SB %s IS %s %s IAC SE",
  1653.                  TELOPT(TELOPT_AUTHENTICATION),
  1654.                  authtype_names[AUTHTYPE_NULL],
  1655.                  authtype_names[AUTHTYPE_NULL]);
  1656. debug(F100,tn_msg,"",0);
  1657. if (tn_deb || debses) tn_debug(tn_msg);
  1658.     }
  1659.     /* Construct the Abort message to send to the host   */
  1660.     /* Basicly we change the authentication type to NULL */
  1661.     sprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
  1662.              sstelnet ? TELQUAL_REPLY : TELQUAL_IS, AUTHTYPE_NULL,
  1663.              AUTHTYPE_NULL, IAC, SE);
  1664.     ttol((CHAR *)buf, 8);
  1665.     /* If there is an error message, and error number construct */
  1666.     /* an explanation to display to the user                    */
  1667.     if (errmsg != NULL) {
  1668.         ckstrncpy(strTmp, errmsg, AUTHTMPBL);
  1669.     } else
  1670.         strTmp[0] = '';
  1671.     if (r != AUTH_SUCCESS) {
  1672.         strcat(strTmp, "rn");
  1673. #ifdef KRB4
  1674.         if ( authentication_version == AUTHTYPE_KERBEROS_V4 ) {
  1675.             strcat(strTmp, (char *)krb_get_err_text_entry(r));
  1676.             debug(F111,"auth_abort",(char *)krb_get_err_text_entry(r),r);
  1677.         }
  1678. #endif
  1679. #ifdef KRB5
  1680.         if ( authentication_version == AUTHTYPE_KERBEROS_V5 ) {
  1681.             strcat(strTmp, error_message(r));
  1682.             debug(F111,"auth_abort",error_message(r),r);
  1683.         }
  1684. #endif
  1685.     }
  1686.     printf("Authentication failed: %srn",strTmp);
  1687. #ifdef CKSYSLOG
  1688.     if (ckxsyslog >= SYSLG_LI && ckxlogging) {
  1689.         cksyslog(SYSLG_LI, 0, "Telnet authentication failure",
  1690.                   (char *) szUserNameRequested,
  1691.                   strTmp);
  1692.     }
  1693. #endif /* CKSYSLOG */
  1694.     authentication_version = AUTHTYPE_NULL;
  1695. }
  1696. /*
  1697.  * Function: Copy data to buffer, doubling IAC character if present.
  1698.  *
  1699.  */
  1700. static int
  1701. #ifdef CK_ANSIC
  1702. copy_for_net(unsigned char *to, unsigned char *from, int c)
  1703. #else
  1704. copy_for_net(to,from,c) unsigned char *to; unsigned char *from; int c;
  1705. #endif
  1706. {
  1707.     int n;
  1708.     n = c;
  1709.     debug(F111,"copy_for_net","before",n);
  1710.     while (c-- > 0) {
  1711.         if ((*to++ = *from++) == IAC) {
  1712.             n++;
  1713.             *to++ = IAC;
  1714.         }
  1715.     }
  1716.     debug(F111,"copy_for_net","after",n);
  1717.     return n;
  1718. }
  1719. #ifdef CK_SSL
  1720. /*  S E N D S S L A U T H S B
  1721.  *  Send a SSL Authentication Subnegotiation to host and
  1722.  *  output appropriate Telnet Debug messages
  1723.  *
  1724.  *  type - Sub Negotiation type
  1725.  *  data - ptr to buffer containing data
  1726.  *  len  - len of buffer if not NUL terminated
  1727.  *
  1728.  *  returns number of characters sent or error value
  1729.  */
  1730. int
  1731. #ifdef CK_ANSIC
  1732. SendSSLAuthSB(int type, void *data, int len)
  1733. #else
  1734. SendSSLAuthSB(type,data,len) int type; void *data; int len;
  1735. #endif
  1736. {
  1737.     int rc;
  1738.     unsigned char *p = str_data + 3;
  1739.     unsigned char *cd = (unsigned char *)data;
  1740.     extern int sstelnet;
  1741.     /* Check for invalid values */
  1742.     if ( type != SSL_START && type != SSL_ACCEPT &&
  1743.          type != SSL_REJECT)
  1744.         return(0);
  1745.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1746.         if (ttchk() < 0)
  1747.   return(0);
  1748.         else
  1749.   return(1);
  1750.     }
  1751.     if (len == -1)                        /* Use strlen() for len */
  1752.         len = strlen((char *)cd);
  1753.     /* Construct Message */
  1754.     *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1755.     *p++ = AUTHTYPE_SSL;
  1756.     *p = AUTH_CLIENT_TO_SERVER;
  1757.     *p |= auth_how;
  1758. #ifdef CK_ENCRYPTION
  1759.     *p |= auth_crypt;
  1760. #endif
  1761.     p++;
  1762.     *p++ = type;
  1763.     while (len-- > 0) {
  1764.         if ((*p++ = *cd++) == IAC)
  1765.             *p++ = IAC;
  1766.         }
  1767.     *p++ = IAC;
  1768.     *p++ = SE;
  1769.     /* Handle Telnet Debugging Messages */
  1770.     if (deblog || tn_deb || debses) {
  1771.         int i;
  1772.         int deblen=p-str_data-2;
  1773.         char *s=NULL;
  1774.         int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1775.             (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
  1776.         switch (type) {
  1777.         case SSL_START:
  1778.             s = "START";
  1779.             break;
  1780.         case SSL_ACCEPT:
  1781.             s = "ACCEPT";
  1782.             break;
  1783.         case SSL_REJECT:
  1784.             s = "REJECT";
  1785.             break;
  1786.         }
  1787. sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
  1788.                  TELOPT(TELOPT_AUTHENTICATION),
  1789.                  str_data[3] == TELQUAL_REPLY ? "REPLY" :
  1790.                  str_data[3] == TELQUAL_IS ? "IS" : "???",
  1791.                  authtype_names[authentication_version],
  1792.                  authmode_names[mode],
  1793.                  s);
  1794. #ifdef HEXDISP
  1795.         {
  1796.             int was_hex = 1;
  1797.             for ( i=7;i<deblen;i++ ) {
  1798.                 if ( str_data[i] < 32 || str_data[i] >= 127) {
  1799.                     sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
  1800.                     was_hex = 1;
  1801.                 } else {
  1802.                     sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
  1803.                     was_hex = 0;
  1804.                 }
  1805.                 strcat(tn_msg,hexbuf);
  1806.             }
  1807.             if ( !was_hex )
  1808.                 strcat(tn_msg,"" ");
  1809.         }
  1810. #else /* HEXDISP */
  1811.         memcpy(hexbuf,&str_data[7],deblen-7);
  1812.         hexbuf[deblen-7] = ' ';
  1813.         hexbuf[deblen-6] = '';
  1814.         strcat(tn_msg,hexbuf);
  1815. #endif /* HEXDISP */
  1816.         strcat(tn_msg,"IAC SE");
  1817. debug(F100,tn_msg,"",0);
  1818. if (tn_deb || debses) tn_debug(tn_msg);
  1819.     }
  1820.     /* Send data */
  1821.     rc = ttol((CHAR *)str_data, p - str_data);
  1822.     return(rc);
  1823. }
  1824. #endif  /* CK_SSL */
  1825. int
  1826. tn_how_ok(int how)
  1827. {
  1828.     switch ( tn_auth_how ) {
  1829.     case TN_AUTH_HOW_ANY:
  1830.         return(1);
  1831.     case TN_AUTH_HOW_ONE_WAY:
  1832.         return((how & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY);
  1833.     case TN_AUTH_HOW_MUTUAL:
  1834.         return((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL);
  1835.     default:
  1836.         return(0);
  1837.     }
  1838. }
  1839. int
  1840. tn_enc_ok(int enc)
  1841. {
  1842.     switch ( tn_auth_enc ) {
  1843.     case TN_AUTH_ENC_ANY:
  1844.         return(1);
  1845.     case TN_AUTH_ENC_NONE:
  1846.         return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_OFF);
  1847.     case TN_AUTH_ENC_TELOPT:
  1848.         return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT);
  1849.     case TN_AUTH_ENC_EXCH:
  1850.         return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_AFTER_EXCHANGE);
  1851.     default:
  1852.         return(0);
  1853.     }
  1854. }
  1855. static int
  1856. atok(int at) {
  1857.     int i;
  1858.     if ( auth_type_user[0] == AUTHTYPE_AUTO )
  1859.         return(1);
  1860.     if ( auth_type_user[0] == AUTHTYPE_NULL )
  1861.         return(0);
  1862.     for ( i=0;
  1863.           i<AUTHTYPLSTSZ && auth_type_user[i] != AUTHTYPE_NULL;
  1864.           i++ ) {
  1865.         if ( auth_type_user[i] == at )
  1866.             return(1);
  1867.     }
  1868.     return(0);
  1869. }
  1870. /*
  1871.  * Function: Parse authentication send command
  1872.  *
  1873.  * Parameters:
  1874.  *  parsedat - the sub-command data.
  1875.  *
  1876.  * end_sub - index of the character in the 'parsedat' array which
  1877.  * is the last byte in a sub-negotiation
  1878.  *
  1879.  * Returns: Kerberos error code.
  1880.  */
  1881. static int
  1882. #ifdef CK_ANSIC
  1883. auth_send(unsigned char *parsedat, int end_sub)
  1884. #else
  1885. auth_send(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  1886. #endif
  1887. {
  1888.     unsigned char buf[1024];
  1889.     unsigned char *pname;
  1890.     int plen;
  1891.     int r;
  1892.     int i;
  1893.     int mode;
  1894. #ifdef MIT_CURRENT
  1895. #ifdef CK_ENCRYPTION
  1896.     krb5_data data;
  1897.     krb5_enc_data encdata;
  1898.     krb5_error_code code;
  1899.     krb5_keyblock random_key;
  1900. #endif /* ENCRYPTION */
  1901. #endif /* MIT_CURRENT */
  1902. #ifdef KRB5
  1903.     int krb5_msg = 0;
  1904. #endif /* KRB5 */
  1905. #ifdef KRB4
  1906.     int krb4_msg = 0;
  1907.  #endif /* KRB4 */
  1908. #ifdef CK_SSL
  1909.     if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  1910. return(AUTH_SUCCESS);
  1911. #endif /* CK_SSL */
  1912.     auth_how = -1;              /* We have not found an auth method  */
  1913.     auth_crypt = 0;             /* We are not using encryption (yet) */
  1914.     /* Search the list of acceptable Authentication types sent from */
  1915.     /* the host and find one that we support                        */
  1916.     /* For Kerberos authentications, try to determine if we have a  */
  1917.     /* valid TGT, if not skip over the authentication type because  */
  1918.     /* we wouldn't be able to successfully login anyway.  Perhaps   */
  1919.     /* there is another supported authentication which we could use */
  1920. #ifdef NO_FTP_AUTH
  1921.     /* If the userid is "ftp" or "anonymous" refuse to perform AUTH */
  1922.     /* for Kerberos or SRP.                                         */
  1923. #endif /* NO_FTP_AUTH */
  1924.     if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
  1925.     for (i = 2; i+1 <= end_sub; i += 2) {
  1926. #ifdef NTLM
  1927.         if (parsedat[i] == AUTHTYPE_NTLM &&
  1928.              ck_ntlm_is_valid() &&
  1929.              ntlm_auth_send() == 0) {
  1930.             if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  1931.                  tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  1932. #ifdef CK_ENCRYPTION
  1933.                 /* NTLM does not support Telnet Encryption */
  1934.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  1935.                     continue;
  1936.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  1937. #endif /* CK_ENCRYPTION */
  1938.                 TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1939.                 TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1940.                 authentication_version = AUTHTYPE_NTLM;
  1941.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  1942.                 break;
  1943.             }
  1944.         }
  1945. #endif /* NTLM */
  1946. #ifdef CK_SSL
  1947.         if ( parsedat[i] == AUTHTYPE_SSL && ssl_initialized &&
  1948. #ifdef SSLDLL
  1949.              ck_ssleay_is_installed() &&
  1950. #endif /* SSLDLL */
  1951.              !tls_active_flag && !ssl_active_flag && ssl_load_certs()
  1952.              ) {
  1953.             if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  1954.                  tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  1955. #ifdef CK_ENCRYPTION
  1956.                 /* SSL does not support Telnet Encryption */
  1957.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  1958.                     continue;
  1959.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  1960. #endif /* CK_ENCRYPTION */
  1961.                 TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1962.                 TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  1963.                 authentication_version = AUTHTYPE_SSL;
  1964.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  1965.                 break;
  1966.             }
  1967.         }
  1968. #endif /* SSL */
  1969. #ifdef CK_SRP
  1970.         if ( parsedat[i] == AUTHTYPE_SRP
  1971. #ifdef SRPDLL
  1972.              && hSRP
  1973. #endif /* SRPDLL */
  1974. #ifdef NO_FTP_AUTH
  1975.              && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
  1976. #endif /* NO_FTP_AUTH */
  1977.              ) {
  1978.             if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  1979.                  tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  1980. #ifdef CK_ENCRYPTION
  1981.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK)
  1982. #ifndef PRE_SRP_1_4_5
  1983.                      /* Do not support ENCRYPT_USING_TELOPT yet. */
  1984.                      &&
  1985.                      (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  1986.                        TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF)
  1987. #endif /* PRE_SRP_1_4_5 */
  1988.                      )
  1989.                     continue;
  1990.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  1991.                 if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  1992.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  1993.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  1994.                 }
  1995. #endif /* CK_ENCRYPTION */
  1996.                 authentication_version = AUTHTYPE_SRP;
  1997.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  1998.                 break;
  1999.             }
  2000.         }
  2001. #endif /* SRP */
  2002. #ifdef KRB5
  2003.         if (parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
  2004. #ifdef OS2
  2005.              hKRB5_32 &&
  2006. #endif /* OS2 */
  2007. #ifdef NO_FTP_AUTH
  2008.              strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2009. #endif /* NO_FTP_AUTH */
  2010.              ck_krb5_is_installed() && !krb5_msg) {
  2011.             /* Without encryption we can't perform mutual authentication */
  2012.             if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2013.                  !ck_crypt_is_installed())
  2014.                 continue;
  2015.             /* Skip over entries that request credential forwarding */
  2016.             /* if we are not forwarding.                            */
  2017.             if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
  2018.                 (forward_flag &&
  2019.                   ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
  2020.                 continue;
  2021.             if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2022.                                 parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2023.                                 parsedat[i+1] & INI_CRED_FWD_MASK) )
  2024.             {
  2025.                 /* If we are auto-getting TGTs, try */
  2026.                 if ( !ck_krb5_is_tgt_valid() ) {
  2027.                 printf("Kerberos 5: Ticket Getting Ticket not valid.rn");
  2028.                 }
  2029.                 krb5_msg = 1;
  2030.             }
  2031.             else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2032.                       AUTH_CLIENT_TO_SERVER &&
  2033.                       tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2034. #ifdef CK_ENCRYPTION
  2035.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2036.                      (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2037.                        TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2038.                     continue;
  2039.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2040.                 if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2041.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2042.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2043.                 }
  2044. #endif /* CK_ENCRYPTION */
  2045.                 auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
  2046.                 authentication_version = AUTHTYPE_KERBEROS_V5;
  2047.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2048.                 if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2049.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2050.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2051.                 }
  2052.                 break;
  2053.             }
  2054.         }
  2055. #endif /* KRB5 */
  2056. #ifdef KRB4
  2057.         if (parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
  2058. #ifdef OS2
  2059.              hKRB4_32 &&
  2060. #endif /* OS2 */
  2061. #ifdef NO_FTP_AUTH
  2062.              strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2063. #endif /* NO_FTP_AUTH */
  2064.              ck_krb4_is_installed() && !krb4_msg) {
  2065.             int rc = 0;
  2066.             /* Without encryption we can't perform mutual authentication */
  2067.             if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2068.                  !ck_crypt_is_installed() )
  2069.                 continue;
  2070.             if ( !k4_auth_send() )
  2071.             {
  2072.                 /* If we are auto-getting TGTs, try */
  2073.                 if ( !ck_krb4_is_tgt_valid() ) {
  2074.                     printf("Kerberos 4: Ticket Getting Ticket not valid.rn");
  2075.                 }
  2076.                 krb4_msg = 1;
  2077.             }
  2078.             else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2079.                       AUTH_CLIENT_TO_SERVER &&
  2080.                       tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2081. #ifdef CK_ENCRYPTION
  2082.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2083.                      (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2084.                        TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2085.                     continue;
  2086.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2087.                 if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2088.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2089.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2090. }
  2091. #endif /* CK_ENCRYPTION */
  2092.                 authentication_version = AUTHTYPE_KERBEROS_V4;
  2093.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2094.                 if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2095.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2096.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2097.                 }
  2098.                 break;
  2099.             }
  2100.         }
  2101. #endif /* KRB4 */
  2102.     }
  2103.     } else {
  2104.         for (i = 2; i+1 <= end_sub; i += 2) {
  2105. #ifdef CK_SSL
  2106.             if ( atok(AUTHTYPE_SSL) && parsedat[i] == AUTHTYPE_SSL &&
  2107. #ifdef SSLDLL
  2108.                  ck_ssleay_is_installed() &&
  2109. #endif /* SSLDLL */
  2110.                  !tls_active_flag && !ssl_active_flag && ssl_initialized &&
  2111.                  ssl_load_certs()
  2112.                  )
  2113.             {
  2114.                 if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2115.                      tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2116. #ifdef CK_ENCRYPTION
  2117.                     /* SSL does not support Telnet Encryption */
  2118.                     if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2119.                         continue;
  2120.                     auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2121. #endif /* CK_ENCRYPTION */
  2122.                     TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2123.                     TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2124.                     authentication_version = AUTHTYPE_SSL;
  2125.                     auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2126.                     break;
  2127.                 }
  2128.             }
  2129. #endif /* SSL */
  2130. #ifdef CK_SRP
  2131.             if ( atok(AUTHTYPE_SRP) &&
  2132.                  parsedat[i] == AUTHTYPE_SRP
  2133. #ifdef SRPDLL
  2134.                  && hSRP
  2135. #endif /* SRPDLL */
  2136. #ifdef NO_FTP_AUTH
  2137.                  && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
  2138. #endif /* NO_FTP_AUTH */
  2139.                  ) {
  2140.                 if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2141.                      tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2142. #ifdef CK_ENCRYPTION
  2143.                     if ((parsedat[i+1] & AUTH_ENCRYPT_MASK)
  2144. #ifndef PRE_SRP_1_4_5
  2145.                          /* Do not support ENCRYPT_USING_TELOPT yet. */
  2146.                          &&
  2147.                          (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2148.                            TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF)
  2149. #endif /* PRE_SRP_1_4_5 */
  2150.                          )
  2151.                         continue;
  2152.                     auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2153.                     if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2154.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2155.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2156.                     }
  2157. #endif /* CK_ENCRYPTION */
  2158.                     authentication_version = AUTHTYPE_SRP;
  2159.                     auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2160.                     break;
  2161.                 }
  2162.             }
  2163. #endif /* SRP */
  2164. #ifdef KRB5
  2165.             if ( atok(AUTHTYPE_KERBEROS_V5) &&
  2166.                  parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
  2167. #ifdef OS2
  2168.                  hKRB5_32 &&
  2169. #endif /* OS2 */
  2170. #ifdef NO_FTP_AUTH
  2171.                  strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2172. #endif /* NO_FTP_AUTH */
  2173.                  ck_krb5_is_installed() && !krb5_msg) {
  2174.                 /* Without encryption we can't perform mutual authentication */
  2175.                 if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2176.                      !ck_crypt_is_installed())
  2177.                     continue;
  2178.                 /* Skip over entries that request credential forwarding */
  2179.                 /* if we are not forwarding.                            */
  2180.                 if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
  2181.                      (forward_flag &&
  2182.                        ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
  2183.                     continue;
  2184.                 if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2185.                                     parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2186.                                     parsedat[i+1] & INI_CRED_FWD_MASK) )
  2187.                 {
  2188.                     /* If we are auto-getting TGTs, try */
  2189.                     if ( !ck_krb5_is_tgt_valid() ) {
  2190.                         printf(
  2191.    "Kerberos 5: Ticket Getting Ticket not valid.rn");
  2192.                     }
  2193.                     krb5_msg = 1;
  2194.                 }
  2195.                 else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2196.                           AUTH_CLIENT_TO_SERVER &&
  2197.                           tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
  2198.                 {
  2199. #ifdef CK_ENCRYPTION
  2200.                     if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2201. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2202.  TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2203.       continue;
  2204.                     auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2205.                     if (auth_crypt) {
  2206.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2207.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2208.                     }
  2209. #endif /* CK_ENCRYPTION */
  2210.                     authentication_version = AUTHTYPE_KERBEROS_V5;
  2211.                     auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2212.                     if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2213.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2214.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2215.                     }
  2216.                     break;
  2217.                 }
  2218.             }
  2219. #endif /* KRB5 */
  2220. #ifdef KRB4
  2221.             if ( atok(AUTHTYPE_KERBEROS_V4) &&
  2222.                  parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
  2223. #ifdef OS2
  2224.                  hKRB4_32 &&
  2225. #endif /* OS2 */
  2226. #ifdef NO_FTP_AUTH
  2227.                  strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2228. #endif /* NO_FTP_AUTH */
  2229.                  ck_krb4_is_installed() && !krb4_msg) {
  2230.                 int rc = 0;
  2231.                 /* Without encryption we can't perform mutual authentication */
  2232.                 if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2233.                      !ck_crypt_is_installed())
  2234.                     continue;
  2235.                 if ( !k4_auth_send() )
  2236.                 {
  2237.                     /* If we are auto-getting TGTs, try */
  2238.                     if ( !ck_krb4_is_tgt_valid() ) {
  2239.                     printf("Kerberos 4: Ticket Getting Ticket not valid.rn");
  2240.                     }
  2241.                     krb4_msg = 1;
  2242.                 }
  2243.                 else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2244.                           AUTH_CLIENT_TO_SERVER &&
  2245.                           tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
  2246.                 {
  2247. #ifdef CK_ENCRYPTION
  2248.                     if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2249. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2250.  TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2251.       continue;
  2252.                     auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2253.                     if (auth_crypt) {
  2254.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2255.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2256.                     }
  2257. #endif /* CK_ENCRYPTION */
  2258.                     authentication_version = AUTHTYPE_KERBEROS_V4;
  2259.                     auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2260.                     if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2261.                         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2262.                         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2263.                     }
  2264.                     break;
  2265.                 }
  2266.             }
  2267. #endif /* KRB4 */
  2268. #ifdef NTLM
  2269.         if ( atok(AUTHTYPE_NTLM) &&
  2270.              parsedat[i] == AUTHTYPE_NTLM &&
  2271.              ck_ntlm_is_valid() &&
  2272.              ntlm_auth_send() == 0) {
  2273.             if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2274.                  tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2275. #ifdef CK_ENCRYPTION
  2276.                 /* NTLM does not support Telnet Encryption */
  2277.                 if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2278.                     continue;
  2279.                 auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2280. #endif /* CK_ENCRYPTION */
  2281.                 TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2282.                 TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2283.                 authentication_version = AUTHTYPE_NTLM;
  2284.                 auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2285.                 break;
  2286.             }
  2287.         }
  2288. #endif /* NTLM */
  2289.         }
  2290.     }
  2291.     if (auth_how == -1) {               /* Did we find one? */
  2292.         switch ( auth_type_user[0] ) {  /* If not, abort the negotiation */
  2293.         case AUTHTYPE_NULL:
  2294.             auth_abort("User refused to accept any authentication method",0);
  2295.             break;
  2296.         case AUTHTYPE_AUTO:
  2297.             auth_abort("No authentication method available", 0);
  2298.             break;
  2299.         default: {
  2300.             char msg[80];
  2301.             sprintf(msg,"%s could not be negotiated",
  2302.                      authtype_names[auth_type_user[0]]);
  2303.             auth_abort(msg, 0);
  2304.         }
  2305.         }
  2306.         auth_finished(AUTH_REJECT);
  2307.         return AUTH_FAILURE;
  2308.     }
  2309.     printf("Authenticating with %srn",
  2310.             authtype_names[authentication_version]);
  2311.     /* Send Telnet Auth Name message (if necessary) */
  2312.     switch ( authentication_version ) {
  2313.     case AUTHTYPE_SRP:
  2314.     case AUTHTYPE_KERBEROS_V4:
  2315.     case AUTHTYPE_KERBEROS_V5:
  2316.         /* if we do not have a name to login with get one now. */
  2317.         while ( szUserName[0] == '' ) {
  2318.             extern char * tn_pr_uid;
  2319.             readtext(tn_pr_uid && tn_pr_uid[0] ? tn_pr_uid : "Host Userid: ",
  2320.                       szUserName,63);
  2321.         }
  2322.         plen = strlen(szUserName);
  2323.         pname = (unsigned char *) szUserName;
  2324.         /* Construct Telnet Debugging Message */
  2325.         if (deblog || tn_deb || debses) {
  2326.             sprintf(tn_msg,"TELNET SENT SB %s NAME %s IAC SE",
  2327.                      TELOPT(TELOPT_AUTHENTICATION),
  2328.                      pname);
  2329.             debug(F100,tn_msg,"",0);
  2330.             if (tn_deb || debses) tn_debug(tn_msg);
  2331.         }
  2332.         /* Construct and send Authentication Name subnegotiation */
  2333.         sprintf(buf, "%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
  2334.                  TELQUAL_NAME);
  2335.         memcpy(&buf[4], pname, plen);
  2336.         sprintf(&buf[plen + 4], "%c%c", IAC, SE);
  2337.         ttol((CHAR *)buf, plen+6);
  2338.     }
  2339.     /* Construct Authentication Mode subnegotiation message (if necessary) */
  2340.     switch ( authentication_version ) {
  2341.     case AUTHTYPE_SRP:
  2342.     case AUTHTYPE_KERBEROS_V4:
  2343.     case AUTHTYPE_KERBEROS_V5:
  2344.     case AUTHTYPE_NTLM:
  2345.         mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  2346.             (auth_crypt ? AUTH_ENCRYPT_USING_TELOPT : AUTH_ENCRYPT_OFF)
  2347. #ifdef USE_INI_CRED_FWD
  2348.                 | (((authentication_version == AUTHTYPE_KERBEROS_V5) &&
  2349.                   auth_fwd)?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
  2350. #endif /* USE_INI_CRED_FWD */
  2351.                     ;
  2352.         sprintf(buf, "%c%c%c%c%c%c%c",
  2353.                  IAC, SB, TELOPT_AUTHENTICATION,
  2354.                  TELQUAL_IS,
  2355.                  authentication_version,
  2356.                  mode,
  2357.                  KRB_AUTH);
  2358.         break;
  2359.     }
  2360.     /* Send initial authentication data */
  2361.     switch ( authentication_version ) {
  2362. #ifdef CK_SSL
  2363.     case AUTHTYPE_SSL:
  2364.         SendSSLAuthSB(SSL_START,NULL,0);
  2365.         break;
  2366. #endif /* SSL */
  2367. #ifdef CK_SRP
  2368.     case AUTHTYPE_SRP:
  2369.         sprintf(&buf[7], "%c%c", IAC, SE);
  2370.         if (deblog || tn_deb || debses) {
  2371.             int i;
  2372.             sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
  2373.                      TELOPT(TELOPT_AUTHENTICATION),
  2374.                      authtype_names[authentication_version],
  2375.                      authmode_names[mode]);
  2376.             strcat(tn_msg,"IAC SE");
  2377.             debug(F100,tn_msg,"",0);
  2378.             if (tn_deb || debses) tn_debug(tn_msg);
  2379.         }
  2380.         ttol((CHAR *)buf, 9);
  2381.         break;
  2382. #endif /* SRP */
  2383. #ifdef NTLM
  2384.     case AUTHTYPE_NTLM: {
  2385.         int length = 0;
  2386.         length = copy_for_net(&buf[7],(char *)&NTLMSecBuf[0],2*sizeof(ULONG));
  2387.         length += copy_for_net(&buf[7+length], NTLMSecBuf[0].pvBuffer,
  2388.                                   NTLMSecBuf[0].cbBuffer);
  2389.         sprintf(&buf[7+length], "%c%c", IAC, SE);
  2390.         if (deblog || tn_deb || debses) {
  2391.             int i;
  2392.             sprintf(tn_msg,"TELNET SENT SB %s IS %s %s NTLM_AUTH ",
  2393.                      TELOPT(TELOPT_AUTHENTICATION),
  2394.                      authtype_names[authentication_version],
  2395.                      authmode_names[mode]);
  2396. #ifdef HEXDISP
  2397.             {
  2398.                 int was_hex = 1;
  2399.                 for ( i=0;i<length;i++ ) {
  2400.                     if ( buf[i+7] < 32 || buf[i+7] >= 127) {
  2401.                         sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
  2402.                         was_hex = 1;
  2403.                     } else {
  2404.                         sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
  2405.                         was_hex = 0;
  2406.                     }
  2407.                     strcat(tn_msg,hexbuf);
  2408.                 }
  2409.                 if ( !was_hex )
  2410.                     strcat(tn_msg,"" ");
  2411.             }
  2412. #else /* HEXDISP */
  2413.             memcpy(hexbuf,&buf[7],length);
  2414.             hexbuf[length] = ' ';
  2415.             hexbuf[length+1] = '';
  2416.             strcat(tn_msg,hexbuf);
  2417. #endif /* HEXDISP */
  2418.             strcat(tn_msg,"IAC SE");
  2419.             debug(F100,tn_msg,"",0);
  2420.             if (tn_deb || debses) tn_debug(tn_msg);
  2421.         }
  2422.         ttol((CHAR *)buf, length+9);
  2423.         break;
  2424.     }
  2425. #endif /* NTLM */
  2426. #ifdef KRB4
  2427.     case AUTHTYPE_KERBEROS_V4:
  2428.         k4_auth.length = copy_for_net(&buf[7], k4_auth.dat, k4_auth.length);
  2429.         sprintf(&buf[k4_auth.length+7], "%c%c", IAC, SE);
  2430.         if (deblog || tn_deb || debses) {
  2431.             int i;
  2432.             sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
  2433.                      TELOPT(TELOPT_AUTHENTICATION),
  2434.                      authtype_names[authentication_version],
  2435.                      authmode_names[mode]);
  2436. #ifdef HEXDISP
  2437.             {
  2438.                 int was_hex = 1;
  2439.                 for ( i=0;i<k4_auth.length;i++ ) {
  2440.                     if ( buf[i+7] < 32 || buf[i+7] >= 127) {
  2441.                         sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
  2442.                         was_hex = 1;
  2443.                     } else {
  2444.                         sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
  2445.                         was_hex = 0;
  2446.                     }
  2447.                     strcat(tn_msg,hexbuf);
  2448.                 }
  2449.                 if ( !was_hex )
  2450.                     strcat(tn_msg,"" ");
  2451.             }
  2452. #else /* HEXDISP */
  2453.             memcpy(hexbuf,&buf[7],k4_auth.length);
  2454.             hexbuf[k4_auth.length] = ' ';
  2455.             hexbuf[k4_auth.length+1] = '';
  2456.             strcat(tn_msg,hexbuf);
  2457. #endif /* HEXDISP */
  2458.             strcat(tn_msg,"IAC SE");
  2459.             debug(F100,tn_msg,"",0);
  2460.             if (tn_deb || debses) tn_debug(tn_msg);
  2461.         }
  2462.         ttol((CHAR *)buf, k4_auth.length+9);
  2463. #ifndef REMOVE_FOR_EXPORT
  2464. #ifdef CK_ENCRYPTION
  2465.         /*
  2466.          * If we are doing mutual authentication, get set up to send
  2467.          * the challenge, and verify it when the response comes back.
  2468.          */
  2469.         if ((auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  2470.             register int i;
  2471.             int rc = 0;
  2472. #ifdef MIT_CURRENT
  2473.             data.data = cred.session;
  2474.             data.length = 8; /* sizeof(cred.session) */;
  2475.             if (code = krb5_c_random_seed(k5_context, &data)) {
  2476.                 com_err("libtelnet", code,
  2477.                          "while seeding random number generator");
  2478.                 return(0);
  2479.             }
  2480.             if (code = krb5_c_make_random_key(k5_context,
  2481.                                                ENCTYPE_DES_CBC_RAW,
  2482.                                                &random_key)) {
  2483.                 com_err("libtelnet", code,
  2484.                          "while creating random session key");
  2485.                 return(0);
  2486.             }
  2487.             /* the krb4 code uses ecb mode, but on a single block
  2488.             with a zero ivec, ecb and cbc are the same */
  2489.             k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
  2490.             k4_krbkey.length = 8;
  2491.             k4_krbkey.contents = cred.session;
  2492.             encdata.ciphertext.data = random_key.contents;
  2493.             encdata.ciphertext.length = random_key.length;
  2494.             encdata.enctype = ENCTYPE_UNKNOWN;
  2495.             data.data = k4_session_key;
  2496.             data.length = 8;
  2497.             code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  2498.                                    &encdata, &data);
  2499.             krb5_free_keyblock_contents(k5_context, &random_key);
  2500.             if (code) {
  2501.                 com_err("libtelnet", code, "while encrypting random key");
  2502.                 return(0);
  2503.             }
  2504.             encdata.ciphertext.data = k4_session_key;
  2505.             encdata.ciphertext.length = 8;
  2506.             encdata.enctype = ENCTYPE_UNKNOWN;
  2507.             data.data = k4_challenge;
  2508.             data.length = 8;
  2509.             code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  2510.                                    &encdata, &data);
  2511. #else /* MIT_CURRENT */
  2512.             memset(k4_sched,0,sizeof(Schedule));
  2513.             hexdump("auth_send",cred.session,8);
  2514.             rc = des_key_sched(cred.session, k4_sched);
  2515.             if ( rc == -1 ) {
  2516.                 printf("?Invalid DES key specified in credentialsrn");
  2517.                 debug(F110,"auth_send",
  2518.       "invalid DES Key specified in credentials",0);
  2519.             } else if ( rc == -2 ) {
  2520.                 printf("?Weak DES key specified in credentialsrn");
  2521.                 debug(F110,"auth_send",
  2522.       "weak DES Key specified in credentials",0);
  2523.             } else if ( rc != 0 ) {
  2524.                 printf("?DES Key Schedule not set by credentialsrn");
  2525.                 debug(F110,"auth_send",
  2526.       "DES Key Schedule not set by credentials",0);
  2527.             }
  2528.             hexdump("auth_send schedule",k4_sched,8*16);
  2529.             des_set_random_generator_seed(cred.session);
  2530.             do {
  2531.                 des_new_random_key(k4_session_key);
  2532.                 des_fixup_key_parity(k4_session_key);
  2533.             } while ( ck_des_is_weak_key(k4_session_key) );
  2534.             hexdump("auth_send des_new_random_key(k4_session_key)",
  2535.                      k4_session_key,8);
  2536.             /* Decrypt the session key so that we can send it to the */
  2537.             /* host as a challenge                                   */
  2538. #ifdef NT
  2539.             des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 0);
  2540. #else /* NT */
  2541.             des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 0);
  2542. #endif /* NT */
  2543.     hexdump(
  2544. "auth_send des_ecb_encrypt(k4_session_key,k4_session_key,0)",
  2545.                 k4_session_key,8
  2546.     );
  2547.             /* Prepare the result of the challenge */
  2548.             /* Decrypt the session_key, add 1, and then encrypt it */
  2549.             /* The result stored in k4_challenge should match the  */
  2550.             /* KRB4_RESPONSE value from the host.                  */
  2551. #ifdef NT
  2552.             des_ecb_encrypt(k4_session_key, k4_challenge, k4_sched, 0);
  2553. #else /* NT */
  2554.             des_ecb_encrypt(&k4_session_key, &k4_challenge, k4_sched, 0);
  2555. #endif /* NT */
  2556.             hexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,0)",
  2557.                      k4_challenge,8);
  2558. #endif /* MIT_CURRENT */
  2559.             /*
  2560.             * Increment the challenge by 1, and encrypt it for
  2561.             * later comparison.
  2562.             */
  2563.             for (i = 7; i >= 0; --i) {
  2564.                 register int x;
  2565.                 x = (unsigned int)k4_challenge[i] + 1;
  2566.                 k4_challenge[i] = x;    /* ignore overflow */
  2567.                 if (x < 256)            /* if no overflow, all done */
  2568.                     break;
  2569.             }
  2570.             hexdump("auth_send k4_challenge+1",k4_challenge,8);
  2571. #ifdef MIT_CURRENT
  2572.             data.data = k4_challenge;
  2573.             data.length = 8;
  2574.             encdata.ciphertext.data = k4_challenge;
  2575.             encdata.ciphertext.length = 8;
  2576.             encdata.enctype = ENCTYPE_UNKNOWN;
  2577.             if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0, &data,
  2578.                                        &encdata)) {
  2579.                 com_err("libtelnet", code, "while encrypting random key");
  2580.                 return(0);
  2581.             }
  2582. #else /* MIT_CURRENT */
  2583. #ifdef NT
  2584.             des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
  2585. #else /* NT */
  2586.             des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
  2587. #endif /* NT */
  2588.             hexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,1)",
  2589.                      k4_challenge,8);
  2590. #endif /* MIT_CURRENT */
  2591.         }
  2592. #endif  /* ENCRYPTION */
  2593. #endif /* REMOVE_FOR_EXPORT */
  2594.         break;
  2595. #endif /* KRB4 */
  2596. #ifdef KRB5
  2597.     case AUTHTYPE_KERBEROS_V5:
  2598.         k5_auth.length = copy_for_net(&buf[7], k5_auth.data, k5_auth.length);
  2599.         sprintf(&buf[k5_auth.length+7], "%c%c", IAC, SE);
  2600.         if (deblog || tn_deb || debses) {
  2601.             int i;
  2602.             sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
  2603.                      TELOPT(TELOPT_AUTHENTICATION),
  2604.                      authtype_names[authentication_version],
  2605.                      authmode_names[mode]);
  2606. #ifdef HEXDISP
  2607.             {
  2608.                 int was_hex = 1;
  2609.                 for ( i=0;i<k5_auth.length;i++ ) {
  2610.                     if ( buf[i+7] < 32 || buf[i+7] >= 127) {
  2611.                         sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
  2612.                         was_hex = 1;
  2613.                     } else {
  2614.                         sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
  2615.                         was_hex = 0;
  2616.                     }
  2617.                     strcat(tn_msg,hexbuf);
  2618.                 }
  2619.                 if ( !was_hex )
  2620.                     strcat(tn_msg,"" ");
  2621.             }
  2622. #else /* HEXDISP */
  2623.             memcpy(hexbuf,&buf[7],k5_auth.length);
  2624.             hexbuf[k5_auth.length] = ' ';
  2625.             hexbuf[k5_auth.length+1] = '';
  2626.             strcat(tn_msg,hexbuf);
  2627. #endif /* HEXDISP */
  2628.             strcat(tn_msg,"IAC SE");
  2629.             debug(F100,tn_msg,"",0);
  2630.             if (tn_deb || debses) tn_debug(tn_msg);
  2631.         }
  2632.         ttol((CHAR *)buf, k5_auth.length+9);
  2633.         break;
  2634. #endif /* KRB5 */
  2635.     }
  2636.     return AUTH_SUCCESS;
  2637. }
  2638. /*
  2639.  * Function: Parse authentication REPLY command
  2640.  *
  2641.  * Parameters:
  2642.  *  parsedat - the sub-command data.
  2643.  *
  2644.  * end_sub - index of the character in the 'parsedat' array which
  2645.  * is the last byte in a sub-negotiation
  2646.  *
  2647.  * Returns: Kerberos error code.
  2648.  */
  2649. static int
  2650. #ifdef CK_ANSIC
  2651. auth_reply(unsigned char *parsedat, int end_sub)
  2652. #else
  2653. auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  2654. #endif
  2655. {
  2656.     int n = AUTH_FAILURE;
  2657.     if ( parsedat[2] != authentication_version ) {
  2658.         printf("Authentication version mismatch (%s [%d] != %s [%d])rn",
  2659.                 AUTHTYPE_NAME(parsedat[2]),parsedat[2],
  2660.                 AUTHTYPE_NAME(authentication_version),authentication_version);
  2661.         auth_finished(AUTH_REJECT);
  2662.         return(AUTH_FAILURE);
  2663.     }
  2664.     if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
  2665.         printf("Authentication mode mismatch (%s != %s)rn",
  2666.                 AUTHMODE_NAME(parsedat[3]),
  2667.                 AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
  2668.         auth_finished(AUTH_REJECT);
  2669.         return(AUTH_FAILURE);
  2670.     }
  2671. #ifdef KRB4
  2672.     if (authentication_version == AUTHTYPE_KERBEROS_V4)
  2673.         n = k4_auth_reply(parsedat, end_sub);
  2674. #endif
  2675. #ifdef KRB5
  2676.     if (authentication_version == AUTHTYPE_KERBEROS_V5)
  2677.         n = k5_auth_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  2678. #endif
  2679. #ifdef CK_SRP
  2680.     if (authentication_version == AUTHTYPE_SRP)
  2681.         n = srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  2682. #endif /* SRP */
  2683. #ifdef CK_SSL
  2684.     if (authentication_version == AUTHTYPE_SSL)
  2685.         n = ssl_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  2686. #endif /* SSL */
  2687. #ifdef NTLM
  2688.     if (authentication_version == AUTHTYPE_NTLM)
  2689.         n = ntlm_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  2690. #endif /* NTLM */
  2691.     return n;
  2692. }
  2693. /*
  2694.  * Function: Parse authentication IS command
  2695.  *
  2696.  * Parameters:
  2697.  *  parsedat - the sub-command data.
  2698.  *
  2699.  * end_sub - index of the character in the 'parsedat' array which
  2700.  * is the last byte in a sub-negotiation
  2701.  *
  2702.  * Returns: Kerberos error code.
  2703.  */
  2704. static int
  2705. #ifdef CK_ANSIC
  2706. auth_is(unsigned char *parsedat, int end_sub)
  2707. #else
  2708. auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  2709. #endif
  2710. {
  2711.     int n = AUTH_FAILURE;
  2712.     if ( authentication_version == AUTHTYPE_AUTO ) {
  2713.         authentication_version = parsedat[2];
  2714.         auth_how = (parsedat[3] & AUTH_HOW_MASK);
  2715.         auth_crypt = (parsedat[3] & AUTH_ENCRYPT_MASK);
  2716.         auth_fwd = (parsedat[3] & INI_CRED_FWD_MASK);
  2717.         debug(F111,"auth_is","authentication_version",authentication_version);
  2718.         debug(F111,"auth_is","auth_how",auth_how);
  2719.         debug(F111,"auth_is","auth_crypt",auth_crypt);
  2720.         debug(F111,"auth_is","auth_fwd",auth_fwd);
  2721.     }
  2722.     if ( parsedat[2] != authentication_version ) {
  2723.         printf("Authentication version mismatch (%s [%d] != %s [%d])rn",
  2724.                 AUTHTYPE_NAME(parsedat[2]),parsedat[2],
  2725.                 AUTHTYPE_NAME(authentication_version),authentication_version);
  2726.         auth_finished(AUTH_REJECT);
  2727.         return(AUTH_FAILURE);
  2728.     }
  2729.     if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
  2730.         printf("Authentication mode mismatch (%s != %s)rn",
  2731.                 AUTHMODE_NAME(parsedat[3]),
  2732.                 AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
  2733.         auth_finished(AUTH_REJECT);
  2734.         return(AUTH_FAILURE);
  2735.     }
  2736. #ifdef KRB4
  2737.     if (authentication_version == AUTHTYPE_KERBEROS_V4)
  2738.         n = k4_auth_is(parsedat, end_sub);
  2739. #endif
  2740. #ifdef KRB5
  2741.     if (authentication_version == AUTHTYPE_KERBEROS_V5)
  2742.         n = k5_auth_is(parsedat[3],parsedat, end_sub);
  2743. #endif
  2744. #ifdef CK_SRP
  2745.     if (authentication_version == AUTHTYPE_SRP)
  2746.         n = srp_is(parsedat[3], parsedat, end_sub);
  2747. #endif /* SRP */
  2748. #ifdef CK_SSL
  2749.     if (authentication_version == AUTHTYPE_SSL) {
  2750.         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2751.         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2752.         n = ssl_is(parsedat, end_sub);
  2753.     }
  2754. #endif /* SSL */
  2755. #ifdef NTLM
  2756.     if (authentication_version == AUTHTYPE_NTLM) {
  2757.         TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2758.         TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2759.         n = ntlm_is(parsedat, end_sub);
  2760.     }
  2761. #endif /* NTLM */
  2762.     debug(F111,"auth_is","n",n);
  2763.     return n;
  2764. }
  2765. /*
  2766.  * Function: Parse authentication NAME command
  2767.  *
  2768.  * Parameters:
  2769.  *  parsedat - the sub-command data.
  2770.  *
  2771.  * end_sub - index of the character in the 'parsedat' array which
  2772.  * is the last byte in a sub-negotiation
  2773.  *
  2774.  * Returns: Kerberos error code.
  2775.  */
  2776. static int
  2777. #ifdef CK_ANSIC
  2778. auth_name(unsigned char *parsedat, int end_sub)
  2779. #else
  2780. auth_name(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  2781. #endif
  2782. {
  2783.     int len = (end_sub-2) > 63 ? 63 : (end_sub-2);
  2784.     if ( len > 0 ) {
  2785.         memcpy(szUserNameRequested,&parsedat[2],len);
  2786.         szUserNameRequested[len] = '';
  2787.     } else
  2788.       szUserNameRequested[0] = '';
  2789.     debug(F111,"auth_name szUserNameRequested",szUserNameRequested,len);
  2790.     return(AUTH_SUCCESS);
  2791. }
  2792. /*
  2793.  * Function: Parse the athorization sub-options and reply.
  2794.  *
  2795.  * Parameters:
  2796.  * parsedat - sub-option string to parse.
  2797.  *
  2798.  * end_sub - last charcter position in parsedat.
  2799.  */
  2800. int
  2801. auth_parse(unsigned char *parsedat, int end_sub)
  2802. {
  2803.     int rc = AUTH_FAILURE;
  2804.     switch (parsedat[1]) {
  2805.     case TELQUAL_SEND:
  2806.         rc = auth_send(parsedat, end_sub);
  2807.         break;
  2808.     case TELQUAL_REPLY:
  2809.         rc= auth_reply(parsedat, end_sub);
  2810.         break;
  2811.     case TELQUAL_IS:
  2812.         rc = auth_is(parsedat, end_sub);
  2813.         break;
  2814.     case TELQUAL_NAME:
  2815.         rc = auth_name(parsedat, end_sub);
  2816.         break;
  2817.     }
  2818.     debug(F111,"auth_parse","rc",rc);
  2819.     return(rc);
  2820. }
  2821. /*
  2822.  * Function: Initialization routine called kstream encryption system.
  2823.  *
  2824.  * Parameters:
  2825.  *  data - user data.
  2826.  */
  2827. int
  2828. #ifdef CK_ANSIC
  2829. auth_init(kstream ks)
  2830. #else
  2831. auth_init(ks) kstream_ptr ks;
  2832. #endif
  2833. {
  2834. #ifdef FORWARD
  2835.     forwarded_tickets = 0;  /* were tickets forwarded? */
  2836. #endif /* FORWARD */
  2837. #ifdef CK_ENCRYPTION
  2838.     encrypt_init(ks,cx_type);
  2839. #endif
  2840.     return 0;
  2841. }
  2842. /*
  2843.  * Function: Destroy routine called kstream encryption system.
  2844.  *
  2845.  * Parameters:
  2846.  *  data - user data.
  2847.  */
  2848. VOID
  2849. #ifdef CK_ANSIC
  2850. auth_destroy(void)
  2851. #else
  2852. auth_destroy()
  2853. #endif
  2854. {
  2855. }
  2856. /*
  2857.  * Function: Callback to encrypt a block of characters
  2858.  *
  2859.  * Parameters:
  2860.  *  out - return as pointer to converted buffer.
  2861.  *
  2862.  *  in - the buffer to convert
  2863.  *
  2864.  * Returns: number of characters converted.
  2865.  */
  2866. int
  2867. #ifdef CK_ANSIC
  2868. auth_encrypt(struct kstream_data_block *out,
  2869.      struct kstream_data_block *in)
  2870. #else
  2871. auth_encrypt(out,in)
  2872.     struct kstream_data_block *out; struct kstream_data_block *in;
  2873. #endif
  2874. {
  2875.     out->ptr = in->ptr;
  2876.     out->length = in->length;
  2877.     return(out->length);
  2878. }