# HG changeset patch # User Raimund Renkert # Date 1398778003 -7200 # Node ID a097dd86cb4d5c209cb66fadc255e248602d7563 # Parent ca583ffe728aaf0f5fd0118840ea290635676d6c# Parent fd29ab9cadafedd8ce464d6692daf9dc18b2f379 merged. diff -r ca583ffe728a -r a097dd86cb4d CMakeLists.txt --- a/CMakeLists.txt Tue Apr 29 15:26:02 2014 +0200 +++ b/CMakeLists.txt Tue Apr 29 15:26:43 2014 +0200 @@ -21,6 +21,15 @@ include(CTest) include(GenerateCppcheck) +include(HGVersion) + +if(HG_REVISION) + set(PROJECT_VERSION ${HG_REVISION}) +else() + set(PROJECT_VERSION unknown) +endif() + +add_definitions(-DVERSION="${PROJECT_VERSION}") find_package(PolarSSL) include_directories(${POLARSSL_INCLUDE_DIR}) @@ -102,3 +111,10 @@ # Documentation configure_file (doc/Doxyfile.in doc/Doxyfile) add_subdirectory(doc) + +# Configure packaging script for testing +list(GET NSS_LIBRARIES 1 NSS_BASE_DIR) +get_filename_component(NSS_BASE_DIR ${NSS_BASE_DIR} PATH) + +set(NSS_BASE_DIR "${NSS_BASE_DIR}/..") +configure_file (packaging/tmp-createpackage.sh.in packaging/tmp-createpackage.sh) diff -r ca583ffe728a -r a097dd86cb4d cinst/main.c --- a/cinst/main.c Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/main.c Tue Apr 29 15:26:43 2014 +0200 @@ -325,7 +325,6 @@ if (ret != 0) { ERRORPRINTF ("Failed to write nss stores"); - DEBUGPRINTF ("Hello World"); } /* Make valgrind happy */ diff -r ca583ffe728a -r a097dd86cb4d cinst/mozilla.c --- a/cinst/mozilla.c Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/mozilla.c Tue Apr 29 15:26:43 2014 +0200 @@ -381,7 +381,6 @@ if (!cn_str || !o_str) { DEBUGPRINTF("FATAL: Could not parse certificate!"); - DEBUGPRINTF("data len: %u \n", secitemp->len); exit(ERR_INVALID_CERT); } name_len = strlen(cn_str) + strlen(o_str) + 4; @@ -439,34 +438,27 @@ char *cert_name = nss_cert_name(dercert); DEBUGPRINTF("INSTALLING cert: '%s' to: %s\n", cert_name, pdir); - if (NSS_Initialize(pdir, "", "", "secmod.db", 0) == SECSuccess) + pk11slot = PK11_GetInternalKeySlot(); + cert = CERT_DecodeCertFromPackage((char *)dercert->data, + (int)dercert->len); + trust = (CERTCertTrust *)xmalloc(sizeof(CERTCertTrust)); + CERT_DecodeTrustString(trust, "C"); + if ((PK11_ImportCert(pk11slot, cert, CK_INVALID_HANDLE, + cert_name, PR_FALSE) + == SECSuccess) && + (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, trust) + == SECSuccess)) { - pk11slot = PK11_GetInternalKeySlot(); - cert = CERT_DecodeCertFromPackage((char *)dercert->data, - (int)dercert->len); - trust = (CERTCertTrust *)xmalloc(sizeof(CERTCertTrust)); - CERT_DecodeTrustString(trust, "C"); - if ((PK11_ImportCert(pk11slot, cert, CK_INVALID_HANDLE, - cert_name, PR_FALSE) - == SECSuccess) && - (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, trust) - == SECSuccess)) - { - success = true; - } - else - { - DEBUGPRINTF("Failed to install certificate '%s' to '%s'!\n", cert_name, pdir); - } - CERT_DestroyCertificate (cert); - free(trust); - PK11_FreeSlot(pk11slot); - NSS_Shutdown(); + success = true; } else { - DEBUGPRINTF("Could not open nss certificate store in %s!\n", pdir); + DEBUGPRINTF("Failed to install certificate '%s' to '%s'!\n", cert_name, pdir); + ERRORPRINTF("Error installing certificate err: %i\n", PORT_GetError()); } + CERT_DestroyCertificate (cert); + free(trust); + PK11_FreeSlot(pk11slot); free(cert_name); return success; @@ -545,18 +537,25 @@ apply_to_certs_and_profiles(bool fn(char *, SECItem *), seciteml_t **certs, char **pdirs) { - SECItem *cert; bool success = true; - while ((cert = seciteml_pop(certs)) != NULL) + for (int i=0; pdirs[i] != NULL; i++) { - for (int i=0; pdirs[i] != NULL; i++) + seciteml_t *iter = *certs; + if (NSS_Initialize(pdirs[i], "", "", "secmod.db", 0) != SECSuccess) { + DEBUGPRINTF("Could not open nss certificate store in %s!\n", pdirs[i]); + continue; + } + + while (iter != NULL && iter->item != NULL) + { + SECItem *cert = iter->item; if (! (*fn)(pdirs[i], cert)) success = false; + iter = iter->next; } - free(cert->data); - free(cert); + NSS_Shutdown(); } return success; diff -r ca583ffe728a -r a097dd86cb4d cinst/nss-secitemlist.c --- a/cinst/nss-secitemlist.c Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/nss-secitemlist.c Tue Apr 29 15:26:43 2014 +0200 @@ -20,6 +20,20 @@ *list = newlelt; } +void +seciteml_free (seciteml_t **list) +{ + seciteml_t *oldlelt; + + while (*list != NULL) + { + oldlelt = *list; + *list = oldlelt->next; + free(oldlelt->item); + free(oldlelt); + } +} + SECItem *seciteml_pop (seciteml_t **list) { seciteml_t *oldlelt; diff -r ca583ffe728a -r a097dd86cb4d cinst/nss-secitemlist.h --- a/cinst/nss-secitemlist.h Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/nss-secitemlist.h Tue Apr 29 15:26:43 2014 +0200 @@ -44,4 +44,14 @@ */ SECItem *seciteml_pop (seciteml_t **list); +/** + * @brief Free a secitem list + * + * Frees a secitem list + * + * @param[inout] list pointer to the list which should be freed. set to NULL + */ +void seciteml_free (seciteml_t **list); + + #endif diff -r ca583ffe728a -r a097dd86cb4d cinst/nssstore_win.c --- a/cinst/nssstore_win.c Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/nssstore_win.c Tue Apr 29 15:26:43 2014 +0200 @@ -61,22 +61,13 @@ #define PROCESS_TIMEOUT 30000 -#define PRINTLASTERROR(msg) \ - char *my_error = getLastErrorMsg(); \ - if (my_error) { \ - DEBUGPRINTF(msg " : %s\n", my_error); \ - ERRORPRINTF(msg" : %s\n", my_error); \ - free (my_error); \ - } \ - DEBUGPRINTF ("Failed to get error information\n"); - /**@brief Write strv of instructions to a handle * * Writes the null terminated list of instructions to * the handle. * -* @param [in] base64 encoded der certificates to write -* @param [in] write_handle to write to +* @param [in] certificates base64 encoded der certificate to write +* @param [in] write_handle handle to write to * @param [in] remove weather the certificate should be installed or removed * * @returns true on success, false on failure @@ -85,38 +76,61 @@ write_instructions(char **certificates, HANDLE write_handle, bool remove) { + bool retval = false; int i = 0; - int cHandle = -1; - FILE *write_stream = NULL; + const char *line_end = "\r\n"; + char *line_start = NULL; if (!certificates) { return true; } - cHandle = _open_osfhandle ((intptr_t)write_handle, 0); + line_start = remove ? "R:" : "I:"; - if (cHandle == -1) - { - ERRORPRINTF ("Failed to open write handle.\n"); - } - - write_stream = _fdopen(cHandle, "w"); for (i = 0; certificates[i]; i++) { - int ret = 0; - if (remove) - ret = fprintf (write_stream, "R:%s\n", certificates[i]); - else - ret = fprintf (write_stream, "I:%s\n", certificates[i]); - - if (ret <= 0) + DWORD written = 0; + DWORD inst_len = strlen (certificates[i]); + retval = WriteFile (write_handle, (LPCVOID) line_start, 2, &written, NULL); + if (!retval) { - DEBUGPRINTF ("Failed to write everything.\n"); - break; + PRINTLASTERROR ("Failed to write line start\n"); + return false; + } + if (written != 2) + { + ERRORPRINTF ("Failed to write line start\n"); + retval = false; + return false; + } + written = 0; + retval = WriteFile (write_handle, (LPCVOID) certificates[i], inst_len, &written, NULL); + if (!retval) + { + PRINTLASTERROR ("Failed to write certificate\n"); + return false; + } + if (inst_len != written) + { + ERRORPRINTF ("Failed to write everything\n"); + retval = false; + return false; + } + written = 0; + retval = WriteFile (write_handle, (LPCVOID) line_end, 2, &written, NULL); + if (!retval) + { + PRINTLASTERROR ("Failed to write line end\n"); + return false; + } + if (written != 2) + { + ERRORPRINTF ("Failed to write full line end\n"); + retval = false; + return false; } } - return true; } @@ -453,13 +467,23 @@ GENERIC_WRITE, 0, /* don't share */ NULL, /* use the security attributes from the folder */ - OPEN_ALWAYS, + OPEN_ALWAYS | TRUNCATE_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) + { + hFile = CreateFileW(path, + GENERIC_WRITE, + 0, /* don't share */ + NULL, /* use the security attributes from the folder */ + CREATE_NEW, + 0, + NULL); + } if (hFile == INVALID_HANDLE_VALUE) { - ERRORPRINTF ("Failed to create file\n"); + PRINTLASTERROR ("Failed to create file\n"); xfree(path); return NULL; } diff -r ca583ffe728a -r a097dd86cb4d cinst/windowsstore.c --- a/cinst/windowsstore.c Tue Apr 29 15:26:02 2014 +0200 +++ b/cinst/windowsstore.c Tue Apr 29 15:26:43 2014 +0200 @@ -192,6 +192,7 @@ if (!hStore) { + ERRORPRINTF ("Failed to access store.\n"); return ERR_STORE_ACCESS_DENIED; } diff -r ca583ffe728a -r a097dd86cb4d cmake/HGVersion.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake/HGVersion.cmake Tue Apr 29 15:26:43 2014 +0200 @@ -0,0 +1,57 @@ +# Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik +# Software engineering by Intevation GmbH +# +# This file is Free Software under the GNU GPL (v>=2) +# and comes with ABSOLUTELY NO WARRANTY! +# See LICENSE.txt for details. + +# This makes some variables available to generate a nice version number for +# hg managed repositories. +# It sets HG_REVISION_TAG to the value of the latest tag +# HG_REVISION_DIST to the differences between the tag and the current tip +# HG_REVISION_ID to the actual revision +# based on code found in the lemon graph library https://lemon.cs.elte.hu +# HG_REVISON to a nice combination of those. +find_package(Hg) +if (HG_FOUND) + EXECUTE_PROCESS( + COMMAND + hg log -r. --template "{latesttag}" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE HG_REVISION_TAG + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + EXECUTE_PROCESS( + COMMAND + hg log -r. --template "{latesttagdistance}" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE HG_REVISION_DIST + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + EXECUTE_PROCESS( + COMMAND + hg log -r. --template "{node|short}" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE HG_REVISION_ID + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + IF(HG_REVISION_TAG STREQUAL "") + SET(HG_REVISION_ID "hg-tip") + ELSE() + IF(HG_REVISION_TAG STREQUAL "null") + SET(HG_REVISION_TAG "trunk") + ELSEIF(HG_REVISION_TAG MATCHES "^r") + STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG) + ENDIF() + IF(HG_REVISION_DIST STREQUAL "0") + SET(HG_REVISION ${HG_REVISION_TAG}) + ELSE() + SET(HG_REVISION + "${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}") + ENDIF() + ENDIF() +ENDIF() diff -r ca583ffe728a -r a097dd86cb4d common/logging.h --- a/common/logging.h Tue Apr 29 15:26:02 2014 +0200 +++ b/common/logging.h Tue Apr 29 15:26:43 2014 +0200 @@ -17,6 +17,8 @@ * @brief Logging and debugging functions */ +#include + #ifdef WIN32 #include @@ -79,8 +81,31 @@ * * Prints an error to stderr */ -#define ERRORPRINTF(fmt, ...) fprintf(stderr, DEBUGPREFIX "ERROR: " fmt, ##__VA_ARGS__); +#ifdef WIN32 +# define ERRORPRINTF(fmt, ...) \ + { \ + char buf[512]; \ + snprintf(buf, 511, "ERROR: " fmt, ##__VA_ARGS__); \ + buf[511] = '\0'; \ + OutputDebugStringA(buf); \ + } +#else +# define ERRORPRINTF(fmt, ...) fprintf(stderr, DEBUGPREFIX "ERROR: " fmt, ##__VA_ARGS__); +#endif +/** + * @def PRINTLASTERROR(msg) + * @brief Prints the last windows error with a custom message + * + * Prints an error to stderr + */ +#define PRINTLASTERROR(msg) \ + char *my_error = getLastErrorMsg(); \ + if (my_error) { \ + ERRORPRINTF(msg" : %s\n", my_error); \ + free (my_error); \ + } \ + ERRORPRINTF ("Failed to get error information\n"); #ifdef __cplusplus diff -r ca583ffe728a -r a097dd86cb4d common/util.c --- a/common/util.c Tue Apr 29 15:26:02 2014 +0200 +++ b/common/util.c Tue Apr 29 15:26:43 2014 +0200 @@ -6,6 +6,8 @@ * See LICENSE.txt for details. */ #include "util.h" +#include "logging.h" + #ifndef _WIN32 #include #include @@ -36,3 +38,82 @@ #endif return ret; } + +bool is_admin() +{ +#ifndef _WIN32 + /* TODO implement */ + return false; +#else + bool retval = false; + BOOL in_admin_group = FALSE; + HANDLE hToken = NULL; + HANDLE hTokenToCheck = NULL; + DWORD cbSize = 0; + TOKEN_ELEVATION_TYPE elevation; + BYTE admin_id[SECURITY_MAX_SID_SIZE]; + + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_QUERY | TOKEN_DUPLICATE, &hToken)) + { + PRINTLASTERROR ("Failed to duplicate process token.\n"); + return false; + } + + if (!GetTokenInformation(hToken, TokenElevationType, &elevation, + sizeof(elevation), &cbSize)) + { + PRINTLASTERROR ("Failed to get token information.\n"); + goto done; + } + + /* If limited check the the linked token instead */ + if (TokenElevationTypeLimited == elevation) + { + if (!GetTokenInformation(hToken, TokenLinkedToken, &hTokenToCheck, + sizeof(hTokenToCheck), &cbSize)) + { + PRINTLASTERROR ("Failed to get the linked token.\n"); + goto done; + } + } + + if (!hTokenToCheck) /* The linked token is already of the correct type */ + { + if (!DuplicateToken(hToken, SecurityIdentification, &hTokenToCheck)) + { + PRINTLASTERROR ("Failed to duplicate token for identification.\n"); + goto done; + } + } + + /* Do the sid dance for the adminSID */ + cbSize = sizeof(admin_id); + if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &admin_id, + &cbSize)) + { + PRINTLASTERROR ("Failed to get admin sid.\n"); + goto done; + } + + /* The actual check */ + if (!CheckTokenMembership(hTokenToCheck, &admin_id, &in_admin_group)) + { + PRINTLASTERROR ("Failed to check token membership.\n"); + goto done; + } + + if (in_admin_group) + { + /* Winbool to standard bool */ + retval = true; + } + +done: + if (hToken) CloseHandle(hToken); + if (hTokenToCheck) CloseHandle(hTokenToCheck); + + return retval; +#endif +} + diff -r ca583ffe728a -r a097dd86cb4d common/util.h --- a/common/util.h Tue Apr 29 15:26:02 2014 +0200 +++ b/common/util.h Tue Apr 29 15:26:43 2014 +0200 @@ -12,6 +12,10 @@ */ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Check if the current process is running with elevated privileges. * * Elevates the current process token to check if it is marked as elevated. @@ -20,4 +24,17 @@ * @returns true if the current process is elevated.*/ bool is_elevated(); +/**@brief Check if the user is in the administrators group. + * + * The function checks if the account that startet this process + * belongs to a user that is a member of the Administrators group. + * + * @returns True if the user is in the admin group. False otherwise or on error. + */ +bool is_admin(); + +#ifdef __cplusplus +} +#endif + #endif // COMMON_UTIL_H diff -r ca583ffe728a -r a097dd86cb4d packaging/filelist.nsh --- a/packaging/filelist.nsh Tue Apr 29 15:26:02 2014 +0200 +++ b/packaging/filelist.nsh Tue Apr 29 15:26:43 2014 +0200 @@ -9,7 +9,7 @@ ; Keep it updated if you add new things. File "${files_dir}/cinst.exe" -File "${files_dir}/m13ui.exe" +File "${files_dir}/trustbridge.exe" File "${files_dir}/mozilla.exe" ; NSS: This should ultimately be static diff -r ca583ffe728a -r a097dd86cb4d packaging/tmp-createpackage.sh --- a/packaging/tmp-createpackage.sh Tue Apr 29 15:26:02 2014 +0200 +++ b/packaging/tmp-createpackage.sh Tue Apr 29 15:26:43 2014 +0200 @@ -15,7 +15,7 @@ TMPDIR=$(mktemp -d) -EXEFILES=$(find . -name cinst.exe -o -name m13ui.exe -o -name mozilla.exe) +EXEFILES=$(find . -name cinst.exe -o -name trustbridge.exe -o -name mozilla.exe) cp $NSSDIR/*.dll $TMPDIR cp $EXEFILES $TMPDIR diff -r ca583ffe728a -r a097dd86cb4d packaging/tmp-createpackage.sh.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packaging/tmp-createpackage.sh.in Tue Apr 29 15:26:43 2014 +0200 @@ -0,0 +1,29 @@ +# Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik +# Software engineering by Intevation GmbH +# +# This file is Free Software under the GNU GPL (v>=2) +# and comes with ABSOLUTELY NO WARRANTY! +# See LICENSE.txt for details. + +#!/bin/bash + +#NSSDIR is hackish as this will be replaced by static compiling +# anyway + +NSSDIR="@NSS_BASE_DIR@/bin/" + +TMPDIR=$(mktemp -d) + +EXEFILES=$(find . -name cinst.exe -o -name trustbridge.exe -o -name mozilla.exe) + +cp $NSSDIR/*.dll $TMPDIR +cp $EXEFILES $TMPDIR + +echo $TMPDIR +makensis -Dfiles_dir=$TMPDIR \ + -Dcompany="Bundesamt für Sicherheit in der Informationstechnik" \ + -Dversion_number=@PROJECT_VERSION@ \ + -Dsetupname="@CMAKE_BINARY_DIR@/TrustBridge-@PROJECT_VERSION@.exe" \ + -Dproductname="TrustBridge" \ + -Dproductname_short="TrustBridge" @CMAKE_SOURCE_DIR@/packaging/trustbridge.nsi +rm -r $TMPDIR diff -r ca583ffe728a -r a097dd86cb4d packaging/trustbridge.nsi --- a/packaging/trustbridge.nsi Tue Apr 29 15:26:02 2014 +0200 +++ b/packaging/trustbridge.nsi Tue Apr 29 15:26:43 2014 +0200 @@ -5,9 +5,6 @@ ; and comes with ABSOLUTELY NO WARRANTY! ; See LICENSE.txt for details. -; renameme.nsi -; TODO Rename it! -; ; This script creates the installer for renameme it needs the ; following definitions to be set when calling makensis: ; @@ -36,7 +33,8 @@ ;-------------------------------- ;Version Information (for installer file properties) -VIProductVersion "${version_number}" ;needs integer format: x.x.x.x +;VIProductVersion "${version_number}" ;needs integer format: x.x.x.x +VIProductVersion 1.0.0.0 VIAddVersionKey "ProductName" "${productname_short}" VIAddVersionKey "Comments" "${productname_short} ist Freie Software" VIAddVersionKey "CompanyName" "${company}" @@ -71,7 +69,7 @@ !define MUI_WELCOMEPAGE_TITLE "Willkommen bei der Installation des ${productname}" !define MUI_WELCOMEPAGE_TEXT "Dieser Assistent wird Sie durch die Installation von \ ${productname} begleiten. $\r$\n$\r$\n\ -Der ${productname} ist eine Anwendung um Wurzelzertifikate auf ihrem System \ +${productname} ist eine Anwendung um Wurzelzertifikate auf ihrem System \ zu installieren und aktuell zu halten. $\r$\n$\r$\n\ Klicken Sie auf Weiter, um fortzufahren." @@ -87,12 +85,13 @@ ; Pages !define MUI_FINISHPAGE_TITLE "Die Installation war erfolgreich" -!define MUI_FINISHPAGE_TEXT "Der ${productname} wurde auf Ihrem \ +!define MUI_FINISHPAGE_TEXT "${productname} wurde auf Ihrem \ Computer installliert. $\r$\n$\r$\n\ Klicken Sie auf 'Fertig stellen', um den Installations-Assistenten\ zu schließen." -!define MUI_FINISHPAGE_RUN $INSTDIR\m13ui.exe +!define MUI_FINISHPAGE_RUN $INSTDIR\trustbridge.exe !define MUI_FINISHPAGE_RUN_TEXT "Anwendung starten" +!define MUI_FINISHPAGE_RUN_FUNCTION RunAsUser !define MUI_FINISHPAGE_LINK "Mehr unter http://www.bsi.bund.de" !define MUI_FINISHPAGE_LINK_LOCATION "http://www.bsi.bund.de" @@ -116,6 +115,13 @@ !insertmacro MULTIUSER_INIT FunctionEnd +; If we run elevated we do not want to run +; the UI elevated as this could be a security +; problem. +Function RunAsUser + ExecShell "" "$INSTDIR\trustbridge.exe" +FunctionEnd + ;-------------------------------- ; UnInstall Functions @@ -130,14 +136,17 @@ WriteRegStr SHCTX "Software\${productname_short}" "" $INSTDIR - ;Create uninstaller +; Set up autostart + WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Run" "TrustBridge" "$INSTDIR\trustbridge.exe --tray" + +;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ;Create shortcuts CreateDirectory "$SMPROGRAMS\$StartMenuFolder" - CreateShortCut "$SMPROGRAMS\$StartMenuFolder\${productname}.lnk" "$INSTDIR\m13ui.exe" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\${productname}.lnk" "$INSTDIR\trustbridge.exe" !insertmacro MUI_STARTMENU_WRITE_END diff -r ca583ffe728a -r a097dd86cb4d ui/CMakeLists.txt --- a/ui/CMakeLists.txt Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/CMakeLists.txt Tue Apr 29 15:26:43 2014 +0200 @@ -12,26 +12,33 @@ find_package(Qt5LinguistTools) -set(CERTIFICATELIST_SOURCES +# Common code is used in either the client or the administrator +# application or in unit tests. +set(UICOMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/certificatelist.cpp ${CMAKE_CURRENT_SOURCE_DIR}/certificate.cpp -) - -set(DOWNLOADER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/downloader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sslconnection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sslhelp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/aboutdialog.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/createcertlistdialog.cpp ) +# Cmake does not correctly identify gcc windres when cross compiling +# making this line neccessary to set the correct flags for it. +# See: http://public.kitware.com/Bug/view.php?id=11773 +SET(CMAKE_RC_COMPILE_OBJECT + " -Ocoff ") + set(TRUSTBRIDGE_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/helpdialog.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/aboutdialog.cpp ${CMAKE_CURRENT_SOURCE_DIR}/statusdialog.cpp ${CMAKE_CURRENT_SOURCE_DIR}/certificateitemdelegate.cpp ${CMAKE_CURRENT_SOURCE_DIR}/separatoritemdelegate.cpp ${CMAKE_CURRENT_SOURCE_DIR}/installwrapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/img/icon.rc ${CERTIFICATELIST_SOURCES} ${DOWNLOADER_SOURCES} ) @@ -42,9 +49,6 @@ ${CMAKE_CURRENT_SOURCE_DIR}/certificatetablemodel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/certificatetabledelegate.cpp ${CMAKE_CURRENT_SOURCE_DIR}/createinstallerdialog.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/createcertlistdialog.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/aboutdialog.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/sslhelp.cpp ${CERTIFICATELIST_SOURCES} ) @@ -107,6 +111,12 @@ set(ADMINSTRATOR_SOURCES_WITH_RESOURCES ${ADMINSTRATOR_SOURCES}) qt5_add_resources(ADMINSTRATOR_SOURCES_WITH_RESOURCES ${ADMINSTRATOR_RESOURCES}) +if(WIN32) + # This option causes cmake to use the appropiate liker flags to hide + # the console Window on Windows + set (_add_executable_params WIN32) +endif() + if(Qt5LinguistTools_FOUND) # Include translation as a resource # This works in the source directory to enable the rcc dependencies to be found @@ -116,7 +126,9 @@ qt5_add_resources(ADMINISTRATOR_L10N ${CMAKE_CURRENT_BINARY_DIR}/administrator.qrc) qt5_create_translation(ADMINISTRATOR_TRANSLATION ${ADMINSTRATOR_SOURCES_WITH_RESOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/l10n/administrator_de_DE.ts) - add_executable(administrator ${ADMINSTRATOR_SOURCES_WITH_RESOURCES} + add_executable(trustbridge-admin + ${_add_executable_params} + ${ADMINSTRATOR_SOURCES_WITH_RESOURCES} ${ADMINISTRATOR_L10N} ${ADMINISTRATOR_TRANSLATION} ) @@ -125,24 +137,34 @@ qt5_add_resources(TRUSTBRIDGE_L10N ${CMAKE_CURRENT_BINARY_DIR}/trustbridge.qrc) qt5_create_translation(TRUSTBRIDGE_TRANSLATION ${TRUSTBRIDGE_SOURCES_WITH_RESOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/l10n/trustbridge_de_DE.ts) - add_executable(trustbridge ${TRUSTBRIDGE_SOURCES_WITH_RESOURCES} + add_executable(trustbridge + ${_add_executable_params} + ${TRUSTBRIDGE_SOURCES_WITH_RESOURCES} ${TRUSTBRIDGE_L10N} ${TRUSTBRIDGE_TRANSLATION} ) else() message (STATUS "WARNING: Could not find qt linguist tools. Translation will not be included.") - add_executable(administrator ${ADMINSTRATOR_SOURCES_WITH_RESOURCES}) - add_executable(trustbridge ${TRUSTBRIDGE_SOURCES_WITH_RESOURCES}) + add_executable(trustbridge-admin + ${_add_executable_params} + ${ADMINSTRATOR_SOURCES_WITH_RESOURCES}) + add_executable(trustbridge + ${_add_executable_params} + ${TRUSTBRIDGE_SOURCES_WITH_RESOURCES}) endif() -target_link_libraries(administrator Qt5::Widgets +add_library(ui_common STATIC ${UICOMMON_SOURCES}) + +target_link_libraries(trustbridge-admin Qt5::Widgets + ui_common trustbridge_common ${POLARSSL_LIBRARIES} ${EXTRA_STATIC_LIBS} ${PROFILING_LIBS}) target_link_libraries(trustbridge Qt5::Widgets + ui_common trustbridge_common ${POLARSSL_LIBRARIES} ${EXTRA_STATIC_LIBS} @@ -153,4 +175,4 @@ add_subdirectory(tests) install(TARGETS trustbridge DESTINATION bin) -install(TARGETS administrator DESTINATION bin) +install(TARGETS trustbridge-admin DESTINATION bin) diff -r ca583ffe728a -r a097dd86cb4d ui/administrator.cpp --- a/ui/administrator.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/administrator.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -19,7 +19,7 @@ #endif #ifndef APPNAME -#define APPNAME "trustbridge-administration" +#define APPNAME "trustbridge-admin" #endif #ifndef ORGANIZATION diff -r ca583ffe728a -r a097dd86cb4d ui/administratorwindow.cpp --- a/ui/administratorwindow.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/administratorwindow.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -138,14 +138,16 @@ void AdministratorWindow::loadCertificateFile() { + QString lastCertFile = mSettings.value("LastCertList", QDir::homePath()).toString(); QString certFile = QFileDialog::getOpenFileName( - this, tr("Select certificate list file"), QDir::homePath(), "*.txt"); + this, tr("Select certificate list file"), lastCertFile, "*.txt"); mCertList.readList(certFile.toLocal8Bit().constData()); if (!mCertList.isValid()) { - qDebug() << "Not a valid list."; + QMessageBox::warning(this, tr("Error!"), tr("Failed to load the certificate list.")); } else { certificateModel->removeAll(); loadCertificateTable(); + mSettings.setValue("LastCertList", certFile); } } diff -r ca583ffe728a -r a097dd86cb4d ui/createcertlistdialog.cpp --- a/ui/createcertlistdialog.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/createcertlistdialog.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -258,7 +258,16 @@ return; } - if (!outputFile.copy(archiveDir.filePath("current_certificates.txt"))) { + QString curCerts = archiveDir.filePath("current_certificates.txt"); + + if (QFile::exists(curCerts)) { + if (!QFile::remove(curCerts)) { + showErrorMessage(tr("Failed to update current_certificates.txt")); + return; + } + } + + if (!outputFile.copy(curCerts)) { showErrorMessage(tr("Failed to write current_certificates file.")); return; } diff -r ca583ffe728a -r a097dd86cb4d ui/createinstallerdialog.cpp --- a/ui/createinstallerdialog.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/createinstallerdialog.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -14,13 +14,25 @@ #include #include #include +#include +#include CreateInstallerDialog::CreateInstallerDialog(QMainWindow *parent) : - QDialog(parent) + QDialog(parent), + mProgress(this) { + QSettings settings; setWindowTitle(tr("Create binary installer")); setupGUI(); resize(500, 250); + mCertFile->setText(settings.value("CodeSignCert", QString()).toString()); + mBinaryFolder->setText(settings.value("LastBinaryFolder", QString()).toString()); + mSaveFile->setText(settings.value("LastBinOutputFolder", QString()).toString()); + + connect(&mNSISProc, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(processFinished(int, QProcess::ExitStatus))); + connect(&mNSISProc, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(processError(QProcess::ProcessError))); } void CreateInstallerDialog::setupGUI() @@ -37,7 +49,7 @@ QLabel *header = new QLabel("

