This commit is contained in:
manojampalam 2016-05-10 22:43:42 -07:00
parent 351f141a6b
commit b6aca59c71
3 changed files with 78 additions and 88 deletions

View File

@ -207,93 +207,74 @@ userauth_pubkey(Authctxt *authctxt)
* On pure win32 try to logon using lsa first. * On pure win32 try to logon using lsa first.
*/ */
#ifdef WIN32_FIXME #ifdef WIN32_FIXME
{
#define SSH_AGENT_ROOT "SOFTWARE\\SSH\\Agent"
HKEY agent_root = 0;
DWORD agent_pid = 0, tmp_size = 4, pipe_server_pid = 0xff;
int sock = -1, r;
u_char *blob = NULL;
size_t blen = 0;
DWORD token = 0;
HANDLE h = INVALID_HANDLE_VALUE;
struct sshbuf *msg = NULL;
authctxt -> methoddata = NULL; while (1) {
RegOpenKeyEx(HKEY_LOCAL_MACHINE, SSH_AGENT_ROOT, 0, KEY_QUERY_VALUE, &agent_root);
/* if (agent_root)
* Retrieve name of current login user (i.e. sshd process owner). RegQueryValueEx(agent_root, "ProcessId", 0, NULL, &agent_pid, &tmp_size);
*/
GetUserName(currentUser, &currentUserSize);
/* h = CreateFile(
* Try to get token from lsa, but only if targetUser != currentUser. "\\\\.\\pipe\\ssh-authagent", // pipe name
* Owerthise we already have targetUser's token in current thread, so GENERIC_READ | // read and write access
* we only need key verify from original OpenSSH code. GENERIC_WRITE,
*/ 0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_FLAG_OVERLAPPED, // attributes
NULL); // no template file
if (h == INVALID_HANDLE_VALUE)
break;
targetIsCurrent = (strcmp(currentUser, authctxt -> user) == 0); if (!GetNamedPipeServerProcessId(h, &pipe_server_pid) || (agent_pid != pipe_server_pid))
break;
if (targetIsCurrent)
{
doOpenSSHVerify = 1;
}
else
{
loginStat = LsaLogon(&authctxt->methoddata, HomeDirLsaW,
authctxt -> user, pkblob, blen, sig, slen,
buffer_ptr(&b), buffer_len(&b), datafellows);
/* sock = w32_allocate_fd_for_handle(h, FALSE);
* If lsa logon process success. msg = sshbuf_new();
*/ if (!msg)
break;
if (loginStat == 0) if ((r = sshbuf_put_cstring(msg, "keyauthenticate")) != 0 ||
{ (r = sshkey_to_blob(key, &blob, &blen)) != 0 ||
/* (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
* And user authorized OK. (r = sshbuf_put_cstring(msg, authctxt->pw->pw_name)) != 0 ||
*/ (r = sshbuf_put_string(msg, sig, slen)) != 0 ||
(r = sshbuf_put_string(msg, buffer_ptr(&b), buffer_len(&b))) != 0 ||
if (authctxt->methoddata) (r = ssh_request_reply(sock, msg, msg)) != 0 ||
{ (r = sshbuf_get_u32(msg, &token)) != 0 )
doOpenSSHVerify = 0; break;
/*
* This is part of openssh authorization needed for parsing
* 'options' block in key.
*/
authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user);
if (PRIVSEP(user_key_allowed(authctxt -> pw, key, 1))) // PRAGMA:TODO
{
authenticated = 1;
}
else
{
authenticated = 0;
}
buffer_free(&b);
free(sig); break;
}
} }
} if (agent_root)
RegCloseKey(agent_root);
if (doOpenSSHVerify) if (blob)
{ free(blob);
/* if (sock != -1)
* If lsa fails, test for correct signature using openssh code. close(sock);
*/ if (msg)
sshbuf_free(msg);
authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user);
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)) //PRAGMA:TODO
&&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1)
{
authenticated = 1;
}
}
/*
* Original code.
*/
#else /* #ifdef WIN32_FIXME */ if (token) {
authenticated = 1;
authctxt->methoddata = token;
}
}
#else /* #ifdef WIN32_FIXME */
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),

View File

@ -154,7 +154,7 @@ ssh_get_authentication_socket(int *fdp)
} }
/* Communicate with agent: send request and read reply */ /* Communicate with agent: send request and read reply */
static int int
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
{ {
int r; int r;

View File

@ -36,6 +36,7 @@
#include <ntstatus.h> #include <ntstatus.h>
#include "agent.h" #include "agent.h"
#include "agent-request.h" #include "agent-request.h"
#include "key.h"
static void static void
InitLsaString(LSA_STRING *lsa_string, const char *str) InitLsaString(LSA_STRING *lsa_string, const char *str)
@ -65,8 +66,8 @@ generate_user_token(wchar_t* user) {
DWORD cbProfile; DWORD cbProfile;
InitLsaString(&logon_process_name, "ssh-agent"); InitLsaString(&logon_process_name, "ssh-agent");
InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A); //InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
//InitLsaString(&auth_package_name, "Negotiate"); InitLsaString(&auth_package_name, "Negotiate");
InitLsaString(&originName, "sshd"); InitLsaString(&originName, "sshd");
if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS) if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS)
goto done; goto done;
@ -127,12 +128,13 @@ done:
int process_authagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { int process_authagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
int r = 0; int r = 0;
char* opn, key_blob, user, sig, blob; char *opn, *key_blob, *user, *sig, *blob;
size_t opn_len, key_blob_len, user_len, sig_len, blob_len; size_t opn_len, key_blob_len, user_len, sig_len, blob_len;
struct sshkey *key = NULL; struct sshkey *key = NULL;
HANDLE token = NULL, dup_token = NULL; HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
wchar_t wuser[MAX_USER_NAME_LEN]; wchar_t wuser[MAX_USER_NAME_LEN];
PWSTR wuser_home = NULL; PWSTR wuser_home = NULL;
ULONG client_pid;
user = NULL; user = NULL;
if ((r = sshbuf_get_string_direct(request, &opn, &opn_len)) != 0 || if ((r = sshbuf_get_string_direct(request, &opn, &opn_len)) != 0 ||
@ -148,12 +150,17 @@ int process_authagent_request(struct sshbuf* request, struct sshbuf* response, s
goto done; goto done;
} }
if (0 == MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, wuser, MAX_USER_NAME_LEN) { if (0 == MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, wuser, MAX_USER_NAME_LEN)) {
r = GetLastError(); r = GetLastError();
goto done; goto done;
} }
if ((token = generate_user_token(wuser)) == 0) { if (key_verify(key, sig, sig_len, blob, blob_len) != 1 ||
(token = generate_user_token(wuser)) == 0 ||
(FALSE == GetNamedPipeClientProcessId(con->connection, &client_pid)) ||
( (client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
(FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
(sshbuf_put_u32(response, dup_token) != 0) ) {
r = EINVAL; r = EINVAL;
goto done; goto done;
} }
@ -167,5 +174,7 @@ done:
CloseHandle(token); CloseHandle(token);
if (wuser_home) if (wuser_home)
CoTaskMemFree(wuser_home); CoTaskMemFree(wuser_home);
if (client_proc)
CloseHandle(client_proc);
return r; return r;
} }