]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Merge branch 'master' of ssh://tartarus.org/putty
authorOwen Dunn <owen@greenend.org.uk>
Fri, 27 Nov 2015 19:44:25 +0000 (19:44 +0000)
committerOwen Dunn <owen@greenend.org.uk>
Fri, 27 Nov 2015 19:44:25 +0000 (19:44 +0000)
Recipe
mkfiles.pl
windows/wincapi.c [new file with mode: 0644]
windows/wincapi.h [new file with mode: 0644]
windows/window.c
windows/winsecur.c
windows/winsecur.h
windows/winshare.c

diff --git a/Recipe b/Recipe
index 0978e877dcd509d92b4b2feb541f5e227d4f87fb..fc8e444a55a16ea84ee79c1031bfdf6db5f46095 100644 (file)
--- a/Recipe
+++ b/Recipe
 #  - XFLAGS=/DDEBUG
 #      Causes PuTTY to enable internal debugging.
 #
+#  - XFLAGS=/DUNPROTECT
+#      Disable tightened ACL on PuTTY process so that e.g. debuggers
+#      can attach to it.
+#
 #  - XFLAGS=/DMALLOC_LOG
 #      Causes PuTTY to emit a file called putty_mem.log, logging every
 #      memory allocation and free, so you can track memory leaks.
@@ -224,7 +228,7 @@ SSH      = ssh sshcrc sshdes sshmd5 sshrsa sshrand sshsha sshblowf
          + sshdh sshcrcda sshpubk sshzlib sshdss x11fwd portfwd
          + sshaes sshccp sshsh256 sshsh512 sshbn wildcard pinger ssharcf
          + sshgssc pgssapi sshshare sshecc
-WINSSH   = SSH winnoise winsecur winpgntc wingss winshare winnps winnpc
+WINSSH   = SSH winnoise wincapi winpgntc wingss winshare winnps winnpc
          + winhsock errsock
 UXSSH    = SSH uxnoise uxagentc uxgss uxshare
 
@@ -235,7 +239,7 @@ SFTP     = sftp int64 logging
 # Pageant or PuTTYgen).
 MISC     = timing callback misc version settings tree234 proxy conf be_misc
 WINMISC  = MISC winstore winnet winhandl cmdline windefs winmisc winproxy
-         + wintime winhsock errsock
+         + wintime winhsock errsock winsecur
 UXMISC   = MISC uxstore uxsel uxnet uxpeer cmdline uxmisc uxproxy time
 OSXMISC  = MISC uxstore uxsel osxsel uxnet uxpeer uxmisc uxproxy time
 
index 59ecfdc4952b6a033e55287cecf062e66b8f268e..90e4f9dc1b9747fd099934de40fe59b72946ccdb 100755 (executable)
@@ -636,7 +636,7 @@ if (defined $makefiles{'vc'}) {
       "CFLAGS = /nologo /W3 /O1 " .
       (join " ", map {"-I$dirpfx$_"} @srcdirs) .
       " /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500\n".
-      "LFLAGS = /incremental:no /fixed\n".
+      "LFLAGS = /incremental:no /dynamicbase /nxcompat\n".
       "RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
       " -DWIN32 -D_WIN32 -DWINVER=0x0400\n".
       "\n".
diff --git a/windows/wincapi.c b/windows/wincapi.c
new file mode 100644 (file)
index 0000000..2550b6d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * wincapi.c: implementation of wincapi.h.
+ */
+
+#include "putty.h"
+
+#if !defined NO_SECURITY
+
+#define WINCAPI_GLOBAL
+#include "wincapi.h"
+
+int got_crypt(void)
+{
+    static int attempted = FALSE;
+    static int successful;
+    static HMODULE crypt;
+
+    if (!attempted) {
+        attempted = TRUE;
+        crypt = load_system32_dll("crypt32.dll");
+        successful = crypt &&
+            GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory);
+    }
+    return successful;
+}
+
+#endif /* !defined NO_SECURITY */
diff --git a/windows/wincapi.h b/windows/wincapi.h
new file mode 100644 (file)
index 0000000..06ee2d3
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * wincapi.h: Windows Crypto API functions defined in wincrypt.c
+ * that use the crypt32 library. Also centralises the machinery
+ * for dynamically loading that library.
+ */
+
+#if !defined NO_SECURITY
+
+#ifndef WINCAPI_GLOBAL
+#define WINCAPI_GLOBAL extern
+#endif
+
+DECL_WINDOWS_FUNCTION(WINCAPI_GLOBAL, BOOL, CryptProtectMemory,
+                     (LPVOID,DWORD,DWORD));
+
+int got_crypt(void);
+
+#endif
index 23f98a476da825ac25a66a084a5d80a8a35aee4f..2677145fef517b0f68f50333600b3e41a5315195 100644 (file)
@@ -19,6 +19,7 @@
 #include "terminal.h"
 #include "storage.h"
 #include "win_res.h"
