1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Move the dynamic loading of advapi into its own module.

There's now a winsecur.[ch], which centralises helper functions using
the Windows security stuff in advapi.h (currently just get_user_sid),
and also centralises the run-time loading of those functions and
checking they're all there.

[originally from svn r10082]
This commit is contained in:
Simon Tatham 2013-11-17 14:05:29 +00:00
parent e5a3e28eec
commit f6f78f8355
7 changed files with 126 additions and 100 deletions

6
Recipe
View File

@ -300,7 +300,7 @@ SSH = ssh sshcrc sshdes sshmd5 sshrsa sshrand sshsha sshblowf
+ sshdh sshcrcda sshpubk sshzlib sshdss x11fwd portfwd
+ sshaes sshsh256 sshsh512 sshbn wildcard pinger ssharcf
+ sshgssc pgssapi
WINSSH = SSH winnoise winpgntc wingss winhsock errsock
WINSSH = SSH winnoise winsecur winpgntc wingss winhsock errsock
UXSSH = SSH uxnoise uxagentc uxgss
# SFTP implementation (pscp, psftp).
@ -350,8 +350,8 @@ psftp : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
+ psftp.res winnojmp LIBS
pageant : [G] winpgnt sshrsa sshpubk sshdes sshbn sshmd5 version tree234
+ misc sshaes sshsha winpgntc sshdss sshsh256 sshsh512 winutils
+ winmisc winhelp conf pageant.res LIBS
+ misc sshaes sshsha winsecur winpgntc sshdss sshsh256 sshsh512
+ winutils winmisc winhelp conf pageant.res LIBS
puttygen : [G] winpgen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand winnoise sshsha winstore misc winctrls sshrsa sshdss winmisc

View File

@ -14,7 +14,7 @@
#if !defined NO_SECURITY
#include <aclapi.h>
#include "winsecur.h"
Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
int overlapped);
@ -27,9 +27,6 @@ Socket new_named_pipe_client(const char *pipename, Plug plug)
char *err;
Socket ret;
extern int advapi_initialised;
init_advapi(); /* for get_user_sid. FIXME: do better. */
assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
assert(strchr(pipename + 9, '\\') == NULL);

View File

