summaryrefslogtreecommitdiffstats
path: root/src/windows/wintel/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows/wintel/auth.c')
-rw-r--r--src/windows/wintel/auth.c415
1 files changed, 235 insertions, 180 deletions
diff --git a/src/windows/wintel/auth.c b/src/windows/wintel/auth.c
index f3956ac11b..6a7db72653 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 */