ckuath.c
资源名称:cku197.tar.Z [点击查看]
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:270k
源码类别:
通讯/手机编程
开发平台:
Windows_Unix
- char *ckathv = "Authentication, 7.0.141, 19 Dec 1999";
- /*
- C K U A T H . C -- Authentication for C-Kermit
- Copyright (C) 1999, 2000,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
- Author: Jeffrey E Altman (jaltman@columbia.edu)
- */
- /*
- * Based on a concatenation of all necessary source files distributed with the
- * Kerberos 5 NT Alpha 2 Telnet package from MIT with significant changes.
- * Additional copyrights included with affected code.
- */
- /*
- * Implements Kerberos 4/5, SRP, SSL, NTLM authentication and START_TLS
- */
- #include "ckcdeb.h"
- #ifdef CK_AUTHENTICATION
- #include "ckcker.h"
- #include "ckucmd.h" /* For struct keytab */
- #include "ckcnet.h"
- #ifdef CRYPT_DLL
- #ifndef LIBDES
- #define LIBDES
- #endif /* LIBDES */
- #ifdef OS2
- #ifdef NT
- #include <windows.h>
- #else /* NT */
- #define INCL_DOSMODULEMGR
- #include <os2.h>
- #endif /* NT */
- #endif /* OS2 */
- #endif /* CRYPT_DLL */
- #ifdef NT
- #define KRB5_AUTOCONF__
- #define NTLM
- #endif /* NT */
- #ifdef CK_KERBEROS
- #define KINIT
- #define KLIST
- #define KDESTROY
- #define CHECKADDRS
- #else /* CK_KERBEROS */
- #ifdef KRB4
- #undef KRB4
- #endif /* KRB4 */
- #ifdef KRB5
- #undef KRB5
- #endif /* KRB5 */
- #ifdef KRB524
- #undef KRB524
- #endif /* KRB524 */
- #endif /* CK_KERBEROS */
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #include <fcntl.h>
- #include <malloc.h>
- #ifdef OS2
- #include <io.h>
- #endif /* OS2 */
- #ifdef KRB5
- #include "krb5.h"
- #include "com_err.h"
- #ifdef HAVE_PWD_H
- #include <pwd.h>
- #endif
- #ifdef UNIX
- #define krb5_free_unparsed_name(con,val) free((char FAR *)(val))
- #endif /* UNIX */
- #endif /* KRB5 */
- #ifdef KRB4
- #define des_cblock Block
- #define des_key_schedule Schedule
- #ifdef NT
- #define _WINDOWS
- #include "kerberosIV/krb.h"
- #else /* NT */
- #ifdef KRB524
- #include "kerberosIV/krb.h"
- _PROTOTYP(const char * krb_get_err_text_entry, (int));
- #else /* KRB524 */
- #ifdef SOLARIS
- #ifndef sun
- /* for some reason the Makefile entries for the Solaris systems have -Usun */
- #define sun
- #endif /* sun */
- #endif /* SOLARIS */
- #include "krb.h"
- #define krb_get_err_text_entry krb_get_err_text
- #endif /* KRB524 */
- #endif /* NT */
- #else /* KRB4 */
- #ifdef CK_SSL
- #define des_cblock Block
- #define des_key_schedule Schedule
- #endif /* CK_SSL */
- #endif /* KRB4 */
- #include "ckuath.h"
- #ifdef CK_KERBEROS
- #ifndef KRB5
- #define NOBLOCKDEF
- #endif /* KRB5 */
- #ifdef KRB524
- #define NOBLOCKDEF
- #endif /* KRB524 */
- #endif /* CK_KERBEROS */
- #include "ckuat2.h"
- #ifdef CK_SSL
- #ifdef LIBDES
- #ifndef HEADER_DES_H
- #define HEADER_DES_H
- #endif /* HEADER_DES_H */
- #endif /* LIBDES */
- #include "ck_ssl.h"
- #endif /* SSL */
- #define PWD_SZ 128
- #ifndef LIBDES
- #ifdef UNIX
- #define des_set_random_generator_seed(x) des_init_random_number_generator(x)
- #endif /* UNIX */
- #endif /* LIBDES */
- /*
- * Globals
- */
- int authentication_version = AUTHTYPE_NULL;
- int auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_AUTO, AUTHTYPE_NULL};
- static int auth_how=0;
- static int auth_crypt=0;
- static int auth_fwd=0;
- /* These are state completion variables */
- int accept_complete = 0;
- static int mutual_complete = 0;
- #ifdef KRB4
- #ifdef OS2
- /* The Leash implementation of Kerberos 4 used by Kermit 95 */
- /* has an extended Credentials structure that includes the */
- /* ip address of the ticket in readable form. */
- #ifdef KRB4
- #ifndef ADDR_SZ
- #define ADDR_SZ 40 /* From Leash krb.h */
- #endif /* ADDR_SZ */
- struct leash_credentials {
- char service[ANAME_SZ]; /* Service name */
- char instance[INST_SZ]; /* Instance */
- char realm[REALM_SZ]; /* Auth domain */
- C_Block session; /* Session key */
- int lifetime; /* Lifetime */
- int kvno; /* Key version number */
- KTEXT_ST ticket_st; /* The ticket itself */
- long issue_date; /* The issue time */
- char pname[ANAME_SZ]; /* Principal's name */
- char pinst[INST_SZ]; /* Principal's instance */
- char address[ADDR_SZ]; /* IP Address in ticket */
- };
- typedef struct leash_credentials LEASH_CREDENTIALS;
- #endif /* KRB4 */
- static LEASH_CREDENTIALS cred;
- #else /* OS2 */
- static CREDENTIALS cred;
- #endif /* OS2 */
- static KTEXT_ST k4_auth;
- static char k4_name[ANAME_SZ];
- static AUTH_DAT k4_adat = { 0 };
- static char * k4_keyfile = "/etc/srvtab";
- static MSG_DAT k4_msg_data;
- #ifdef CK_ENCRYPTION
- static Block k4_session_key = { 0 };
- static Schedule k4_sched;
- static Block k4_challenge = { 0 };
- #ifdef MIT_CURRENT
- static krb5_keyblock k4_krbkey;
- #endif /* MIT_CURRENT */
- #endif /* ENCRYPTION */
- #define KRB4_SERVICE_NAME "rcmd"
- _PROTOTYP(static int k4_auth_send,(VOID));
- _PROTOTYP(static int k4_auth_reply,(unsigned char *, int));
- _PROTOTYP(static int k4_auth_is,(unsigned char *, int));
- #endif /* KRB4 */
- #ifdef KRB5
- static krb5_data k5_auth;
- static krb5_auth_context auth_context;
- static krb5_keyblock *k5_session_key = NULL;
- #ifdef FORWARD
- _PROTOTYP(void kerberos5_forward,(VOID));
- #endif /* FORWARD */
- #define KRB5_SERVICE_NAME "host"
- _PROTOTYP(static int k5_auth_send,(int,int,int));
- _PROTOTYP(static int k5_auth_reply,(int, unsigned char *, int));
- _PROTOTYP(static int k5_auth_is,(int,unsigned char *, int));
- _PROTOTYP(static int SendK5AuthSB,(int, void *, int));
- #endif /* KRB5 */
- #ifdef CK_SRP
- _PROTOTYP(static int srp_reply,(int, unsigned char *, int));
- _PROTOTYP(static int srp_is,(int, unsigned char *, int));
- #endif /* SRP */
- _PROTOTYP(void auth_finished, (int));
- #ifdef CK_ENCRYPTION
- static int encrypt_flag = 1;
- #endif
- #ifdef FORWARD
- int forward_flag = 0; /* forward tickets? */
- int forwardable_flag = 1; /* get forwardable tickets to forward? */
- int forwarded_tickets = 0; /* were tickets forwarded? */
- #endif
- static unsigned char str_data[4096] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_KERBEROS_V5, };
- #define AUTHTMPBL 2048
- static char strTmp[AUTHTMPBL+1];
- char szUserNameRequested[UIDBUFLEN+1]; /* for incoming connections */
- char szUserNameAuthenticated[UIDBUFLEN+1];/* for incoming connections */
- char szHostName[UIDBUFLEN+1];
- static char szLocalHostName[UIDBUFLEN+1];
- static char szIP[16];
- static char szUserName[UIDBUFLEN+1];
- static int validUser = AUTH_REJECT; /* User starts out invalid */
- static struct kstream_crypt_ctl_block ctl;
- static kstream g_kstream=NULL;
- #ifdef KRB5
- static krb5_context k5_context=NULL;
- static krb5_creds * ret_cred=NULL;
- static krb5_context telnet_context=NULL;
- static char * telnet_srvtab = NULL;
- static char * telnet_krb5_realm = NULL;
- static krb5_ticket * k5_ticket = NULL;
- #endif /* KRB5 */
- #ifdef CK_SRP
- #include <t_pwd.h>
- #include <t_client.h>
- #include <t_server.h>
- static struct t_server * ts = NULL;
- static struct t_client * tc = NULL;
- #ifdef PRE_SRP_1_4_4
- #ifndef PRE_SRP_1_4_5
- #define PRE_SRP_1_4_5
- #endif /* PRE_SRP_1_4_5 */
- static struct t_pw * tpw = NULL;
- static struct t_conf * tconf = NULL;
- #endif /* PRE_SRP_1_4_4 */
- static int srp_waitresp = 0; /* Flag to indicate readiness for response */
- static struct t_num * B; /* Holder for B */
- static char srp_passwd[PWD_SZ];
- #endif /* CK_SRP */
- #ifdef CK_KERBEROS
- #ifdef RLOGCODE
- #define OPTS_FORWARD_CREDS 0x00000002
- #define OPTS_FORWARDABLE_CREDS 0x00000001
- #define RLOGIN_BUFSIZ 5120
- char des_inbuf[2*RLOGIN_BUFSIZ]; /* needs to be > largest read size */
- char des_outpkt[2*RLOGIN_BUFSIZ+4]; /* needs to be > largest write size */
- #ifdef KRB5
- krb5_data desinbuf,desoutbuf;
- krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
- #endif /* KRB5 */
- static char storage[2*RLOGIN_BUFSIZ]; /* storage for the decryption */
- static int nstored = 0;
- static char *store_ptr = storage;
- static int rlog_encrypt = 0;
- #endif /* RLOGCODE */
- extern char * krb5_d_principal; /* Default principal */
- extern char * krb5_d_instance; /* Default instance */
- extern char * krb5_d_realm; /* Default realm */
- extern char * krb5_d_cc; /* Default credentials cache */
- extern char * krb5_d_srv; /* Default service name */
- extern int krb5_d_lifetime; /* Default lifetime */
- extern int krb5_d_forwardable;
- extern int krb5_d_proxiable;
- extern int krb5_d_renewable;
- extern int krb5_autoget;
- extern int krb5_checkaddrs;
- extern int krb5_d_getk4;
- extern int krb5_errno;
- extern char * krb5_errmsg;
- extern char * krb4_d_principal; /* Default principal */
- extern char * krb4_d_realm; /* Default realm */
- extern char * krb4_d_srv; /* Default service name */
- extern int krb4_d_lifetime; /* Default lifetime */
- extern int krb4_d_preauth;
- extern char * krb4_d_instance;
- extern int krb4_autoget;
- extern int krb4_checkaddrs;
- extern int krb4_errno;
- extern char * krb4_errmsg;
- #endif /* CK_KERBEROS */
- extern char tn_msg[], hexbuf[]; /* from ckcnet.c */
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
- extern int deblog, debses, tn_deb;
- extern int sstelnet, inserver;
- #ifdef CK_LOGIN
- extern int ckxanon;
- #endif /* CK_LOGIN */
- extern int tn_auth_how;
- extern int tn_auth_enc;
- #ifdef CK_ENCRYPTION
- extern int cx_type;
- #endif /* CK_ENCRYPTION */
- #ifdef OS2
- #include "ckoath.c"
- #endif /* OS2 */
- int
- ck_krb5_is_installed()
- {
- #ifdef KRB5
- #ifdef OS2
- return(hKRB5_32 != NULL);
- #else /* OS2 */
- return(1);
- #endif /* OS2 */
- #else /* KRB5 */
- return(0);
- #endif /* KRB5 */
- }
- int
- ck_krb4_is_installed()
- {
- #ifdef KRB4
- #ifdef OS2
- return(hKRB4_32 != NULL);
- #else /* OS2 */
- return(1);
- #endif /* OS2 */
- #else /* KRB4 */
- return(0);
- #endif /* KRB4 */
- }
- int
- ck_srp_is_installed()
- {
- #ifdef CK_SRP
- #ifdef SRPDLL
- return(hSRP != NULL);
- #else /* SRPDLL */
- return(1);
- #endif /* SRPDLL */
- #else /* SRP */
- return(0);
- #endif /* SRP */
- }
- int
- ck_crypt_is_installed()
- {
- #ifdef CK_ENCRYPTION
- #ifdef CRYPT_DLL
- return(hCRYPT != NULL);
- #else /* CRYPT_DLL */
- return(1);
- #endif /* CRYPT_DLL */
- #else /* ENCRYPTION */
- return(0);
- #endif /* ENCRYPTION */
- }
- int
- ck_ntlm_is_installed()
- {
- #ifdef NT
- return(hSSPI != NULL);
- #else /* NT */
- return(0);
- #endif /* NT */
- }
- /* C K _ K R B _ I N I T
- * Initialize the Kerberos system for a pending connection
- * hostname - a reverse DNS lookup of the hostname when possible
- * ipaddr - the ip address of the host
- * username - the name the user wants to connect under not necessarily
- * the same as principal
- * socket - the socket handle (ttyfd in Kermit speak)
- *
- * Returns: 1 on success and 0 on failure
- */
- int
- #ifdef CK_ANSIC
- ck_auth_init( char * hostname, char * ipaddr, char * username, int socket )
- #else /* CK_ANSIC */
- ck_auth_init( hostname, ipaddr, username, socket )
- char * hostname; char * ipaddr; char *username; int socket;
- #endif /* CK_ANSIC */
- {
- #ifdef OS2
- if ( !ck_auth_loaddll() ) {
- TELOPT_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- return(0);
- }
- #endif /* OS2 */
- if ( !!ck_crypt_is_installed() ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- if (!hostname) hostname = "";
- if (!ipaddr) ipaddr = "";
- if (!username) username = "";
- ckstrncpy( szUserName, username, UIDBUFLEN );
- ckstrncpy( szHostName, hostname, UIDBUFLEN );
- ckstrncpy( szIP, ipaddr, 16 );
- szUserNameRequested[0] = ' ';
- szUserNameAuthenticated[0] = ' ';
- validUser = AUTH_REJECT;
- if ( sstelnet )
- str_data[3] = TELQUAL_REPLY;
- else
- str_data[3] = TELQUAL_IS;
- debug(F110,"ck_auth_init Username",username,0);
- debug(F110,"ck_auth_init Hostname",hostname,0);
- debug(F110,"ck_auth_init Ipaddr",ipaddr,0);
- #ifdef KRB5
- /* free previous ret_cred */
- if ( ret_cred ) {
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- }
- /* and context */
- if ( k5_context ) {
- krb5_free_context(k5_context);
- k5_context = NULL;
- }
- /* create k5_context */
- krb5_init_context(&k5_context);
- #ifndef MIT_CURRENT
- krb5_init_ets(k5_context);
- #endif /* MIT_CURRENT */
- memset(&k5_auth,0,sizeof(k5_auth));
- if (auth_context) {
- krb5_auth_con_free(k5_context, auth_context);
- auth_context = 0;
- }
- #ifdef CK_ENCRYPTION
- if (k5_session_key) {
- krb5_free_keyblock(k5_context, k5_session_key);
- k5_session_key = 0;
- }
- #endif /* ENCRYPTION */
- #endif /* KRB5 */
- #ifdef KRB4
- #ifdef CK_ENCRYPTION
- /* Initialize buffers used for authentication */
- memset(&k4_session_key, 0, sizeof(k4_session_key));
- memset(&k4_challenge, 0, sizeof(k4_challenge));
- #endif /* ENCRYPTION */
- #endif /* KRB4 */
- kstream_destroy();
- auth_how = 0;
- auth_crypt = 0;
- auth_fwd = 0;
- accept_complete = 0;
- mutual_complete = 0;
- authentication_version = AUTHTYPE_NULL;
- #ifdef CK_KERBEROS
- #ifdef RLOGCODE
- rlog_encrypt = 0;
- nstored = 0;
- store_ptr = storage;
- memset(storage,0,sizeof(storage));
- #endif /* RLOGCODE */
- #endif /* CK_KERBEROS */
- #ifdef CK_SRP
- srp_waitresp = 0;
- #endif /* SRP */
- /* create kstream from socket */
- /* a kstream is simply a structure containing the socket handle */
- /* and pointers to the appropriate functions for encryption, */
- /* decryption, and the like. */
- ctl.encrypt = auth_encrypt;
- ctl.decrypt = auth_decrypt;
- ctl.init = auth_init;
- ctl.destroy = auth_destroy;
- if (!kstream_create_from_fd(socket, &ctl, NULL))
- return(0);
- return(1);
- }
- int
- ck_tn_auth_valid()
- {
- return(validUser);
- }
- /* C K _ K R B _ A U T H _ I N _ P R O G R E S S
- *
- * Is an authentication negotiation still in progress?
- *
- */
- int
- #ifdef CK_ANSIC
- ck_tn_auth_in_progress(void)
- #else
- ck_tn_auth_in_progress()
- #endif
- {
- switch (authentication_version) {
- case AUTHTYPE_AUTO:
- return(1);
- case AUTHTYPE_NULL:
- return(0);
- #ifdef KRB4
- case AUTHTYPE_KERBEROS_V4:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 4 !accept_complete",
- "",0);
- return(1);
- }
- else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 4 !mutual_complete",
- "",0);
- return(1);
- }
- else
- return(0);
- #endif /* KRB4 */
- #ifdef KRB5
- case AUTHTYPE_KERBEROS_V5:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 5 !accept_complete",
- "",0);
- return(1);
- }
- else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
- debug(F100,"ck_auth_in_progress() Kerberos 5 !mutual_complete",
- "",0);
- return(1);
- }
- else
- return(0);
- #endif /* KRB5 */
- #ifdef CK_SRP
- case AUTHTYPE_SRP:
- if (!accept_complete || srp_waitresp)
- return(1);
- else
- return(0);
- #endif /* CK_SRP */
- #ifdef NTLM
- case AUTHTYPE_NTLM:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() NTLM !accept_complete",
- "",0);
- return(1);
- }
- else
- return(0);
- #endif /* NTLM */
- case AUTHTYPE_SSL:
- if (!accept_complete) {
- debug(F100,"ck_auth_in_progress() SSL !accept_complete",
- "",0);
- return(1);
- }
- else
- return(0);
- default:
- return(0);
- }
- return(0);
- }
- /* C K _ K R B _ T N _ A U T H _ R E Q U E S T
- *
- * Builds a Telnet Authentication Send Negotiation providing the
- * list of supported authentication methods. To be used only
- * when accepting incoming connections as only the server (DO) side of the
- * Telnet negotiation is allowed to send an AUTH SEND.
- *
- * Returns: 0 on success and -1 on failure
- */
- int
- #ifdef CK_ANSIC
- ck_tn_auth_request(void)
- #else
- ck_tn_auth_request()
- #endif
- {
- static unsigned char str_request[64] = { IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_SEND };
- int i = 4, rc = -1;
- #ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return(0);
- }
- #endif /* CK_SSL */
- if ( deblog || tn_deb || debses )
- strcpy(tn_msg,"TELNET SENT SB AUTHENTICATION SEND ");
- /* Create a list of acceptable Authentication types to send to */
- /* the client and let it choose find one that we support */
- /* For those authentication methods that support Encryption or */
- /* Credentials Forwarding we must send all of the appropriate */
- /* combinations based upon the state of */
- /* TELOPT_x_MODE(TELOPT_ENCRYPTION) and forward_flag. */
- if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
- /* Microsoft's Telnet client won't perform authentication if */
- /* NTLM is not first. */
- #ifdef NTLM
- if ( ck_ntlm_is_valid() ) {
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_NTLM;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* NTLM */
- #ifdef KRB5
- if (1
- #ifdef OS2
- && hKRB5_32
- #endif /* OS2 */
- ) {
- #ifdef CK_ENCRYPTION
- #ifdef USE_INI_CRED_FWD
- if ( forward_flag &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) )
- {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- str_request[i] |= INI_CRED_FWD_ON;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* USE_INI_CRED_FWD */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- #ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- }
- #endif /* KRB5 */
- #ifdef KRB4
- if (1
- #ifdef OS2
- && hKRB4_32
- #endif /* OS2 */
- ) {
- #ifdef CK_ENCRYPTION
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) )
- {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- #ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- }
- #endif /* KRB4 */
- #ifdef CK_SRP
- if ( 1
- #ifdef SRPDLL
- && hSRP
- #endif /* SRPDLL */
- ) {
- #ifndef PRE_SRP_1_4_5
- /* Dont' do this yet. SRP when it uses the ENCRYPT_USING_TELOPT */
- /* flag it must perform a checksum of the auth-type-pair but there */
- /* is no mechansim to do that yet. */
- #ifdef CK_ENCRYPTION
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- #endif /* PRE_SRP_1_4_5 */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* SRP */
- #ifdef CK_SSL
- if ( 1
- #ifdef SSLDLL
- && ck_ssleay_is_installed()
- #endif /* SSLDLL */
- && !tls_active_flag && !ssl_active_flag && ssl_initialized
- ) {
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_SSL;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* CK_SSL */
- } else {
- int j;
- for ( j=0;
- j<AUTHTYPLSTSZ && auth_type_user[j] != AUTHTYPE_NULL;
- j++) {
- #ifdef NTLM
- if (auth_type_user[j] == AUTHTYPE_NTLM &&
- ck_ntlm_is_valid()) {
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_NTLM;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* NTLM */
- #ifdef CK_SSL
- if ( auth_type_user[j] == AUTHTYPE_SSL
- #ifdef SSLDLL
- && ck_ssleay_is_installed()
- #endif /* SSLDLL */
- && !tls_active_flag && !ssl_active_flag && ssl_initialized
- )
- {
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_SSL;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* CK_SSL */
- #ifdef CK_SRP
- if ( auth_type_user[j] == AUTHTYPE_SRP
- #ifdef SRPDLL
- && hSRP
- #endif /* SRPDLL */
- )
- {
- #ifndef PRE_SRP_1_4_5
- /* Dont' do this yet. SRP when it uses the ENCRYPT_USING_TELOPT */
- /* flag it must perform a checksum of the auth-type-pair but there */
- /* is no mechansim to do that yet. */
- #ifdef CK_ENCRYPTION
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- #endif /* PRE_SRP_1_4_5 */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- str_request[i++] = AUTHTYPE_SRP;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- #endif /* SRP */
- #ifdef KRB5
- if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V5
- #ifdef OS2
- && hKRB5_32
- #endif /* OS2 */
- )
- {
- #ifdef CK_ENCRYPTION
- #ifdef USE_INI_CRED_FWD
- if ( forward_flag &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- str_request[i] |= INI_CRED_FWD_ON;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* USE_INI_CRED_FWD */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- #ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V5;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- }
- #endif /* KRB5 */
- #ifdef KRB4
- if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V4
- #ifdef OS2
- && hKRB4_32
- #endif /* OS2 */
- )
- {
- #ifdef CK_ENCRYPTION
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_RF &&
- (tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ((TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
- TELOPT_U_MODE(TELOPT_ENCRYPTION)) != TN_NG_MU &&
- (tn_auth_enc == TN_AUTH_ENC_ANY ||
- tn_auth_enc == TN_AUTH_ENC_NONE) )
- {
- #ifdef CK_ENCRYPTION
- /* Can't perform mutual authentication without encryption */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ");
- i++;
- }
- #endif /* CK_ENCRYPTION */
- if ( tn_auth_how == TN_AUTH_HOW_ANY ||
- tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
- str_request[i++] = AUTHTYPE_KERBEROS_V4;
- str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
- str_request[i] |= AUTH_ENCRYPT_OFF;
- if ( deblog || tn_deb || debses )
- strcat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ");
- i++;
- }
- }
- }
- #endif /* KRB4 */
- }
- }
- str_request[i++] = IAC;
- str_request[i++] = SE;
- if ( deblog || tn_deb || debses ) {
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Send data */
- rc = ttol((CHAR *)str_request, i);
- if ( rc == i )
- return(0);
- else
- return(-1);
- }
- #ifdef CK_ENCRYPTION
- VOID
- ck_tn_enc_start()
- {
- if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
- return;
- if (!TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop &&
- (!encrypt_is_decrypting() || !encrypt_is_encrypting())) {
- debug(F110,"ck_tn_enc_start","nothing to do",0);
- return;
- }
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
- if (TELOPT_ME(TELOPT_ENCRYPTION) && !encrypt_is_encrypting()) {
- debug(F110,"ck_tn_enc_start","encrypt_request_start",0);
- encrypt_request_start();
- }
- if (TELOPT_U(TELOPT_ENCRYPTION) && !encrypt_is_decrypting()) {
- debug(F110,"ck_tn_enc_start","encrypt_send_request_start",0);
- encrypt_send_request_start();
- }
- tn_wait("encrypt start");
- tn_push();
- }
- VOID
- ck_tn_enc_stop()
- {
- if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
- return;
- if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop ||
- !(encrypt_is_decrypting() || encrypt_is_encrypting())) {
- debug(F110,"ck_tn_enc_stop","nothing to do",0);
- return;
- }
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
- if (TELOPT_U(TELOPT_ENCRYPTION) && encrypt_is_decrypting()) {
- debug(F110,"ck_tn_enc_stop","encrypt_send_request_end",0);
- encrypt_send_request_end();
- }
- if (TELOPT_ME(TELOPT_ENCRYPTION) && encrypt_is_encrypting()) {
- debug(F110,"ck_tn_enc_stop","encrypt_send_end",0);
- encrypt_send_end();
- }
- tn_wait("encrypt stop");
- tn_push();
- }
- #endif /* CK_ENCRYPTION */
- /* C K _ K R B _ T N _ S B _ A U T H
- * An interface between the C-Kermit Telnet Command Parser and the Authent-
- * ication option parser implemented in the Kerberos Telnet client.
- *
- * sb - the subnegotiation as calculated in ckcnet.c
- * len - the length of the buffer
- *
- * Returns: 0 on success and -1 on failure
- */
- int
- #ifdef CK_ANSIC
- ck_tn_sb_auth(char * sb, int len)
- #else /* CK_ANSIC */
- ck_tn_sb_auth(sb,len) char * sb; int len;
- #endif /* CK_ANSIC */
- {
- /* auth_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
- /* and it wants the length to exclude the IAC SE bytes */
- char buf[1024];
- int rc = -1;
- buf[0] = SB;
- memcpy( &buf[1], sb, len );
- buf[len+1] = ' ';
- rc = auth_parse(buf,len+1-2);
- debug(F111,"ck_tn_sb_auth","rc",rc);
- if (rc == AUTH_FAILURE) {
- authentication_version = AUTHTYPE_NULL;
- #ifdef OS2
- ipadl25();
- #endif /* OS2 */
- return(-1);
- }
- #ifdef OS2
- ipadl25();
- #endif /* OS2 */
- return(0);
- }
- /* C K _ K R B _ T N _ S B _ E N C R Y P T
- * An interface between the C-Kermit Telnet Command Parser and the Encryption
- * option parser implemented in the Kerberos Telnet client.
- *
- * sb - the subnegotiation as calculated in ckcnet.c
- * len - the length of the buffer
- *
- * Returns: Always returns 0 for success since encrypt_parse is void
- */
- int
- #ifdef CK_ANSIC
- ck_tn_sb_encrypt(char * sb, int len)
- #else
- ck_tn_sb_encrypt(sb,len) char * sb; int len;
- #endif /* CK_ANSIC */
- {
- /* encrypt_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
- /* and it wants the length to exclude the IAC SE bytes */
- #ifdef CK_ENCRYPTION
- char buf[1024];
- buf[0] = SB;
- memcpy( &buf[1], sb, len );
- buf[len+1] = ' ';
- if (encrypt_parse(buf,len+1-2) < 0)
- return(-1);
- /* This is a hack. It does not belong here but should really be in */
- /* encrypt_parse() but in K95 the encrypt_parse() routine does not */
- /* have access to the telopt_states array. */
- if ( buf[1] == ENCRYPT_REQEND )
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
- else if ( buf[1] == ENCRYPT_REQSTART )
- TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
- #ifdef OS2
- ipadl25();
- #endif /* OS2 */
- #endif /* ENCRYPTION */
- return(0);
- }
- /* C K _ K R B _ E N C R Y P T I N G
- * Returns 1 if we are encrypting and 0 if we are not
- */
- int
- #ifdef CK_ANSIC
- ck_tn_encrypting(VOID)
- #else /* CK_ANSIC */
- ck_tn_encrypting()
- #endif /* CK_ANSIC */
- {
- #ifdef CK_ENCRYPTION
- if ( g_kstream == NULL )
- return(0);
- if ( g_kstream->encrypt && encrypt_is_encrypting()) {
- debug(F111,"ck_tn_encrypting","encrypting",
- g_kstream->encrypt_type);
- return(g_kstream->encrypt_type);
- }
- #endif /* CK_ENCRYPTION */
- debug(F110,"ck_tn_encrypting","not encrypting",0);
- return(0);
- }
- /* C K _ K R B _ D E C R Y P T I N G
- * Returns 1 if we are decrypting and 0 if we are not
- */
- int
- #ifdef CK_ANSIC
- ck_tn_decrypting(VOID)
- #else
- ck_tn_decrypting()
- #endif /* CK_ANSIC */
- {
- #ifdef CK_ENCRYPTION
- if ( g_kstream == NULL )
- return(0);
- if ( g_kstream->decrypt && encrypt_is_decrypting()) {
- debug(F111,"ck_tn_decrypting","decrypting",
- g_kstream->decrypt_type);
- return(g_kstream->decrypt_type);
- }
- #endif /* CK_ENCRYPTION */
- debug(F110,"ck_tn_decrypting","not decrypting",0);
- return(0);
- }
- /* C K _ K R B _ A U T H E N T I C A T E D
- * Returns the authentication type: AUTHTYPE_NULL, AUTHTYPE_KERBEROS4,
- * or AUTHTYPE_KERBEROS5, AUTHTYPE_SRP, ... (see ckctel.h)
- */
- int
- #ifdef CK_ANSIC
- ck_tn_authenticated(VOID)
- #else
- ck_tn_authenticated()
- #endif
- {
- return(authentication_version);
- }
- /* C K _ K R B _ E N C R Y P T
- * encrypts n characters in s if we are encrypting
- */
- VOID
- #ifdef CK_ANSIC
- ck_tn_encrypt( char * s, int n )
- #else
- ck_tn_encrypt( s,n ) char * s; int n;
- #endif
- {
- #ifdef CK_ENCRYPTION
- struct kstream_data_block i;
- if (g_kstream->encrypt && encrypt_is_encrypting()) {
- #ifdef DEBUG
- hexdump("from plaintext", s, n);
- #endif
- i.ptr = s;
- i.length = n;
- g_kstream->encrypt(&i, NULL);
- #ifdef DEBUG
- hexdump("to cyphertext", s, n);
- #endif
- }
- else debug(F101,"ck_tn_encrypt not encrypting","",n);
- #endif /* ENCRYPTION */
- }
- /* C K _ K R B _ D E C R Y P T
- * decrypts n characters in s if we are decrypting
- */
- VOID
- #ifdef CK_ANSIC
- ck_tn_decrypt( char * s, int n )
- #else
- ck_tn_decrypt( s,n ) char * s; int n;
- #endif
- {
- #ifdef CK_ENCRYPTION
- struct kstream_data_block i;
- if (g_kstream->decrypt && encrypt_is_decrypting()) {
- #ifdef DEBUG
- hexdump("from cyphertext", s, n);
- #endif
- i.ptr = s;
- i.length = n;
- g_kstream->decrypt(&i, NULL);
- #ifdef DEBUG
- hexdump("to plaintext", s, n);
- #endif
- }
- else debug(F101,"ck_tn_decrypt not decrypting","",n);
- #endif /* ENCRYPTION */
- }
- /* S E N D K 5 A U T H S B
- * Send a Kerberos 5 Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
- static int
- #ifdef CK_ANSIC
- SendK5AuthSB(int type, void *data, int len)
- #else
- SendK5AuthSB(type,data,len) int type; void *data; int len;
- #endif
- {
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
- #ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
- #endif /* CK_SSL */
- if ( type < 0 || type > 6 ) /* Check for invalid values */
- return(0);
- if (!cd) {
- cd = (unsigned char *)"";
- len = 0;
- }
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_KERBEROS_V5;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
- #ifdef CK_ENCRYPTION
- *p |= auth_crypt;
- #endif
- #ifdef USE_INI_CRED_FWD
- if (auth_fwd)
- *p |= INI_CRED_FWD_ON;
- #endif /* USE_INI_CRED_FWD */
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF)
- #ifdef USE_INI_CRED_FWD
- | (auth_fwd?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
- #endif /* USE_INI_CRED_FWD */
- ;
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "RESPONSE";
- break;
- case 4:
- s = "FORWARD";
- break;
- case 5:
- s = "FORWARD_ACCEPT";
- break;
- case 6:
- s = "FORWARD_REJECT";
- break;
- }
- sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
- TELOPT(TELOPT_AUTHENTICATION),
- str_data[3] == TELQUAL_IS ? "IS" :
- str_data[3] == TELQUAL_REPLY ? "REPLY" : "???",
- authtype_names[authentication_version],
- authmode_names[mode],
- s);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=7;i<deblen;i++ ) {
- if ( str_data[i] < 32 || str_data[i] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&str_data[7],deblen-7);
- hexbuf[deblen-7] = ' ';
- hexbuf[deblen-6] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Send data */
- rc = ttol((CHAR *)str_data, p - str_data);
- debug(F111,"SendK5AuthSB","ttol()",rc);
- return(rc);
- }
- /* S E N D K 4 A U T H S B
- * Send a Kerberos 4 Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
- static int
- #ifdef CK_ANSIC
- SendK4AuthSB(int type, void *data, int len)
- #else
- SendK4AuthSB(type,data,len) int type; void *data; int len;
- #endif
- {
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
- int mode = (auth_how & AUTH_HOW_MASK) |
- (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF) ;
- if ( type < 0 || type > 4 ) /* Check for invalid values */
- return(0);
- #ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
- #endif /* CK_SSL */
- if (!cd) {
- cd = (unsigned char *)"";
- len = 0;
- }
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_KERBEROS_V4;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= mode;
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "CHALLENGE";
- break;
- case 4:
- s = "RESPONSE";
- break;
- }
- sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
- TELOPT(TELOPT_AUTHENTICATION),
- str_data[3] == TELQUAL_IS ? "IS" :
- (str_data[3] == TELQUAL_REPLY ? "REPLY" : "???"),
- authtype_names[authentication_version],
- authmode_names[mode],
- s);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=7;i<deblen;i++ ) {
- if ( str_data[i] < 32 || str_data[i] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&str_data[7],deblen-7);
- hexbuf[deblen-7] = ' ';
- hexbuf[deblen-6] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Send data */
- rc = ttol((CHAR *)str_data, p - str_data);
- debug(F111,"SendK4AuthSB","ttol()",rc);
- return(rc);
- }
- /* S E N D S R P A U T H S B
- * Send a SRP Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
- static int
- #ifdef CK_ANSIC
- SendSRPAuthSB(int type, void *data, int len)
- #else
- SendSRPAuthSB(type,data,len) int type; void *data; int len;
- #endif
- {
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
- /* Check for invalid values */
- if ( type != SRP_EXP && type != SRP_RESPONSE &&
- type != SRP_REJECT && type != SRP_ACCEPT &&
- type != SRP_CHALLENGE && type != SRP_PARAMS &&
- type != SRP_AUTH)
- return(0);
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_SRP;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
- #ifdef CK_ENCRYPTION
- *p |= auth_crypt;
- #endif
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
- switch (type) {
- case 0:
- s = "AUTH";
- break;
- case 1:
- s = "REJECT";
- break;
- case 2:
- s = "ACCEPT";
- break;
- case 3:
- s = "CHALLENGE";
- break;
- case 4:
- s = "RESPONSE";
- break;
- case 5:
- s = "FORWARD";
- break;
- case 6:
- s = "FORWARD_ACCEPT";
- break;
- case 7:
- s = "FORWARD_REJECT";
- break;
- case 8:
- s = "EXP";
- break;
- case 9:
- s = "PARAMS";
- break;
- }
- sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
- TELOPT(TELOPT_AUTHENTICATION),
- str_data[3] == TELQUAL_REPLY ? "REPLY" :
- str_data[3] == TELQUAL_IS ? "IS" : "???",
- authtype_names[authentication_version],
- authmode_names[mode],
- s);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=7;i<deblen;i++ ) {
- if ( str_data[i] < 32 || str_data[i] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&str_data[7],deblen-7);
- hexbuf[deblen-7] = ' ';
- hexbuf[deblen-6] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Send data */
- rc = ttol((CHAR *)str_data, p - str_data);
- return(rc);
- }
- #ifdef CK_ENCRYPTION
- /*
- * Function: Enable or disable the encryption process.
- *
- * Parameters:
- * enable - TRUE to enable, FALSE to disable.
- */
- static VOID
- #ifdef CK_ANSIC
- auth_encrypt_enable(BOOL enable)
- #else
- auth_encrypt_enable(enable) BOOL enable;
- #endif
- {
- encrypt_flag = enable;
- }
- #endif
- /*
- * Function: Abort the authentication process
- *
- * Parameters:
- */
- static VOID
- #ifdef CK_ANSIC
- auth_abort(char *errmsg, long r)
- #else
- auth_abort(errmsg,r) char *errmsg; long r;
- #endif
- {
- char buf[9];
- extern int sstelnet;
- #ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- return;
- }
- #endif /* CK_SSL */
- debug(F111,"auth_abort",errmsg,r);
- /* Construct Telnet Debugging messages */
- if (deblog || tn_deb || debses) {
- sprintf(tn_msg,"TELNET SENT SB %s IS %s %s IAC SE",
- TELOPT(TELOPT_AUTHENTICATION),
- authtype_names[AUTHTYPE_NULL],
- authtype_names[AUTHTYPE_NULL]);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Construct the Abort message to send to the host */
- /* Basicly we change the authentication type to NULL */
- sprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
- sstelnet ? TELQUAL_REPLY : TELQUAL_IS, AUTHTYPE_NULL,
- AUTHTYPE_NULL, IAC, SE);
- ttol((CHAR *)buf, 8);
- /* If there is an error message, and error number construct */
- /* an explanation to display to the user */
- if (errmsg != NULL) {
- ckstrncpy(strTmp, errmsg, AUTHTMPBL);
- } else
- strTmp[0] = ' ';
- if (r != AUTH_SUCCESS) {
- strcat(strTmp, "rn");
- #ifdef KRB4
- if ( authentication_version == AUTHTYPE_KERBEROS_V4 ) {
- strcat(strTmp, (char *)krb_get_err_text_entry(r));
- debug(F111,"auth_abort",(char *)krb_get_err_text_entry(r),r);
- }
- #endif
- #ifdef KRB5
- if ( authentication_version == AUTHTYPE_KERBEROS_V5 ) {
- strcat(strTmp, error_message(r));
- debug(F111,"auth_abort",error_message(r),r);
- }
- #endif
- }
- printf("Authentication failed: %srn",strTmp);
- #ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_LI && ckxlogging) {
- cksyslog(SYSLG_LI, 0, "Telnet authentication failure",
- (char *) szUserNameRequested,
- strTmp);
- }
- #endif /* CKSYSLOG */
- authentication_version = AUTHTYPE_NULL;
- }
- /*
- * Function: Copy data to buffer, doubling IAC character if present.
- *
- */
- static int
- #ifdef CK_ANSIC
- copy_for_net(unsigned char *to, unsigned char *from, int c)
- #else
- copy_for_net(to,from,c) unsigned char *to; unsigned char *from; int c;
- #endif
- {
- int n;
- n = c;
- debug(F111,"copy_for_net","before",n);
- while (c-- > 0) {
- if ((*to++ = *from++) == IAC) {
- n++;
- *to++ = IAC;
- }
- }
- debug(F111,"copy_for_net","after",n);
- return n;
- }
- #ifdef CK_SSL
- /* S E N D S S L A U T H S B
- * Send a SSL Authentication Subnegotiation to host and
- * output appropriate Telnet Debug messages
- *
- * type - Sub Negotiation type
- * data - ptr to buffer containing data
- * len - len of buffer if not NUL terminated
- *
- * returns number of characters sent or error value
- */
- int
- #ifdef CK_ANSIC
- SendSSLAuthSB(int type, void *data, int len)
- #else
- SendSSLAuthSB(type,data,len) int type; void *data; int len;
- #endif
- {
- int rc;
- unsigned char *p = str_data + 3;
- unsigned char *cd = (unsigned char *)data;
- extern int sstelnet;
- /* Check for invalid values */
- if ( type != SSL_START && type != SSL_ACCEPT &&
- type != SSL_REJECT)
- return(0);
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
- if (ttchk() < 0)
- return(0);
- else
- return(1);
- }
- if (len == -1) /* Use strlen() for len */
- len = strlen((char *)cd);
- /* Construct Message */
- *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
- *p++ = AUTHTYPE_SSL;
- *p = AUTH_CLIENT_TO_SERVER;
- *p |= auth_how;
- #ifdef CK_ENCRYPTION
- *p |= auth_crypt;
- #endif
- p++;
- *p++ = type;
- while (len-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- /* Handle Telnet Debugging Messages */
- if (deblog || tn_deb || debses) {
- int i;
- int deblen=p-str_data-2;
- char *s=NULL;
- int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
- switch (type) {
- case SSL_START:
- s = "START";
- break;
- case SSL_ACCEPT:
- s = "ACCEPT";
- break;
- case SSL_REJECT:
- s = "REJECT";
- break;
- }
- sprintf(tn_msg,"TELNET SENT SB %s %s %s %s %s ",
- TELOPT(TELOPT_AUTHENTICATION),
- str_data[3] == TELQUAL_REPLY ? "REPLY" :
- str_data[3] == TELQUAL_IS ? "IS" : "???",
- authtype_names[authentication_version],
- authmode_names[mode],
- s);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=7;i<deblen;i++ ) {
- if ( str_data[i] < 32 || str_data[i] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",str_data[i]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",str_data[i]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&str_data[7],deblen-7);
- hexbuf[deblen-7] = ' ';
- hexbuf[deblen-6] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Send data */
- rc = ttol((CHAR *)str_data, p - str_data);
- return(rc);
- }
- #endif /* CK_SSL */
- int
- tn_how_ok(int how)
- {
- switch ( tn_auth_how ) {
- case TN_AUTH_HOW_ANY:
- return(1);
- case TN_AUTH_HOW_ONE_WAY:
- return((how & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY);
- case TN_AUTH_HOW_MUTUAL:
- return((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL);
- default:
- return(0);
- }
- }
- int
- tn_enc_ok(int enc)
- {
- switch ( tn_auth_enc ) {
- case TN_AUTH_ENC_ANY:
- return(1);
- case TN_AUTH_ENC_NONE:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_OFF);
- case TN_AUTH_ENC_TELOPT:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT);
- case TN_AUTH_ENC_EXCH:
- return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_AFTER_EXCHANGE);
- default:
- return(0);
- }
- }
- static int
- atok(int at) {
- int i;
- if ( auth_type_user[0] == AUTHTYPE_AUTO )
- return(1);
- if ( auth_type_user[0] == AUTHTYPE_NULL )
- return(0);
- for ( i=0;
- i<AUTHTYPLSTSZ && auth_type_user[i] != AUTHTYPE_NULL;
- i++ ) {
- if ( auth_type_user[i] == at )
- return(1);
- }
- return(0);
- }
- /*
- * Function: Parse authentication send command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
- static int
- #ifdef CK_ANSIC
- auth_send(unsigned char *parsedat, int end_sub)
- #else
- auth_send(parsedat,end_sub) unsigned char *parsedat; int end_sub;
- #endif
- {
- unsigned char buf[1024];
- unsigned char *pname;
- int plen;
- int r;
- int i;
- int mode;
- #ifdef MIT_CURRENT
- #ifdef CK_ENCRYPTION
- krb5_data data;
- krb5_enc_data encdata;
- krb5_error_code code;
- krb5_keyblock random_key;
- #endif /* ENCRYPTION */
- #endif /* MIT_CURRENT */
- #ifdef KRB5
- int krb5_msg = 0;
- #endif /* KRB5 */
- #ifdef KRB4
- int krb4_msg = 0;
- #endif /* KRB4 */
- #ifdef CK_SSL
- if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
- return(AUTH_SUCCESS);
- #endif /* CK_SSL */
- auth_how = -1; /* We have not found an auth method */
- auth_crypt = 0; /* We are not using encryption (yet) */
- /* Search the list of acceptable Authentication types sent from */
- /* the host and find one that we support */
- /* For Kerberos authentications, try to determine if we have a */
- /* valid TGT, if not skip over the authentication type because */
- /* we wouldn't be able to successfully login anyway. Perhaps */
- /* there is another supported authentication which we could use */
- #ifdef NO_FTP_AUTH
- /* If the userid is "ftp" or "anonymous" refuse to perform AUTH */
- /* for Kerberos or SRP. */
- #endif /* NO_FTP_AUTH */
- if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
- for (i = 2; i+1 <= end_sub; i += 2) {
- #ifdef NTLM
- if (parsedat[i] == AUTHTYPE_NTLM &&
- ck_ntlm_is_valid() &&
- ntlm_auth_send() == 0) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- /* NTLM does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- #endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_NTLM;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* NTLM */
- #ifdef CK_SSL
- if ( parsedat[i] == AUTHTYPE_SSL && ssl_initialized &&
- #ifdef SSLDLL
- ck_ssleay_is_installed() &&
- #endif /* SSLDLL */
- !tls_active_flag && !ssl_active_flag && ssl_load_certs()
- ) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- /* SSL does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- #endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_SSL;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* SSL */
- #ifdef CK_SRP
- if ( parsedat[i] == AUTHTYPE_SRP
- #ifdef SRPDLL
- && hSRP
- #endif /* SRPDLL */
- #ifdef NO_FTP_AUTH
- && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
- #endif /* NO_FTP_AUTH */
- ) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK)
- #ifndef PRE_SRP_1_4_5
- /* Do not support ENCRYPT_USING_TELOPT yet. */
- &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF)
- #endif /* PRE_SRP_1_4_5 */
- )
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_SRP;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* SRP */
- #ifdef KRB5
- if (parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
- #ifdef OS2
- hKRB5_32 &&
- #endif /* OS2 */
- #ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
- #endif /* NO_FTP_AUTH */
- ck_krb5_is_installed() && !krb5_msg) {
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
- /* Skip over entries that request credential forwarding */
- /* if we are not forwarding. */
- if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
- (forward_flag &&
- ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
- continue;
- if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf("Kerberos 5: Ticket Getting Ticket not valid.rn");
- }
- krb5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
- authentication_version = AUTHTYPE_KERBEROS_V5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
- #endif /* KRB5 */
- #ifdef KRB4
- if (parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
- #ifdef OS2
- hKRB4_32 &&
- #endif /* OS2 */
- #ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
- #endif /* NO_FTP_AUTH */
- ck_krb4_is_installed() && !krb4_msg) {
- int rc = 0;
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed() )
- continue;
- if ( !k4_auth_send() )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb4_is_tgt_valid() ) {
- printf("Kerberos 4: Ticket Getting Ticket not valid.rn");
- }
- krb4_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_KERBEROS_V4;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
- #endif /* KRB4 */
- }
- } else {
- for (i = 2; i+1 <= end_sub; i += 2) {
- #ifdef CK_SSL
- if ( atok(AUTHTYPE_SSL) && parsedat[i] == AUTHTYPE_SSL &&
- #ifdef SSLDLL
- ck_ssleay_is_installed() &&
- #endif /* SSLDLL */
- !tls_active_flag && !ssl_active_flag && ssl_initialized &&
- ssl_load_certs()
- )
- {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- /* SSL does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- #endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_SSL;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* SSL */
- #ifdef CK_SRP
- if ( atok(AUTHTYPE_SRP) &&
- parsedat[i] == AUTHTYPE_SRP
- #ifdef SRPDLL
- && hSRP
- #endif /* SRPDLL */
- #ifdef NO_FTP_AUTH
- && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
- #endif /* NO_FTP_AUTH */
- ) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK)
- #ifndef PRE_SRP_1_4_5
- /* Do not support ENCRYPT_USING_TELOPT yet. */
- &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF)
- #endif /* PRE_SRP_1_4_5 */
- )
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_SRP;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* SRP */
- #ifdef KRB5
- if ( atok(AUTHTYPE_KERBEROS_V5) &&
- parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
- #ifdef OS2
- hKRB5_32 &&
- #endif /* OS2 */
- #ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
- #endif /* NO_FTP_AUTH */
- ck_krb5_is_installed() && !krb5_msg) {
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
- /* Skip over entries that request credential forwarding */
- /* if we are not forwarding. */
- if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
- (forward_flag &&
- ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
- continue;
- if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
- parsedat[i+1] & AUTH_ENCRYPT_MASK,
- parsedat[i+1] & INI_CRED_FWD_MASK) )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb5_is_tgt_valid() ) {
- printf(
- "Kerberos 5: Ticket Getting Ticket not valid.rn");
- }
- krb5_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
- {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if (auth_crypt) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_KERBEROS_V5;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
- #endif /* KRB5 */
- #ifdef KRB4
- if ( atok(AUTHTYPE_KERBEROS_V4) &&
- parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
- #ifdef OS2
- hKRB4_32 &&
- #endif /* OS2 */
- #ifdef NO_FTP_AUTH
- strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
- #endif /* NO_FTP_AUTH */
- ck_krb4_is_installed() && !krb4_msg) {
- int rc = 0;
- /* Without encryption we can't perform mutual authentication */
- if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
- !ck_crypt_is_installed())
- continue;
- if ( !k4_auth_send() )
- {
- /* If we are auto-getting TGTs, try */
- if ( !ck_krb4_is_tgt_valid() ) {
- printf("Kerberos 4: Ticket Getting Ticket not valid.rn");
- }
- krb4_msg = 1;
- }
- else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
- AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
- {
- #ifdef CK_ENCRYPTION
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
- (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
- TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- if (auth_crypt) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- #endif /* CK_ENCRYPTION */
- authentication_version = AUTHTYPE_KERBEROS_V4;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- if ( auth_how == AUTH_HOW_ONE_WAY ) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- }
- break;
- }
- }
- #endif /* KRB4 */
- #ifdef NTLM
- if ( atok(AUTHTYPE_NTLM) &&
- parsedat[i] == AUTHTYPE_NTLM &&
- ck_ntlm_is_valid() &&
- ntlm_auth_send() == 0) {
- if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
- tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
- #ifdef CK_ENCRYPTION
- /* NTLM does not support Telnet Encryption */
- if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
- continue;
- auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
- #endif /* CK_ENCRYPTION */
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- authentication_version = AUTHTYPE_NTLM;
- auth_how = parsedat[i+1] & AUTH_HOW_MASK;
- break;
- }
- }
- #endif /* NTLM */
- }
- }
- if (auth_how == -1) { /* Did we find one? */
- switch ( auth_type_user[0] ) { /* If not, abort the negotiation */
- case AUTHTYPE_NULL:
- auth_abort("User refused to accept any authentication method",0);
- break;
- case AUTHTYPE_AUTO:
- auth_abort("No authentication method available", 0);
- break;
- default: {
- char msg[80];
- sprintf(msg,"%s could not be negotiated",
- authtype_names[auth_type_user[0]]);
- auth_abort(msg, 0);
- }
- }
- auth_finished(AUTH_REJECT);
- return AUTH_FAILURE;
- }
- printf("Authenticating with %srn",
- authtype_names[authentication_version]);
- /* Send Telnet Auth Name message (if necessary) */
- switch ( authentication_version ) {
- case AUTHTYPE_SRP:
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_KERBEROS_V5:
- /* if we do not have a name to login with get one now. */
- while ( szUserName[0] == ' ' ) {
- extern char * tn_pr_uid;
- readtext(tn_pr_uid && tn_pr_uid[0] ? tn_pr_uid : "Host Userid: ",
- szUserName,63);
- }
- plen = strlen(szUserName);
- pname = (unsigned char *) szUserName;
- /* Construct Telnet Debugging Message */
- if (deblog || tn_deb || debses) {
- sprintf(tn_msg,"TELNET SENT SB %s NAME %s IAC SE",
- TELOPT(TELOPT_AUTHENTICATION),
- pname);
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- /* Construct and send Authentication Name subnegotiation */
- sprintf(buf, "%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_NAME);
- memcpy(&buf[4], pname, plen);
- sprintf(&buf[plen + 4], "%c%c", IAC, SE);
- ttol((CHAR *)buf, plen+6);
- }
- /* Construct Authentication Mode subnegotiation message (if necessary) */
- switch ( authentication_version ) {
- case AUTHTYPE_SRP:
- case AUTHTYPE_KERBEROS_V4:
- case AUTHTYPE_KERBEROS_V5:
- case AUTHTYPE_NTLM:
- mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
- (auth_crypt ? AUTH_ENCRYPT_USING_TELOPT : AUTH_ENCRYPT_OFF)
- #ifdef USE_INI_CRED_FWD
- | (((authentication_version == AUTHTYPE_KERBEROS_V5) &&
- auth_fwd)?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
- #endif /* USE_INI_CRED_FWD */
- ;
- sprintf(buf, "%c%c%c%c%c%c%c",
- IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_IS,
- authentication_version,
- mode,
- KRB_AUTH);
- break;
- }
- /* Send initial authentication data */
- switch ( authentication_version ) {
- #ifdef CK_SSL
- case AUTHTYPE_SSL:
- SendSSLAuthSB(SSL_START,NULL,0);
- break;
- #endif /* SSL */
- #ifdef CK_SRP
- case AUTHTYPE_SRP:
- sprintf(&buf[7], "%c%c", IAC, SE);
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
- TELOPT(TELOPT_AUTHENTICATION),
- authtype_names[authentication_version],
- authmode_names[mode]);
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- ttol((CHAR *)buf, 9);
- break;
- #endif /* SRP */
- #ifdef NTLM
- case AUTHTYPE_NTLM: {
- int length = 0;
- length = copy_for_net(&buf[7],(char *)&NTLMSecBuf[0],2*sizeof(ULONG));
- length += copy_for_net(&buf[7+length], NTLMSecBuf[0].pvBuffer,
- NTLMSecBuf[0].cbBuffer);
- sprintf(&buf[7+length], "%c%c", IAC, SE);
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s IS %s %s NTLM_AUTH ",
- TELOPT(TELOPT_AUTHENTICATION),
- authtype_names[authentication_version],
- authmode_names[mode]);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=0;i<length;i++ ) {
- if ( buf[i+7] < 32 || buf[i+7] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&buf[7],length);
- hexbuf[length] = ' ';
- hexbuf[length+1] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- ttol((CHAR *)buf, length+9);
- break;
- }
- #endif /* NTLM */
- #ifdef KRB4
- case AUTHTYPE_KERBEROS_V4:
- k4_auth.length = copy_for_net(&buf[7], k4_auth.dat, k4_auth.length);
- sprintf(&buf[k4_auth.length+7], "%c%c", IAC, SE);
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
- TELOPT(TELOPT_AUTHENTICATION),
- authtype_names[authentication_version],
- authmode_names[mode]);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=0;i<k4_auth.length;i++ ) {
- if ( buf[i+7] < 32 || buf[i+7] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&buf[7],k4_auth.length);
- hexbuf[k4_auth.length] = ' ';
- hexbuf[k4_auth.length+1] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- ttol((CHAR *)buf, k4_auth.length+9);
- #ifndef REMOVE_FOR_EXPORT
- #ifdef CK_ENCRYPTION
- /*
- * If we are doing mutual authentication, get set up to send
- * the challenge, and verify it when the response comes back.
- */
- if ((auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- register int i;
- int rc = 0;
- #ifdef MIT_CURRENT
- data.data = cred.session;
- data.length = 8; /* sizeof(cred.session) */;
- if (code = krb5_c_random_seed(k5_context, &data)) {
- com_err("libtelnet", code,
- "while seeding random number generator");
- return(0);
- }
- if (code = krb5_c_make_random_key(k5_context,
- ENCTYPE_DES_CBC_RAW,
- &random_key)) {
- com_err("libtelnet", code,
- "while creating random session key");
- return(0);
- }
- /* the krb4 code uses ecb mode, but on a single block
- with a zero ivec, ecb and cbc are the same */
- k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
- k4_krbkey.length = 8;
- k4_krbkey.contents = cred.session;
- encdata.ciphertext.data = random_key.contents;
- encdata.ciphertext.length = random_key.length;
- encdata.enctype = ENCTYPE_UNKNOWN;
- data.data = k4_session_key;
- data.length = 8;
- code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
- &encdata, &data);
- krb5_free_keyblock_contents(k5_context, &random_key);
- if (code) {
- com_err("libtelnet", code, "while encrypting random key");
- return(0);
- }
- encdata.ciphertext.data = k4_session_key;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
- data.data = k4_challenge;
- data.length = 8;
- code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
- &encdata, &data);
- #else /* MIT_CURRENT */
- memset(k4_sched,0,sizeof(Schedule));
- hexdump("auth_send",cred.session,8);
- rc = des_key_sched(cred.session, k4_sched);
- if ( rc == -1 ) {
- printf("?Invalid DES key specified in credentialsrn");
- debug(F110,"auth_send",
- "invalid DES Key specified in credentials",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified in credentialsrn");
- debug(F110,"auth_send",
- "weak DES Key specified in credentials",0);
- } else if ( rc != 0 ) {
- printf("?DES Key Schedule not set by credentialsrn");
- debug(F110,"auth_send",
- "DES Key Schedule not set by credentials",0);
- }
- hexdump("auth_send schedule",k4_sched,8*16);
- des_set_random_generator_seed(cred.session);
- do {
- des_new_random_key(k4_session_key);
- des_fixup_key_parity(k4_session_key);
- } while ( ck_des_is_weak_key(k4_session_key) );
- hexdump("auth_send des_new_random_key(k4_session_key)",
- k4_session_key,8);
- /* Decrypt the session key so that we can send it to the */
- /* host as a challenge */
- #ifdef NT
- des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 0);
- #else /* NT */
- des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 0);
- #endif /* NT */
- hexdump(
- "auth_send des_ecb_encrypt(k4_session_key,k4_session_key,0)",
- k4_session_key,8
- );
- /* Prepare the result of the challenge */
- /* Decrypt the session_key, add 1, and then encrypt it */
- /* The result stored in k4_challenge should match the */
- /* KRB4_RESPONSE value from the host. */
- #ifdef NT
- des_ecb_encrypt(k4_session_key, k4_challenge, k4_sched, 0);
- #else /* NT */
- des_ecb_encrypt(&k4_session_key, &k4_challenge, k4_sched, 0);
- #endif /* NT */
- hexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,0)",
- k4_challenge,8);
- #endif /* MIT_CURRENT */
- /*
- * Increment the challenge by 1, and encrypt it for
- * later comparison.
- */
- for (i = 7; i >= 0; --i) {
- register int x;
- x = (unsigned int)k4_challenge[i] + 1;
- k4_challenge[i] = x; /* ignore overflow */
- if (x < 256) /* if no overflow, all done */
- break;
- }
- hexdump("auth_send k4_challenge+1",k4_challenge,8);
- #ifdef MIT_CURRENT
- data.data = k4_challenge;
- data.length = 8;
- encdata.ciphertext.data = k4_challenge;
- encdata.ciphertext.length = 8;
- encdata.enctype = ENCTYPE_UNKNOWN;
- if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0, &data,
- &encdata)) {
- com_err("libtelnet", code, "while encrypting random key");
- return(0);
- }
- #else /* MIT_CURRENT */
- #ifdef NT
- des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
- #else /* NT */
- des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
- #endif /* NT */
- hexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,1)",
- k4_challenge,8);
- #endif /* MIT_CURRENT */
- }
- #endif /* ENCRYPTION */
- #endif /* REMOVE_FOR_EXPORT */
- break;
- #endif /* KRB4 */
- #ifdef KRB5
- case AUTHTYPE_KERBEROS_V5:
- k5_auth.length = copy_for_net(&buf[7], k5_auth.data, k5_auth.length);
- sprintf(&buf[k5_auth.length+7], "%c%c", IAC, SE);
- if (deblog || tn_deb || debses) {
- int i;
- sprintf(tn_msg,"TELNET SENT SB %s IS %s %s AUTH ",
- TELOPT(TELOPT_AUTHENTICATION),
- authtype_names[authentication_version],
- authmode_names[mode]);
- #ifdef HEXDISP
- {
- int was_hex = 1;
- for ( i=0;i<k5_auth.length;i++ ) {
- if ( buf[i+7] < 32 || buf[i+7] >= 127) {
- sprintf(hexbuf,"%s%02X ",was_hex?"":"" ",buf[i+7]);
- was_hex = 1;
- } else {
- sprintf(hexbuf,"%s%c",was_hex?""":"",buf[i+7]);
- was_hex = 0;
- }
- strcat(tn_msg,hexbuf);
- }
- if ( !was_hex )
- strcat(tn_msg,"" ");
- }
- #else /* HEXDISP */
- memcpy(hexbuf,&buf[7],k5_auth.length);
- hexbuf[k5_auth.length] = ' ';
- hexbuf[k5_auth.length+1] = ' ';
- strcat(tn_msg,hexbuf);
- #endif /* HEXDISP */
- strcat(tn_msg,"IAC SE");
- debug(F100,tn_msg,"",0);
- if (tn_deb || debses) tn_debug(tn_msg);
- }
- ttol((CHAR *)buf, k5_auth.length+9);
- break;
- #endif /* KRB5 */
- }
- return AUTH_SUCCESS;
- }
- /*
- * Function: Parse authentication REPLY command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
- static int
- #ifdef CK_ANSIC
- auth_reply(unsigned char *parsedat, int end_sub)
- #else
- auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
- #endif
- {
- int n = AUTH_FAILURE;
- if ( parsedat[2] != authentication_version ) {
- printf("Authentication version mismatch (%s [%d] != %s [%d])rn",
- AUTHTYPE_NAME(parsedat[2]),parsedat[2],
- AUTHTYPE_NAME(authentication_version),authentication_version);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
- printf("Authentication mode mismatch (%s != %s)rn",
- AUTHMODE_NAME(parsedat[3]),
- AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- #ifdef KRB4
- if (authentication_version == AUTHTYPE_KERBEROS_V4)
- n = k4_auth_reply(parsedat, end_sub);
- #endif
- #ifdef KRB5
- if (authentication_version == AUTHTYPE_KERBEROS_V5)
- n = k5_auth_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
- #endif
- #ifdef CK_SRP
- if (authentication_version == AUTHTYPE_SRP)
- n = srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
- #endif /* SRP */
- #ifdef CK_SSL
- if (authentication_version == AUTHTYPE_SSL)
- n = ssl_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
- #endif /* SSL */
- #ifdef NTLM
- if (authentication_version == AUTHTYPE_NTLM)
- n = ntlm_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
- #endif /* NTLM */
- return n;
- }
- /*
- * Function: Parse authentication IS command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
- static int
- #ifdef CK_ANSIC
- auth_is(unsigned char *parsedat, int end_sub)
- #else
- auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
- #endif
- {
- int n = AUTH_FAILURE;
- if ( authentication_version == AUTHTYPE_AUTO ) {
- authentication_version = parsedat[2];
- auth_how = (parsedat[3] & AUTH_HOW_MASK);
- auth_crypt = (parsedat[3] & AUTH_ENCRYPT_MASK);
- auth_fwd = (parsedat[3] & INI_CRED_FWD_MASK);
- debug(F111,"auth_is","authentication_version",authentication_version);
- debug(F111,"auth_is","auth_how",auth_how);
- debug(F111,"auth_is","auth_crypt",auth_crypt);
- debug(F111,"auth_is","auth_fwd",auth_fwd);
- }
- if ( parsedat[2] != authentication_version ) {
- printf("Authentication version mismatch (%s [%d] != %s [%d])rn",
- AUTHTYPE_NAME(parsedat[2]),parsedat[2],
- AUTHTYPE_NAME(authentication_version),authentication_version);
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
- printf("Authentication mode mismatch (%s != %s)rn",
- AUTHMODE_NAME(parsedat[3]),
- AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
- auth_finished(AUTH_REJECT);
- return(AUTH_FAILURE);
- }
- #ifdef KRB4
- if (authentication_version == AUTHTYPE_KERBEROS_V4)
- n = k4_auth_is(parsedat, end_sub);
- #endif
- #ifdef KRB5
- if (authentication_version == AUTHTYPE_KERBEROS_V5)
- n = k5_auth_is(parsedat[3],parsedat, end_sub);
- #endif
- #ifdef CK_SRP
- if (authentication_version == AUTHTYPE_SRP)
- n = srp_is(parsedat[3], parsedat, end_sub);
- #endif /* SRP */
- #ifdef CK_SSL
- if (authentication_version == AUTHTYPE_SSL) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- n = ssl_is(parsedat, end_sub);
- }
- #endif /* SSL */
- #ifdef NTLM
- if (authentication_version == AUTHTYPE_NTLM) {
- TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- n = ntlm_is(parsedat, end_sub);
- }
- #endif /* NTLM */
- debug(F111,"auth_is","n",n);
- return n;
- }
- /*
- * Function: Parse authentication NAME command
- *
- * Parameters:
- * parsedat - the sub-command data.
- *
- * end_sub - index of the character in the 'parsedat' array which
- * is the last byte in a sub-negotiation
- *
- * Returns: Kerberos error code.
- */
- static int
- #ifdef CK_ANSIC
- auth_name(unsigned char *parsedat, int end_sub)
- #else
- auth_name(parsedat,end_sub) unsigned char *parsedat; int end_sub;
- #endif
- {
- int len = (end_sub-2) > 63 ? 63 : (end_sub-2);
- if ( len > 0 ) {
- memcpy(szUserNameRequested,&parsedat[2],len);
- szUserNameRequested[len] = ' ';
- } else
- szUserNameRequested[0] = ' ';
- debug(F111,"auth_name szUserNameRequested",szUserNameRequested,len);
- return(AUTH_SUCCESS);
- }
- /*
- * Function: Parse the athorization sub-options and reply.
- *
- * Parameters:
- * parsedat - sub-option string to parse.
- *
- * end_sub - last charcter position in parsedat.
- */
- int
- auth_parse(unsigned char *parsedat, int end_sub)
- {
- int rc = AUTH_FAILURE;
- switch (parsedat[1]) {
- case TELQUAL_SEND:
- rc = auth_send(parsedat, end_sub);
- break;
- case TELQUAL_REPLY:
- rc= auth_reply(parsedat, end_sub);
- break;
- case TELQUAL_IS:
- rc = auth_is(parsedat, end_sub);
- break;
- case TELQUAL_NAME:
- rc = auth_name(parsedat, end_sub);
- break;
- }
- debug(F111,"auth_parse","rc",rc);
- return(rc);
- }
- /*
- * Function: Initialization routine called kstream encryption system.
- *
- * Parameters:
- * data - user data.
- */
- int
- #ifdef CK_ANSIC
- auth_init(kstream ks)
- #else
- auth_init(ks) kstream_ptr ks;
- #endif
- {
- #ifdef FORWARD
- forwarded_tickets = 0; /* were tickets forwarded? */
- #endif /* FORWARD */
- #ifdef CK_ENCRYPTION
- encrypt_init(ks,cx_type);
- #endif
- return 0;
- }
- /*
- * Function: Destroy routine called kstream encryption system.
- *
- * Parameters:
- * data - user data.
- */
- VOID
- #ifdef CK_ANSIC
- auth_destroy(void)
- #else
- auth_destroy()
- #endif
- {
- }
- /*
- * Function: Callback to encrypt a block of characters
- *
- * Parameters:
- * out - return as pointer to converted buffer.
- *
- * in - the buffer to convert
- *
- * Returns: number of characters converted.
- */
- int
- #ifdef CK_ANSIC
- auth_encrypt(struct kstream_data_block *out,
- struct kstream_data_block *in)
- #else
- auth_encrypt(out,in)
- struct kstream_data_block *out; struct kstream_data_block *in;
- #endif
- {
- out->ptr = in->ptr;
- out->length = in->length;
- return(out->length);
- }