mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-03-22 10:50:07 +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
|
#define SSH_AGENT_RSA_SHA2_512 0x04
|
||||||
|
|
||||||
struct ssh_agent_struct {
|
struct ssh_agent_struct {
|
||||||
|
#ifndef _WIN32
|
||||||
struct ssh_socket_struct *sock;
|
struct ssh_socket_struct *sock;
|
||||||
|
#endif
|
||||||
ssh_buffer ident;
|
ssh_buffer ident;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/* agent.c */
|
/* agent.c */
|
||||||
/**
|
/**
|
||||||
* @brief Create a new ssh agent structure.
|
* @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,
|
ssh_string ssh_agent_sign_data(ssh_session session,
|
||||||
const ssh_key pubkey,
|
const ssh_key pubkey,
|
||||||
struct ssh_buffer_struct *data);
|
struct ssh_buffer_struct *data);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __AGENT_H */
|
#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_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_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);
|
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,
|
LIBSSH_API int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
|
||||||
ssh_public_key publickey);
|
ssh_public_key publickey);
|
||||||
#endif
|
|
||||||
LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphrase);
|
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,
|
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
|
||||||
const char *filename, const char *passphrase);
|
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);
|
fd_set *readfds, struct timeval *timeout);
|
||||||
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
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);
|
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);
|
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_blocking(ssh_session session, int blocking);
|
||||||
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
|
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
|
||||||
ssh_counter rcounter);
|
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,
|
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
||||||
const char *username,
|
const char *username,
|
||||||
const ssh_key privkey);
|
const ssh_key privkey);
|
||||||
#ifndef _WIN32
|
|
||||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||||
const char *username);
|
const char *username);
|
||||||
#endif
|
|
||||||
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
||||||
const char *username,
|
const char *username,
|
||||||
const char *passphrase);
|
const char *passphrase);
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
* the agent returns the signed data
|
* the agent returns the signed data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -46,9 +45,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include "libssh/agent.h"
|
#include "libssh/agent.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/socket.h"
|
#include "libssh/socket.h"
|
||||||
@ -58,11 +54,21 @@
|
|||||||
#include "libssh/pki.h"
|
#include "libssh/pki.h"
|
||||||
#include "libssh/bytearray.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 */
|
/* macro to check for "agent failure" message */
|
||||||
#define agent_failed(x) \
|
#define agent_failed(x) \
|
||||||
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
|
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
|
||||||
((x) == SSH2_AGENT_FAILURE))
|
((x) == SSH2_AGENT_FAILURE))
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) {
|
static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) {
|
||||||
char *b = buf;
|
char *b = buf;
|
||||||
size_t pos = 0;
|
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;
|
return pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ssh_agent ssh_agent_new(struct ssh_session_struct *session) {
|
ssh_agent ssh_agent_new(struct ssh_session_struct *session) {
|
||||||
ssh_agent agent = NULL;
|
ssh_agent agent = NULL;
|
||||||
@ -133,12 +140,16 @@ ssh_agent ssh_agent_new(struct ssh_session_struct *session) {
|
|||||||
ZERO_STRUCTP(agent);
|
ZERO_STRUCTP(agent);
|
||||||
|
|
||||||
agent->count = 0;
|
agent->count = 0;
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
agent->sock = ssh_socket_new(session);
|
agent->sock = ssh_socket_new(session);
|
||||||
if (agent->sock == NULL) {
|
if (agent->sock == NULL) {
|
||||||
SAFE_FREE(agent);
|
SAFE_FREE(agent);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
agent->channel = NULL;
|
agent->channel = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +176,7 @@ int ssh_set_agent_channel(ssh_session session, ssh_channel channel){
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
/** @brief sets the SSH agent socket.
|
/** @brief sets the SSH agent socket.
|
||||||
* The SSH agent will be used to authenticate this client using
|
* The SSH agent will be used to authenticate this client using
|
||||||
* the given socket to communicate with the ssh-agent. The caller
|
* 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);
|
ssh_socket_close(agent->sock);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ssh_agent_free(ssh_agent agent) {
|
void ssh_agent_free(ssh_agent agent) {
|
||||||
if (agent) {
|
if (agent) {
|
||||||
if (agent->ident) {
|
if (agent->ident) {
|
||||||
SSH_BUFFER_FREE(agent->ident);
|
SSH_BUFFER_FREE(agent->ident);
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
if (agent->sock) {
|
if (agent->sock) {
|
||||||
ssh_agent_close(agent);
|
ssh_agent_close(agent);
|
||||||
ssh_socket_free(agent->sock);
|
ssh_socket_free(agent->sock);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
SAFE_FREE(agent);
|
SAFE_FREE(agent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
static int agent_connect(ssh_session session) {
|
static int agent_connect(ssh_session session) {
|
||||||
const char *auth_sock = NULL;
|
const char *auth_sock = NULL;
|
||||||
|
|
||||||
@ -227,6 +243,7 @@ static int agent_connect(ssh_session session) {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static int agent_decode_reply(struct ssh_session_struct *session, int type) {
|
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
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
static int agent_talk(struct ssh_session_struct *session,
|
static int agent_talk(struct ssh_session_struct *session,
|
||||||
struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) {
|
struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) {
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
@ -280,7 +299,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = PULL_BE_U32(payload, 0);
|
len = PULL_BE_U32(payload, 0);
|
||||||
if (len > 256 * 1024) {
|
if (len > AGENT_MSG_MAXLEN) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session, SSH_FATAL,
|
||||||
"Authentication response too long: %u", len);
|
"Authentication response too long: %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
@ -307,6 +326,78 @@ static int agent_talk(struct ssh_session_struct *session,
|
|||||||
return 0;
|
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)
|
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
|
||||||
{
|
{
|
||||||
ssh_buffer request = NULL;
|
ssh_buffer request = NULL;
|
||||||
@ -459,6 +550,7 @@ int ssh_agent_is_running(ssh_session session) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
if (ssh_socket_is_open(session->agent->sock)) {
|
if (ssh_socket_is_open(session->agent->sock)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -470,6 +562,10 @@ int ssh_agent_is_running(ssh_session session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#else
|
||||||
|
HWND hwnd = FindWindow("Pageant", "Pageant");
|
||||||
|
return hwnd != NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_string ssh_agent_sign_data(ssh_session session,
|
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;
|
return sig_blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
@ -2372,7 +2372,6 @@ end:
|
|||||||
return sig_blob;
|
return sig_blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||||
struct ssh_buffer_struct *buf,
|
struct ssh_buffer_struct *buf,
|
||||||
const ssh_key pubkey)
|
const ssh_key pubkey)
|
||||||
@ -2422,7 +2421,6 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
|||||||
|
|
||||||
return sig_blob;
|
return sig_blob;
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
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);
|
ssh_set_blocking(session, 1);
|
||||||
session->maxchannel = FIRST_CHANNEL;
|
session->maxchannel = FIRST_CHANNEL;
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
session->agent = ssh_agent_new(session);
|
session->agent = ssh_agent_new(session);
|
||||||
if (session->agent == NULL) {
|
if (session->agent == NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
/* OPTIONS */
|
/* OPTIONS */
|
||||||
session->opts.StrictHostKeyChecking = 1;
|
session->opts.StrictHostKeyChecking = 1;
|
||||||
@ -242,9 +240,7 @@ void ssh_free(ssh_session session)
|
|||||||
crypto_free(session->current_crypto);
|
crypto_free(session->current_crypto);
|
||||||
crypto_free(session->next_crypto);
|
crypto_free(session->next_crypto);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
ssh_agent_free(session->agent);
|
ssh_agent_free(session->agent);
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
ssh_key_free(session->srv.dsa_key);
|
ssh_key_free(session->srv.dsa_key);
|
||||||
session->srv.dsa_key = NULL;
|
session->srv.dsa_key = NULL;
|
||||||
@ -292,9 +288,7 @@ void ssh_free(ssh_session session)
|
|||||||
}
|
}
|
||||||
ssh_list_free(session->out_queue);
|
ssh_list_free(session->out_queue);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
ssh_agent_state_free (session->agent_state);
|
ssh_agent_state_free (session->agent_state);
|
||||||
#endif
|
|
||||||
session->agent_state = NULL;
|
session->agent_state = NULL;
|
||||||
|
|
||||||
SAFE_FREE(session->auth.auto_state);
|
SAFE_FREE(session->auth.auto_state);
|
||||||
|
Loading…
Reference in New Issue
Block a user