summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2009-07-06 12:59:13 +0000
committerMatt Johnston <matt@ucc.asn.au>2009-07-06 12:59:13 +0000
commit842e8f52e3cd511b48d4f46bbfd67b1c86f30733 (patch)
tree25f52a38fb21d20051e2e44faa40ab25f45a5cad
parenta09f4c9219b21736a1038d9b38b37c1592a63328 (diff)
downloaddropbear-842e8f52e3cd511b48d4f46bbfd67b1c86f30733.tar.gz
New standard linked list to use, rather than adhoc SignKeyList or TCPFwdList
-rw-r--r--Makefile.in4
-rw-r--r--agentfwd.h7
-rw-r--r--auth.h20
-rw-r--r--buffer.c14
-rw-r--r--buffer.h1
-rw-r--r--cli-agentfwd.c59
-rw-r--r--cli-authpubkey.c75
-rw-r--r--cli-chansession.c13
-rw-r--r--cli-runopts.c47
-rw-r--r--cli-tcpfwd.c84
-rw-r--r--list.c49
-rw-r--r--list.h28
-rw-r--r--runopts.h6
-rw-r--r--session.h2
-rw-r--r--signkey.c14
-rw-r--r--signkey.h14
-rw-r--r--tcpfwd.h9
17 files changed, 254 insertions, 192 deletions
diff --git a/Makefile.in b/Makefile.in
index efd9e57..fe10204 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -20,7 +20,7 @@ COMMONOBJS=dbutil.o buffer.o \
dss.o bignum.o \
signkey.o rsa.o random.o \
queue.o \
- atomicio.o compat.o fake-rfc2553.o
+ atomicio.o compat.o fake-rfc2553.o
SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
svr-authpasswd.o svr-authpubkey.o svr-authpubkeyoptions.o svr-session.o svr-service.o \
@@ -30,7 +30,7 @@ SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o \
- cli-agentfwd.o
+ cli-agentfwd.o list.o
CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
common-channel.o common-chansession.o termcodes.o loginrec.o \
diff --git a/agentfwd.h b/agentfwd.h
index 8575b0c..e1794a7 100644
--- a/agentfwd.h
+++ b/agentfwd.h
@@ -28,6 +28,7 @@
#include "chansession.h"
#include "channel.h"
#include "auth.h"
+#include "list.h"
/* An agent reply can be reasonably large, as it can
* contain a list of all public keys held by the agent.
@@ -35,11 +36,13 @@
#define MAX_AGENT_REPLY 10000
int agentreq(struct ChanSess * chansess);
-void agentsetauth(struct ChanSess *chansess);
void agentcleanup(struct ChanSess * chansess);
void agentset(struct ChanSess *chansess);
-void load_agent_keys(struct SignKeyList * ret_list);
+/* client functions */
+void load_agent_keys(m_list * ret_list);
+void agent_buf_sign(buffer *sigblob, sign_key *key,
+ const unsigned char *data, unsigned int len);
#ifdef __hpux
#define seteuid(a) setresuid(-1, (a), -1)
diff --git a/auth.h b/auth.h
index a35416c..d22f812 100644
--- a/auth.h
+++ b/auth.h
@@ -124,26 +124,6 @@ struct AuthState {
};
-/* Sources for signing keys */
-typedef enum {
- SIGNKEY_SOURCE_RAW_FILE,
- SIGNKEY_SOURCE_AGENT,
-} signkey_source;
-
-struct SignKeyList;
-/* A singly linked list of signing keys */
-struct SignKeyList {
-
- sign_key *key;
- int type; /* The type of key */
- struct SignKeyList *next;
- signkey_source source;
- char *filename;
- /* the buffer? for encrypted keys, so we can later get
- * the private key portion */
-
-};
-
#ifdef ENABLE_SVR_PUBKEY_OPTIONS
struct PubKeyOptions;
struct PubKeyOptions {
diff --git a/buffer.c b/buffer.c
index 579fa6f..7394993 100644
--- a/buffer.c
+++ b/buffer.c
@@ -223,6 +223,20 @@ unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) {
return ret;
}
+/* Return a string as a newly allocated buffer */
+buffer * buf_getstringbuf(buffer *buf) {
+ buffer *ret;
+ unsigned char* str;
+ unsigned int len;
+ str = buf_getstring(buf, &len);
+ ret = m_malloc(sizeof(*ret));
+ ret->data = str;
+ ret->len = len;
+ ret->size = len;
+ ret->pos = 0;
+ return ret;
+}
+
/* Just increment the buffer position the same as if we'd used buf_getstring,
* but don't bother copying/malloc()ing for it */
void buf_eatstring(buffer *buf) {
diff --git a/buffer.h b/buffer.h
index f9aa6fa..5964370 100644
--- a/buffer.h
+++ b/buffer.h
@@ -55,6 +55,7 @@ void buf_putbyte(buffer* buf, unsigned char val);
unsigned char* buf_getptr(buffer* buf, unsigned int len);
unsigned char* buf_getwriteptr(buffer* buf, unsigned int len);
unsigned char* buf_getstring(buffer* buf, unsigned int *retlen);
+buffer * buf_getstringbuf(buffer *buf);
void buf_eatstring(buffer *buf);
void buf_putint(buffer* buf, unsigned int val);
void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len);
diff --git a/cli-agentfwd.c b/cli-agentfwd.c
index b47a6cc..0a5661d 100644
--- a/cli-agentfwd.c
+++ b/cli-agentfwd.c
@@ -22,10 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. */
-/* The basic protocol use to communicate with the agent is defined in
- * draft-ylonen-ssh-protocol-00.txt, with the ssh2 extensions defined through
- * openssh's implementation. */
-
#include "includes.h"
#ifdef ENABLE_CLI_AGENTFWD
@@ -45,6 +41,9 @@
#include "signkey.h"
#include "auth.h"
+/* The protocol implemented to talk to OpenSSH's SSH2 agent is documented in
+ PROTOCOL.agent in recent OpenSSH source distributions (5.1p1 has it). */
+
static int new_agent_chan(struct Channel * channel);
const struct ChanType cli_chan_agent = {
@@ -161,13 +160,12 @@ out:
return inbuf;
}
-static void agent_get_key_list(int fd, struct SignKeyList * ret_list)
+static void agent_get_key_list(int fd, m_list * ret_list)
{
buffer * inbuf = NULL;
unsigned int num = 0;
unsigned char packet_type;
unsigned int i;
- struct SignKeyList *key = NULL;
int ret;
inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES);
@@ -177,14 +175,11 @@ static void agent_get_key_list(int fd, struct SignKeyList * ret_list)
}
/* The reply has a format of:
- * byte packet_type
- * int num_keys
- *
- * string keyblob1
- * string comment1
- * ...
- * string keyblob(n)
- * string comment(n)
+ byte SSH2_AGENT_IDENTITIES_ANSWER
+ uint32 num_keys
+ Followed by zero or more consecutive keys, encoded as:
+ string key_blob
+ string key_comment
*/
packet_type = buf_getbyte(inbuf);
if (packet_type != SSH2_AGENT_IDENTITIES_ANSWER) {
@@ -195,25 +190,24 @@ static void agent_get_key_list(int fd, struct SignKeyList * ret_list)
for (i = 0; i < num; i++) {
sign_key * pubkey = NULL;
int key_type = DROPBEAR_SIGNKEY_ANY;
+ buffer * key_buf;
struct SignKeyList *nextkey = NULL;
- nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
- ret_list->next = nextkey;
- ret_list = nextkey;
-
+ /* each public key is encoded as a string */
+ key_buf = buf_getstringbuf(inbuf);
pubkey = new_sign_key();
- ret = buf_get_pub_key(inbuf, pubkey, &key_type);
+ ret = buf_get_pub_key(key_buf, pubkey, &key_type);
+ buf_free(key_buf);
if (ret != DROPBEAR_SUCCESS) {
/* This is slack, properly would cleanup vars etc */
dropbear_exit("Bad pubkey received from agent");
}
+ pubkey->type = key_type;
+ pubkey->source = SIGNKEY_SOURCE_AGENT;
- key->key = pubkey;
- key->next = NULL;
- key->type = key_type;
- key->source = SIGNKEY_SOURCE_AGENT;
+ list_append(ret_list, pubkey);
- /* We'll ignore the comment */
+ /* We'll ignore the comment for now. might want it later.*/
buf_eatstring(inbuf);
}
@@ -224,8 +218,9 @@ out:
}
}
-/* Returned keys are appended to ret_list */
-void load_agent_keys(struct SignKeyList * ret_list)
+/* Returned keys are prepended to ret_list, which will
+ be updated. */
+void load_agent_keys(m_list *ret_list)
{
int fd;
fd = connect_agent();
@@ -237,13 +232,9 @@ void load_agent_keys(struct SignKeyList * ret_list)
agent_get_key_list(fd, ret_list);
close(fd);
}
-
-// general procedure:
-// - get the list of keys from the agent
-// - foreach, send a dummy userauth_pubkey message to the server and see
-// if it lets us in
-// - if it does, sign and auth
-// - if not, repeat.
-//
+
+void agent_buf_sign(buffer *sigblob, sign_key *key,
+ const unsigned char *data, unsigned int len) {
+}
#endif
diff --git a/cli-authpubkey.c b/cli-authpubkey.c
index b7ecd55..0ad0031 100644
--- a/cli-authpubkey.c
+++ b/cli-authpubkey.c
@@ -30,6 +30,7 @@
#include "ssh.h"
#include "runopts.h"
#include "auth.h"
+#include "agentfwd.h"
#ifdef ENABLE_CLI_PUBKEY_AUTH
static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign);
@@ -37,31 +38,23 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign);
/* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
* We use it to remove the key we tried from the list */
void cli_pubkeyfail() {
-
- struct SignKeyList *keyitem;
- struct SignKeyList **previtem;
-
- TRACE(("enter cli_pubkeyfail"))
- previtem = &cli_opts.privkeys;
-
- /* Find the key we failed with, and remove it */
- for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
- if (keyitem == cli_ses.lastprivkey) {
- *previtem = keyitem->next;
+ m_list_elem *iter;
+ for (iter = cli_opts.privkeys->first; iter; iter = iter->next) {
+ sign_key *iter_key = (sign_key*)iter->item;
+
+ if (iter_key == cli_ses.lastprivkey)
+ {
+ /* found the failing key */
+ list_remove(iter);
+ sign_key_free(iter_key);
+ cli_ses.lastprivkey = NULL;
+ return;
}
- previtem = &keyitem;
}
-
- sign_key_free(cli_ses.lastprivkey->key); /* It won't be used again */
- m_free(cli_ses.lastprivkey->filename);
- m_free(cli_ses.lastprivkey);
-
- TRACE(("leave cli_pubkeyfail"))
}
void recv_msg_userauth_pk_ok() {
-
- struct SignKeyList *keyitem = NULL;
+ m_list_elem *iter;
buffer* keybuf = NULL;
char* algotype = NULL;
unsigned int algolen;
@@ -81,9 +74,9 @@ void recv_msg_userauth_pk_ok() {
/* Iterate through our keys, find which one it was that matched, and
* send a real request with that key */
- for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
-
- if (keyitem->type != keytype) {
+ for (iter = cli_opts.privkeys->first; iter; iter = iter->next) {
+ sign_key *key = (sign_key*)iter->item;
+ if (key->type != keytype) {
/* Types differed */
TRACE(("types differed"))
continue;
@@ -91,7 +84,7 @@ void recv_msg_userauth_pk_ok() {
/* Now we compare the contents of the key */
keybuf->pos = keybuf->len = 0;
- buf_put_pub_key(keybuf, keyitem->key, keytype);
+ buf_put_pub_key(keybuf, key, keytype);
buf_setpos(keybuf, 0);
buf_incrpos(keybuf, 4); /* first int is the length of the remainder (ie
remotelen) which has already been taken from
@@ -115,11 +108,11 @@ void recv_msg_userauth_pk_ok() {
}
buf_free(keybuf);
- if (keyitem != NULL) {
+ if (iter != NULL) {
TRACE(("matching key"))
/* XXX TODO: if it's an encrypted key, here we ask for their
* password */
- send_msg_userauth_pubkey(keyitem->key, keytype, 1);
+ send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1);
} else {
TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
}
@@ -127,6 +120,25 @@ void recv_msg_userauth_pk_ok() {
TRACE(("leave recv_msg_userauth_pk_ok"))
}
+void cli_buf_put_sign(buffer* buf, sign_key *key, int type,
+ const unsigned char *data, unsigned int len)
+{
+ if (key->source == SIGNKEY_SOURCE_AGENT) {
+ /* Format the agent signature ourselves, as buf_put_sign would. */
+ buffer *sigblob;
+ sigblob = buf_new(MAX_PUBKEY_SIZE);
+ agent_buf_sign(sigblob, key, data, len);
+ buf_setpos(sigblob, 0);
+ buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
+ sigblob->len);
+
+ buf_free(sigblob);
+ } else {
+ buf_put_sign(buf, key, type, data, len);
+ }
+
+}
+
/* TODO: make it take an agent reference to use as well */
static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
@@ -170,6 +182,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
TRACE(("leave send_msg_userauth_pubkey"))
}
+/* Returns 1 if a key was tried */
int cli_auth_pubkey() {
TRACE(("enter cli_auth_pubkey"))
@@ -177,15 +190,15 @@ int cli_auth_pubkey() {
if (cli_opts.agent_fwd &&
!cli_opts.agent_keys_loaded) {
/* 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->first) {
+ sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
/* Send a trial request */
- send_msg_userauth_pubkey(cli_opts.privkeys->key,
- cli_opts.privkeys->type, 0);
- cli_ses.lastprivkey = cli_opts.privkeys;
+ send_msg_userauth_pubkey(key, key->type, 0);
+ cli_ses.lastprivkey = key;
TRACE(("leave cli_auth_pubkey-success"))
return 1;
} else {
diff --git a/cli-chansession.c b/cli-chansession.c
index dc8e641..9dc0224 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -424,16 +424,3 @@ void cli_send_chansess_request() {
TRACE(("leave cli_send_chansess_request"))
}
-
-
-#if 0
- while (cli_opts.localfwds != NULL) {
- ret = cli_localtcp(cli_opts.localfwds->listenport,
- cli_opts.localfwds->connectaddr,
- cli_opts.localfwds->connectport);
- if (ret == DROPBEAR_FAILURE) {
- dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
- cli_opts.localfwds->listenport,
- cli_opts.localfwds->connectaddr,
- cli_opts.localfwds->connectport);
-#endif
diff --git a/cli-runopts.c b/cli-runopts.c
index a7c0f82..eab33b7 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -29,6 +29,7 @@
#include "dbutil.h"
#include "algo.h"
#include "tcpfwd.h"
+#include "list.h"
cli_runopts cli_opts; /* GLOBAL */
@@ -40,7 +41,7 @@ static void fill_own_user();
static void loadidentityfile(const char* filename);
#endif
#ifdef ENABLE_CLI_ANYTCPFWD
-static void addforward(const char* str, struct TCPFwdList** fwdlist);
+static void addforward(const char* str, m_list *fwdlist);
#endif
#ifdef ENABLE_CLI_NETCAT
static void add_netcat(const char *str);
@@ -128,14 +129,14 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.always_accept_key = 0;
cli_opts.is_subsystem = 0;
#ifdef ENABLE_CLI_PUBKEY_AUTH
- cli_opts.privkeys = NULL;
+ cli_opts.privkeys = list_new();
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
- cli_opts.localfwds = NULL;
+ cli_opts.localfwds = list_new();
opts.listen_fwd_all = 0;
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
- cli_opts.remotefwds = NULL;
+ cli_opts.remotefwds = list_new();
#endif
#ifdef ENABLE_CLI_AGENTFWD
cli_opts.agent_fwd = 0;
@@ -165,7 +166,7 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_REMOTETCPFWD
if (nextisremote) {
TRACE(("nextisremote true"))
- addforward(argv[i], &cli_opts.remotefwds);
+ addforward(argv[i], cli_opts.remotefwds);
nextisremote = 0;
continue;
}
@@ -173,7 +174,7 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_LOCALTCPFWD
if (nextislocal) {
TRACE(("nextislocal true"))
- addforward(argv[i], &cli_opts.localfwds);
+ addforward(argv[i], cli_opts.localfwds);
nextislocal = 0;
continue;
}
@@ -406,8 +407,6 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_PUBKEY_AUTH
static void loadidentityfile(const char* filename) {
-
- struct SignKeyList * nextkey;
sign_key *key;
int keytype;
@@ -417,13 +416,10 @@ static void loadidentityfile(const char* filename) {
fprintf(stderr, "Failed loading keyfile '%s'\n", filename);
sign_key_free(key);
} else {
- nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
- nextkey->key = key;
- nextkey->filename = m_strdup(filename);
- nextkey->next = cli_opts.privkeys;
- nextkey->type = keytype;
- nextkey->source = SIGNKEY_SOURCE_RAW_FILE;
- cli_opts.privkeys = nextkey;
+ key->type = keytype;
+ key->source = SIGNKEY_SOURCE_RAW_FILE;
+ key->filename = m_strdup(filename);
+ list_append(cli_opts.privkeys, key);
}
}
#endif
@@ -435,12 +431,13 @@ multihop_passthrough_args() {
char *ret;
int total;
unsigned int len = 0;
- struct SignKeyList *nextkey;
+ m_list_elem *iter;
/* Fill out -i and -W options that make sense for all
* the intermediate processes */
- for (nextkey = cli_opts.privkeys; nextkey; nextkey = nextkey->next)
+ for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
{
- len += 3 + strlen(nextkey->filename);
+ sign_key * key = (sign_key*)iter->item;
+ len += 3 + strlen(key->filename);
}
len += 20; // space for -W <size>, terminator.
ret = m_malloc(len);
@@ -452,10 +449,11 @@ multihop_passthrough_args() {
total += written;
}
- for (nextkey = cli_opts.privkeys; nextkey; nextkey = nextkey->next)
+ for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
{
+ sign_key * key = (sign_key*)iter->item;
const size_t size = len - total;
- int written = snprintf(ret+total, size, "-i %s", nextkey->filename);
+ int written = snprintf(ret+total, size, "-i %s", key->filename);
dropbear_assert(written < size);
total += written;
}
@@ -621,12 +619,12 @@ static void fill_own_user() {
#ifdef ENABLE_CLI_ANYTCPFWD
/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
* set, and add it to the forwarding list */
-static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
+static void addforward(const char* origstr, m_list *fwdlist) {
char * listenport = NULL;
char * connectport = NULL;
char * connectaddr = NULL;
- struct TCPFwdList* newfwd = NULL;
+ struct TCPFwdEntry* newfwd = NULL;
char * str = NULL;
TRACE(("enter addforward"))
@@ -653,7 +651,7 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
*connectport = '\0';
connectport++;
- newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList));
+ newfwd = m_malloc(sizeof(struct TCPFwdEntry));
/* Now we check the ports - note that the port ints are unsigned,
* the check later only checks for >= MAX_PORT */
@@ -680,8 +678,7 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
}
newfwd->have_reply = 0;
- newfwd->next = *fwdlist;
- *fwdlist = newfwd;
+ list_append(fwdlist, newfwd);
TRACE(("leave addforward: done"))
return;
diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c
index 0e60090..0242654 100644
--- a/cli-tcpfwd.c
+++ b/cli-tcpfwd.c
@@ -59,27 +59,22 @@ static const struct ChanType cli_chan_tcplocal = {
#ifdef ENABLE_CLI_LOCALTCPFWD
void setup_localtcp() {
-
+ m_list_elem *iter;
int ret;
TRACE(("enter setup_localtcp"))
- if (cli_opts.localfwds == NULL) {
- TRACE(("cli_opts.localfwds == NULL"))
- }
-
- while (cli_opts.localfwds != NULL) {
- ret = cli_localtcp(cli_opts.localfwds->listenport,
- cli_opts.localfwds->connectaddr,
- cli_opts.localfwds->connectport);
+ for (iter = cli_opts.localfwds->first; iter; iter = iter->next) {
+ struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item;
+ ret = cli_localtcp(fwd->listenport,
+ fwd->connectaddr,
+ fwd->connectport);
if (ret == DROPBEAR_FAILURE) {
dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
- cli_opts.localfwds->listenport,
- cli_opts.localfwds->connectaddr,
- cli_opts.localfwds->connectport);
- }
-
- cli_opts.localfwds = cli_opts.localfwds->next;
+ fwd->listenport,
+ fwd->connectaddr,
+ fwd->connectport);
+ }
}
TRACE(("leave setup_localtcp"))
@@ -148,60 +143,47 @@ static void send_msg_global_request_remotetcp(int port) {
* being in the same order as we sent the requests. This is the ordering
* of the cli_opts.remotefwds list */
void cli_recv_msg_request_success() {
-
/* Nothing in the packet. We just mark off that we have received the reply,
* so that we can report failure for later ones. */
- struct TCPFwdList * iter = NULL;
-
- iter = cli_opts.remotefwds;
- while (iter != NULL) {
- if (!iter->have_reply)
- {
- iter->have_reply = 1;
+ m_list_elem * iter = NULL;
+ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
+ struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
+ if (!fwd->have_reply) {
+ fwd->have_reply = 1;
return;
}
- iter = iter->next;
}
}
void cli_recv_msg_request_failure() {
- struct TCPFwdList * iter = NULL;
-
- iter = cli_opts.remotefwds;
- while (iter != NULL) {
- if (!iter->have_reply)
- {
- iter->have_reply = 1;
- dropbear_log(LOG_WARNING, "Remote TCP forward request failed (port %d -> %s:%d)", iter->listenport, iter->connectaddr, iter->connectport);
+ m_list_elem *iter;
+ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
+ struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
+ if (!fwd->have_reply) {
+ fwd->have_reply = 1;
+ dropbear_log(LOG_WARNING, "Remote TCP forward request failed (port %d -> %s:%d)", fwd->listenport, fwd->connectaddr, fwd->connectport);
return;
}
- iter = iter->next;
}
}
void setup_remotetcp() {
-
- struct TCPFwdList * iter = NULL;
-
+ m_list_elem *iter;
TRACE(("enter setup_remotetcp"))
- if (cli_opts.remotefwds == NULL) {
- TRACE(("cli_opts.remotefwds == NULL"))
+ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
+ struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
+ send_msg_global_request_remotetcp(fwd->listenport);
}
- iter = cli_opts.remotefwds;
-
- while (iter != NULL) {
- send_msg_global_request_remotetcp(iter->listenport);
- iter = iter->next;
- }
TRACE(("leave setup_remotetcp"))
}
static int newtcpforwarded(struct Channel * channel) {
unsigned int origport;
- struct TCPFwdList * iter = NULL;
+ m_list_elem * iter = NULL;
+ struct TCPFwdEntry *fwd;
char portstring[NI_MAXSERV];
int sock;
int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
@@ -212,13 +194,11 @@ static int newtcpforwarded(struct Channel * channel) {
origport = buf_getint(ses.payload);
/* Find which port corresponds */
- iter = cli_opts.remotefwds;
-
- while (iter != NULL) {
- if (origport == iter->listenport) {
+ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
+ fwd = (struct TCPFwdEntry*)iter->item;
+ if (origport == fwd->listenport) {
break;
}
- iter = iter->next;
}
if (iter == NULL) {
@@ -228,8 +208,8 @@ static int newtcpforwarded(struct Channel * channel) {
goto out;
}
- snprintf(portstring, sizeof(portstring), "%d", iter->connectport);
- sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
+ snprintf(portstring, sizeof(portstring), "%d", fwd->connectport);
+ sock = connect_remote(fwd->connectaddr, portstring, 1, NULL);
if (sock < 0) {
TRACE(("leave newtcpdirect: sock failed"))
err = SSH_OPEN_CONNECT_FAILED;
diff --git a/list.c b/list.c
new file mode 100644
index 0000000..8be1a3a
--- /dev/null
+++ b/list.c
@@ -0,0 +1,49 @@
+#include "options.h"
+#include "dbutil.h"
+#include "list.h"
+
+void list_append(m_list *list, void *item) {
+ m_list_elem *elem;
+
+ elem = m_malloc(sizeof(*elem));
+ elem->item = item;
+ elem->list = list;
+ elem->next = NULL;
+ if (!list->first) {
+ list->first = elem;
+ elem->prev = NULL;
+ } else {
+ elem->prev = list->last;
+ list->last->next = elem;
+ }
+ list->last = elem;
+}
+
+m_list * list_new() {
+ m_list *ret = m_malloc(sizeof(m_list));
+ ret->first = ret->last = NULL;
+ return ret;
+}
+
+void * list_remove(m_list_elem *elem) {
+ void *item = elem->item;
+ m_list *list = elem->list;
+ if (list->first == elem)
+ {
+ list->first = elem->next;
+ }
+ if (list->last == elem)
+ {
+ list->last = elem->prev;
+ }
+ if (elem->prev)
+ {
+ elem->prev->next = elem->next;
+ }
+ if (elem->next)
+ {
+ elem->next->prev = elem->prev;
+ }
+ m_free(elem);
+ return item;
+} \ No newline at end of file
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..678fff1
--- /dev/null
+++ b/list.h
@@ -0,0 +1,28 @@
+#ifndef _DROPBEAR_LIST_H
+#define _DROPBEAR_LIST_H
+
+struct _m_list;
+
+struct _m_list_elem {
+ void *item;
+ struct _m_list_elem *next;
+ struct _m_list_elem *prev;
+ struct _m_list *list;
+};
+
+typedef struct _m_list_elem m_list_elem;
+
+struct _m_list {
+ m_list_elem *first;
+ m_list_elem *last;
+};
+
+typedef struct _m_list m_list;
+
+m_list * list_new();
+void list_append(m_list *list, void *item);
+/* returns the item for the element removed */
+void * list_remove(m_list_elem *elem);
+
+
+#endif /* _DROPBEAR_LIST_H */ \ No newline at end of file
diff --git a/runopts.h b/runopts.h
index bc35435..e672a4e 100644
--- a/runopts.h
+++ b/runopts.h
@@ -112,13 +112,13 @@ typedef struct cli_runopts {
int backgrounded;
int is_subsystem;
#ifdef ENABLE_CLI_PUBKEY_AUTH
- struct SignKeyList *privkeys; /* Keys to use for public-key auth */
+ m_list *privkeys; /* Keys to use for public-key auth */
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
- struct TCPFwdList * remotefwds;
+ m_list * remotefwds;
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
- struct TCPFwdList * localfwds;
+ m_list * localfwds;
#endif
#ifdef ENABLE_CLI_AGENTFWD
int agent_fwd;
diff --git a/session.h b/session.h
index 5a4569e..d02666d 100644
--- a/session.h
+++ b/session.h
@@ -261,7 +261,7 @@ struct clientsession {
info request from the server for
interactive auth.*/
#endif
- struct SignKeyList *lastprivkey;
+ sign_key *lastprivkey;
int retval; /* What the command exit status was - we emulate it */
#if 0
diff --git a/signkey.c b/signkey.c
index c1ef5e2..9bc4845 100644
--- a/signkey.c
+++ b/signkey.c
@@ -40,8 +40,10 @@ sign_key * new_sign_key() {
#ifdef DROPBEAR_RSA
ret->rsakey = NULL;
#endif
+ ret->filename = NULL;
+ ret->type = DROPBEAR_SIGNKEY_NONE;
+ ret->source = SIGNKEY_SOURCE_INVALID;
return ret;
-
}
/* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally
@@ -81,6 +83,9 @@ int signkey_type_from_name(const char* name, int namelen) {
}
#endif
+ TRACE(("signkey_type_from_name unexpected key type."))
+ printhex("Key type", name, namelen);
+
return DROPBEAR_SIGNKEY_NONE;
}
@@ -101,8 +106,11 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) {
m_free(ident);
if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
+ TRACE(("buf_get_pub_key bad type - got %d, expected %d", keytype, type))
return DROPBEAR_FAILURE;
}
+
+ TRACE(("buf_get_pub_key keytype is %d"))
*type = keytype;
@@ -255,6 +263,8 @@ void sign_key_free(sign_key *key) {
key->rsakey = NULL;
#endif
+ m_free(key->filename);
+
m_free(key);
TRACE(("leave sign_key_free"))
}
@@ -358,7 +368,6 @@ void buf_put_sign(buffer* buf, sign_key *key, int type,
const unsigned char *data, unsigned int len) {
buffer *sigblob;
-
sigblob = buf_new(MAX_PUBKEY_SIZE);
#ifdef DROPBEAR_DSS
@@ -374,7 +383,6 @@ void buf_put_sign(buffer* buf, sign_key *key, int type,
if (sigblob->len == 0) {
dropbear_exit("non-matching signing type");
}
-
buf_setpos(sigblob, 0);
buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
sigblob->len);
diff --git a/signkey.h b/signkey.h
index 4038b2d..9bcbfc9 100644
--- a/signkey.h
+++ b/signkey.h
@@ -29,8 +29,22 @@
#include "dss.h"
#include "rsa.h"
+
+/* Sources for signing keys */
+typedef enum {
+ SIGNKEY_SOURCE_RAW_FILE,
+ SIGNKEY_SOURCE_AGENT,
+ SIGNKEY_SOURCE_INVALID,
+} signkey_source;
+
struct SIGN_key {
+ int type; /* The type of key (dss or rsa) */
+ signkey_source source;
+ char *filename;
+ /* the buffer? for encrypted keys, so we can later get
+ * the private key portion */
+
#ifdef DROPBEAR_DSS
dss_key * dsskey;
#endif
diff --git a/tcpfwd.h b/tcpfwd.h
index 251612e..34da314 100644
--- a/tcpfwd.h
+++ b/tcpfwd.h
@@ -25,6 +25,7 @@
#define _TCPFWD_H
#include "channel.h"
+#include "list.h"
struct TCPListener {
@@ -43,16 +44,13 @@ struct TCPListener {
enum {direct, forwarded} tcp_type;
};
-/* A link in a list of forwards */
-struct TCPFwdList {
-
+/* A forwarding entry */
+struct TCPFwdEntry {
const unsigned char* connectaddr;
unsigned int connectport;
unsigned int listenport;
unsigned int have_reply; /* is set to 1 after a reply has been received
when setting up the forwarding */
- struct TCPFwdList * next;
-
};
/* Server */
@@ -70,5 +68,4 @@ void cli_recv_msg_request_failure();
/* Common */
int listen_tcpfwd(struct TCPListener* tcpinfo);
-
#endif