*/
#ifdef KRB4
+/* this code must be compiled in the krb5 tree. disgustingly, there
+ is code in here which declares structures which happen to mirror
+ the krb4 des structures. I didn't want to rototill this *completely*
+ so this is how it's going to work. --marc */
+#include <krb5.h>
#include <sys/types.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include "misc.h"
extern auth_debug_mode;
+extern krb5_context telnet_context;
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
AUTHTYPE_KERBEROS_V4, };
#ifdef ENCRYPTION
static Block session_key = { 0 };
static Schedule sched;
+static krb5_keyblock krbkey;
static Block challenge = { 0 };
#endif /* ENCRYPTION */
} else {
str_data[3] = TELQUAL_IS;
}
+
+ kerberos5_init(NULL, server);
+
return(1);
}
Authenticator *ap;
{
KTEXT_ST auth;
-#ifdef ENCRYPTION
- Block enckey;
-#endif /* ENCRYPTION */
char instance[INST_SZ];
char *realm;
char *krb_realmofhost();
char *krb_get_phost();
CREDENTIALS cred;
int r;
+#ifdef ENCRYPTION
+ krb5_data data;
+ krb5_enc_data encdata;
+ krb5_error_code code;
+ krb5_keyblock random_key;
+#endif
printf("[ Trying KERBEROS4 ... ]\r\n");
if (!UserNameRequested) {
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
register int i;
- des_key_sched(cred.session, sched);
- des_init_random_number_generator(cred.session);
- des_new_random_key(session_key);
- des_ecb_encrypt(session_key, session_key, sched, 0);
- des_ecb_encrypt(session_key, challenge, sched, 0);
+ data.data = cred.session;
+ data.length = 8; /* sizeof(cred.session) */;
+
+ if (code = krb5_c_random_seed(telnet_context, &data)) {
+ com_err("libtelnet", code,
+ "while seeding random number generator");
+ return(0);
+ }
+
+ if (code = krb5_c_make_random_key(telnet_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 */
+ krbkey.enctype = ENCTYPE_DES_CBC_RAW;
+ krbkey.length = 8;
+ krbkey.contents = cred.session;
+
+ encdata.ciphertext.data = random_key.contents;
+ encdata.ciphertext.length = random_key.length;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ data.data = session_key;
+ data.length = 8;
+
+ code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0,
+ &encdata, &data);
+
+ krb5_free_keyblock_contents(telnet_context, &random_key);
+
+ if (code) {
+ com_err("libtelnet", code, "while encrypting random key");
+ return(0);
+ }
+
+ encdata.ciphertext.data = session_key;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ data.data = challenge;
+ data.length = 8;
+
+ code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0,
+ &encdata, &data);
+
/*
* Increment the challenge by 1, and encrypt it for
* later comparison.
if (x < 256) /* if no overflow, all done */
break;
}
- des_ecb_encrypt(challenge, challenge, sched, 1);
+
+ data.data = challenge;
+ data.length = 8;
+
+ encdata.ciphertext.data = challenge;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0, &data,
+ &encdata)) {
+ com_err("libtelnet", code, "while encrypting random key");
+ return(0);
+ }
}
#endif /* ENCRYPTION */
{
#ifdef ENCRYPTION
Session_Key skey;
- Block datablock;
+ Block datablock, tmpkey;
+ krb5_data kdata;
+ krb5_enc_data encdata;
+ krb5_error_code code;
#endif /* ENCRYPTION */
char realm[REALM_SZ];
char instance[INST_SZ];
* Initialize the random number generator since it's
* used later on by the encryption routine.
*/
- des_init_random_number_generator(session_key);
- des_key_sched(session_key, sched);
+
+ kdata.data = session_key;
+ kdata.length = 8;
+
+ if (code = krb5_c_random_seed(telnet_context, &kdata)) {
+ com_err("libtelnet", code,
+ "while seeding random number generator");
+ return;
+ }
+
memcpy((void *)datablock, (void *)data, sizeof(Block));
/*
* Take the received encrypted challenge, and encrypt
* it again to get a unique session_key for the
* ENCRYPT option.
*/
- des_ecb_encrypt(datablock, session_key, sched, 1);
+ krbkey.enctype = ENCTYPE_DES_CBC_RAW;
+ krbkey.length = 8;
+ krbkey.contents = session_key;
+
+ kdata.data = datablock;
+ kdata.length = 8;
+
+ encdata.ciphertext.data = tmpkey;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0,
+ &kdata, &encdata)) {
+ com_err("libtelnet", code, "while encrypting random key");
+ return;
+ }
+
skey.type = SK_DES;
skey.length = 8;
- skey.data = session_key;
+ skey.data = tmpkey;
encrypt_session_key(&skey, 1);
/*
* Now decrypt the received encrypted challenge,
* increment by one, re-encrypt it and send it back.
*/
- des_ecb_encrypt(datablock, challenge, sched, 0);
+ encdata.ciphertext.data = datablock;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ kdata.data = challenge;
+ kdata.length = 8;
+
+ if (code = krb5_c_decrypt(telnet_context, &krbkey, 0, 0,
+ &encdata, &kdata)) {
+ com_err("libtelnet", code, "while decrypting challenge");
+ return;
+ }
+
for (r = 7; r >= 0; r--) {
register int t;
t = (unsigned int)challenge[r] + 1;
if (t < 256) /* if no overflow, all done */
break;
}
- des_ecb_encrypt(challenge, challenge, sched, 1);
+
+ kdata.data = challenge;
+ kdata.length = 8;
+
+ encdata.ciphertext.data = challenge;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ if (code = krb5_c_encrypt(telnet_context, &krbkey, 0, 0,
+ &kdata, &encdata)) {
+ com_err("libtelnet", code, "while decrypting challenge");
+ return;
+ }
+
Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge));
#endif /* ENCRYPTION */
break;
{
#ifdef ENCRYPTION
Session_Key skey;
+ krb5_data kdata;
+ krb5_enc_data encdata;
+ krb5_error_code code;
+
#endif /* ENCRYPTION */
if (cnt-- < 1)
#else /* ENCRYPTION */
Data(ap, KRB_CHALLENGE, (void *)session_key,
sizeof(session_key));
- des_ecb_encrypt(session_key, session_key, sched, 1);
+
+ kdata.data = session_key;
+ kdata.length = 8;
+
+ encdata.ciphertext.data = session_key;
+ encdata.ciphertext.length = 8;
+ encdata.enctype = ENCTYPE_UNKNOWN;
+
+ if (code = krb5_c_encrypt(telnet_context, &krbkey,
+ 0, 0, &kdata, &encdata)) {
+ com_err("libtelnet", code,
+ "while encrypting session_key");
+ return;
+ }
+
skey.type = SK_DES;
skey.length = 8;
skey.data = session_key;