" + tr("Create binary installer") + "

"); QLabel *description = new QLabel( - tr("Create and sign a TrustBridge binary installer from source.")); + tr("Create and sign a TrustBridge binary installer.")); headerSubLayout->insertSpacing(0, 40); headerSubLayout->addWidget(description); QFrame *headerSeparator = new QFrame(); @@ -48,22 +60,22 @@ headerLayout->addWidget(headerSeparator); headerLayout->insertSpacing(4, 10); - QLabel *archiveLabel = new QLabel(tr("Select source archive:")); - QLabel *certLabel = new QLabel(tr("Select code signing certificate (secret key):")); + QLabel *archiveLabel = new QLabel(tr("Select binary folder:")); + QLabel *certLabel = new QLabel(tr("Select code signing certificate:")); QLabel *saveLabel = new QLabel(tr("Select output folder:")); labelLayout->addWidget(archiveLabel); labelLayout->addWidget(certLabel); labelLayout->addWidget(saveLabel); - mArchiveFile = new QLineEdit(); + mBinaryFolder = new QLineEdit(); mCertFile = new QLineEdit(); mSaveFile = new QLineEdit(); - fieldLayout->addWidget(mArchiveFile); + fieldLayout->addWidget(mBinaryFolder); fieldLayout->addWidget(mCertFile); fieldLayout->addWidget(mSaveFile); QPushButton *archiveSelect = new QPushButton("..."); - connect(archiveSelect, SIGNAL(clicked()), this, SLOT(openArchiveSelect())); + connect(archiveSelect, SIGNAL(clicked()), this, SLOT(openFolderSelect())); archiveSelect->setFixedWidth(30); QPushButton *certSelect = new QPushButton("..."); connect(certSelect, SIGNAL(clicked()), this, SLOT(openCertificateSelect())); @@ -100,35 +112,109 @@ setLayout(topLayout); + mProgress.setWindowModality(Qt::WindowModal); + mProgress.setLabelText(tr("Creating installer package...")); + mProgress.setCancelButton(0); + mProgress.setRange(0,0); + mProgress.setMinimumDuration(0); + return; } void CreateInstallerDialog::openCertificateSelect() { + QSettings settings; QString certFile = QFileDialog::getOpenFileName( - this, tr("Select certificate"), QDir::homePath(), "*.pem *.der *.crt"); + this, tr("Select certificate"), + mCertFile->text().isEmpty() ? QDir::homePath() : mCertFile->text(), + "*.pem *.der *.crt"); + settings.setValue("CodeSignCert", certFile); mCertFile->setText(certFile); } -void CreateInstallerDialog::openArchiveSelect() +void CreateInstallerDialog::openFolderSelect() { - QString archiveFile = QFileDialog::getOpenFileName( - this, tr("Select source archive"), QDir::homePath(), "*.zip *.tar.gz"); - mArchiveFile->setText(archiveFile); + QSettings settings; + QString archiveFolder = QFileDialog::getExistingDirectory( + this, tr("Select binary folder"), + mBinaryFolder->text().isEmpty() ? QDir::homePath() : mBinaryFolder->text()); + mBinaryFolder->setText(archiveFolder); + settings.setValue("LastBinaryFolder", archiveFolder); } void CreateInstallerDialog::openSaveLocation() { + QSettings settings; QString saveFile = QFileDialog::getExistingDirectory( - this, tr("Select target location"), QDir::homePath()); + this, tr("Select target location"), + mSaveFile->text().isEmpty() ? QDir::homePath() : mSaveFile->text()); mSaveFile->setText(saveFile); + settings.setValue("LastBinOutputFolder", saveFile); +} + +void CreateInstallerDialog::showErrorMessage(const QString &msg) +{ + QMessageBox::warning(this, tr("Error!"), msg); +} + +void CreateInstallerDialog::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + qDebug() << "Finished: " << mNSISProc.readAll(); + mProgress.cancel(); +} + +void CreateInstallerDialog::processError(QProcess::ProcessError error) +{ + qDebug() << "Error: " << mNSISProc.readAll(); + mProgress.cancel(); } void CreateInstallerDialog::createInstaller() { - qDebug() << "and now create the installer using:"; - qDebug() << "source archive: " << mArchiveFile->text(); - qDebug() << "certificate: " << mCertFile->text(); - qDebug() << "target" << mSaveFile->text(); - // TODO + QDir binDir(mBinaryFolder->text()); + QDir outDir(mSaveFile->text()); + if (mBinaryFolder->text().isEmpty() || !binDir.exists()) { + showErrorMessage(tr("Please select an existing input folder.")); + return; + } + if (mCertFile->text().isEmpty()) { + showErrorMessage(tr("Please select a codesigning certificate.")); + return; + } + if (mSaveFile->text().isEmpty() || !outDir.exists()) { + showErrorMessage(tr("Please select a output folder.")); + return; + } + QSettings options(binDir.filePath("meta.ini"), QSettings::IniFormat); + options.sync(); + QStringList keys = options.allKeys(); + if (options.status() != QSettings::NoError || keys.size() < 1) { + showErrorMessage(tr("Folder %1 does not appear to contain a meta.ini") + .arg(binDir.path())); + return; + } + + /* Copy windows directory contents to tmpdir */ + QStringList arguments; + mNSISProc.setProgram("makensis"); + mNSISProc.setProcessChannelMode(QProcess::MergedChannels); + mNSISProc.setWorkingDirectory(outDir.path()); + arguments << QString::fromLatin1("-Dfiles_dir=") + binDir.path() + "/windows"; + foreach (const QString &key, keys) { + arguments << QString::fromLatin1("-D%1=%2").arg(key, + options.value(key, QString()).toString()); + } + + arguments << binDir.path() + "/trustbridge.nsi"; + + qDebug() << "Starting makensis with arguments: " << arguments; + mNSISProc.setArguments(arguments); + mNSISProc.start(); + mProgress.show(); + + if (!mNSISProc.waitForStarted() || + mNSISProc.state() == QProcess::NotRunning) { + showErrorMessage(tr("Failed to start makensis.\n" + "Please ensure that makensis is installed and in your PATH variable.")); + } } diff -r ca583ffe728a -r a097dd86cb4d ui/createinstallerdialog.h --- a/ui/createinstallerdialog.h Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/createinstallerdialog.h Tue Apr 29 15:26:43 2014 +0200 @@ -11,6 +11,8 @@ #include #include #include +#include +#include /** * @file createinstallerdialog.h * @brief The dialog to show settings and create an installer. @@ -31,14 +33,27 @@ void setupGUI(); QLineEdit *mCertFile; - QLineEdit *mArchiveFile; + QLineEdit *mBinaryFolder; QLineEdit *mSaveFile; + QProcess mNSISProc; + QProgressDialog mProgress; + + /** @brief show an error message with QMessageBox + * + * @param [in] msg The message to show + */ + void showErrorMessage(const QString &msg); + private slots: void openCertificateSelect(); - void openArchiveSelect(); + void openFolderSelect(); void openSaveLocation(); void createInstaller(); + + /* Slots for the creator process */ + void processError(QProcess::ProcessError error); + void processFinished(int exitCode, QProcess::ExitStatus exitStatus); }; #endif // CREATEINSTALLERDIALOG_H diff -r ca583ffe728a -r a097dd86cb4d ui/img/icon.ico Binary file ui/img/icon.ico has changed diff -r ca583ffe728a -r a097dd86cb4d ui/img/icon.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/img/icon.rc Tue Apr 29 15:26:43 2014 +0200 @@ -0,0 +1,1 @@ +IDI_ICON1 ICON DISCARDABLE "icon.ico" diff -r ca583ffe728a -r a097dd86cb4d ui/installwrapper.cpp --- a/ui/installwrapper.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/installwrapper.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -15,6 +15,7 @@ #include #include "logging.h" +#include "util.h" #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */ @@ -95,7 +96,11 @@ shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExecInfo.lpVerb = L"runas"; + if (!is_admin()) { + shExecInfo.lpVerb = L"open"; + } else { + shExecInfo.lpVerb = L"runas"; + } shExecInfo.lpFile = reinterpret_cast (cinstFileName.utf16()); shExecInfo.lpParameters = reinterpret_cast (parameters.utf16()); diff -r ca583ffe728a -r a097dd86cb4d ui/l10n/administrator_de_DE.ts --- a/ui/l10n/administrator_de_DE.ts Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/l10n/administrator_de_DE.ts Tue Apr 29 15:26:43 2014 +0200 @@ -4,45 +4,14 @@ AboutDialog - - TrustBridge - - - - - Version: - - - - - TrustBridge is a secure root certificate installer for Windows and Linux. - - - - The root certificate lists are managed by the German <a href="https://www.bsi.bund.de">Federal Office for Information Security (BSI)</a>. - Die Liste der Wurzelzertifikate wird vom <a href="https://www.bsi.bund.de">Bundesamt für Sicherheit in der Informationstechnik (BSI)</a> verwaltet. - - - - The software was developed by the companies <a href="http://www.intevation.de">Intevation GmbH</a> and <a href="http://www.dn-systems.de">DN-Systems GmbH</a>, <br> contracted by the German Federal Office for Information Security (BSI). - - - + Die Liste der Wurzelzertifikate wird vom <a href="https://www.bsi.bund.de">Bundesamt für Sicherheit in der Informationstechnik (BSI)</a> verwaltet. - - TrustBridge is Free Software licensed under GNU GPL v2+. - -Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik - - - - Close - Schließen + Schließen @@ -80,11 +49,21 @@ In der Liste enthaltene Zertifikate: - + Select certificate list file Zertifikatsliste auswählen + + Error! + Fehler! + + + + Failed to load the certificate list. + Fehler beim Laden der Zertifikatsliste + + All managed root certificates of the certificate list: Alle verwalteten Wurzelzertifikate der Zertifikatsliste: @@ -118,7 +97,7 @@ Zertifikatslistendatei auswählen - + Select certificate Zertifikat auswählen @@ -177,10 +156,8 @@ CreateCertListDialog - - Save certificate list - Zertifikatsliste speichern + Zertifikatsliste speichern Save all managed root certificates in a new, signed certificate list @@ -196,94 +173,78 @@ Liste signieren - Save all managed root certificates in a new, signed certificate list. - Eine neue, signierte Zertifikatsliste erstellen. - - - - In addition, each certificate list will be saved automatically in the archive directory: - - Zusätzlich wird jede Zertifikatsliste automatisch in diesem Ordner Archiviert: - - - - Save list - Liste speichern + Eine neue, signierte Zertifikatsliste erstellen. - - Cancel - Abbrechen - - - - Error! - Fehler! + In addition, each certificate list will be saved automatically in the archive directory: + + Zusätzlich wird jede Zertifikatsliste automatisch in diesem Ordner Archiviert: - - Select certificate - Zertifikat auswählen + Save list + Liste speichern - - Failed to write list to: %1 - Fehler beim schreiben der Liste in Datei: %1 + Cancel + Abbrechen - + Error! + Fehler! + + + Select certificate + Zertifikat auswählen + + + Failed to write list to: %1 + Fehler beim schreiben der Liste in Datei: %1 + + Failed to load certificate: %1 English wording is wrong - Fehler beim laden des Schlüssels: %1 - - - - Only 3072 bit RSA keys are supported by the current format. - Nur 3027 bit RSA Schlüssel werden vom aktuellen Format unterstützt. - - - - Select target location - Zielordner auswählen - - - - Please select a valid rsa key. - Kein Signaturschlüssel ausgewählt. + Fehler beim laden des Schlüssels: %1 - - Please select an output location first. - Kein Zielordner angegeben. - - - - Failed to create archive location. - Fehler beim erstellen des Archivordners. + Only 3072 bit RSA keys are supported by the current format. + Nur 3027 bit RSA Schlüssel werden vom aktuellen Format unterstützt. - - Failed Archive a copy. - Fehler beim speichern der Archivkopie. + Select target location + Zielordner auswählen - - Failed to write current_certificates file. - Fehler beim schreiben der Datei "current_certificates". + Please select a valid rsa key. + Kein Signaturschlüssel ausgewählt. - + Please select an output location first. + Kein Zielordner angegeben. + + + Failed to create archive location. + Fehler beim erstellen des Archivordners. + + + Failed Archive a copy. + Fehler beim speichern der Archivkopie. + + + Failed to write current_certificates file. + Fehler beim schreiben der Datei "current_certificates". + + Saved certificate list: %1 - Zertifikatsliste: %1 gespeichert. + Zertifikatsliste: %1 gespeichert. CreateInstallerDialog - - + + Create binary installer Installationspaket erstellen @@ -292,47 +253,96 @@ Ein TrustBridge-Installationspaket aus den Quellen erstellen und signieren. - - Create and sign a TrustBridge binary installer from source. - + Select source archive: + Quellcode-Archiv auswählen: - - Select source archive: - Quellcode-Archiv auswählen: + Select code signing certificate (secret key): + Code Signing Zertifikat auswählen (privater Schlüssel): - Select code signing certificate (secret key): - Code Signing Zertifikat auswählen (privater Schlüssel): + Create and sign a TrustBridge binary installer. + Erzeugt und signiert ein TrustBridge-Installationspaket. - + + Select binary folder: + Binärverzeichnis auswählen: + + + + Select code signing certificate: + Code-Signing-Zertifikat auswählen: + + + Select output folder: Ausgabeverzeichnis auswählen: - + Create installer Installationspaket erzeugen - + Cancel Abbrechen - + + Creating installer package... + Installationspaket wird erstellt... + + + Select certificate Zertifikat auswählen - - Select source archive - Archiv auswählen + + Select binary folder + Binärverzeichnis auswählen - + + Error! + Fehler! + + + + Please select an existing input folder. + Bitte wählen Sie ein existierendes Eingabeverzeichnis. + + + + Please select a codesigning certificate. + Bitte wählen Sie ein Code-Signing-Zertifikat. + + + + Please select a output folder. + Bitte wählen Sie ein Ausgabeverzeichnis. + + + + Folder %1 does not appear to contain a meta.ini + Das Verzeichnis %1 enthält keine meta.ini Datei + + + + Failed to start makensis. +Please ensure that makensis is installed and in your PATH variable. + Fehler beim Starten von makensis. +Bitte versichern Sie sich, dass makensis korrekt installiert und in der PATH-Variable enthalten ist. + + + Select source archive + Archiv auswählen + + + Select target location Zielort auswählen @@ -340,22 +350,8 @@ QObject - - Certificate: - <bold>%1</bold> - %2, %3 - -Serial number: -%4 -Valid from: <bold>%5</bold> to <bold>%6</bold> - -Issued by: .. - - - - Failed to parse certificate - Fehler beim Parsen des Zertifikats + Fehler beim Parsen des Zertifikats diff -r ca583ffe728a -r a097dd86cb4d ui/l10n/trustbridge_de_DE.ts --- a/ui/l10n/trustbridge_de_DE.ts Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/l10n/trustbridge_de_DE.ts Tue Apr 29 15:26:43 2014 +0200 @@ -2,392 +2,300 @@ - AboutDialog - - - TrustBridge - - - - - Version: - - - - - TrustBridge is a secure root certificate installer for Windows and Linux. - - - - - The root certificate lists are managed by the German <a href="https://www.bsi.bund.de">Federal Office for Information Security (BSI)</a>. - - - - - - - The software was developed by the companies <a href="http://www.intevation.de">Intevation GmbH</a> and <a href="http://www.dn-systems.de">DN-Systems GmbH</a>, <br> contracted by the German Federal Office for Information Security (BSI). - - - - - - - TrustBridge is Free Software licensed under GNU GPL v2+. - -Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik - - - - - Close - - - - - Downloader - - - Invalid response - - - - - - - - Connection lost - - - - - Invalid response from the server - - - - - Failed to initialize SSL Module. - - - - - Failed to connect. - - - - - Connected - - - - - Closing - - - - HelpDialog This dialog contains some text to help the user. - + Dieser Dialog enthält die Hilfe für den Benutzer. Close - + Schließen InstallWrapper - + Could not find certificate installation process. - - - - - Failed to write temporary file. - - - - - Error executing process: %1 - - - - - Error monitoring process: %1 - + Der Zertifikatsinstallations-Prozess konnte nicht gefunden werden. - - Certificate installation timed out. - - - - - Failed to check process status: %1 - + + Failed to write temporary file. + Fehler beim Schreiben der temporären Datei. - - The process failed with return code. %1 - + + Error executing process: %1 + Auführungsfehler: %1 - - Failed to start installer process. - + + Error monitoring process: %1 + Fehlerüberwachung: %1 - + + Certificate installation timed out. + Zeitüberschreitung bei der Zertifikatsinstallation. + + + + Failed to check process status: %1 + Fehler in der Prozess-Statusprüfung: %1 + + + + The process failed with return code. %1 + Der Prozess ist fehlgeschlagen. Fehlercode: %1 + + + + Failed to start installer process. + Fehler beim Starten des Installer-Prozess. + + + Failed to complete installation. - + Fehler beim Abschließen der Installation. MainWindow - + An updated certificate list is available. Click here to install. - - - - - An update for %1 is available. Click here to install. - - - - - New Software version is available. - + Eine aktualisierte Zertifikatsliste ist verfügbar. Klicken Sie hier zum Installieren. - - Do you want to install the new Version? - - - - - Check for Updates - + + An update for %1 is available. Click here to install. + Eine Aktualisierung für %1 ist verfügbar. Klicken Sie hier zum Installieren. - - - - Quit - + + New Software version is available. + Neue Softwareversion verfügbar. - - TrustBridge - + + Do you want to install the new Version? + typo: _v_ersion + Möchten Sie die neue Version installieren? - + + Check for Updates + Aktualisierungen prüfen + + + + + + Quit + Beenden + + + + TrustBridge + TrustBridge + + + Menu Menü - + Force Update - - - - - - Settings - - - - - Statusdialog - - - - - Help - - - - - About - - - - - Managed Certificates - + Aktualisierung erzwingen - - - Current List Date: %1 - - - - - Autoupdate - - - - - Autostart - - - - - Install selected - - - - - Details - - - - - Subject Common Name: - - - - - Subject Organisation: - - - - - Issuer Common Name: - - - - - Issuer Organisation: - + + Settings + Einstellungen - - Valid from: - - - - - Valid to: - - - - - Fingerprint: - - - - - New List Date: %1 - + + Statusdialog + Statusdialog - - New certificates to install - - - - - New certificates to remove - + + Help + Hilfe - - Old certificates to install - + + About + "TrustBridge" ergänzen + Über TrustBridge - - Old certificates to remove - + + Managed Certificates + Verwaltete Zertifikate - - Error executing update - + + + + Current List Date: %1 + Datum der aktuellen Liste: %1 - + + Autoupdate + Automatische Aktualisierung + + + + Autostart + Start der Anwendung bei Systemstart + + + + Install selected + Jetzt installieren + + + + Details + Details + + + + Subject Common Name: + Inhaber CN: + + + + Subject Organisation: + Inhaber Organisation: + + + + Issuer Common Name: + Aussteller CN: + + + + Issuer Organisation: + Aussteller Organidation: + + + + Valid from: + Gültig ab: + + + + Valid to: + Gültig bis: + + + + Fingerprint: + Fingerprint: + + + + New List Date: %1 + Datum der neuen Liste: %1 + + + + New certificates to install + Neu zu installierende Zertifikate + + + + New certificates to remove + Neu zu löschende Zertifikate + + + + Old certificates to install + Bisher installierte Zertifikate + + + + Old certificates to remove + Bisher gelöschte Zertifikate + + + + Error executing update + Fehler bei der Aktualisierung + + + Installing certificates... - + Zertifikate werden installiert... QObject - - Certificate: - <bold>%1</bold> - %2, %3 - -Serial number: -%4 -Valid from: <bold>%5</bold> to <bold>%6</bold> - -Issued by: .. - - - - - Failed to parse certificate - - - - + Couldn't detect any system tray on this system. This software can only be used in a desktop environment. - + Es konnte kein SystemTray auf diesem System gefunden werden. Diese Software kann nur in einer Desktopumgebung verwendet werden. StatusDialog - The following certificates are successfully installed: - + The following certificates are successfully installed: + + Die folgenden Zertifikate wurden erfolgreich installiert: - * Email CA 2013 + * Email CA 2013 + - * Server CA 2010 + * Server CA 2010 + - The following certificates are successfully removed: + +The following certificates are successfully removed: + - * Email CA 2010 + * Email CA 2010 + - Errors while processing certificates: + +Errors while processing certificates: + - * PCA-1-Verwaltung-08 + * PCA-1-Verwaltung-08 + Close - + Schließen diff -r ca583ffe728a -r a097dd86cb4d ui/main.cpp --- a/ui/main.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/main.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -48,10 +48,10 @@ QSettings settings; settings.beginGroup("settings"); - int autoStart = settings.value("autostart").toInt(); + bool autoStart = settings.value("autostart", true).toBool(); settings.endGroup(); - if (trayMode && autoStart <= 0) { + if (trayMode && !autoStart) { return 0; } diff -r ca583ffe728a -r a097dd86cb4d ui/mainwindow.cpp --- a/ui/mainwindow.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/mainwindow.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -50,6 +50,7 @@ #include "certificateitemdelegate.h" #include "separatoritemdelegate.h" #include "installwrapper.h" +#include "util.h" MainWindow::MainWindow(bool trayMode): mTrayMode(trayMode) @@ -392,11 +393,11 @@ connect(mAutoStartOption, SIGNAL(stateChanged(int)), this, SLOT(saveAutoStart(int))); mSettings.beginGroup("settings"); - int autoUpdate = mSettings.value("autoupdate").toInt(); - int autoStart = mSettings.value("autostart").toInt(); + bool autoUpdate = mSettings.value("autoupdate", false).toBool(); + bool autoStart = mSettings.value("autostart", true).toBool(); mSettings.endGroup(); - mAutoUpdateOption->setCheckState(autoUpdate > 0 ? Qt::Checked : Qt::Unchecked); - mAutoStartOption->setCheckState(autoStart > 0 ? Qt::Checked : Qt::Unchecked); + mAutoUpdateOption->setCheckState(autoUpdate ? Qt::Checked : Qt::Unchecked); + mAutoStartOption->setCheckState(autoStart ? Qt::Checked : Qt::Unchecked); // The buttons. @@ -414,6 +415,13 @@ bottomLayout->addWidget(quitButton); bottomLayout->setAlignment(quitButton, Qt::AlignBottom); +#ifdef Q_OS_WIN + if (is_admin()) { + QIcon uacShield = QApplication::style()->standardIcon(QStyle::SP_VistaShield); + installButton->setIcon(uacShield); + } +#endif + // The certificate details QGroupBox *detailBox = new QGroupBox(tr("Details")); QLabel *subjectCN = new QLabel(tr("Subject Common Name:")); @@ -525,24 +533,32 @@ } // Add separators and certificates to list widget. - mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++)); - foreach (const Certificate &cert, newInstallCerts) { - mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++)); + if (!newInstallCerts.isEmpty()) { + mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++)); + foreach (const Certificate &cert, newInstallCerts) { + mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++)); + } } - mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++)); - foreach (const Certificate &cert, newRemoveCerts) { - mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++)); + if (!newRemoveCerts.isEmpty()) { + mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++)); + foreach (const Certificate &cert, newRemoveCerts) { + mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++)); + } } - mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++)); - foreach (const Certificate &cert, oldInstallCerts) { - mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++)); + if (!oldInstallCerts.isEmpty()) { + mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++)); + foreach (const Certificate &cert, oldInstallCerts) { + mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++)); + } } - mCertListWidget->addItem(createSeparator(tr("Old certificates to remove"), i++)); - foreach (const Certificate &cert, oldRemoveCerts) { - mCertListWidget->addItem(createListItem(cert, Certificate::RemoveOld, i++)); + if (!oldRemoveCerts.isEmpty()) { + mCertListWidget->addItem(createSeparator(tr("Old certificates to remove"), i++)); + foreach (const Certificate &cert, oldRemoveCerts) { + mCertListWidget->addItem(createListItem(cert, Certificate::RemoveOld, i++)); + } } } @@ -732,14 +748,14 @@ void MainWindow::saveAutoUpdate(int state) { mSettings.beginGroup("settings"); - mSettings.setValue("autoupdate", state); + mSettings.setValue("autoupdate", state != Qt::Unchecked); mSettings.endGroup(); } void MainWindow::saveAutoStart(int state) { mSettings.beginGroup("settings"); - mSettings.setValue("autostart", state); + mSettings.setValue("autostart", state != Qt::Unchecked); mSettings.endGroup(); } diff -r ca583ffe728a -r a097dd86cb4d ui/tests/CMakeLists.txt --- a/ui/tests/CMakeLists.txt Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/tests/CMakeLists.txt Tue Apr 29 15:26:43 2014 +0200 @@ -31,7 +31,9 @@ ${CMAKE_CURRENT_SOURCE_DIR}/data/testdata.qrc) add_executable(${_name} ${_test_sources_with_resources}) add_test(tb-${_name} ${_name}) - target_link_libraries(${_name} Qt5::Test Qt5::Widgets + target_link_libraries(${_name} + ui_common + Qt5::Test Qt5::Widgets trustbridge_common ${POLARSSL_LIBRARIES} ${EXTRA_STATIC_LIBS}) @@ -44,26 +46,24 @@ # Downloader if (HIAWATHA_EXECUTABLE) - set(DOWNLOADER_SOURCES_WITH_RESOURCES ${DOWNLOADER_SOURCES}) qt5_add_resources(DOWNLOADER_SOURCES_WITH_RESOURCES ${TRUSTBRIDGE_RESOURCES}) add_custom_test(downloadertest.cpp "${DOWNLOADER_SOURCES_WITH_RESOURCES}") endif() # Cinstprocess -add_custom_test(cinstprocesstest.cpp "${CERTIFICATELIST_SOURCES}") +add_custom_test(cinstprocesstest.cpp "") add_dependencies(cinstprocesstest cinst) add_custom_test(commontest.cpp "") -add_custom_test(createcertlisttest.cpp "${CERTIFICATELIST_SOURCES};${CMAKE_SOURCE_DIR}/ui/sslhelp.cpp;${CMAKE_SOURCE_DIR}/ui/createcertlistdialog.cpp") +add_custom_test(createcertlisttest.cpp "") if (WIN32) - add_custom_test(windowsstoretest.cpp "${CERTIFICATELIST_SOURCES};${CMAKE_SOURCE_DIR}/cinst/windowsstore.c") + add_custom_test(windowsstoretest.cpp "${CMAKE_SOURCE_DIR}/cinst/windowsstore.c") endif (WIN32) if (NSS_FOUND) include_directories(${NSS_INCLUDE_DIRS}) set(NSSTEST_SOURCES - ${CERTIFICATELIST_SOURCES} ${CMAKE_SOURCE_DIR}/cinst/nssstore_linux.c ${CMAKE_SOURCE_DIR}/cinst/nssstore_win.c) add_custom_test(nsstest.cpp "${NSSTEST_SOURCES}") diff -r ca583ffe728a -r a097dd86cb4d ui/tests/nsstest.cpp --- a/ui/tests/nsstest.cpp Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/tests/nsstest.cpp Tue Apr 29 15:26:43 2014 +0200 @@ -89,9 +89,22 @@ /* Create the profiles.ini `s set environment variables*/ // fakeHome.setAutoRemove(false); #ifndef WIN32 - QVERIFY(!setenv ("HOME", fakeHome.path().toLocal8Bit().constData(), 1)); fakeFirefoxDir = QDir(fakeHome.path() + "/.mozilla/firefox"); fakeThunderbirdDir = QDir(fakeHome.path() + "/.thunderbird"); + + /* Copy the current systems NSSSHARED db in the fake home for benchmark tests */ + QDir fakeNSSSharedDir = fakeHome.path() + "/.pki/nssdb"; + QVERIFY(fakeNSSSharedDir.mkpath(fakeNSSSharedDir.path())); + qDebug() << "Copying: " << QDir::homePath() + "/.pki/nssdb/cert9.db" << + " to " << fakeNSSSharedDir.path() + "cert9.db"; + QVERIFY(QFile::copy(QDir::homePath() + "/.pki/nssdb/cert9.db", + fakeNSSSharedDir.path() + "cert9.db")); + QVERIFY(QFile::copy(QDir::homePath() + "/.pki/nssdb/key4.db", + fakeNSSSharedDir.path() + "key4.db")); + QVERIFY(QFile::copy(QDir::homePath() + "/.pki/nssdb/pkcs11.txt", + fakeNSSSharedDir.path() + "pkcs11.txt")); + + QVERIFY(!setenv ("HOME", fakeHome.path().toLocal8Bit().constData(), 1)); #else { char buf[fakeHome.path().toLocal8Bit().size() + 9]; @@ -225,4 +238,26 @@ } } +void NSSTest::benchmarkInstall() +{ + char ** to_install = NULL, + ** to_remove = NULL; + + QList instList; + + /* Install all certificates */ + foreach (const Certificate &cert, validList.getCertificates()) { + if (!cert.isInstallCert()) + continue; + instList << cert; + strv_append (&to_install, cert.base64Line().toLatin1().constData() + 2, + cert.base64Line().size() - 2); + } + QVERIFY((size_t) instList.size() == strv_length(to_install)); + QVERIFY(strv_length(to_install) != 0); + + QBENCHMARK { + write_stores_nss(to_install, to_remove); + } +} QTEST_GUILESS_MAIN (NSSTest); diff -r ca583ffe728a -r a097dd86cb4d ui/tests/nsstest.h --- a/ui/tests/nsstest.h Tue Apr 29 15:26:02 2014 +0200 +++ b/ui/tests/nsstest.h Tue Apr 29 15:26:43 2014 +0200 @@ -34,6 +34,7 @@ private Q_SLOTS: void initTestCase(); void testInstRemove(); + void benchmarkInstall(); }; #endif // NSSTEST_H