+#include "winsecur.h"
 
 #ifndef NO_MULTIMON
 #include <multimon.h>
@@ -390,6 +391,19 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        return 1;
     }
 
+    /*
+     * Protect our process
+     */
+    {
+#ifndef UNPROTECT
+        char *error = NULL;
+        if (! setprocessacl(error)) {
+           logevent(NULL, "Could not restrict process ACL: %s",
+                    error);
+       }
+        sfree(error);
+#endif
+    }
     /*
      * Process the command line.
      */
index df93a74c5baa4954ecabdb669200f7e8e7af0718..9cdac26c3ba36bf11a09c5d40d6ecf6257714e88 100644 (file)
 #define WINSECUR_GLOBAL
 #include "winsecur.h"
 
+/* Initialised once, then kept around to reuse forever */
+static PSID worldsid, networksid, usersid;
+
+
 int got_advapi(void)
 {
     static int attempted = FALSE;
@@ -32,21 +36,6 @@ int got_advapi(void)
     return successful;
 }
 
-int got_crypt(void)
-{
-    static int attempted = FALSE;
-    static int successful;
-    static HMODULE crypt;
-
-    if (!attempted) {
-        attempted = TRUE;
-        crypt = load_system32_dll("crypt32.dll");
-        successful = crypt &&
-            GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory);
-    }
-    return successful;
-}
-
 PSID get_user_sid(void)
 {
     HANDLE proc = NULL, tok = NULL;
@@ -99,32 +88,17 @@ PSID get_user_sid(void)
     return ret;
 }
 
