X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=libmoonshot%2Flibmoonshot-msrpc.c;h=6a2010d89241ff4917167c4e3df7e300aed7500f;hb=cc8495fdeae73745d095525e843c750e7c277dce;hp=df29b2f8b194fec4f2c9aca140956ad0f09034b5;hpb=4100eec3ab57f256c915866b71df1dfa40ddc593;p=moonshot-ui.git diff --git a/libmoonshot/libmoonshot-msrpc.c b/libmoonshot/libmoonshot-msrpc.c index df29b2f..6a2010d 100644 --- a/libmoonshot/libmoonshot-msrpc.c +++ b/libmoonshot/libmoonshot-msrpc.c @@ -40,11 +40,28 @@ #include "libmoonshot-common.h" #include "moonshot-msrpc.h" +#include #include +#include #define MOONSHOT_ENDPOINT_NAME "/org/janet/Moonshot" #define MOONSHOT_INSTALL_PATH_KEY "Software\\Moonshot" +void *__RPC_USER MIDL_user_allocate (size_t size) { + return malloc (size); +} + +void __RPC_USER MIDL_user_free (void *data) { + if (data == NULL) + return; + + free (data); +} + +void moonshot_free (void *data) +{ + free (data); +} static MoonshotError *moonshot_error_new_from_status (MoonshotErrorCode code, DWORD status) @@ -54,6 +71,40 @@ static MoonshotError *moonshot_error_new_from_status (MoonshotErrorCode code, error->message = malloc (256); FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, (LPSTR)error->message, 255, NULL); + return error; +} + +static MoonshotError *moonshot_error_new_with_status (MoonshotErrorCode code, + DWORD status, + const char *format, ...) +{ + MoonshotError *error = malloc (sizeof (MoonshotError)); + char *buffer; + va_list args; + int length; + + va_start (args, format); + + error->code = code; + + buffer = malloc (strlen (format) + 256 + 3); + strcpy (buffer, format); + strcat (buffer, ": "); + + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + status, + 0, + (LPSTR)buffer + strlen (format) + 3, + 255, + NULL); + + length = _vscprintf (buffer, args); + error->message = malloc (length + 1); + _vsnprintf (error->message, length, buffer, args); + free (buffer); + + va_end (args); return error; } @@ -63,6 +114,7 @@ static void launch_server (MoonshotError **error) { STARTUPINFO startup_info = { 0 }; PROCESS_INFORMATION process_info = { 0 }; LONG status; + BOOL success; DWORD value_type; DWORD length; char exe_path[1024]; @@ -73,45 +125,62 @@ static void launch_server (MoonshotError **error) { KEY_READ, &key); - if (status != 0) { - *error = moonshot_error_new (MOONSHOT_ERROR_OS_ERROR, - "Unable to read registry key HKLM\\%s", - MOONSHOT_INSTALL_PATH_KEY); + if (status == ERROR_FILE_NOT_FOUND) { + *error = moonshot_error_new + (MOONSHOT_ERROR_INSTALLATION_ERROR, + "Moonshot is not installed correctly on this system. " + "(Registry key HKLM\\%s was not found).", + MOONSHOT_INSTALL_PATH_KEY); + return; + } else if (status != 0) { + *error = moonshot_error_new_with_status + (MOONSHOT_ERROR_OS_ERROR, + status, + "Unable to read registry key HKLM\\%s", + MOONSHOT_INSTALL_PATH_KEY); return; } length = 1023; - status = RegQueryValueEx (key, NULL, NULL, &value_type, exe_path, &length); + status = RegQueryValueEx (key, NULL, NULL, &value_type, (LPBYTE )exe_path, &length); if (value_type != REG_SZ) { - *error = moonshot_error_new (MOONSHOT_ERROR_OS_ERROR, - "Value of registry key HKLM\\%s is invalid. " - "Please set it to point to the location of " - "moonshot.exe", - MOONSHOT_INSTALL_PATH_KEY); + *error = moonshot_error_new_with_status + (MOONSHOT_ERROR_INSTALLATION_ERROR, + status, + "Value of registry key HKLM\\%s is invalid. Please set it " + "to point to the location of moonshot.exe", + MOONSHOT_INSTALL_PATH_KEY); return; } if (status != 0) { - *error = moonshot_error_new (MOONSHOT_ERROR_OS_ERROR, - "Unable to read value of registry key HKLM\\%s", - MOONSHOT_INSTALL_PATH_KEY); + *error = moonshot_error_new_with_status + (MOONSHOT_ERROR_OS_ERROR, + status, + "Unable to read value of registry key HKLM\\%s", + MOONSHOT_INSTALL_PATH_KEY); return; } startup_info.cb = sizeof (startup_info); - - status = CreateProcess (exe_path, NULL, - NULL, NULL, - FALSE, DETACHED_PROCESS, - NULL, NULL, - &startup_info, &process_info); - - if (status != 0) { - *error = moonshot_error_new (MOONSHOT_ERROR_UNABLE_TO_START_SERVICE, - "Unable to spawn the moonshot server at '%s'", - exe_path); + success = CreateProcess (exe_path, + NULL, + NULL, + NULL, + TRUE, + DETACHED_PROCESS, + NULL, + NULL, + &startup_info, &process_info); + + if (! success) { + *error = moonshot_error_new_with_status + (MOONSHOT_ERROR_UNABLE_TO_START_SERVICE, + GetLastError (), + "Unable to spawn the moonshot server at '%s'", + exe_path); return; } } @@ -134,12 +203,15 @@ static void bind_rpc (MoonshotError **error) status = RpcMgmtIsServerListening (moonshot_binding_handle); if (status == RPC_S_NOT_LISTENING) { - //launch_server (error); + launch_server (error); + + if (*error != NULL) + return; + + /* Allow 1 minute for the server to launch before we time out */ + for (i=0; i<600; i++) { + Sleep (100); /* ms */ - /* Allow 5 seconds for the server to launch before we time out */ - //for (i=0; i<50; i++) { - // Sleep (100); /* ms */ -/* status = RpcMgmtIsServerListening (moonshot_binding_handle); if (status == RPC_S_OK) @@ -147,7 +219,7 @@ static void bind_rpc (MoonshotError **error) if (status != RPC_S_NOT_LISTENING) break; - }*/ + } } if (status != RPC_S_OK) @@ -158,7 +230,6 @@ static void bind_rpc (MoonshotError **error) static void init_rpc (MoonshotError **error) { static volatile LONG binding_init_flag = 2; - int status; /* Hack to avoid requiring a moonshot_init() function. Windows does not * provide any synchronisation primitives that can be statically init'ed, @@ -201,7 +272,7 @@ int moonshot_get_identity (const char *nai, char **subject_alt_name_constraint_out, MoonshotError **error) { - int success; + int success = FALSE; RpcAsyncCall call; init_rpc (error); @@ -211,12 +282,16 @@ int moonshot_get_identity (const char *nai, rpc_async_call_init (&call); - nai_out = NULL; - password_out = NULL; - server_certificate_hash_out = NULL; - ca_certificate_out = NULL; - subject_name_constraint_out = NULL; - subject_alt_name_constraint_out = NULL; + if (nai == NULL) nai = ""; + if (password == NULL) password = ""; + if (service == NULL) service = ""; + + *nai_out = NULL; + *password_out = NULL; + *server_certificate_hash_out = NULL; + *ca_certificate_out = NULL; + *subject_name_constraint_out = NULL; + *subject_alt_name_constraint_out = NULL; RPC_TRY_EXCEPT { moonshot_get_identity_rpc (&call, @@ -260,7 +335,7 @@ int moonshot_get_default_identity (char **nai_out, char **subject_alt_name_constraint_out, MoonshotError **error) { - int success; + int success = FALSE; RpcAsyncCall call; init_rpc (error); @@ -270,12 +345,12 @@ int moonshot_get_default_identity (char **nai_out, rpc_async_call_init (&call); - nai_out = NULL; - password_out = NULL; - server_certificate_hash_out = NULL; - ca_certificate_out = NULL; - subject_name_constraint_out = NULL; - subject_alt_name_constraint_out = NULL; + *nai_out = NULL; + *password_out = NULL; + *server_certificate_hash_out = NULL; + *ca_certificate_out = NULL; + *subject_name_constraint_out = NULL; + *subject_alt_name_constraint_out = NULL; RPC_TRY_EXCEPT { moonshot_get_default_identity_rpc (&call, @@ -306,3 +381,77 @@ int moonshot_get_default_identity (char **nai_out, return TRUE; }; + +int moonshot_install_id_card (const char *display_name, + const char *user_name, + const char *password, + const char *realm, + char *rules_patterns[], + int rules_patterns_length, + char *rules_always_confirm[], + int rules_always_confirm_length, + char *services[], + int services_length, + const char *ca_cert, + const char *subject, + const char *subject_alt, + const char *server_cert, + int force_flat_file_store, + MoonshotError **error) +{ + int success = FALSE; + + init_rpc (error); + if (*error != NULL) + return FALSE; + + if (user_name == NULL) user_name = ""; + if (password == NULL) password = ""; + if (realm == NULL) realm = ""; + if (ca_cert == NULL) ca_cert = ""; + if (subject == NULL) subject = ""; + if (subject_alt == NULL) subject_alt = ""; + if (server_cert == NULL) server_cert = ""; + + RPC_TRY_EXCEPT { + success = moonshot_install_id_card_rpc (display_name, + user_name, + password, + realm, + rules_patterns, + rules_patterns_length, + rules_always_confirm, + rules_always_confirm_length, + services, + services_length, + ca_cert, + subject, + subject_alt, + server_cert, + force_flat_file_store); + } + RPC_EXCEPT { + *error = moonshot_error_new_from_status (MOONSHOT_ERROR_IPC_ERROR, + RPC_GET_EXCEPTION_CODE ()); + } + RPC_END_EXCEPT + return success; +} + +BOOL WINAPI DllMain (HINSTANCE hinst, + DWORD reason, + void *reserved) +{ + if (reason == DLL_PROCESS_DETACH) { + /* Process exiting/DLL being unloaded. This is a good + * opportunity to free the RPC binding. + * + * FIXME: we can't use the msrpc-mingw routine for this in case + * it was already unloaded. I'd love to work out how to link + * that library statically into libmoonshot-0.dll. + */ + RpcBindingFree (&moonshot_binding_handle); + } + + return TRUE; +}