mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Merge branch 'master' of ssh://tartarus.org/putty
This commit is contained in:
commit
d8fdb49451
8
Recipe
8
Recipe
@ -114,6 +114,10 @@
|
|||||||
# - XFLAGS=/DDEBUG
|
# - XFLAGS=/DDEBUG
|
||||||
# Causes PuTTY to enable internal debugging.
|
# 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
|
# - XFLAGS=/DMALLOC_LOG
|
||||||
# Causes PuTTY to emit a file called putty_mem.log, logging every
|
# Causes PuTTY to emit a file called putty_mem.log, logging every
|
||||||
# memory allocation and free, so you can track memory leaks.
|
# 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
|
+ sshdh sshcrcda sshpubk sshzlib sshdss x11fwd portfwd
|
||||||
+ sshaes sshccp sshsh256 sshsh512 sshbn wildcard pinger ssharcf
|
+ sshaes sshccp sshsh256 sshsh512 sshbn wildcard pinger ssharcf
|
||||||
+ sshgssc pgssapi sshshare sshecc
|
+ sshgssc pgssapi sshshare sshecc
|
||||||
WINSSH = SSH winnoise winsecur winpgntc wingss winshare winnps winnpc
|
WINSSH = SSH winnoise wincapi winpgntc wingss winshare winnps winnpc
|
||||||
+ winhsock errsock
|
+ winhsock errsock
|
||||||
UXSSH = SSH uxnoise uxagentc uxgss uxshare
|
UXSSH = SSH uxnoise uxagentc uxgss uxshare
|
||||||
|
|
||||||
@ -235,7 +239,7 @@ SFTP = sftp int64 logging
|
|||||||
# Pageant or PuTTYgen).
|
# Pageant or PuTTYgen).
|
||||||
MISC = timing callback misc version settings tree234 proxy conf be_misc
|
MISC = timing callback misc version settings tree234 proxy conf be_misc
|
||||||
WINMISC = MISC winstore winnet winhandl cmdline windefs winmisc winproxy
|
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
|
UXMISC = MISC uxstore uxsel uxnet uxpeer cmdline uxmisc uxproxy time
|
||||||
OSXMISC = MISC uxstore uxsel osxsel uxnet uxpeer uxmisc uxproxy time
|
OSXMISC = MISC uxstore uxsel osxsel uxnet uxpeer uxmisc uxproxy time
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ if (defined $makefiles{'vc'}) {
|
|||||||
"CFLAGS = /nologo /W3 /O1 " .
|
"CFLAGS = /nologo /W3 /O1 " .
|
||||||
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
|
||||||
" /D_WINDOWS /D_WIN32_WINDOWS=0x500 /DWINVER=0x500\n".
|
" /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).
|
"RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
|
||||||
" -DWIN32 -D_WIN32 -DWINVER=0x0400\n".
|
" -DWIN32 -D_WIN32 -DWINVER=0x0400\n".
|
||||||
"\n".
|
"\n".
|
||||||
|
27
windows/wincapi.c
Normal file
27
windows/wincapi.c
Normal file
@ -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 */
|
18
windows/wincapi.h
Normal file
18
windows/wincapi.h
Normal file
@ -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
|
@ -19,6 +19,7 @@
|
|||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "win_res.h"
|
#include "win_res.h"
|
||||||
|
#include "winsecur.h"
|
||||||
|
|
||||||
#ifndef NO_MULTIMON
|
#ifndef NO_MULTIMON
|
||||||
#include <multimon.h>
|
#include <multimon.h>
|
||||||
@ -390,6 +391,19 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
return 1;
|
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.
|
* Process the command line.
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
#define WINSECUR_GLOBAL
|
#define WINSECUR_GLOBAL
|
||||||
#include "winsecur.h"
|
#include "winsecur.h"
|
||||||
|
|
||||||
|
/* Initialised once, then kept around to reuse forever */
|
||||||
|
static PSID worldsid, networksid, usersid;
|
||||||
|
|
||||||
|
|
||||||
int got_advapi(void)
|
int got_advapi(void)
|
||||||
{
|
{
|
||||||
static int attempted = FALSE;
|
static int attempted = FALSE;
|
||||||
@ -32,21 +36,6 @@ int got_advapi(void)
|
|||||||
return successful;
|
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)
|
PSID get_user_sid(void)
|
||||||
{
|
{
|
||||||
HANDLE proc = NULL, tok = NULL;
|
HANDLE proc = NULL, tok = NULL;
|
||||||
@ -99,6 +88,52 @@ PSID get_user_sid(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getsids(char *error)
|
||||||
|
{
|
||||||
|
SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
|
||||||
|
SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
error=NULL;
|
||||||
|
|
||||||
|
if (!usersid) {
|
||||||
|
if ((usersid = get_user_sid()) == NULL) {
|
||||||
|
error = dupprintf("unable to construct SID for current user: %s",
|
||||||
|
win_strerror(GetLastError()));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
win_strerror(GetLastError()));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "
|
||||||
|
"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,
|
int make_private_security_descriptor(DWORD permissions,
|
||||||
PSECURITY_DESCRIPTOR *psd,
|
PSECURITY_DESCRIPTOR *psd,
|
||||||
PACL *acl,
|
PACL *acl,
|
||||||
@ -110,44 +145,13 @@ int make_private_security_descriptor(DWORD permissions,
|
|||||||
int acl_err;
|
int acl_err;
|
||||||
int ret = FALSE;
|
int ret = FALSE;
|
||||||
|
|
||||||
/* Initialised once, then kept around to reuse forever */
|
|
||||||
static PSID worldsid, networksid, usersid;
|
|
||||||
|
|
||||||
*psd = NULL;
|
*psd = NULL;
|
||||||
*acl = NULL;
|
*acl = NULL;
|
||||||
*error = NULL;
|
*error = NULL;
|
||||||
|
|
||||||
if (!got_advapi()) {
|
if (!getsids(*error))
|
||||||
*error = dupprintf("unable to load advapi32.dll");
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (!usersid) {
|
|
||||||
if ((usersid = get_user_sid()) == NULL) {
|
|
||||||
*error = dupprintf("unable to construct SID for current user: %s",
|
|
||||||
win_strerror(GetLastError()));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
|
||||||
win_strerror(GetLastError()));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 "
|
|
||||||
"local same-user access only: %s",
|
|
||||||
win_strerror(GetLastError()));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(ea, 0, sizeof(ea));
|
memset(ea, 0, sizeof(ea));
|
||||||
ea[0].grfAccessPermissions = permissions;
|
ea[0].grfAccessPermissions = permissions;
|
||||||
@ -218,4 +222,74 @@ int make_private_security_descriptor(DWORD permissions,
|
|||||||
return ret;
|
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 */
|
#endif /* !defined NO_SECURITY */
|
||||||
|
@ -32,13 +32,6 @@ DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, SetEntriesInAclA,
|
|||||||
(ULONG, PEXPLICIT_ACCESS, PACL, PACL *));
|
(ULONG, PEXPLICIT_ACCESS, PACL, PACL *));
|
||||||
int got_advapi(void);
|
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
|
* Find the SID describing the current user. The return value (if not
|
||||||
* NULL for some error-related reason) is smalloced.
|
* NULL for some error-related reason) is smalloced.
|
||||||
@ -60,4 +53,6 @@ int make_private_security_descriptor(DWORD permissions,
|
|||||||
PACL *acl,
|
PACL *acl,
|
||||||
char **error);
|
char **error);
|
||||||
|
|
||||||
|
int setprocessacl(char *error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
|
||||||
#include "winsecur.h"
|
#include "wincapi.h"
|
||||||
|
|
||||||
#ifdef COVERITY
|
#ifdef COVERITY
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user