@ -14,6 +14,7 @@
#include "ssh.h"
#include "misc.h"
#include "tree234.h"
#include "winsecur.h"
#include <shellapi.h>
@ -2065,7 +2066,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
/*
* Attempt to get the security API we need.
*/
if (!init_advapi()) {
if (!got_advapi()) {
MessageBox(NULL,
"Unable to access security APIs. Pageant will\n"
"not run, in case it causes a security breach.",

View File

@ -8,7 +8,7 @@
#include "putty.h"
#ifndef NO_SECURITY
#include <aclapi.h>
#include "winsecur.h"
#endif
#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
@ -70,88 +70,6 @@ DWORD WINAPI agent_query_thread(LPVOID param)
#endif
/*
* Dynamically load advapi32.dll for SID manipulation. In its absence,
* we degrade gracefully.
*/
#ifndef NO_SECURITY
int advapi_initialised = FALSE;
static HMODULE advapi;
DECL_WINDOWS_FUNCTION(static, BOOL, OpenProcessToken,
(HANDLE, DWORD, PHANDLE));
DECL_WINDOWS_FUNCTION(static, BOOL, GetTokenInformation,
(HANDLE, TOKEN_INFORMATION_CLASS,
LPVOID, DWORD, PDWORD));
DECL_WINDOWS_FUNCTION(static, BOOL, InitializeSecurityDescriptor,
(PSECURITY_DESCRIPTOR, DWORD));
DECL_WINDOWS_FUNCTION(static, BOOL, SetSecurityDescriptorOwner,
(PSECURITY_DESCRIPTOR, PSID, BOOL));
DECL_WINDOWS_FUNCTION(, DWORD, GetSecurityInfo,
(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID *, PSID *, PACL *, PACL *,
PSECURITY_DESCRIPTOR *));
int init_advapi(void)
{
advapi = load_system32_dll("advapi32.dll");
return advapi &&
GET_WINDOWS_FUNCTION(advapi, GetSecurityInfo) &&
GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) &&
GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) &&
GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) &&
GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner);
}
PSID get_user_sid(void)
{
HANDLE proc = NULL, tok = NULL;
TOKEN_USER *user = NULL;
DWORD toklen, sidlen;
PSID sid = NULL, ret = NULL;
if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
GetCurrentProcessId())) == NULL)
goto cleanup;
if (!p_OpenProcessToken(proc, TOKEN_QUERY, &tok))
goto cleanup;
if (!p_GetTokenInformation(tok, TokenUser, NULL, 0, &toklen) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto cleanup;
if ((user = (TOKEN_USER *)LocalAlloc(LPTR, toklen)) == NULL)
goto cleanup;
if (!p_GetTokenInformation(tok, TokenUser, user, toklen, &toklen))
goto cleanup;
sidlen = GetLengthSid(user->User.Sid);
sid = (PSID)smalloc(sidlen);
if (!CopySid(sidlen, sid, user->User.Sid))
goto cleanup;
/* Success. Move sid into the return value slot, and null it out
* to stop the cleanup code freeing it. */
ret = sid;
sid = NULL;
cleanup:
if (proc != NULL)
CloseHandle(proc);
if (tok != NULL)
CloseHandle(tok);
if (user != NULL)
LocalFree(user);
if (sid != NULL)
sfree(sid);
return ret;
}
#endif
int agent_query(void *in, int inlen, void **out, int *outlen,
void (*callback)(void *, void *, int), void *callback_ctx)
{
@ -175,7 +93,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
psa = NULL;
#ifndef NO_SECURITY
if (advapi_initialised || init_advapi()) {
if (got_advapi()) {
/*
* Make the file mapping we create for communication with
* Pageant owned by the user SID rather than the default. This

86
windows/winsecur.c Normal file
View File

@ -0,0 +1,86 @@
/*
* winsecur.c: implementation of winsecur.h.
*/
#include <stdio.h>
#include <stdlib.h>
#include "putty.h"
#if !defined NO_SECURITY
#define WINSECUR_GLOBAL
#include "winsecur.h"
int got_advapi(void)
{
static int attempted = FALSE;
static int successful;
static HMODULE advapi;
if (!attempted) {
attempted = TRUE;
advapi = load_system32_dll("advapi32.dll");
successful = advapi &&
GET_WINDOWS_FUNCTION(advapi, GetSecurityInfo) &&
GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) &&
GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) &&
GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) &&
GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner);
}
return successful;
}
PSID get_user_sid(void)
{
HANDLE proc = NULL, tok = NULL;
TOKEN_USER *user = NULL;
DWORD toklen, sidlen;
PSID sid = NULL, ret = NULL;
if (!got_advapi())
goto cleanup;
if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
GetCurrentProcessId())) == NULL)
goto cleanup;
if (!p_OpenProcessToken(proc, TOKEN_QUERY, &tok))
goto cleanup;
if (!p_GetTokenInformation(tok, TokenUser, NULL, 0, &toklen) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto cleanup;
if ((user = (TOKEN_USER *)LocalAlloc(LPTR, toklen)) == NULL)
goto cleanup;
if (!p_GetTokenInformation(tok, TokenUser, user, toklen, &toklen))
goto cleanup;
sidlen = GetLengthSid(user->User.Sid);
sid = (PSID)smalloc(sidlen);
if (!CopySid(sidlen, sid, user->User.Sid))
goto cleanup;
/* Success. Move sid into the return value slot, and null it out
* to stop the cleanup code freeing it. */
ret = sid;
sid = NULL;
cleanup:
if (proc != NULL)
CloseHandle(proc);
if (tok != NULL)
CloseHandle(tok);
if (user != NULL)
LocalFree(user);
if (sid != NULL)
sfree(sid);
return ret;
}
#endif /* !defined NO_SECURITY */

32
windows/winsecur.h Normal file
View File

@ -0,0 +1,32 @@
/*
* winsecur.h: some miscellaneous security-related helper functions,
* defined in winsecur.c, that use the advapi32 library. Also
* centralises the machinery for dynamically loading that library.
*/
#if !defined NO_SECURITY
#include <aclapi.h>
#ifndef WINSECUR_GLOBAL
#define WINSECUR_GLOBAL extern
#endif
DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, OpenProcessToken,
(HANDLE, DWORD, PHANDLE));
DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, GetTokenInformation,
(HANDLE, TOKEN_INFORMATION_CLASS,
LPVOID, DWORD, PDWORD));
DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, InitializeSecurityDescriptor,
(PSECURITY_DESCRIPTOR, DWORD));
DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, SetSecurityDescriptorOwner,
(PSECURITY_DESCRIPTOR, PSID, BOOL));
DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, GetSecurityInfo,
(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID *, PSID *, PACL *, PACL *,
PSECURITY_DESCRIPTOR *));
int got_advapi(void);
PSID get_user_sid(void);
#endif

View File

@ -516,14 +516,6 @@ void agent_schedule_callback(void (*callback)(void *, void *, int),
void *callback_ctx, void *data, int len);
#define FLAG_SYNCAGENT 0x1000
/*
* winpgntc.c also exports these two functions which are used by the
* server side of Pageant as well, to get the user SID for comparing
* with clients'.
*/
int init_advapi(void); /* initialises everything needed by get_user_sid */
PSID get_user_sid(void);
/*
* Exports from winser.c.
*/