# HG changeset patch # User Andre Heinecke # Date 1403888032 -7200 # Node ID 4ad764bfb39caf2f5eaeacb71daa18ac956d95d5 # Parent f1795a232418691eed69f3c4a35cdd503b0688bf Add writing of the NSS line into the registry diff -r f1795a232418 -r 4ad764bfb39c cinst/nssstore_win.c --- a/cinst/nssstore_win.c Fri Jun 27 16:18:10 2014 +0200 +++ b/cinst/nssstore_win.c Fri Jun 27 18:53:52 2014 +0200 @@ -56,6 +56,9 @@ #define APPNAME L"cinst" #endif +/**@def The name of the nss installation process */ +#define NSS_APP_NAME L"mozilla.exe" + #ifndef SELECTION_FILE_NAME #define SELECTION_FILE_NAME L"currently_selected.txt" #endif @@ -358,6 +361,8 @@ goto done; } + error = false; + done: xfree (current_user); @@ -377,6 +382,53 @@ return retval; } +/** @brief Build the command line for the NSS installation process + * + * Caller has to free the return value + * + * @param [in] selection_file the certificates to install + * + * @returns the command line to install the certificates. */ +static wchar_t* +get_command_line(wchar_t *selection_file) +{ + LPWSTR retval; + char *install_dir = get_install_dir(); + wchar_t *w_inst_dir; + size_t cmd_line_len = 0; + + if (install_dir == NULL) + { + ERRORPRINTF ("Failed to get installation directory"); + return NULL; + } + + w_inst_dir = utf8_to_wchar (install_dir, strlen(install_dir)); + xfree (install_dir); + + if (w_inst_dir == NULL) + { + ERRORPRINTF ("Failed to convert installation directory"); + return NULL; + } + + /* installdir + dirsep + quotes + process name + space + quotes + selection_file + + NULL */ + cmd_line_len = wcslen (w_inst_dir) + 1 + 2 + wcslen (NSS_APP_NAME) + + + 1 + 2 + wcslen(selection_file) + 1; + retval = xmalloc (cmd_line_len * sizeof(wchar_t)); + + wcscpy_s (retval, cmd_line_len, L"\""); + wcscat_s (retval, cmd_line_len, w_inst_dir); + wcscat_s (retval, cmd_line_len, L"\\"); + wcscat_s (retval, cmd_line_len, NSS_APP_NAME); + wcscat_s (retval, cmd_line_len, L"\" \""); + wcscat_s (retval, cmd_line_len, selection_file); + wcscat_s (retval, cmd_line_len, L"\""); + + return retval; +} + /**@brief Register NSS process as runOnce for other users * * Loads the registry hives of other users on the system and @@ -396,9 +448,66 @@ register_proccesses_for_others (wchar_t *selection_file) { char **hives = locate_other_hives(); + int i = 0; + wchar_t *run_command = NULL; + if (hives == NULL) + { + DEBUGPRINTF ("No hives found."); + return; + } + run_command = get_command_line (selection_file); + for (i = 0; hives[i] != NULL; i++) + { + LONG ret = 0; + wchar_t *hivepath = utf8_to_wchar (hives[i], strlen(hives[i])); + HKEY key_handle = NULL; + + if (hivepath == NULL) + { + ERRORPRINTF ("Failed to read hive path"); + continue; + } + ret = RegLoadKeyW (HKEY_LOCAL_MACHINE, APPNAME L"_tmphive", hivepath); + + xfree (hivepath); + hivepath = NULL; + + if (ret != ERROR_SUCCESS) + { + /* This is somewhat expected if the registry is not located + in the standard location. Failure is accepted in that case. */ + PRINTLASTERROR ("Failed to load hive."); + continue; + } + + ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE, + APPNAME L"_tmphive\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", + 0, + KEY_WRITE, + &key_handle); + + if (ret != ERROR_SUCCESS) + { + ERRORPRINTF ("Failed to find RunOnce key in other registry."); + RegUnLoadKey (HKEY_LOCAL_MACHINE, APPNAME L"_tmphive"); + continue; + } + + ret = RegSetValueExW (key_handle, APPNAME, 0, REG_SZ, (LPBYTE) run_command, + (wcslen(run_command) + 1) * sizeof(wchar_t)); + + if (ret != ERROR_SUCCESS) + { + ERRORPRINTF ("Failed to write RunOnce key."); + } + + RegCloseKey (key_handle); + RegUnLoadKey (HKEY_LOCAL_MACHINE, APPNAME L"_tmphive"); + } + + xfree (run_command); strv_free (hives); - printf("Selection file %S", selection_file); } /**@brief Start the process to install / remove @@ -421,7 +530,6 @@ PROCESS_INFORMATION piProcInfo = {0}; STARTUPINFOW siStartInfo = {0}; BOOL success = FALSE; - size_t cmd_line_len = 0; if (!selection_file) { @@ -441,12 +549,13 @@ restrict token -> hChildToken */ - cmd_line_len = wcslen (lpApplicationName) + wcslen(selection_file) + 2; - lpCommandLine = xmalloc (cmd_line_len * sizeof(wchar_t)); + lpCommandLine = get_command_line (selection_file); - wcscpy_s (lpCommandLine, cmd_line_len, lpApplicationName); - wcscpy_s (lpCommandLine, cmd_line_len, L" "); - wcscat_s (lpCommandLine, cmd_line_len, selection_file); + if (lpCommandLine == NULL) + { + ERRORPRINTF ("Failed to build command line."); + return false; + } DEBUGPRINTF ("Starting %S with command line %S\n", lpApplicationName, lpCommandLine); diff -r f1795a232418 -r 4ad764bfb39c common/util.c --- a/common/util.c Fri Jun 27 16:18:10 2014 +0200 +++ b/common/util.c Fri Jun 27 18:53:52 2014 +0200 @@ -20,6 +20,40 @@ #endif #ifdef WIN32 +char * get_install_dir() +{ + wchar_t wPath[MAX_PATH]; + char *utf8path = NULL; + char *dirsep = NULL; + + if (!GetModuleFileNameW (NULL, wPath, MAX_PATH - 1)) + { + PRINTLASTERROR ("Failed to obtain module file name. Path too long?"); + return NULL; + } + + /* wPath might not be 0 terminated */ + wPath[MAX_PATH - 1] = '\0'; + + utf8path = wchar_to_utf8 (wPath, wcsnlen(wPath, MAX_PATH)); + + if (utf8path == NULL) + { + ERRORPRINTF ("Failed to convert module path to utf-8"); + return NULL; + } + + /* Cut away the executable name */ + dirsep = strrchr(utf8path, '\\'); + if (dirsep == NULL) + { + ERRORPRINTF ("Failed to find directory seperator."); + return NULL; + } + *dirsep = '\0'; + return utf8path; +} + static PSID copy_sid(PSID from) { diff -r f1795a232418 -r 4ad764bfb39c common/util.h --- a/common/util.h Fri Jun 27 16:18:10 2014 +0200 +++ b/common/util.h Fri Jun 27 18:53:52 2014 +0200 @@ -51,6 +51,17 @@ * @returns A copy of the process owners sid or NULL on error. */ PSID get_process_owner(HANDLE hProcess); + +/**@brief Get the directory in which the current process resides in + * + * Look up the directory in which the current process is placed. + * If the path is longer then MAX_PATH NULL is returned. + * + * Returns a utf-8 encoded string that has to be freed by the caller + * + * @returns The directory of the current process + */ +char * get_install_dir(); #endif #ifdef __cplusplus