mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-03-14 10:10:06 +08:00
Add support for pageant in libssh.
This commit is contained in:
parent
ef43da390e
commit
95c30ebc9c
@ -71,13 +71,14 @@
|
||||
#define SSH_AGENT_RSA_SHA2_512 0x04
|
||||
|
||||
struct ssh_agent_struct {
|
||||
#ifndef _WIN32
|
||||
struct ssh_socket_struct *sock;
|
||||
#endif
|
||||
ssh_buffer ident;
|
||||
unsigned int count;
|
||||
ssh_channel channel;
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
/* agent.c */
|
||||
/**
|
||||
* @brief Create a new ssh agent structure.
|
||||
@ -115,6 +116,5 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
|
||||
ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
const ssh_key pubkey,
|
||||
struct ssh_buffer_struct *data);
|
||||
#endif
|
||||
|
||||
#endif /* __AGENT_H */
|
||||
|
@ -34,10 +34,8 @@ typedef struct ssh_public_key_struct* ssh_public_key;
|
||||
LIBSSH_API int ssh_auth_list(ssh_session session);
|
||||
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
|
||||
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
|
||||
#ifndef _WIN32
|
||||
LIBSSH_API int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
|
||||
ssh_public_key publickey);
|
||||
#endif
|
||||
LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphrase);
|
||||
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
|
||||
const char *filename, const char *passphrase);
|
||||
|
@ -730,7 +730,9 @@ LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socke
|
||||
fd_set *readfds, struct timeval *timeout);
|
||||
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
||||
LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel);
|
||||
#ifndef _WIN32
|
||||
LIBSSH_API int ssh_set_agent_socket(ssh_session session, socket_t fd);
|
||||
#endif
|
||||
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
|
||||
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
|
||||
ssh_counter rcounter);
|
||||
@ -749,10 +751,8 @@ LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
|
||||
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
||||
const char *username,
|
||||
const ssh_key privkey);
|
||||
#ifndef _WIN32
|
||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||
const char *username);
|
||||
#endif
|
||||
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
||||
const char *username,
|
||||
const char *passphrase);
|
||||
|
@ -33,7 +33,6 @@
|
||||
* the agent returns the signed data
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@ -46,9 +45,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "libssh/agent.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/socket.h"
|
||||
@ -58,11 +54,21 @@
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bytearray.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#define AGENT_MSG_MAXLEN 256 * 1024
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
|
||||
((x) == SSH2_AGENT_FAILURE))
|
||||
|
||||
#ifndef _WIN32
|
||||
static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) {
|
||||
char *b = buf;
|
||||
size_t pos = 0;
|
||||
@ -122,6 +128,7 @@ static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ssh_agent ssh_agent_new(struct ssh_session_struct *session) {
|
||||
ssh_agent agent = NULL;
|
||||
@ -133,12 +140,16 @@ ssh_agent ssh_agent_new(struct ssh_session_struct *session) {
|
||||
ZERO_STRUCTP(agent);
|
||||
|
||||
agent->count = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
agent->sock = ssh_socket_new(session);
|
||||
if (agent->sock == NULL) {
|
||||
SAFE_FREE(agent);
|
||||
return NULL;
|
||||
}
|
||||
agent->channel = NULL;
|
||||
#endif
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
@ -165,6 +176,7 @@ int ssh_set_agent_channel(ssh_session session, ssh_channel channel){
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/** @brief sets the SSH agent socket.
|
||||
* The SSH agent will be used to authenticate this client using
|
||||
* the given socket to communicate with the ssh-agent. The caller
|
||||
@ -192,20 +204,24 @@ void ssh_agent_close(struct ssh_agent_struct *agent) {
|
||||
|
||||
ssh_socket_close(agent->sock);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ssh_agent_free(ssh_agent agent) {
|
||||
if (agent) {
|
||||
if (agent->ident) {
|
||||
SSH_BUFFER_FREE(agent->ident);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (agent->sock) {
|
||||
ssh_agent_close(agent);
|
||||
ssh_socket_free(agent->sock);
|
||||
}
|
||||
#endif
|
||||
SAFE_FREE(agent);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static int agent_connect(ssh_session session) {
|
||||
const char *auth_sock = NULL;
|
||||
|
||||
@ -227,6 +243,7 @@ static int agent_connect(ssh_session session) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static int agent_decode_reply(struct ssh_session_struct *session, int type) {
|
||||
@ -248,6 +265,8 @@ static int agent_decode_reply(struct ssh_session_struct *session, int type) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
static int agent_talk(struct ssh_session_struct *session,
|
||||
struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) {
|
||||
uint32_t len = 0;
|
||||
@ -280,7 +299,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
}
|
||||
|
||||
len = PULL_BE_U32(payload, 0);
|
||||
if (len > 256 * 1024) {
|
||||
if (len > AGENT_MSG_MAXLEN) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Authentication response too long: %u", len);
|
||||
return -1;
|
||||
@ -307,6 +326,78 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define AGENT_COPYDATA_ID 0x804e50ba;
|
||||
|
||||
static int agent_talk(struct ssh_session_struct *session,
|
||||
struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) {
|
||||
HWND hwnd = FindWindow("Pageant", "Pageant");
|
||||
if (hwnd == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Pageant message window not found: %u", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
char map_name[39];
|
||||
sprintf(map_name, "libssh_agent_%08x_%016zx",
|
||||
GetCurrentProcessId(), (size_t)session->agent);
|
||||
|
||||
HANDLE hmap = CreateFileMapping(NULL, NULL, PAGE_READWRITE,
|
||||
0, AGENT_MSG_MAXLEN + sizeof(uint32_t), map_name);
|
||||
if (hmap == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to create file mapping: %u", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = MapViewOfFile(hmap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
if (buf == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to map the file mapping into memory: %u", GetLastError());
|
||||
CloseHandle(hmap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t len = ssh_buffer_get_len(request);
|
||||
SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len);
|
||||
PUSH_BE_U32(buf, 0, len);
|
||||
memcpy(buf + sizeof(uint32_t), ssh_buffer_get(request), len);
|
||||
|
||||
COPYDATASTRUCT data;
|
||||
data.dwData = AGENT_COPYDATA_ID;
|
||||
data.cbData = strlen(map_name) + 1;
|
||||
data.lpData = map_name;
|
||||
if (SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&data) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Pageant returned an error");
|
||||
UnmapViewOfFile(buf);
|
||||
CloseHandle(hmap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = PULL_BE_U32(buf, 0);
|
||||
if (len > AGENT_MSG_MAXLEN) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Authentication response too long: %u", len);
|
||||
UnmapViewOfFile(buf);
|
||||
CloseHandle(hmap);
|
||||
return -1;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_TRACE, "Response length: %u", len);
|
||||
|
||||
int rc = ssh_buffer_add_data(reply, buf + sizeof(uint32_t), len);
|
||||
UnmapViewOfFile(buf);
|
||||
CloseHandle(hmap);
|
||||
if (rc < 0) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Not enough space");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
|
||||
{
|
||||
ssh_buffer request = NULL;
|
||||
@ -459,6 +550,7 @@ int ssh_agent_is_running(ssh_session session) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
if (ssh_socket_is_open(session->agent->sock)) {
|
||||
return 1;
|
||||
} else {
|
||||
@ -470,6 +562,10 @@ int ssh_agent_is_running(ssh_session session) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
HWND hwnd = FindWindow("Pageant", "Pageant");
|
||||
return hwnd != NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
@ -591,4 +687,3 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -2372,7 +2372,6 @@ end:
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||
struct ssh_buffer_struct *buf,
|
||||
const ssh_key pubkey)
|
||||
@ -2422,7 +2421,6 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||
|
||||
return sig_blob;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
|
@ -97,12 +97,10 @@ ssh_session ssh_new(void)
|
||||
ssh_set_blocking(session, 1);
|
||||
session->maxchannel = FIRST_CHANNEL;
|
||||
|
||||
#ifndef _WIN32
|
||||
session->agent = ssh_agent_new(session);
|
||||
if (session->agent == NULL) {
|
||||
goto err;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* OPTIONS */
|
||||
session->opts.StrictHostKeyChecking = 1;
|
||||
@ -242,9 +240,7 @@ void ssh_free(ssh_session session)
|
||||
crypto_free(session->current_crypto);
|
||||
crypto_free(session->next_crypto);
|
||||
|
||||
#ifndef _WIN32
|
||||
ssh_agent_free(session->agent);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
ssh_key_free(session->srv.dsa_key);
|
||||
session->srv.dsa_key = NULL;
|
||||
@ -292,9 +288,7 @@ void ssh_free(ssh_session session)
|
||||
}
|
||||
ssh_list_free(session->out_queue);
|
||||
|
||||
#ifndef _WIN32
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
#endif
|
||||
session->agent_state = NULL;
|
||||
|
||||
SAFE_FREE(session->auth.auto_state);
|
||||
|
Loading…
Reference in New Issue
Block a user