- if (security_module)
- return 1; /* already initialised */
-
- security_module = LoadLibrary("secur32.dll");
- if (security_module) {
- GET_SSPI_FUNCTION(security_module, AcquireCredentialsHandleA);
- GET_SSPI_FUNCTION(security_module, InitializeSecurityContextA);
- GET_SSPI_FUNCTION(security_module, FreeContextBuffer);
- GET_SSPI_FUNCTION(security_module, FreeCredentialsHandle);
- GET_SSPI_FUNCTION(security_module, DeleteSecurityContext);
- GET_SSPI_FUNCTION(security_module, QueryContextAttributesA);
- GET_SSPI_FUNCTION(security_module, MakeSignature);
- return 1;
+ HMODULE module;
+ HKEY regkey;
+ struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
+ char *path;
+
+ list->libraries = snewn(3, struct ssh_gss_library);
+ list->nlibraries = 0;
+
+ /* MIT Kerberos GSSAPI implementation */
+ /* TODO: For 64-bit builds, check for gssapi64.dll */
+ module = NULL;
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\MIT\\Kerberos", ®key)
+ == ERROR_SUCCESS) {
+ DWORD type, size;
+ LONG ret;
+ char *buffer;
+
+ /* Find out the string length */
+ ret = RegQueryValueEx(regkey, "InstallDir", NULL, &type, NULL, &size);
+
+ if (ret == ERROR_SUCCESS && type == REG_SZ) {
+ buffer = snewn(size + 20, char);
+ ret = RegQueryValueEx(regkey, "InstallDir", NULL,
+ &type, buffer, &size);
+ if (ret == ERROR_SUCCESS && type == REG_SZ) {
+ strcat(buffer, "\\bin\\gssapi32.dll");
+ module = LoadLibrary(buffer);
+ }
+ sfree(buffer);
+ }
+ RegCloseKey(regkey);
+ }
+ if (module) {
+ struct ssh_gss_library *lib =
+ &list->libraries[list->nlibraries++];
+
+ lib->id = 0;
+ lib->gsslogmsg = "Using GSSAPI from GSSAPI32.DLL";
+ lib->handle = (void *)module;
+
+#define BIND_GSS_FN(name) \
+ lib->u.gssapi.name = (t_gss_##name) GetProcAddress(module, "gss_" #name)
+
+ BIND_GSS_FN(delete_sec_context);
+ BIND_GSS_FN(display_status);
+ BIND_GSS_FN(get_mic);
+ BIND_GSS_FN(import_name);
+ BIND_GSS_FN(init_sec_context);
+ BIND_GSS_FN(release_buffer);
+ BIND_GSS_FN(release_cred);
+ BIND_GSS_FN(release_name);
+
+#undef BIND_GSS_FN
+
+ ssh_gssapi_bind_fns(lib);
+ }
+
+ /* Microsoft SSPI Implementation */
+ module = load_system32_dll("secur32.dll");
+ if (module) {
+ struct ssh_gss_library *lib =
+ &list->libraries[list->nlibraries++];
+
+ lib->id = 1;
+ lib->gsslogmsg = "Using SSPI from SECUR32.DLL";
+ lib->handle = (void *)module;
+
+ GET_WINDOWS_FUNCTION(module, AcquireCredentialsHandleA);
+ GET_WINDOWS_FUNCTION(module, InitializeSecurityContextA);
+ GET_WINDOWS_FUNCTION(module, FreeContextBuffer);
+ GET_WINDOWS_FUNCTION(module, FreeCredentialsHandle);
+ GET_WINDOWS_FUNCTION(module, DeleteSecurityContext);
+ GET_WINDOWS_FUNCTION(module, QueryContextAttributesA);
+ GET_WINDOWS_FUNCTION(module, MakeSignature);
+
+ ssh_sspi_bind_fns(lib);
+ }
+
+ /*
+ * Custom GSSAPI DLL.
+ */
+ module = NULL;
+ path = conf_get_filename(conf, CONF_ssh_gss_custom)->path;
+ if (*path) {
+ module = LoadLibrary(path);