-int make_private_security_descriptor(DWORD permissions,
-                                     PSECURITY_DESCRIPTOR *psd,
-                                     PACL *acl,
-                                     char **error)
+int getsids(char *error)
 {
     SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
     SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
-    EXPLICIT_ACCESS ea[3];
-    int acl_err;
-    int ret = FALSE;
+    int ret;
 
-    /* Initialised once, then kept around to reuse forever */
-    static PSID worldsid, networksid, usersid;
-
-    *psd = NULL;
-    *acl = NULL;
-    *error = NULL;
-
-    if (!got_advapi()) {
-        *error = dupprintf("unable to load advapi32.dll");
-        goto cleanup;
-    }
+    error=NULL;
 
     if (!usersid) {
         if ((usersid = get_user_sid()) == NULL) {
-            *error = dupprintf("unable to construct SID for current user: %s",
+            error = dupprintf("unable to construct SID for current user: %s",
                                win_strerror(GetLastError()));
             goto cleanup;
         }
@@ -133,7 +107,7 @@ int make_private_security_descriptor(DWORD permissions,
     if (!worldsid) {
         if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                       0, 0, 0, 0, 0, 0, 0, &worldsid)) {
-            *error = dupprintf("unable to construct SID for world: %s",
+            error = dupprintf("unable to construct SID for world: %s",
                                win_strerror(GetLastError()));
             goto cleanup;
         }
@@ -142,13 +116,43 @@ int make_private_security_descriptor(DWORD permissions,
     if (!networksid) {
         if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
                                       0, 0, 0, 0, 0, 0, 0, &networksid)) {
-            *error = dupprintf("unable to construct SID for "
+            error = dupprintf("unable to construct SID for "
                                "local same-user access only: %s",
                                win_strerror(GetLastError()));
             goto cleanup;
         }
     }
 
+    ret=TRUE;
+
+ cleanup:
+    if (ret) {
+      sfree(error);
+      error = NULL;
+    }
+    return ret;
+}
+  
+
+int make_private_security_descriptor(DWORD permissions,
+                                     PSECURITY_DESCRIPTOR *psd,
+                                     PACL *acl,
+                                     char **error)
+{
+    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
+    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
+    EXPLICIT_ACCESS ea[3];
+    int acl_err;
+    int ret = FALSE;
+
+
+    *psd = NULL;
+    *acl = NULL;
+    *error = NULL;
+
+    if (!getsids(*error))
+      goto cleanup;
+
     memset(ea, 0, sizeof(ea));
     ea[0].grfAccessPermissions = permissions;
     ea[0].grfAccessMode = REVOKE_ACCESS;
@@ -218,4 +222,74 @@ int make_private_security_descriptor(DWORD permissions,
     return ret;
 }
 
+int setprocessacl(char *error)
+{
+    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
+    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
+    EXPLICIT_ACCESS ea[2];
+    int acl_err;
+    int ret=FALSE;
+    PACL acl = NULL;
+
+    static const nastyace=WRITE_DAC | WRITE_OWNER |
+       PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
+       PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION |
+       PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
+       PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE |
+       PROCESS_SUSPEND_RESUME;
+
+    if (!getsids(error))
+       goto cleanup;
+
+    memset(ea, 0, sizeof(ea));
+
+    /* Everyone: deny */
+    ea[0].grfAccessPermissions = nastyace;
+    ea[0].grfAccessMode = DENY_ACCESS;
+    ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+    ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
+
+    /* User: user ace */
+    ea[1].grfAccessPermissions = ~nastyace & 0x1fff;
+    ea[1].grfAccessMode = GRANT_ACCESS;
+    ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+    ea[1].Trustee.ptstrName = (LPTSTR)usersid;
+
+    acl_err = p_SetEntriesInAclA(2, ea, NULL, &acl);
+
+    if (acl_err != ERROR_SUCCESS || acl == NULL) {
+       error = dupprintf("unable to construct ACL: %s",
+                         win_strerror(acl_err));
+        goto cleanup;
+    }
+
+    if (ERROR_SUCCESS !=
+       SetSecurityInfo(
+                       GetCurrentProcess(),
+                       SE_KERNEL_OBJECT,
+                       OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+                       usersid,
+                       NULL,
+                       acl,
+                       NULL
+                       )) {
+       error=dupprintf("Unable to set process ACL: %s",
+                       win_strerror(GetLastError()));
+       goto cleanup;
+    }
+                     
+
+    ret=TRUE;
+    
+  cleanup:
+    if (!ret) {
+        if (acl) {
+            LocalFree(acl);
+            acl = NULL;
+        }
+    }
+    return ret;
+}  
 #endif /* !defined NO_SECURITY */
index bd64982768aaf3d18f4add9c15c88730928f08cf..03e8314d7b72bfacc1b80160dd26011f9ee7a43a 100644 (file)
@@ -32,13 +32,6 @@ DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, SetEntriesInAclA,
                      (ULONG, PEXPLICIT_ACCESS, PACL, PACL *));
 int got_advapi(void);
 
-/*
- * Functions loaded from crypt32.dll.
- */
-DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, CryptProtectMemory,
-                     (LPVOID, DWORD, DWORD));
-int got_crypt(void);
-
 /*
  * Find the SID describing the current user. The return value (if not
  * NULL for some error-related reason) is smalloced.
@@ -60,4 +53,6 @@ int make_private_security_descriptor(DWORD permissions,
                                      PACL *acl,
                                      char **error);
 
+int setprocessacl(char *error);
+
 #endif
index 2f21638e76c6c01b914a576291c171b4c0768156..5f1c7244010ff401a4da4889c674b349884654b0 100644 (file)
@@ -14,7 +14,7 @@
 #include "proxy.h"
 #include "ssh.h"
 
-#include "winsecur.h"
+#include "wincapi.h"
 
 #ifdef COVERITY
 /*