mirror of
https://github.com/clearml/dropbear
synced 2025-05-30 01:48:37 +00:00
Talking to the agent works now. Can't interpret the pubkeys.
--HG-- branch : agent-client extra : convert_revision : 357373f28e889108178b8627480fd24bc26dcbd7
This commit is contained in:
parent
c6582dbe37
commit
9dc9aff016
@ -39,7 +39,7 @@ void agentsetauth(struct ChanSess *chansess);
|
|||||||
void agentcleanup(struct ChanSess * chansess);
|
void agentcleanup(struct ChanSess * chansess);
|
||||||
void agentset(struct ChanSess *chansess);
|
void agentset(struct ChanSess *chansess);
|
||||||
|
|
||||||
void load_agent_keys();
|
void load_agent_keys(struct SignKeyList * ret_list);
|
||||||
|
|
||||||
#ifdef __hpux
|
#ifdef __hpux
|
||||||
#define seteuid(a) setresuid(-1, (a), -1)
|
#define seteuid(a) setresuid(-1, (a), -1)
|
||||||
|
@ -94,13 +94,14 @@ static int new_agent_chan(struct Channel * channel) {
|
|||||||
|
|
||||||
/* Sends a request to the agent, returning a newly allocated buffer
|
/* Sends a request to the agent, returning a newly allocated buffer
|
||||||
* with the response */
|
* with the response */
|
||||||
|
/* This function will block waiting for a response - it will
|
||||||
|
* only be used by client authentication (not for forwarded requests)
|
||||||
|
* won't cause problems for interactivity. */
|
||||||
/* Packet format (from draft-ylonen)
|
/* Packet format (from draft-ylonen)
|
||||||
4 bytes Length, msb first. Does not include length itself.
|
4 bytes Length, msb first. Does not include length itself.
|
||||||
1 byte Packet type. The value 255 is reserved for future extensions.
|
1 byte Packet type. The value 255 is reserved for future extensions.
|
||||||
data Any data, depending on packet type. Encoding as in the ssh packet
|
data Any data, depending on packet type. Encoding as in the ssh packet
|
||||||
protocol.
|
protocol.
|
||||||
|
|
||||||
In this case, data is always empty
|
|
||||||
*/
|
*/
|
||||||
static buffer * agent_request(int fd, unsigned char type) {
|
static buffer * agent_request(int fd, unsigned char type) {
|
||||||
|
|
||||||
@ -113,16 +114,17 @@ static buffer * agent_request(int fd, unsigned char type) {
|
|||||||
|
|
||||||
buf_putint(payload, 1);
|
buf_putint(payload, 1);
|
||||||
buf_putbyte(payload, type);
|
buf_putbyte(payload, type);
|
||||||
|
buf_setpos(payload, 0);
|
||||||
|
|
||||||
ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len);
|
ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len);
|
||||||
if ((size_t)ret != payload->len) {
|
if ((size_t)ret != payload->len) {
|
||||||
TRACE(("write failed for agent_request"))
|
TRACE(("write failed fd %d for agent_request, %s", fd, strerror(errno)))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_free(payload);
|
buf_free(payload);
|
||||||
payload = NULL;
|
payload = NULL;
|
||||||
|
TRACE(("Wrote out bytes for agent_request"))
|
||||||
/* Now we read the response */
|
/* Now we read the response */
|
||||||
inbuf = buf_new(4);
|
inbuf = buf_new(4);
|
||||||
ret = atomicio(read, fd, buf_getwriteptr(inbuf, 4), 4);
|
ret = atomicio(read, fd, buf_getwriteptr(inbuf, 4), 4);
|
||||||
@ -130,19 +132,27 @@ static buffer * agent_request(int fd, unsigned char type) {
|
|||||||
TRACE(("read of length failed for agent_request"))
|
TRACE(("read of length failed for agent_request"))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
buf_setpos(inbuf, 0);
|
||||||
|
buf_setlen(inbuf, ret);
|
||||||
|
|
||||||
readlen = buf_getint(inbuf);
|
readlen = buf_getint(inbuf);
|
||||||
if (readlen > MAX_AGENT_REPLY) {
|
if (readlen > MAX_AGENT_REPLY) {
|
||||||
TRACE(("agent reply is too big"));
|
TRACE(("agent reply is too big"));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE(("agent_request readlen is %d", readlen))
|
||||||
|
|
||||||
buf_resize(inbuf, readlen);
|
buf_resize(inbuf, readlen);
|
||||||
|
buf_setpos(inbuf, 0);
|
||||||
ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen);
|
ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen);
|
||||||
if ((size_t)ret != readlen) {
|
if ((size_t)ret != readlen) {
|
||||||
TRACE(("read of data failed for agent_request"))
|
TRACE(("read of data failed for agent_request"))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
buf_incrwritepos(inbuf, readlen);
|
||||||
|
buf_setpos(inbuf, 0);
|
||||||
|
TRACE(("agent_request success, length %d", readlen))
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (payload)
|
if (payload)
|
||||||
@ -151,17 +161,18 @@ out:
|
|||||||
return inbuf;
|
return inbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct SignKeyList * agent_get_key_list(int fd)
|
static void agent_get_key_list(int fd, struct SignKeyList * ret_list)
|
||||||
{
|
{
|
||||||
buffer * inbuf = NULL;
|
buffer * inbuf = NULL;
|
||||||
unsigned int num = 0;
|
unsigned int num = 0;
|
||||||
unsigned char packet_type;
|
unsigned char packet_type;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct SignKeyList *retkey = NULL, *key = NULL;
|
struct SignKeyList *key = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES);
|
inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES);
|
||||||
if (!inbuf) {
|
if (!inbuf) {
|
||||||
|
TRACE(("agent_request returned no identities"))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,11 +198,8 @@ static struct SignKeyList * agent_get_key_list(int fd)
|
|||||||
struct SignKeyList *nextkey = NULL;
|
struct SignKeyList *nextkey = NULL;
|
||||||
|
|
||||||
nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
|
nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
|
||||||
if (key)
|
ret_list->next = nextkey;
|
||||||
key->next = nextkey;
|
ret_list = nextkey;
|
||||||
else
|
|
||||||
retkey = nextkey;
|
|
||||||
key = nextkey;
|
|
||||||
|
|
||||||
pubkey = new_sign_key();
|
pubkey = new_sign_key();
|
||||||
ret = buf_get_pub_key(inbuf, pubkey, &key_type);
|
ret = buf_get_pub_key(inbuf, pubkey, &key_type);
|
||||||
@ -214,14 +222,11 @@ out:
|
|||||||
buf_free(inbuf);
|
buf_free(inbuf);
|
||||||
inbuf = NULL;
|
inbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_agent_keys()
|
/* Returned keys are appended to ret_list */
|
||||||
|
void load_agent_keys(struct SignKeyList * ret_list)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct SignKeyList * ret_list;
|
|
||||||
int fd;
|
int fd;
|
||||||
fd = connect_agent();
|
fd = connect_agent();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@ -229,7 +234,7 @@ void load_agent_keys()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_list = agent_get_key_list(fd);
|
agent_get_key_list(fd, ret_list);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,11 +174,11 @@ int cli_auth_pubkey() {
|
|||||||
|
|
||||||
TRACE(("enter cli_auth_pubkey"))
|
TRACE(("enter cli_auth_pubkey"))
|
||||||
|
|
||||||
if (cli_opts.privkeys == NULL &&
|
if (cli_opts.agent_fwd &&
|
||||||
cli_opts.agent_fwd &&
|
|
||||||
!cli_opts.agent_keys_loaded) {
|
!cli_opts.agent_keys_loaded) {
|
||||||
/* get the list of available keys from the agent */
|
/* get the list of available keys from the agent */
|
||||||
load_agent_keys(&cli_opts.privkeys);
|
load_agent_keys(&cli_opts.privkeys);
|
||||||
|
cli_opts.agent_keys_loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cli_opts.privkeys != NULL) {
|
if (cli_opts.privkeys != NULL) {
|
||||||
|
19
dbutil.c
19
dbutil.c
@ -297,14 +297,22 @@ int dropbear_listen(const char* address, const char* port,
|
|||||||
|
|
||||||
/* Connect to a given unix socket. The socket is blocking */
|
/* Connect to a given unix socket. The socket is blocking */
|
||||||
#ifdef ENABLE_CONNECT_UNIX
|
#ifdef ENABLE_CONNECT_UNIX
|
||||||
int connect_unix(const char* addr) {
|
int connect_unix(const char* path) {
|
||||||
struct sockaddr_un egdsock;
|
struct sockaddr_un addr;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
memset((void*)&egdsock, 0x0, sizeof(egdsock));
|
memset((void*)&addr, 0x0, sizeof(addr));
|
||||||
egdsock.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
strlcpy(egdsock.sun_path, addr, sizeof(egdsock.sun_path));
|
strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||||
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
TRACE(("Failed to open unix socket"))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
|
TRACE(("Failed to connect to '%s' socket", path))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -574,7 +582,6 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return retstring;
|
return retstring;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the hostname corresponding to the address addr. On failure, the IP
|
/* Get the hostname corresponding to the address addr. On failure, the IP
|
||||||
|
2
debug.h
2
debug.h
@ -39,7 +39,7 @@
|
|||||||
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
||||||
* since the printing may not sanitise strings etc. This will add a reasonable
|
* since the printing may not sanitise strings etc. This will add a reasonable
|
||||||
* amount to your executable size. */
|
* amount to your executable size. */
|
||||||
/*#define DEBUG_TRACE*/
|
#define DEBUG_TRACE
|
||||||
|
|
||||||
/* All functions writing to the cleartext payload buffer call
|
/* All functions writing to the cleartext payload buffer call
|
||||||
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
||||||
|
11
session.h
11
session.h
@ -215,17 +215,6 @@ struct serversession {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct protocol {
|
|
||||||
int sock; /* read/write with this */
|
|
||||||
buffer * readbuf; /* Pending input data, should read a packet's worth */
|
|
||||||
struct Queue writequeue; /* A queue of output buffers to send */
|
|
||||||
void (*process)(); /* To be called after reading */
|
|
||||||
size_t (*bytes_to_read)();
|
|
||||||
void * state; /* protocol specific */
|
|
||||||
void (*protocol_closed)(); /* to be run when the sock gets closed */
|
|
||||||
void (*loop_handler)(); /* to run at end of each loop */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
KEX_NOTHING,
|
KEX_NOTHING,
|
||||||
KEXINIT_RCVD,
|
KEXINIT_RCVD,
|
||||||
|
Loading…
Reference in New Issue
Block a user