#ifdef KRB4
#include "kerberos.h"
#endif
-#include "telnet.h"
-#include "telopts.h"
-
#ifdef KRB5
#include "krb5.h"
#include "des_int.h"
#include "los-proto.h"
#endif
+#include "telnet.h"
+#include "telopts.h"
+
/*
- * Contants
+ * Constants
*/
#define IS 0
#define SEND 1
#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
#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
*/
#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;
* Parameters:
* enable - TRUE to enable, FALSE to disable.
*/
-static void auth_encrypt_enable(
+static void
+auth_encrypt_enable(
BOOL enable)
{
encrypt_enable = 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) {
#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 */
* 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)
} /* copy_for_net */
-/*+
+/*++
* Function: Parse authentication send command
*
* Parameters:
*
* Returns: Kerberos error code.
*/
-static int auth_send(
+static int
+auth_send(
kstream ks,
unsigned char *parsedat,
int end_sub)
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;
}
#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);
*
* 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.
*
*
* end_sub - last charcter position in parsedat.
*/
-void auth_parse(
+void
+auth_parse(
kstream ks,
unsigned char *parsedat,
int end_sub)
*
* data - user data.
*/
-int INTERFACE auth_init(
+int INTERFACE
+auth_init(
kstream str,
kstream_ptr data)
{
*
* data - user data.
*/
-void INTERFACE auth_destroy(
+void INTERFACE
+auth_destroy(
kstream str)
{
} /* 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)
*
* 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)
} /* 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;
}
- 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);
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 */
return KSUCCESS;
default:
- return KSUCCESS; // Unknown code
+ return KSUCCESS; // Unknown reply type
}
}
#endif /* KRB5 */
****************************************************************************/
-#include <windows.h>
+#include <windows.h>
+#include <stdlib.h>
#include <string.h>
#include "telnet.h"
#include "auth.h"
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
/*+**************************************************************************
/* 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);
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);
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));
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);
}
}
}
+/*+
+ * 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 <host>
+** telnet <host> <port no>
+** telnet -p <port no>
+**
+*/
+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);
+ }
+}