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.
*/
#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;
/*
* Retrieve name of current login user (i.e. sshd process owner).
*/
GetUserName(currentUser, &currentUserSize);
while (1) {
RegOpenKeyEx(HKEY_LOCAL_MACHINE, SSH_AGENT_ROOT, 0, KEY_QUERY_VALUE, &agent_root);
if (agent_root)
RegQueryValueEx(agent_root, "ProcessId", 0, NULL, &agent_pid, &tmp_size);
/*
* Try to get token from lsa, but only if targetUser != currentUser.
* Owerthise we already have targetUser's token in current thread, so
* we only need key verify from original OpenSSH code.
*/
h = CreateFile(
"\\\\.\\pipe\\ssh-authagent", // pipe name
GENERIC_READ | // read and write access
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 (targetIsCurrent)
{
doOpenSSHVerify = 1;
}
else
{
loginStat = LsaLogon(&authctxt->methoddata, HomeDirLsaW,
authctxt -> user, pkblob, blen, sig, slen,
buffer_ptr(&b), buffer_len(&b), datafellows);
if (!GetNamedPipeServerProcessId(h, &pipe_server_pid) || (agent_pid != pipe_server_pid))
break;
/*
* If lsa logon process success.
*/
if (loginStat == 0)
{
/*
* And user authorized OK.
*/
if (authctxt->methoddata)
{
doOpenSSHVerify = 0;
/*
* 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);
sock = w32_allocate_fd_for_handle(h, FALSE);
msg = sshbuf_new();
if (!msg)
break;
if ((r = sshbuf_put_cstring(msg, "keyauthenticate")) != 0 ||
(r = sshkey_to_blob(key, &blob, &blen)) != 0 ||
(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
(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 ||
(r = ssh_request_reply(sock, msg, msg)) != 0 ||
(r = sshbuf_get_u32(msg, &token)) != 0 )
break;
free(sig);
}
}
}
if (doOpenSSHVerify)
{
/*
* If lsa fails, test for correct signature using openssh code.
*/
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.
*/
break;
}
if (agent_root)
RegCloseKey(agent_root);
if (blob)
free(blob);
if (sock != -1)
close(sock);
if (msg)
sshbuf_free(msg);
#else /* #ifdef WIN32_FIXME */
if (token) {
authenticated = 1;
authctxt->methoddata = token;
}
}
#else /* #ifdef WIN32_FIXME */
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
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 */
static int
int
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
{
int r;

View File

@ -36,6 +36,7 @@
#include <ntstatus.h>
#include "agent.h"
#include "agent-request.h"
#include "key.h"
static void
InitLsaString(LSA_STRING *lsa_string, const char *str)
@ -65,8 +66,8 @@ generate_user_token(wchar_t* user) {
DWORD cbProfile;
InitLsaString(&logon_process_name, "ssh-agent");
InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
//InitLsaString(&auth_package_name, "Negotiate");
//InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
InitLsaString(&auth_package_name, "Negotiate");
InitLsaString(&originName, "sshd");
if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS)
goto done;
@ -127,12 +128,13 @@ done:
int process_authagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
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;
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];
PWSTR wuser_home = NULL;
ULONG client_pid;
user = NULL;
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;
}
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();
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;
goto done;
}
@ -167,5 +174,7 @@ done:
CloseHandle(token);
if (wuser_home)
CoTaskMemFree(wuser_home);
if (client_proc)
CloseHandle(client_proc);
return r;
}