From patchwork Wed Dec 19 09:26:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 647 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id qE+LE76pGlzTIAAAIUCqbw for ; Wed, 19 Dec 2018 15:27:42 -0500 Received: from proxy3.mail.iad3b.rsapps.net ([172.31.255.6]) by director10.mail.ord1d.rsapps.net with LMTP id +JnGEL6pGlxhXgAApN4f7A ; Wed, 19 Dec 2018 15:27:42 -0500 Received: from smtp29.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.iad3b.rsapps.net with LMTP id EHybCr6pGly5cQAAM8Wetg ; Wed, 19 Dec 2018 15:27:42 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp29.gate.iad3b.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 883f18ce-03cc-11e9-8737-525400534f55-1-1 Received: from [216.105.38.7] ([216.105.38.7:63792] helo=lists.sourceforge.net) by smtp29.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 6D/CD-10086-DB9AA1C5; Wed, 19 Dec 2018 15:27:41 -0500 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1gZiQQ-0002cU-3s; Wed, 19 Dec 2018 20:26:38 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1gZiQO-0002cH-Qm for openvpn-devel@lists.sourceforge.net; Wed, 19 Dec 2018 20:26:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=LMINViDO9NCbmmiDLxd3vfLUsbfXyml2RauQMJnIJ9M=; b=nGKjX1/8NChcMXN+wf2FBYAfQa E95bfHRXnD+XKRRIoOsgUW2swLvW8ehdqHKUjHtFxIBw6rOgiQIAXHXm4DbAmKXQlIbu0gKWmVBwU Dys7bIw/yCiUOucqwQqWjRhuB7PdASNl8KqTIeP0Ga8iW2D4g9CJjq+b6K+MjM7ytZVU=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=LMINViDO9NCbmmiDLxd3vfLUsbfXyml2RauQMJnIJ9M=; b=IhH83ohFop/oO/AvVGt+pBWqHa q/7WKQd73GV7uLdx4YAFjo3eG4h9c43uI2XPoL8lMzbb7Z9gEdop4Z7VA9Aw0I6AfiHSBccN6m2PU WBRazHUYea9/+t/DxPaPkxNuKymZNV7NbdZJcbHm4OJp03rMZfizUMiYiDN312zwjtVg=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) id 1gZiQL-008SI0-6S for openvpn-devel@lists.sourceforge.net; Wed, 19 Dec 2018 20:26:36 +0000 Received: by pub5.amebis.si (Postfix, from userid 115) id D536320616; Wed, 19 Dec 2018 21:26:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=rozman.si; s=default; t=1545251185; bh=rpD2JrgHFadgKIMDApBHUfnUO04y3gw6KOHgiciFk8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J8AymmrnhvZQ8m66gLqthQRg4xurpQhYGbmnFFEXz8dLHdI4gwWASfXCdJ3nILGQ+ OpwFdUM/ta61mRX2YBV/zKg+UTr0pafnA/Mfy1nkFQvG3MrFkW9C/imKODttSh3NoF pGp7BUUT2MQvRP0YTDwg7mAmw/Sy6Ol8UiA1cP/k= X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on brana.amebis.doma X-Spam-Level: * X-Spam-Status: No, score=1.3 required=5.0 tests=RDNS_NONE autolearn=no autolearn_force=no version=3.4.2 Received: from gw0.selo.doma (unknown [IPv6:2a00:ee2:1206:8101::1]) by pub5.amebis.si (Postfix) with ESMTP id 5FEBF200FE; Wed, 19 Dec 2018 21:26:25 +0100 (CET) Received: from s0.selo.doma (s0.selo.doma [IPv6:2a00:ee2:1206:8101::d]) by gw0.selo.doma (Postfix) with ESMTP id 310F521B9829; Wed, 19 Dec 2018 21:26:25 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Wed, 19 Dec 2018 21:26:09 +0100 Message-Id: <20181219202611.2144-2-simon@rozman.si> X-Mailer: git-send-email 2.19.0.windows.1 In-Reply-To: <20181219202611.2144-1-simon@rozman.si> References: <20181219202611.2144-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1gZiQL-008SI0-6S Subject: [Openvpn-devel] [PATCH 2/4] Extend FindSystemInfo custom action to detect OpenVPNService state X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox --- src/openvpnmsica/openvpnmsica.c | 168 ++++++++++++++++++++++++++++---- 1 file changed, 151 insertions(+), 17 deletions(-) Acked-by: Gert Doering diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 721bd4f8..810c2858 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -44,6 +44,7 @@ #include #ifdef _MSC_VER +#pragma comment(lib, "advapi32.lib") #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "shell32.lib") #pragma comment(lib, "shlwapi.lib") @@ -193,29 +194,34 @@ _openvpnmsica_debug_popup(_In_z_ LPCTSTR szFunctionName) #endif -UINT __stdcall -FindSystemInfo(_In_ MSIHANDLE hInstall) +/** + * Detects Windows version and sets DRIVERCERTIFICATION property to "", "whql", or "attsgn" + * accordingly. + * + * @param hInstall Handle to the installation provided to the DLL custom action + * + * @return ERROR_SUCCESS on success; An error code otherwise + * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx + */ +static UINT +openvpnmsica_set_driver_certification(_In_ MSIHANDLE hInstall) { -#ifdef _MSC_VER -#pragma comment(linker, DLLEXP_EXPORT) -#endif - - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); - UINT uiResult; - BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); - - /* Set MSI session handle in TLS. */ - struct openvpnmsica_tls_data *s = (struct openvpnmsica_tls_data *)TlsGetValue(openvpnmsica_tlsidx_session); - s->hInstall = hInstall; /* Get Windows version. */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) /* 'GetVersionExW': was declared deprecated. */ +#endif OSVERSIONINFOEX ver_info = { .dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX) }; if (!GetVersionEx((LPOSVERSIONINFO)&ver_info)) { uiResult = GetLastError(); msg(M_NONFATAL | M_ERRNO, "%s: GetVersionEx() failed", __FUNCTION__); - goto cleanup_CoInitialize; + return uiResult; } +#ifdef _MSC_VER +#pragma warning(pop) +#endif /* The Windows version is usually spoofed, check using RtlGetVersion(). */ TCHAR szDllPath[0x1000]; @@ -294,17 +300,145 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) { SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"DRIVERCERTIFICATION\") failed", __FUNCTION__); - goto cleanup_CoInitialize; + return uiResult; + } + + return ERROR_SUCCESS; +} + + +/** + * Detects if the OpenVPNService service is in use (running or paused) and sets + * OPENVPNSERVICE to the service process PID, or its path if it is set to + * auto-start, but not running. + * + * @param hInstall Handle to the installation provided to the DLL custom action + * + * @return ERROR_SUCCESS on success; An error code otherwise + * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx + */ +static UINT +openvpnmsica_set_openvpnserv_state(_In_ MSIHANDLE hInstall) +{ + UINT uiResult; + + /* Get Service Control Manager handle. */ + SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); + if (hSCManager == NULL) + { + uiResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: OpenSCManager() failed", __FUNCTION__); + return uiResult; + } + + /* Get OpenVPNService service handle. */ + SC_HANDLE hService = OpenService(hSCManager, TEXT("OpenVPNService"), SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); + if (hService == NULL) + { + uiResult = GetLastError(); + if (uiResult == ERROR_SERVICE_DOES_NOT_EXIST) { + /* This is not actually an error. */ + goto cleanup_OpenSCManager; + } + msg(M_NONFATAL | M_ERRNO, "%s: OpenService(\"OpenVPNService\") failed", __FUNCTION__); + goto cleanup_OpenSCManager; + } + + /* Query service status. */ + SERVICE_STATUS_PROCESS ssp; + DWORD dwBufSize; + if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(ssp), &dwBufSize)) + { + uiResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: QueryServiceStatusEx(\"OpenVPNService\") failed", __FUNCTION__); + goto finish_QueryServiceStatusEx; + } + + switch (ssp.dwCurrentState) + { + case SERVICE_START_PENDING: + case SERVICE_RUNNING: + case SERVICE_STOP_PENDING: + case SERVICE_PAUSE_PENDING: + case SERVICE_PAUSED: + case SERVICE_CONTINUE_PENDING: + { + /* Set OPENVPNSERVICE property to service PID. */ + TCHAR szPID[10/*MAXDWORD in decimal*/ + 1/*terminator*/]; + _stprintf_s( + szPID, _countof(szPID), + TEXT("%u"), + ssp.dwProcessId); + + uiResult = MsiSetProperty(hInstall, TEXT("OPENVPNSERVICE"), szPID); + if (uiResult != ERROR_SUCCESS) + { + SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"OPENVPNSERVICE\") failed", __FUNCTION__); + } + goto cleanup_OpenService; + } + break; + } +finish_QueryServiceStatusEx:; + + // Service is not started. Is it set to auto-start? + // MSDN describes the maximum buffer size for QueryServiceConfig() to be 8kB. + // This is small enough to fit on stack. + BYTE _buffer_8k[8192]; + LPQUERY_SERVICE_CONFIG pQsc = (LPQUERY_SERVICE_CONFIG)_buffer_8k; + dwBufSize = sizeof(_buffer_8k); + if (!QueryServiceConfig(hService, pQsc, dwBufSize, &dwBufSize)) + { + uiResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: QueryServiceStatusEx(\"QueryServiceConfig\") failed", __FUNCTION__); + goto cleanup_OpenService; + } + + if (pQsc->dwStartType <= SERVICE_AUTO_START) + { + uiResult = MsiSetProperty(hInstall, TEXT("OPENVPNSERVICE"), pQsc->lpBinaryPathName); + if (uiResult != ERROR_SUCCESS) + { + SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"OPENVPNSERVICE\") failed", __FUNCTION__); + goto cleanup_OpenService; + } } uiResult = ERROR_SUCCESS; -cleanup_CoInitialize: - if (bIsCoInitialized) CoUninitialize(); +cleanup_OpenService: + CloseServiceHandle(hService); +cleanup_OpenSCManager: + CloseServiceHandle(hSCManager); return uiResult; } +UINT __stdcall +FindSystemInfo(_In_ MSIHANDLE hInstall) +{ +#ifdef _MSC_VER +#pragma comment(linker, DLLEXP_EXPORT) +#endif + + openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + + BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); + + /* Set MSI session handle in TLS. */ + struct openvpnmsica_tls_data *s = (struct openvpnmsica_tls_data *)TlsGetValue(openvpnmsica_tlsidx_session); + s->hInstall = hInstall; + + openvpnmsica_set_driver_certification(hInstall); + openvpnmsica_set_openvpnserv_state(hInstall); + + if (bIsCoInitialized) CoUninitialize(); + return ERROR_SUCCESS; +} + + UINT __stdcall FindTAPInterfaces(_In_ MSIHANDLE hInstall) {