diff options
author | Marc Horowitz <marc@mit.edu> | 1998-10-30 02:56:35 +0000 |
---|---|---|
committer | Marc Horowitz <marc@mit.edu> | 1998-10-30 02:56:35 +0000 |
commit | 1440ab035ba04550ddbbfbff1ee9b5571e3d95db (patch) | |
tree | 9d5e8d2e151a930e044c7d0f7c64053d244577a0 /src/appl/telnet | |
parent | 61ddbf948ba6ee70c1bc049268c3dfa73bc9983e (diff) | |
download | krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.gz krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.xz krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.zip |
pull up 3des implementation from the marc-3des branch
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11001 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/telnet')
-rw-r--r-- | src/appl/telnet/libtelnet/ChangeLog | 7 | ||||
-rw-r--r-- | src/appl/telnet/libtelnet/enc_des.c | 109 | ||||
-rw-r--r-- | src/appl/telnet/libtelnet/kerberos.c | 200 | ||||
-rw-r--r-- | src/appl/telnet/telnet/ChangeLog | 7 | ||||
-rw-r--r-- | src/appl/telnet/telnet/commands.c | 8 |
5 files changed, 280 insertions, 51 deletions
diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog index 494050438..55168c36b 100644 --- a/src/appl/telnet/libtelnet/ChangeLog +++ b/src/appl/telnet/libtelnet/ChangeLog @@ -1,3 +1,10 @@ +1998-10-26 Marc Horowitz <marc@mit.edu> + + * enc_des.c, kerberos.c: the ECB des functions don't exist + anymore, but telnet always encrypted/decrypted one block. Convert + to calls to the new crypto api, with des-cbc-raw, using a single + block. + Tue Mar 3 14:43:30 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> * configure.in: Change test for cgetent to use HAVE_ instead diff --git a/src/appl/telnet/libtelnet/enc_des.c b/src/appl/telnet/libtelnet/enc_des.c index f44700a73..3912b35e9 100644 --- a/src/appl/telnet/libtelnet/enc_des.c +++ b/src/appl/telnet/libtelnet/enc_des.c @@ -31,11 +31,38 @@ * SUCH DAMAGE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + /* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */ #ifdef ENCRYPTION # ifdef AUTHENTICATION # ifdef DES_ENCRYPTION +#include <krb5.h> #include <arpa/telnet.h> #include <stdio.h> #ifdef __STDC__ @@ -53,6 +80,8 @@ extern encrypt_debug_mode; +extern krb5_context telnet_context; + #define CFB 0 #define OFB 1 @@ -65,20 +94,19 @@ extern encrypt_debug_mode; struct fb { - Block krbdes_key; - Schedule krbdes_sched; Block temp_feed; unsigned char fb_feed[64]; int need_start; int state[2]; int keyid[2]; int once; + int validkey; struct stinfo { Block str_output; Block str_feed; Block str_iv; - Block str_ikey; - Schedule str_sched; + unsigned char str_keybytes[8]; /* yuck */ + krb5_keyblock str_key; int str_index; int str_flagshift; } streams[2]; @@ -122,6 +150,29 @@ static void fb64_session P((Session_Key *, int, struct fb *)); void fb64_stream_key P((Block, struct stinfo *)); int fb64_keyid P((int, unsigned char *, int *, struct fb *)); +static void ecb_encrypt(stp, in, out) + struct stinfo *stp; + Block in; + Block out; +{ + krb5_error_code code; + krb5_data din; + krb5_enc_data dout; + + din.length = 8; + din.data = in; + + dout.ciphertext.length = 8; + dout.ciphertext.data = out; + dout.enctype = ENCTYPE_UNKNOWN; + + code = krb5_c_encrypt(telnet_context, &stp->str_key, 0, 0, + &din, &dout); + /* XXX I'm not sure what to do if this fails */ + if (code) + com_err("libtelnet", code, "encrypting stream data"); +} + void cfb64_init(server) int server; @@ -207,7 +258,7 @@ fb64_start(fbp, dir, server) else if ((state & NO_SEND_IV) == 0) break; - if (!VALIDKEY(fbp->krbdes_key)) { + if (!fbp->validkey) { fbp->need_start = 1; break; } @@ -218,9 +269,18 @@ fb64_start(fbp, dir, server) /* * Create a random feed and send it over. */ - des_new_random_key(fbp->temp_feed); - des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, - fbp->krbdes_sched, 1); + { + krb5_data d; + krb5_error_code code; + + d.data = fbp->temp_feed; + d.length = sizeof(fbp->temp_feed); + + if (code = krb5_c_random_make_octets(telnet_context, + &d)) + return(FAILED); + } + p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; @@ -418,23 +478,18 @@ fb64_session(key, server, fbp) int server; struct fb *fbp; { - if (!key || key->type != SK_DES) { if (encrypt_debug_mode) printf("Can't set krbdes's session key (%d != %d)\r\n", key ? key->type : -1, SK_DES); return; } - memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); - fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); - fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); + fbp->validkey = 1; + + fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]); + fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]); - if (fbp->once == 0) { - des_set_random_generator_seed(fbp->krbdes_key); - fbp->once = 1; - } - des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); /* * Now look to see if krbdes_start() was was waiting for * the key to show up. If so, go ahead an call it now @@ -551,12 +606,9 @@ fb64_stream_iv(seed, stp) Block seed; register struct stinfo *stp; { - memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block)); memcpy((void *)stp->str_output, (void *)seed, sizeof(Block)); - des_key_sched(stp->str_ikey, stp->str_sched); - stp->str_index = sizeof(Block); } @@ -565,8 +617,13 @@ fb64_stream_key(key, stp) Block key; register struct stinfo *stp; { - memcpy((void *)stp->str_ikey, (void *)key, sizeof(Block)); - des_key_sched(key, stp->str_sched); + memcpy((void *)stp->str_keybytes, (void *)key, sizeof(Block)); + stp->str_key.length = 8; + stp->str_key.contents = stp->str_keybytes; + /* the original version of this code uses des ecb mode, but + it only ever does one block at a time. cbc with a zero iv + is identical */ + stp->str_key.enctype = ENCTYPE_DES_CBC_RAW; memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); @@ -607,7 +664,7 @@ cfb64_encrypt(s, c) while (c-- > 0) { if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_output, b); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } @@ -641,7 +698,7 @@ cfb64_decrypt(data) index = stp->str_index++; if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_output, b); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ @@ -683,7 +740,7 @@ ofb64_encrypt(s, c) while (c-- > 0) { if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_feed, b); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } @@ -714,7 +771,7 @@ ofb64_decrypt(data) index = stp->str_index++; if (index == sizeof(Block)) { Block b; - des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + ecb_encrypt(stp, stp->str_feed, b); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c index 63738b53b..ed32392c9 100644 --- a/src/appl/telnet/libtelnet/kerberos.c +++ b/src/appl/telnet/libtelnet/kerberos.c @@ -53,7 +53,38 @@ * or implied warranty. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #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> @@ -73,6 +104,7 @@ #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, }; @@ -93,6 +125,7 @@ static AUTH_DAT adat = { 0 }; #ifdef ENCRYPTION static Block session_key = { 0 }; static Schedule sched; +static krb5_keyblock krbkey; static Block challenge = { 0 }; #endif /* ENCRYPTION */ @@ -146,6 +179,9 @@ kerberos4_init(ap, server) } else { str_data[3] = TELQUAL_IS; } + + kerberos5_init(NULL, server); + return(1); } @@ -157,15 +193,18 @@ kerberos4_send(ap) 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) { @@ -216,11 +255,56 @@ kerberos4_send(ap) 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. @@ -232,7 +316,19 @@ kerberos4_send(ap) 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 */ @@ -253,7 +349,10 @@ kerberos4_is(ap, data, cnt) { #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]; @@ -317,24 +416,60 @@ kerberos4_is(ap, data, cnt) * 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; @@ -342,7 +477,20 @@ kerberos4_is(ap, data, cnt) 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; @@ -363,6 +511,10 @@ kerberos4_reply(ap, data, cnt) { #ifdef ENCRYPTION Session_Key skey; + krb5_data kdata; + krb5_enc_data encdata; + krb5_error_code code; + #endif /* ENCRYPTION */ if (cnt-- < 1) @@ -387,7 +539,21 @@ kerberos4_reply(ap, data, cnt) #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; diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog index 6d13e63f2..7d94d0acf 100644 --- a/src/appl/telnet/telnet/ChangeLog +++ b/src/appl/telnet/telnet/ChangeLog @@ -1,3 +1,10 @@ +1998-10-26 Marc Horowitz <marc@mit.edu> + + * commands.c: remove calls to setuid(getuid()). This looks like + it was once an attempt to make it safe to run setuid, but it's not + safe for a number of other reasons, so there's no reason to + pretend. + Sat Oct 10 06:24:55 1998 Geoffrey King <gjking@mit.edu> * telnet.c (telnet): Cosmetic change: Put a newline after "Waiting diff --git a/src/appl/telnet/telnet/commands.c b/src/appl/telnet/telnet/commands.c index 5c8ae3cb7..c23e199cc 100644 --- a/src/appl/telnet/telnet/commands.c +++ b/src/appl/telnet/telnet/commands.c @@ -2378,7 +2378,6 @@ tn(argc, argv) if (connected) { printf("?Already connected to %s\r\n", hostname); - setuid(getuid()); return 0; } if (argc < 2) { @@ -2419,7 +2418,6 @@ tn(argc, argv) } usage: printf("usage: %s [-l user] [-a] host-name [port]\r\n", cmd); - setuid(getuid()); return 0; } if (hostp == 0) @@ -2434,11 +2432,9 @@ tn(argc, argv) temp = sourceroute(hostp, &srp, &srlen); if (temp == 0) { herror(srp); - setuid(getuid()); return 0; } else if (temp == -1) { printf("Bad source route option: %s\r\n", hostp); - setuid(getuid()); return 0; } else { sin.sin_addr.s_addr = temp; @@ -2468,7 +2464,6 @@ tn(argc, argv) hostname = _hostname; } else { herror(hostp); - setuid(getuid()); return 0; } } @@ -2489,7 +2484,6 @@ tn(argc, argv) sin.sin_port = sp->s_port; else { printf("%s: bad port number\r\n", portp); - setuid(getuid()); return 0; } } else { @@ -2500,7 +2494,6 @@ tn(argc, argv) sp = getservbyname("telnet", "tcp"); if (sp == 0) { fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); - setuid(getuid()); return 0; } sin.sin_port = sp->s_port; @@ -2510,7 +2503,6 @@ tn(argc, argv) printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr)); do { net = socket(AF_INET, SOCK_STREAM, 0); - setuid(getuid()); if (net < 0) { perror("telnet: socket"); return 0; |