summaryrefslogtreecommitdiffstats
path: root/src/windows/cns/cns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows/cns/cns.c')
-rw-r--r--src/windows/cns/cns.c335
1 files changed, 147 insertions, 188 deletions
diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c
index 205f933252..8999d9f98c 100644
--- a/src/windows/cns/cns.c
+++ b/src/windows/cns/cns.c
@@ -10,10 +10,6 @@
* <mit-copyright.h>.
*/
-#if !defined(KRB5) && !defined(KRB4)
-#error "Must define either KRB4 or KRB5"
-#endif
-
#include <windows.h>
#include <windowsx.h>
@@ -27,6 +23,9 @@
#include "cns.h"
#include "tktlist.h"
+#include "cns_reg.h"
+
+#include "../lib/gic.h"
enum { /* Actions after login */
LOGIN_AND_EXIT,
@@ -34,12 +33,6 @@ enum { /* Actions after login */
LOGIN_AND_RUN,
};
-#ifndef _WIN32
-typedef MINMAXINFO *LPMINMAXINFO;
-#define GET_WM_COMMAND_MPS(id, hwnd, cmd) \
- (WPARAM)MAKELONG(id, cmd), (LONG)(hwnd)
-#endif
-
/*
* Globals
*/
@@ -55,7 +48,6 @@ BOOL alert; /* Actions on ticket expiration */
BOOL beep;
static BOOL alerted; /* TRUE when user already alerted */
BOOL isblocking = FALSE; /* TRUE when blocked in WinSock */
-static DWORD blocking_timeout; /* Blocking timeout */
static DWORD blocking_end_time; /* Ending count for blocking timeout */
static FARPROC hook_instance; /* handle for blocking hook function */
@@ -76,21 +68,13 @@ krb5_ccache k5_ccache;
*
* Returns: TRUE if we got and dispatched a message, FALSE otherwise.
*/
-BOOL __export CALLBACK
+BOOL CALLBACK
blocking_hook_proc(void)
{
MSG msg;
BOOL rc;
- DWORD now;
- /*
- * The additional timeout logic is required because GetTickCount will
- * wrap approximately every 49.7 days.
- */
- now = GetTickCount();
- if (now >= blocking_end_time &&
- (blocking_end_time >= blocking_end_time - blocking_timeout ||
- now < blocking_end_time - blocking_timeout)) {
+ if (GetTickCount() > blocking_end_time) {
WSACancelBlockingCall();
return FALSE;
}
@@ -127,8 +111,7 @@ start_blocking_hook(int timeout)
return;
isblocking = TRUE;
- blocking_timeout = 1000 * timeout;
- blocking_end_time = GetTickCount() + blocking_timeout;
+ blocking_end_time = GetTickCount() + (1000 * timeout);
#ifdef _WIN32
proc = WSASetBlockingHook(blocking_hook_proc);
#else
@@ -193,10 +176,8 @@ center_dialog(HWND hwnd)
static void
position_dialog(HWND hwnd)
{
- int n;
int scrwidth, scrheight;
HDC hdc;
- char position[256];
int x, y, cx, cy;
if (hwnd == NULL)
@@ -206,12 +187,12 @@ position_dialog(HWND hwnd)
scrwidth = GetDeviceCaps(hdc, HORZRES);
scrheight = GetDeviceCaps(hdc, VERTRES);
ReleaseDC(NULL, hdc);
- GetPrivateProfileString(INI_DEFAULTS, INI_POSITION, "",
- position, sizeof(position), KERBEROS_INI);
+ x = cns_res.x;
+ y = cns_res.y;
+ cx = cns_res.cx;
+ cy = cns_res.cy;
- n = sscanf(position, " [%d , %d , %d , %d", &x, &y, &cx, &cy);
- if (n != 4 ||
- x > scrwidth ||
+ if (x > scrwidth ||
y > scrheight ||
x + cx < 0 ||
y + cy < 0)
@@ -477,7 +458,6 @@ kwin_init_file_menu(HWND hwnd)
{
HMENU hmenu;
int i;
- char login[sizeof(INI_LOGIN)+1];
char menuitem[MAX_K_NAME_SZ + 3];
int id;
BOOL rc;
@@ -488,13 +468,10 @@ kwin_init_file_menu(HWND hwnd)
hmenu = GetSubMenu(hmenu, 0);
assert(hmenu != NULL);
- strcpy(login, INI_LOGIN);
id = 0;
for (i = 0; i < FILE_MENU_MAX_LOGINS; i++) {
- login[sizeof(INI_LOGIN) - 1] = '1' + i;
- login[sizeof(INI_LOGIN)] = 0;
- GetPrivateProfileString(INI_RECENT_LOGINS, login, "",
- &menuitem[3], sizeof(menuitem) - 3, KERBEROS_INI);
+ strcpy(menuitem + 3, cns_res.logins[i]);
+
if (!menuitem[3])
continue;
@@ -527,8 +504,6 @@ kwin_save_file_menu(HWND hwnd)
int id;
int ctitems;
char menuitem[MAX_K_NAME_SZ + 3];
- char login[sizeof(INI_LOGIN)+1];
- BOOL rc;
hmenu = GetMenu(hwnd);
assert(hmenu != NULL);
@@ -536,19 +511,14 @@ kwin_save_file_menu(HWND hwnd)
hmenu = GetSubMenu(hmenu, 0);
assert(hmenu != NULL);
- strcpy(login, INI_LOGIN);
ctitems = GetMenuItemCount(hmenu);
assert(ctitems >= FILE_MENU_ITEMS);
id = 0;
for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) {
GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION);
- login[sizeof(INI_LOGIN) - 1] = '1' + id;
- login[sizeof(INI_LOGIN)] = 0;
- rc = WritePrivateProfileString(INI_RECENT_LOGINS, login,
- &menuitem[3], KERBEROS_INI);
- assert(rc);
+ strcpy(cns_res.logins[id], menuitem + 3);
id++;
}
@@ -607,18 +577,15 @@ kwin_init_name(HWND hwnd, char *fullname)
if (fullname == NULL || fullname[0] == 0) {
#ifdef KRB4
strcpy(name, krb_get_default_user());
- GetPrivateProfileString(INI_DEFAULTS, INI_INSTANCE, "",
- instance, sizeof(instance), KERBEROS_INI);
+ strcpy(instance, cns_res.instance);
krc = krb_get_lrealm(realm, 1);
if (krc != KSUCCESS)
realm[0] = 0;
- GetPrivateProfileString(INI_DEFAULTS, INI_REALM, realm,
- realm, sizeof(realm), KERBEROS_INI);
+ strcpy(realm, cns_res.realm);
#endif /* KRB4 */
#ifdef KRB5
- GetPrivateProfileString(INI_DEFAULTS, INI_USER, "",
- name, sizeof(name), KERBEROS_INI);
+ strcpy(name, cns_res.name);
*realm = '\0';
code = krb5_get_default_realm(k5_context, &ptr);
@@ -626,8 +593,7 @@ kwin_init_name(HWND hwnd, char *fullname)
strcpy(realm, ptr);
/* free(ptr); XXX */
}
- GetPrivateProfileString(INI_DEFAULTS, INI_REALM, realm,
- realm, sizeof(realm), KERBEROS_INI);
+ strcpy(realm, cns_res.realm);
#endif /* KRB5 */
} else {
@@ -702,18 +668,17 @@ kwin_save_name(HWND hwnd)
krb_set_default_user(name);
GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance));
trim(instance);
- WritePrivateProfileString(INI_DEFAULTS, INI_INSTANCE,
- instance, KERBEROS_INI);
+ strcpy(cns_res.instance, instance);
#endif
#ifdef KRB5
- WritePrivateProfileString(INI_DEFAULTS, INI_USER, name, KERBEROS_INI);
+ strcpy(cns_res.name, name);
*instance = '\0';
#endif
GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm));
trim(realm);
- WritePrivateProfileString(INI_DEFAULTS, INI_REALM, realm, KERBEROS_INI);
+ strcpy(cns_res.realm, realm);
kwin_push_login(hwnd, name, instance, realm);
}
@@ -790,9 +755,7 @@ kwin_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
static void
kwin_destroy(HWND hwnd)
{
- char position[256];
RECT r;
- BOOL b;
ticket_destroy(GetDlgItem(hwnd, IDD_TICKET_LIST));
@@ -804,11 +767,10 @@ kwin_destroy(HWND hwnd)
kwin_save_file_menu(hwnd);
GetWindowRect(hwnd, &r);
- sprintf(position, "[%d,%d,%d,%d]", r.left, r.top,
- r.right - r.left, r.bottom - r.top);
- b = WritePrivateProfileString(INI_DEFAULTS, INI_POSITION,
- position, KERBEROS_INI);
- assert(b);
+ cns_res.x = r.left;
+ cns_res.y = r.top;
+ cns_res.cx = r.right - r.left;
+ cns_res.cy = r.bottom - r.top;
KillTimer(hwnd, kwin_timer_id);
}
@@ -1120,27 +1082,27 @@ kwin_timer(HWND hwnd, UINT timer_id)
static void
kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
{
- char name[ANAME_SZ];
- char realm[REALM_SZ];
- char password[MAX_KPW_LEN];
- HCURSOR hcursor;
- BOOL blogin;
- HMENU hmenu;
- char menuitem[MAX_K_NAME_SZ + 3];
- char copyright[128];
- int id;
+ char name[ANAME_SZ];
+ char realm[REALM_SZ];
+ char password[MAX_KPW_LEN];
+ HCURSOR hcursor;
+ BOOL blogin;
+ HMENU hmenu;
+ char menuitem[MAX_K_NAME_SZ + 3];
+ char copyright[128];
+ int id;
#ifdef KRB4
- char instance[INST_SZ];
- int lifetime;
- int krc;
+ char instance[INST_SZ];
+ int lifetime;
+ int krc;
#endif
#ifdef KRB5
- long lifetime;
- krb5_error_code code;
- krb5_principal principal;
- krb5_creds creds;
- krb5_principal server;
- krb5_int32 sec, usec;
+ long lifetime;
+ krb5_error_code code;
+ krb5_principal principal;
+ krb5_creds creds;
+ krb5_get_init_creds_opt opts;
+ gic_data gd;
#endif
#ifdef KRB4
@@ -1223,15 +1185,16 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm));
trim(realm);
GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password));
+ SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, ""); /* nuke the password */
trim(password);
+
#ifdef KRB4
GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance));
trim(instance);
#endif
hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- lifetime = GetPrivateProfileInt(INI_OPTIONS, INI_DURATION,
- DEFAULT_TKT_LIFE * 5, KERBEROS_INI);
+ lifetime = cns_res.lifetime;
start_blocking_hook(BLOCK_MAX_SEC);
#ifdef KRB4
@@ -1241,83 +1204,74 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
#endif
#ifdef KRB5
- do {
- principal = server = NULL;
- memset(&creds, 0, sizeof(creds));
-
- sprintf(menuitem, "%s@%s", name, realm);
- code = krb5_parse_name(k5_context, menuitem, &principal);
- if (code)
- break;
-
- code = krb5_cc_initialize(k5_context, k5_ccache, principal);
- if (code)
- break;
-
- code = krb5_build_principal_ext(k5_context, &server,
- krb5_princ_realm(k5_context, principal)->length,
- krb5_princ_realm(k5_context, principal)->data,
- KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
- krb5_princ_realm(k5_context, principal)->length,
- krb5_princ_realm(k5_context, principal)->data, 0);
- if (code)
- break;
-
- creds.client = principal;
- creds.server = server;
-
- code = krb5_us_timeofday(k5_context, &sec, &usec);
- if (code)
- break;
- creds.times.starttime = 0;
- creds.times.endtime = sec + 60L * lifetime;
- creds.times.renew_till = 0;
-
- /*
- * XXX whether or not the credentials should be
- * forwardable should be a configurable option in the
- * UI.
- */
- code = krb5_get_in_tkt_with_password(k5_context,
- (forwardable ? KDC_OPT_FORWARDABLE : 0),
- NULL, NULL,
- NULL, password, k5_ccache,
- &creds, 0);
- } while (0);
-
+ principal = NULL;
+
+ /*
+ * convert the name + realm into a krb5 principal string and parse it into a principal
+ */
+ sprintf(menuitem, "%s@%s", name, realm);
+ code = krb5_parse_name(k5_context, menuitem, &principal);
+ if (code)
+ goto errorpoint;
+
+ /*
+ * set the various ticket options. First, initialize the structure, then set the ticket
+ * to be forwardable if desired, and set the lifetime.
+ */
+ krb5_get_init_creds_opt_init(&opts);
+ krb5_get_init_creds_opt_set_forwardable(&opts, forwardable);
+ krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime * 60);
+
+ /*
+ * get the initial creds using the password and the options we set above
+ */
+ gd.hinstance = hinstance;
+ gd.hwnd = hwnd;
+ gd.id = ID_VARDLG;
+ code = krb5_get_init_creds_password(k5_context, &creds, principal, password,
+ gic_prompter, &gd, 0, NULL, &opts);
+ if (code)
+ goto errorpoint;
+
+ /*
+ * initialize the credential cache
+ */
+ code = krb5_cc_initialize(k5_context, k5_ccache, principal);
+ if (code)
+ goto errorpoint;
+
+ /*
+ * insert the principal into the cache
+ */
+ code = krb5_cc_store_cred(k5_context, k5_ccache, &creds);
+
+ errorpoint:
+
if (principal)
krb5_free_principal(k5_context, principal);
- if (server)
- krb5_free_principal(k5_context, server);
-
-#endif /* KRB5 */
-
end_blocking_hook();
SetCursor(hcursor);
kwin_set_default_focus(hwnd);
-
-#ifdef KRB4
- if (krc != KSUCCESS) {
- MessageBox(hwnd, krb_get_err_text(krc), "",
- MB_OK | MB_ICONEXCLAMATION);
-
- return; /* TRUE */
- }
-#endif
-
-#ifdef KRB5
+
if (code) {
if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
MessageBox(hwnd, "Password incorrect", NULL,
MB_OK | MB_ICONEXCLAMATION);
else
com_err(NULL, code, "while logging in");
+ }
+#endif /* KRB5 */
+
+#ifdef KRB4
+ if (krc != KSUCCESS) {
+ MessageBox(hwnd, krb_get_err_text(krc), "",
+ MB_OK | MB_ICONEXCLAMATION);
+
return; /* TRUE */
}
#endif
- SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, "");
kwin_save_name(hwnd);
alerted = FALSE;
@@ -1378,25 +1332,22 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
if (isblocking)
return; /* TRUE */
-#ifdef CYGNUS
- strcpy(copyright, " KerbNet for Windows ");
+#ifdef KRB4
+ strcpy(copyright, " Kerberos 4 for Windows ");
+#endif
+#ifdef KRB5
+ strcpy(copyright, " Kerberos V5 for Windows ");
+#endif
#ifdef _WIN32
strcat(copyright, "32-bit\n");
#else
strcat(copyright, "16-bit\n");
#endif
- strcat(copyright, "\n Version 1.11\n\n");
- strcat(copyright, " For support, contact:\n");
+ strcat(copyright, "\n Version 1.12\n\n");
+#ifdef ORGANIZATION
+ strcat(copyright, " For information, contact:\n");
strcat(copyright, ORGANIZATION);
-#else /* Cygnus */
- strcpy(copyright, " Kerberos V5 for Windows ");
-#ifdef _WIN32
- strcat(copyright, "32-bit\n");
-#else
- strcat(copyright, "16-bit\n");
#endif
- strcat(copyright, "\n Version 1.11\n\n");
-#endif /* Cygnus */
MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK);
return; /* TRUE */
@@ -1544,10 +1495,12 @@ kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
switch (message) {
-
HANDLE_MSG(hwnd, WM_GETMINMAXINFO, kwin_getminmaxinfo);
+
HANDLE_MSG(hwnd, WM_DESTROY, kwin_destroy);
+
HANDLE_MSG(hwnd, WM_MEASUREITEM, ticket_measureitem);
+
HANDLE_MSG(hwnd, WM_DRAWITEM, ticket_drawitem);
case WM_SETCURSOR:
@@ -1558,8 +1511,11 @@ kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
HANDLE_MSG(hwnd, WM_SIZE, kwin_size);
+
HANDLE_MSG(hwnd, WM_SYSCOMMAND, kwin_syscommand);
+
HANDLE_MSG(hwnd, WM_TIMER, kwin_timer);
+
HANDLE_MSG(hwnd, WM_PAINT, kwin_paint);
case WM_ERASEBKGND:
@@ -1584,6 +1540,7 @@ kwin_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
HANDLE_MSG(hwnd, WM_INITDIALOG, kwin_initdialog);
+
HANDLE_MSG(hwnd, WM_COMMAND, kwin_command);
}
@@ -1643,6 +1600,7 @@ init_application(HINSTANCE hinstance)
#ifdef KRB4
wm_kerberos_changed = krb_get_notification_message();
#endif
+
#ifdef KRB5
wm_kerberos_changed = krb5_get_notification_message();
#endif
@@ -1683,11 +1641,10 @@ quit_application(HINSTANCE hinstance)
static BOOL
init_instance(HINSTANCE hinstance, int ncmdshow)
{
- char buf[20];
- int i;
- int rc;
WORD versionrequested;
WSADATA wsadata;
+ int rc;
+ int i;
versionrequested = 0x0101; /* We need version 1.1 */
rc = WSAStartup(versionrequested, &wsadata);
@@ -1706,22 +1663,37 @@ init_instance(HINSTANCE hinstance, int ncmdshow)
return FALSE;
}
+#ifdef KRB5
+ {
+ krb5_error_code code;
+
+ code = krb5_init_context(&k5_context);
+ if (!code) {
+#if 0 /* Not needed under windows */
+ krb5_init_ets(k5_context);
+#endif
+ code = k5_init_ccache(&k5_ccache);
+ }
+ if (code) {
+ com_err(NULL, code, "while initializing program");
+ return FALSE;
+ }
+ k5_name_from_ccache(k5_ccache);
+ }
+#endif
+
+ cns_load_registry();
+
/*
* Set up expiration action
*/
- GetPrivateProfileString(INI_EXPIRATION, INI_ALERT, "No",
- buf, sizeof(buf), KERBEROS_INI);
- alert = _stricmp(buf, "Yes") == 0;
- GetPrivateProfileString(INI_EXPIRATION, INI_BEEP, "No",
- buf, sizeof(buf), KERBEROS_INI);
- beep = _stricmp(buf, "Yes") == 0;
+ alert = cns_res.alert;
+ beep = cns_res.beep;
/*
* ticket options
*/
- GetPrivateProfileString(INI_TICKETOPTS, INI_FORWARDABLE, "No",
- buf, sizeof(buf), KERBEROS_INI);
- forwardable = _stricmp(buf, "Yes") == 0;
+ forwardable = cns_res.forwardable;
/*
* Load clock icons
@@ -1733,22 +1705,6 @@ init_instance(HINSTANCE hinstance, int ncmdshow)
krb_start_session(NULL);
#endif
-#ifdef KRB5
- {
- krb5_error_code code;
-
- code = krb5_init_context(&k5_context);
- if (!code)
- code = k5_init_ccache(&k5_ccache);
- if (code) {
- com_err(NULL, code, "while initializing program");
- return FALSE;
- }
- k5_name_from_ccache(k5_ccache);
- }
-
-#endif
-
return TRUE;
}
@@ -1858,6 +1814,7 @@ WinMain(HINSTANCE hinst, HINSTANCE hprevinstance, LPSTR cmdline, int ncmdshow)
if (hprevinstance == NULL)
#endif /* _WIN32 */
+
if (!init_application(hinstance))
return FALSE;
@@ -1897,6 +1854,8 @@ WinMain(HINSTANCE hinst, HINSTANCE hprevinstance, LPSTR cmdline, int ncmdshow)
FreeProcInstance((FARPROC)dlgproc);
#endif
+ cns_save_registry();
+
return 0;
}
@@ -2216,7 +2175,7 @@ k5_name_from_ccache(krb5_ccache k5_ccache)
krb5_principal princ;
char name[ANAME_SZ];
char realm[REALM_SZ];
- char FAR *defname;
+ char *defname;
if (code = krb5_cc_get_principal(k5_context, k5_ccache, &princ))
return FALSE;
@@ -2227,8 +2186,8 @@ k5_name_from_ccache(krb5_ccache k5_ccache)
}
k5_kname_parse(name, realm, defname); /* Extract the components */
- WritePrivateProfileString(INI_DEFAULTS, INI_USER, name, KERBEROS_INI);
- WritePrivateProfileString(INI_DEFAULTS, INI_REALM, realm, KERBEROS_INI);
+ strcpy(cns_res.name, name);
+ strcpy(cns_res.realm, realm);
return TRUE;
}