From 54acb989d349b03478de1f15e7229a79c2c662b1 Mon Sep 17 00:00:00 2001 From: Keith Vetter Date: Sat, 1 Apr 1995 00:55:50 +0000 Subject: [PATCH] Can now specify port to telnet to on the command line git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5331 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/cns/changelo | 4 + src/windows/cns/cns.c | 6 +- src/windows/wintel/auth.c | 415 +++++++++++++++++++--------------- src/windows/wintel/changelo | 6 + src/windows/wintel/telnet.c | 91 ++++++-- src/windows/wintel/wt-proto.h | 2 + 6 files changed, 322 insertions(+), 202 deletions(-) diff --git a/src/windows/cns/changelo b/src/windows/cns/changelo index b0795a0af..a2d9b87e6 100644 --- a/src/windows/cns/changelo +++ b/src/windows/cns/changelo @@ -1,3 +1,7 @@ +Fri Mar 31 16:47:18 1995 Keith Vetter (keithv@fusion.com) + + * cns.c: realms file was not getting saved properly. + Thu Mar 30 16:11:27 1995 Keith Vetter (keithv@fusion.com) * cns.h, cns.c, tktlist.c: improved error handling for a bad cache. diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c index f75c40a45..fbf5cd10e 100644 --- a/src/windows/cns/cns.c +++ b/src/windows/cns/cns.c @@ -866,7 +866,7 @@ opts_command ( strcat(defname, "\\"); strcat(defname, DEF_KRB_CONF); - if (_stricmp(confname, defname) == 0 || !defname[0]) + if (_stricmp(confname, defname) == 0 || !confname[0]) p = NULL; else p = confname; @@ -881,10 +881,10 @@ opts_command ( strcat(defname, "\\"); strcat(defname, DEF_KRB_REALMS); - if (_stricmp(realmsname, defname) == 0 || !defname[0]) + if (_stricmp(realmsname, defname) == 0 || !realmsname[0]) p = NULL; else - p = defname; + p = realmsname; b = WritePrivateProfileString(INI_FILES, INI_KRB_REALMS, p, KERBEROS_INI); assert(b); diff --git a/src/windows/wintel/auth.c b/src/windows/wintel/auth.c index f3956ac11..6a7db7265 100644 --- a/src/windows/wintel/auth.c +++ b/src/windows/wintel/auth.c @@ -7,9 +7,6 @@ #ifdef KRB4 #include "kerberos.h" #endif -#include "telnet.h" -#include "telopts.h" - #ifdef KRB5 #include "krb5.h" #include "des_int.h" @@ -17,8 +14,11 @@ #include "los-proto.h" #endif +#include "telnet.h" +#include "telopts.h" + /* - * Contants + * Constants */ #define IS 0 #define SEND 1 @@ -40,7 +40,7 @@ #define K5_REJECT 1 #define K5_ACCEPT 2 - #define K5_RESPONSE 3 + #define K5_RESPONSE 3 // They had to make it different #define AUTH_WHO_MASK 1 #define AUTH_CLIENT_TO_SERVER 0 @@ -50,7 +50,7 @@ #define AUTH_HOW_ONE_WAY 0 #define AUTH_HOW_MUTUAL 2 - #ifndef KSUCCESS + #ifndef KSUCCESS // Let K5 use K4 constants #define KSUCCESS 0 #define KFAILURE 255 #endif @@ -59,14 +59,23 @@ */ #ifdef KRB4 static CREDENTIALS cred; + static KTEXT_ST auth; + #define KRB_SERVICE_NAME "rcmd" #define KERBEROS_VERSION KERBEROS_V4 + + static int k4_auth_send (void); #endif #ifdef KRB5 static krb5_data auth; static int auth_how; + static krb5_auth_context *auth_context; + #define KRB_SERVICE_NAME "host" #define KERBEROS_VERSION KERBEROS_V5 + + static int k5_auth_send (int how); + static int k5_auth_reply (int how, unsigned char *data, int cnt); #endif BOOL encrypt_enable; @@ -77,7 +86,8 @@ * Parameters: * enable - TRUE to enable, FALSE to disable. */ -static void auth_encrypt_enable( +static void +auth_encrypt_enable( BOOL enable) { encrypt_enable = enable; @@ -91,14 +101,16 @@ static void auth_encrypt_enable( * Parameters: * ks - kstream to send abort message to. */ -static void auth_abort( +static void +auth_abort( kstream ks, char *errmsg, long r) { char buf[9]; - wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, AUTH_NULL, AUTH_NULL, IAC, SE); + wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, AUTH_NULL, + AUTH_NULL, IAC, SE); TelnetSend(ks, (LPSTR)buf, 8, 0); if (errmsg != NULL) { @@ -114,7 +126,8 @@ static void auth_abort( #endif } - MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", MB_OK | MB_ICONEXCLAMATION); + MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", + MB_OK | MB_ICONEXCLAMATION); } } /* auth_abort */ @@ -126,7 +139,8 @@ static void auth_abort( * Parameters: * kstream - kstream to send abort message to. */ -static int copy_for_net( +static int +copy_for_net( unsigned char *to, unsigned char *from, int c) @@ -147,7 +161,7 @@ static int copy_for_net( } /* copy_for_net */ -/*+ +/*++ * Function: Parse authentication send command * * Parameters: @@ -160,7 +174,8 @@ static int copy_for_net( * * Returns: Kerberos error code. */ -static int auth_send( +static int +auth_send( kstream ks, unsigned char *parsedat, int end_sub) @@ -170,14 +185,6 @@ static int auth_send( int plen; int r; int i; - #ifdef KRB4 - KTEXT_ST auth; - char instance[INST_SZ]; - char *realm; - #endif /* KRB4 */ - #ifdef KRB5 - extern int kerberos5_send (int how); - #endif /* KRB5 */ auth_how = -1; @@ -195,57 +202,18 @@ static int auth_send( } #ifdef KRB4 - memset(instance, 0, sizeof(instance)); - - if (realm = krb_get_phost(szHostName)) - lstrcpy(instance, realm); - - realm = krb_realmofhost(szHostName); - - if (!realm) { - strcpy(buf, "Can't find realm for host \""); - strcat(buf, szHostName); - strcat(buf, "\""); - auth_abort(ks, buf, 0); - return KFAILURE; - } - - r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); - - if (r == 0) - r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); - - if (r) { - strcpy(buf, "Can't get \""); - strcat(buf, KRB_SERVICE_NAME); - if (instance[0] != 0) { - strcat(buf, "."); - lstrcat(buf, instance); - } - strcat(buf, "@"); - lstrcat(buf, realm); - strcat(buf, "\" ticket"); - auth_abort(ks, buf, r); - return r; - } - - if (szUserName[0]) - pname = szUserName; - else - pname = cred.pname; - plen = strlen (szUserName); - + r = k4_auth_send (); #endif /* KRB4 */ #ifdef KRB5 - r = kerberos5_send (auth_how); - if (! r) - return KFAILURE; + r = k5_auth_send (auth_how); + #endif /* KRB5 */ - plen = strlen (szUserName); /* Set in kerberos_5 if needed */ - pname = szUserName; + if (! r) + return KFAILURE; - #endif /* KRB5 */ + plen = strlen (szUserName); // Set by k#_send if needed + pname = szUserName; wsprintf(buf, "%c%c%c%c", IAC, SB, AUTHENTICATION, NAME); memcpy (&buf[4], pname, plen); @@ -283,112 +251,25 @@ static int auth_send( * * Returns: Kerberos error code. */ -#ifdef KRB5 -static int auth_reply( +static int +auth_reply( kstream ks, unsigned char *parsedat, int end_sub) { - extern int kerberos5_reply (int how, unsigned char *data, int cnt); int n; - n = kerberos5_reply (0, parsedat, end_sub); + #ifdef KRB4 + n = k4_auth_reply (ks, parsedat, end_sub); + #endif + + #ifdef KRB5 + n = k5_auth_reply (auth_how, parsedat, end_sub); + #endif return n; } -#endif /* KRB5 */ -#ifdef KRB4 -static int auth_reply( - kstream ks, - unsigned char *parsedat, - int end_sub) -{ - time_t t; - int x; - char buf[512]; - int i; - des_cblock session_key; - des_key_schedule sched; - static des_cblock challenge; - - if (end_sub < 4) - return KFAILURE; - - if (parsedat[2] != KERBEROS_V4) - return KFAILURE; - - if (parsedat[4] == K4_REJECT) { - buf[0] = 0; - - for (i = 5; i <= end_sub; i++) { - if (parsedat[i] == IAC) - break; - buf[i-5] = parsedat[i]; - buf[i-4] = 0; - } - if (!buf[0]) - strcpy(buf, "Authentication rejected by remote machine!"); - MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - - return KFAILURE; - } - - if (parsedat[4] == K4_ACCEPT) { - if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) - return KSUCCESS; - - if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) - return KFAILURE; - - des_key_sched(cred.session, sched); - - t = time(NULL); - memcpy(challenge, &t, 4); - memcpy(&challenge[4], &t, 4); - des_ecb_encrypt(&challenge, &session_key, sched, 1); - - /* - * Increment the challenge by 1, and encrypt it for - * later comparison. - */ - for (i = 7; i >= 0; --i) { - x = (unsigned int)challenge[i] + 1; - challenge[i] = x; /* ignore overflow */ - if (x < 256) /* if no overflow, all done */ - break; - } - - des_ecb_encrypt(&challenge, &challenge, sched, 1); - - wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, - KERBEROS_V4, AUTH_CLIENT_TO_SERVER|AUTH_HOW_MUTUAL, K4_CHALLENGE); - memcpy(&buf[7], session_key, 8); - wsprintf(&buf[15], "%c%c", IAC, SE); - TelnetSend(ks, (LPSTR)buf, 17, 0); - - return KSUCCESS; - } - - if (parsedat[4] == K4_RESPONSE) { - if (end_sub < 12) - return KFAILURE; - - if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { - MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", - NULL, MB_OK | MB_ICONEXCLAMATION); - - return KFAILURE; - } - - return KSUCCESS; - } - - return KFAILURE; - -} /* auth_reply */ - -#endif /* KRB4 */ /*+ * Function: Parse the athorization sub-options and reply. * @@ -399,7 +280,8 @@ static int auth_reply( * * end_sub - last charcter position in parsedat. */ -void auth_parse( +void +auth_parse( kstream ks, unsigned char *parsedat, int end_sub) @@ -421,7 +303,8 @@ void auth_parse( * * data - user data. */ -int INTERFACE auth_init( +int INTERFACE +auth_init( kstream str, kstream_ptr data) { @@ -438,7 +321,8 @@ int INTERFACE auth_init( * * data - user data. */ -void INTERFACE auth_destroy( +void INTERFACE +auth_destroy( kstream str) { } /* auth_destroy */ @@ -456,7 +340,8 @@ void INTERFACE auth_destroy( * * Returns: number of characters converted. */ -int INTERFACE auth_encrypt( +int INTERFACE +auth_encrypt( struct kstream_data_block *out, struct kstream_data_block *in, kstream str) @@ -482,7 +367,8 @@ int INTERFACE auth_encrypt( * * Returns: number of characters converted. */ -int INTERFACE auth_decrypt( +int INTERFACE +auth_decrypt( struct kstream_data_block *out, struct kstream_data_block *in, kstream str) @@ -495,21 +381,183 @@ int INTERFACE auth_decrypt( } /* auth_decrypt */ -/*+*/ +/*++*/ +#ifdef KRB4 +/* +** +** K4_auth_send - gets authentication bits we need to send to KDC. +** +** Result is left in auth +** +** Returns: 0 on failure, 1 on success +*/ +static int +k4_auth_send () { + int r; // Return value + char instance[INST_SZ]; + char *realm; + + memset(instance, 0, sizeof(instance)); + + if (realm = krb_get_phost(szHostName)) + lstrcpy(instance, realm); + + realm = krb_realmofhost(szHostName); + + if (!realm) { + strcpy(buf, "Can't find realm for host \""); + strcat(buf, szHostName); + strcat(buf, "\""); + auth_abort(ks, buf, 0); + return KFAILURE; + } + + r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); + + if (r == 0) + r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); + + if (r) { + strcpy(buf, "Can't get \""); + strcat(buf, KRB_SERVICE_NAME); + if (instance[0] != 0) { + strcat(buf, "."); + lstrcat(buf, instance); + } + strcat(buf, "@"); + lstrcat(buf, realm); + strcat(buf, "\" ticket"); + auth_abort(ks, buf, r); + + return r; + } + + if (szUserName[0]) // Copy if not there + strcpy (szUserName, cred.pname); +} + +/*+ + * Function: K4 parse authentication reply command + * + * Parameters: + * ks - kstream to send abort message to. + * + * 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 +k4_auth_reply( + kstream ks, + unsigned char *parsedat, + int end_sub) +{ + time_t t; + int x; + char buf[512]; + int i; + des_cblock session_key; + des_key_schedule sched; + static des_cblock challenge; + + if (end_sub < 4) + return KFAILURE; + + if (parsedat[2] != KERBEROS_V4) + return KFAILURE; + + if (parsedat[4] == K4_REJECT) { + buf[0] = 0; + + for (i = 5; i <= end_sub; i++) { + if (parsedat[i] == IAC) + break; + buf[i-5] = parsedat[i]; + buf[i-4] = 0; + } + + if (!buf[0]) + strcpy(buf, "Authentication rejected by remote machine!"); + MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + + return KFAILURE; + } + + if (parsedat[4] == K4_ACCEPT) { + if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) + return KSUCCESS; + + if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) + return KFAILURE; + + des_key_sched(cred.session, sched); + + t = time(NULL); + memcpy(challenge, &t, 4); + memcpy(&challenge[4], &t, 4); + des_ecb_encrypt(&challenge, &session_key, sched, 1); + + /* + * Increment the challenge by 1, and encrypt it for + * later comparison. + */ + for (i = 7; i >= 0; --i) { + x = (unsigned int)challenge[i] + 1; + challenge[i] = x; /* ignore overflow */ + if (x < 256) /* if no overflow, all done */ + break; + } + + des_ecb_encrypt(&challenge, &challenge, sched, 1); + + wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, + KERBEROS_V4, AUTH_CLIENT_TO_SERVER|AUTH_HOW_MUTUAL, K4_CHALLENGE); + memcpy(&buf[7], session_key, 8); + wsprintf(&buf[15], "%c%c", IAC, SE); + TelnetSend(ks, (LPSTR)buf, 17, 0); + + return KSUCCESS; + } + + if (parsedat[4] == K4_RESPONSE) { + if (end_sub < 12) + return KFAILURE; + + if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { + MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", + NULL, MB_OK | MB_ICONEXCLAMATION); + + return KFAILURE; + } + + return KSUCCESS; + } + + return KFAILURE; + +} /* auth_reply */ + +#endif /* KRB4 */ +/*++*/ #ifdef KRB5 /* ** +** K5_auth_send - gets authentication bits we need to send to KDC. +** ** Code lifted from telnet sample code in the appl directory. +** +** Result is left in auth +** +** Returns: 0 on failure, 1 on success ** */ -krb5_auth_context *auth_context; -krb5_flags krb5_kdc_default_options = KDC_OPT_RENEWABLE_OK; - -/* 0 on failure, 1 on success */ -int -kerberos5_send (int how) +static int +k5_auth_send (int how) { krb5_error_code r; krb5_ccache ccache; @@ -545,7 +593,7 @@ kerberos5_send (int how) } - if (r = krb5_get_credentials(k5_context, krb5_kdc_default_options, + if (r = krb5_get_credentials(k5_context, KDC_OPT_RENEWABLE_OK, ccache, &cred, &new_cred)) { com_err (NULL, r, "while authorizing."); krb5_free_cred_contents(k5_context, &cred); @@ -569,9 +617,16 @@ kerberos5_send (int how) return(1); } -/*+*/ -int -kerberos5_reply (int how, unsigned char *data, int cnt) { + +/*+ +** +** K5_auth_reply -- checks the reply for mutual authentication. +** +** Code lifted from telnet sample code in the appl directory. +** +*/ +static int +k5_auth_reply (int how, unsigned char *data, int cnt) { static int mutual_complete = 0; data += 4; /* Point to status byte */ @@ -620,7 +675,7 @@ kerberos5_reply (int how, unsigned char *data, int cnt) { return KSUCCESS; default: - return KSUCCESS; // Unknown code + return KSUCCESS; // Unknown reply type } } #endif /* KRB5 */ diff --git a/src/windows/wintel/changelo b/src/windows/wintel/changelo index 9364c5f3e..34b6ed30d 100644 --- a/src/windows/wintel/changelo +++ b/src/windows/wintel/changelo @@ -1,3 +1,9 @@ +Fri Mar 31 16:24:52 1995 Keith Vetter (keithv@fusion.com) + + * telnet.c, wt-proto.h: added command line option to set port number + so port is no longer wired to 13131. + * auth.c: made the k4/k5 separation cleaner + Mon Mar 27 20:18:41 1995 Keith Vetter (keithv@fusion.com) * Initial release based upon the K4 version. diff --git a/src/windows/wintel/telnet.c b/src/windows/wintel/telnet.c index a334cf9e1..e8cb4a005 100644 --- a/src/windows/wintel/telnet.c +++ b/src/windows/wintel/telnet.c @@ -20,7 +20,8 @@ ****************************************************************************/ -#include +#include +#include #include #include "telnet.h" #include "auth.h" @@ -35,20 +36,21 @@ HGLOBAL ghCon; SCREEN *fpScr; int debug = 1; -char __near strTmp[1024]; +char __near strTmp[1024]; // Scratch buffer BOOL bAutoConnection = FALSE; char szAutoHostName[64]; +int port_no = 23; char szUserName[64]; char szHostName[64]; #ifdef KRB4 - #define WINDOW_CLASS "telnetWClass_4" + #define WINDOW_CLASS "K4_telnetWClass" #endif #ifdef KRB5 krb5_context k5_context; - #define WINDOW_CLASS "telnetWClass" + #define WINDOW_CLASS "K5_telnetWClass" #endif /*+************************************************************************** @@ -88,11 +90,7 @@ int nCmdShow; /* show-window type (open/icon) */ /* Perform initializations that apply to a specific instance */ - if (lpCmdLine[0]) { - bAutoConnection = TRUE; - lstrcpy((char *) szAutoHostName, lpCmdLine); - } - else bAutoConnection = FALSE; + parse_cmdline (lpCmdLine); if (!InitInstance(hInstance, nCmdShow)) return (FALSE); @@ -369,7 +367,6 @@ MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { ret = WSAGETSELECTERROR(lParam); if (ret) { wsprintf(buf, "Error %d on Connect", ret); - OutputDebugString (buf); MessageBox(NULL, buf, NULL, MB_OK|MB_ICONEXCLAMATION); kstream_destroy(con->ks); GlobalUnlock(ghCon); @@ -401,12 +398,7 @@ MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { remote_addr.sin_addr.S_un.S_un_b.s_b2 = remote_host->h_addr[1]; remote_addr.sin_addr.S_un.S_un_b.s_b3 = remote_host->h_addr[2]; remote_addr.sin_addr.S_un.S_un_b.s_b4 = remote_host->h_addr[3]; - #ifdef KRB4 - remote_addr.sin_port = htons(23); - #endif - #ifdef KRB5 - remote_addr.sin_port = htons(13131); - #endif + remote_addr.sin_port = htons(port_no); connect(con->socket, (struct sockaddr*) &remote_addr, sizeof(struct sockaddr)); @@ -733,9 +725,10 @@ OpenTelnetDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam) { else break; } - SetWindowPos(hDlg, NULL, (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), - (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), 0, 0, - SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW); + SetWindowPos(hDlg, NULL, + (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), + (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), + 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); ReleaseDC(hDlg, hDC); SendMessage(hEdit, WM_USER+1, NULL, NULL); SendMessage(hDlg, WM_SETFOCUS, NULL, NULL); @@ -812,3 +805,63 @@ TelnetSend(kstream ks, char *buf, int len, int flags) { } } } +/*+ + * Function: Trim leading and trailing white space from a string. + * + * Parameters: + * s - the string to trim. + */ +void +trim ( + char *s) +{ + int l; + int i; + + for (i = 0; s[i]; i++) + if (s[i] != ' ' && s[i] != '\t') + break; + + l = strlen(&s[i]); + memmove(s, &s[i], l + 1); + + for (l--; l >= 0; l--) { + if (s[l] != ' ' && s[l] != '\t') + break; + } + s[l + 1] = 0; + +} /* trim */ +/*+ +** +** Parse_cmdline +** +** Reads hostname and port number off the command line. +** +** Formats: telnet +** telnet +** telnet +** telnet -p +** +*/ +void +parse_cmdline (char *cmdline) { + char *ptr; + + bAutoConnection = FALSE; // Initialize to off + if (*cmdline == '\0') // Empty command line? + return; + + trim (cmdline); // Remove excess spaces + ptr = strchr (cmdline, ' '); // Find 2nd token + + if (ptr != NULL) { // Port number given + *ptr++ = '\0'; // Separate into 2 words + port_no = atoi (ptr); + } + + if (*cmdline != '-' && *cmdline != '/') { // Host name given + bAutoConnection = TRUE; + lstrcpy (szAutoHostName, cmdline); + } +} diff --git a/src/windows/wintel/wt-proto.h b/src/windows/wintel/wt-proto.h index 67f550c4f..0563205c7 100644 --- a/src/windows/wintel/wt-proto.h +++ b/src/windows/wintel/wt-proto.h @@ -9,6 +9,8 @@ BOOL FAR PASCAL ConfigSessionDlg(HWND, WORD, WORD, LONG); int OpenTelnetConnection(void); int NEAR DoDialog(char *szDialog, FARPROC lpfnDlgProc); +void parse_cmdline (char *cmdline); + ///HCONNECTION FindConnectionFromPortNum(int ID); ///HCONNECTION FindConnectionFromTelstate(int telstate); ///HCONNECTION FindConnectionFromScreen(HSCREEN hScreen); -- 2.26.2