winverifytrust-20041129
authorJeffrey Altman <jaltman@mit.edu>
Mon, 29 Nov 2004 07:56:35 +0000 (07:56 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 29 Nov 2004 07:56:35 +0000 (07:56 +0000)
Add support for WinVerifyTrust().  If afsd_service.exe is a digitally
signed executable, make sure that all of the associated binaries not
only have the same file version number but are signed as well.

src/WINNT/afsd/NTMakefile
src/WINNT/afsd/afsd_service.c

index c662c68..56e6199 100644 (file)
@@ -337,7 +337,7 @@ $(EXEDIR)\unlog.exe: $(OUT)\cunlog.obj $(OUT)\unlog.res $(EXELIBS)
 AFSD_EXEFILE = $(EXEDIR)\afsd.exe
 
 AFSD_SDKLIBS =\
-       largeint.lib \
+#      largeint.lib \
        netapi32.lib \
         dnsapi.lib \
         mpr.lib \
@@ -349,7 +349,7 @@ AFSD_SDKLIBS =\
         secur32.lib \
         ole32.lib \
         oleaut32.lib \
-        psapi.lib
+        psapi.lib wintrust.lib
 
 AFSD_EXELIBS =\
        $(DESTDIR)\lib\libosi.lib \
index 851d390..c01f214 100644 (file)
@@ -11,7 +11,9 @@
 #include <afs/stds.h>
 
 #include <windows.h>
+#include <softpub.h>
 #include <psapi.h>
+#include <winerror.h>
 #include <string.h>
 #include <setjmp.h>
 #include "afsd.h"
@@ -488,6 +490,66 @@ GetVersionInfo( CHAR * filename, CHAR * szOutput, DWORD dwOutput )
     return retval;
 }
 
+BOOL VerifyTrust(CHAR * filename)
+{
+    WINTRUST_DATA fTrust;
+    WINTRUST_FILE_INFO finfo;
+    GUID trustAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+    GUID subject = WIN_TRUST_SUBJTYPE_RAW_FILEEX;
+    wchar_t wfilename[260];
+    LONG ret;
+
+    if (filename == NULL ) 
+        return FALSE;
+
+    mbstowcs(wfilename, filename, 260);
+
+    finfo.cbStruct = sizeof(finfo);
+    finfo.pcwszFilePath= wfilename;
+    finfo.hFile = INVALID_HANDLE_VALUE;
+    finfo.pgKnownSubject = &subject;
+
+    fTrust.cbStruct = sizeof(fTrust);
+    fTrust.pPolicyCallbackData = NULL;
+    fTrust.pSIPClientData = NULL;
+    fTrust.dwUIChoice = WTD_UI_NONE;
+    fTrust.fdwRevocationChecks = WTD_REVOKE_NONE;
+    fTrust.dwUnionChoice = WTD_CHOICE_FILE;
+    fTrust.pFile = &finfo;
+    fTrust.dwStateAction = WTD_STATEACTION_IGNORE;
+    fTrust.hWVTStateData = NULL;
+    fTrust.pwszURLReference = NULL;
+    fTrust.dwProvFlags = WTD_SAFER_FLAG | WTD_REVOCATION_CHECK_NONE;
+    fTrust.dwUIContext = WTD_UICONTEXT_EXECUTE;
+    
+    ret = WinVerifyTrust(INVALID_HANDLE_VALUE, &trustAction, &fTrust);
+
+    if (ret == ERROR_SUCCESS) {
+        return TRUE;
+    } else {
+        DWORD gle = GetLastError();
+        switch (gle) {
+        case TRUST_E_PROVIDER_UNKNOWN:
+            afsi_log("VerifyTrust failed: \"Generic Verify V2\" Provider Unknown");
+            break;  
+        case TRUST_E_NOSIGNATURE:
+            afsi_log("VerifyTrust failed: Unsigned executable");
+            break;
+        case TRUST_E_EXPLICIT_DISTRUST:
+            afsi_log("VerifyTrust failed: Certificate Marked as Untrusted by the user");
+            break;
+        case TRUST_E_SUBJECT_NOT_TRUSTED:
+            afsi_log("VerifyTrust failed: File is not trusted");
+            break;
+        case CRYPT_E_SECURITY_SETTINGS:
+            afsi_log("VerifyTrust failed: local security options prevent verification");
+            break;
+        default:
+            afsi_log("VerifyTrust failed: 0x%X", GetLastError());
+        }
+        return FALSE;
+    }
+}
 
 BOOL AFSModulesVerify(void)
 {
@@ -495,6 +557,7 @@ BOOL AFSModulesVerify(void)
     CHAR afsdVersion[128];
     CHAR modVersion[128];
     CHAR checkName[1024];
+    BOOL trustVerified = FALSE;
     HMODULE hMods[1024];
     HANDLE hProcess;
     DWORD cbNeeded;
@@ -509,6 +572,8 @@ BOOL AFSModulesVerify(void)
 
     afsi_log("%s version %s", filename, afsdVersion);
 
+    trustVerified = VerifyTrust(filename);
+
     // Get a list of all the modules in this process.
     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                            FALSE, GetCurrentProcessId());
@@ -543,6 +608,10 @@ BOOL AFSModulesVerify(void)
                         afsi_log("Version mismatch: %s", szModName);
                         success = FALSE;
                     }
+                    if ( trustVerified && !VerifyTrust(szModName) ) {
+                        afsi_log("Signature Verification failed: %s", szModName);
+                        success = FALSE;
+                    }
                 }
             }
         }