From 242c074646b250682a5d41540ab91e67b02757a5 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 19 Sep 2018 21:56:44 +0100 Subject: [PATCH] Move low-level functions out into sshcommon.c. These are essentially data-structure maintenance, and it seems silly to have them be part of the same file that manages the topmost structure of the SSH connection. --- Recipe | 2 +- ssh.c | 148 ----------------------------------------------- sshcommon.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 149 deletions(-) create mode 100644 sshcommon.c diff --git a/Recipe b/Recipe index a2728c08..87fc0b67 100644 --- a/Recipe +++ b/Recipe @@ -250,7 +250,7 @@ GTKMAIN = gtkmain cmdline NONSSH = telnet raw rlogin ldisc pinger # SSH back end (putty, plink, pscp, psftp). -SSH = ssh ssh1bpp ssh2bpp ssh2bpp-bare ssh1censor ssh2censor +SSH = ssh sshcommon ssh1bpp ssh2bpp ssh2bpp-bare ssh1censor ssh2censor + sshverstring sshcrc sshdes sshmd5 sshrsa sshrand sshsha sshblowf + sshdh sshcrcda sshpubk sshzlib sshdss x11fwd portfwd + sshaes sshccp sshsh256 sshsh512 sshbn wildcard pinger ssharcf diff --git a/ssh.c b/ssh.c index b38a281b..c73218eb 100644 --- a/ssh.c +++ b/ssh.c @@ -278,8 +278,6 @@ enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM, }; -static void ssh_pkt_ensure(struct PktOut *, int length); -static void ssh_pkt_adddata(struct PktOut *, const void *data, int len); static void ssh2_pkt_send(Ssh, struct PktOut *); static void do_ssh1_login(void *vctx); static void do_ssh2_userauth(void *vctx); @@ -547,100 +545,6 @@ static PktOut *ssh2_gss_authpacket(Ssh ssh, Ssh_gss_ctx gss_ctx, #endif static void ssh2_msg_unexpected(Ssh ssh, PktIn *pktin); -void pq_base_push(PacketQueueBase *pqb, PacketQueueNode *node) -{ - assert(!node->next); - assert(!node->prev); - node->next = &pqb->end; - node->prev = pqb->end.prev; - node->next->prev = node; - node->prev->next = node; -} - -void pq_base_push_front(PacketQueueBase *pqb, PacketQueueNode *node) -{ - assert(!node->next); - assert(!node->prev); - node->prev = &pqb->end; - node->next = pqb->end.next; - node->next->prev = node; - node->prev->next = node; -} - -static PktIn *pq_in_get(PacketQueueBase *pqb, int pop) -{ - PacketQueueNode *node = pqb->end.next; - if (node == &pqb->end) - return NULL; - - if (pop) { - node->next->prev = node->prev; - node->prev->next = node->next; - node->prev = node->next = NULL; - } - - return FROMFIELD(node, PktIn, qnode); -} - -static PktOut *pq_out_get(PacketQueueBase *pqb, int pop) -{ - PacketQueueNode *node = pqb->end.next; - if (node == &pqb->end) - return NULL; - - if (pop) { - node->next->prev = node->prev; - node->prev->next = node->next; - node->prev = node->next = NULL; - } - - return FROMFIELD(node, PktOut, qnode); -} - -void pq_in_init(PktInQueue *pq) -{ - pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end; - pq->get = pq_in_get; -} - -void pq_out_init(PktOutQueue *pq) -{ - pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end; - pq->get = pq_out_get; -} - -void pq_in_clear(PktInQueue *pq) -{ - PktIn *pkt; - while ((pkt = pq_pop(pq)) != NULL) - ssh_unref_packet(pkt); -} - -void pq_out_clear(PktOutQueue *pq) -{ - PktOut *pkt; - while ((pkt = pq_pop(pq)) != NULL) - ssh_free_pktout(pkt); -} - -int pq_base_empty_on_to_front_of(PacketQueueBase *src, PacketQueueBase *dest) -{ - struct PacketQueueNode *srcfirst, *srclast; - - if (src->end.next == &src->end) - return FALSE; - - srcfirst = src->end.next; - srclast = src->end.prev; - srcfirst->prev = &dest->end; - srclast->next = dest->end.next; - srcfirst->prev->next = srcfirst; - srclast->next->prev = srclast; - src->end.next = src->end.prev = &src->end; - - return TRUE; -} - struct queued_handler; struct queued_handler { int msg1, msg2; @@ -1104,34 +1008,6 @@ static void c_write_str(Ssh ssh, const char *buf) c_write(ssh, buf, strlen(buf)); } -void ssh_unref_packet(PktIn *pkt) -{ - if (--pkt->refcount <= 0) - sfree(pkt); -} - -void ssh_free_pktout(PktOut *pkt) -{ - sfree(pkt->data); - sfree(pkt); -} - -static void ssh_pkt_BinarySink_write(BinarySink *bs, - const void *data, size_t len); -PktOut *ssh_new_packet(void) -{ - PktOut *pkt = snew(PktOut); - - BinarySink_INIT(pkt, ssh_pkt_BinarySink_write); - pkt->data = NULL; - pkt->length = 0; - pkt->maxlen = 0; - pkt->downstream_id = 0; - pkt->additional_log_text = NULL; - - return pkt; -} - static int s_write(Ssh ssh, const void *data, int len) { if (len && ssh->logctx) @@ -1162,30 +1038,6 @@ static void ssh_pkt_write(Ssh ssh, PktOut *pkt) queue_idempotent_callback(&ssh->outgoing_data_sender); } -/* - * Packet construction functions. Mostly shared between SSH-1 and SSH-2. - */ -static void ssh_pkt_ensure(PktOut *pkt, int length) -{ - if (pkt->maxlen < length) { - pkt->maxlen = length + 256; - pkt->data = sresize(pkt->data, pkt->maxlen, unsigned char); - } -} -static void ssh_pkt_adddata(PktOut *pkt, const void *data, int len) -{ - pkt->length += len; - ssh_pkt_ensure(pkt, pkt->length); - memcpy(pkt->data + pkt->length - len, data, len); -} - -static void ssh_pkt_BinarySink_write(BinarySink *bs, - const void *data, size_t len) -{ - PktOut *pkt = BinarySink_DOWNCAST(bs, PktOut); - ssh_pkt_adddata(pkt, data, len); -} - /* * Either queue or send a packet, depending on whether queueing is * set. diff --git a/sshcommon.c b/sshcommon.c new file mode 100644 index 00000000..7af086fe --- /dev/null +++ b/sshcommon.c @@ -0,0 +1,161 @@ +/* + * Supporting routines used in common by all the various components of + * the SSH system. + */ + +#include + +#include "ssh.h" +#include "sshchan.h" + +/* ---------------------------------------------------------------------- + * Implementation of PacketQueue. + */ + +void pq_base_push(PacketQueueBase *pqb, PacketQueueNode *node) +{ + assert(!node->next); + assert(!node->prev); + node->next = &pqb->end; + node->prev = pqb->end.prev; + node->next->prev = node; + node->prev->next = node; +} + +void pq_base_push_front(PacketQueueBase *pqb, PacketQueueNode *node) +{ + assert(!node->next); + assert(!node->prev); + node->prev = &pqb->end; + node->next = pqb->end.next; + node->next->prev = node; + node->prev->next = node; +} + +static PktIn *pq_in_get(PacketQueueBase *pqb, int pop) +{ + PacketQueueNode *node = pqb->end.next; + if (node == &pqb->end) + return NULL; + + if (pop) { + node->next->prev = node->prev; + node->prev->next = node->next; + node->prev = node->next = NULL; + } + + return FROMFIELD(node, PktIn, qnode); +} + +static PktOut *pq_out_get(PacketQueueBase *pqb, int pop) +{ + PacketQueueNode *node = pqb->end.next; + if (node == &pqb->end) + return NULL; + + if (pop) { + node->next->prev = node->prev; + node->prev->next = node->next; + node->prev = node->next = NULL; + } + + return FROMFIELD(node, PktOut, qnode); +} + +void pq_in_init(PktInQueue *pq) +{ + pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end; + pq->get = pq_in_get; +} + +void pq_out_init(PktOutQueue *pq) +{ + pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end; + pq->get = pq_out_get; +} + +void pq_in_clear(PktInQueue *pq) +{ + PktIn *pkt; + while ((pkt = pq_pop(pq)) != NULL) + ssh_unref_packet(pkt); +} + +void pq_out_clear(PktOutQueue *pq) +{ + PktOut *pkt; + while ((pkt = pq_pop(pq)) != NULL) + ssh_free_pktout(pkt); +} + +int pq_base_empty_on_to_front_of(PacketQueueBase *src, PacketQueueBase *dest) +{ + struct PacketQueueNode *srcfirst, *srclast; + + if (src->end.next == &src->end) + return FALSE; + + srcfirst = src->end.next; + srclast = src->end.prev; + srcfirst->prev = &dest->end; + srclast->next = dest->end.next; + srcfirst->prev->next = srcfirst; + srclast->next->prev = srclast; + src->end.next = src->end.prev = &src->end; + + return TRUE; +} + +/* ---------------------------------------------------------------------- + * Low-level functions for the packet structures themselves. + */ + +static void ssh_pkt_BinarySink_write(BinarySink *bs, + const void *data, size_t len); +PktOut *ssh_new_packet(void) +{ + PktOut *pkt = snew(PktOut); + + BinarySink_INIT(pkt, ssh_pkt_BinarySink_write); + pkt->data = NULL; + pkt->length = 0; + pkt->maxlen = 0; + pkt->downstream_id = 0; + pkt->additional_log_text = NULL; + pkt->qnode.next = pkt->qnode.prev = NULL; + + return pkt; +} + +static void ssh_pkt_ensure(PktOut *pkt, int length) +{ + if (pkt->maxlen < length) { + pkt->maxlen = length + 256; + pkt->data = sresize(pkt->data, pkt->maxlen, unsigned char); + } +} +static void ssh_pkt_adddata(PktOut *pkt, const void *data, int len) +{ + pkt->length += len; + ssh_pkt_ensure(pkt, pkt->length); + memcpy(pkt->data + pkt->length - len, data, len); +} + +static void ssh_pkt_BinarySink_write(BinarySink *bs, + const void *data, size_t len) +{ + PktOut *pkt = BinarySink_DOWNCAST(bs, PktOut); + ssh_pkt_adddata(pkt, data, len); +} + +void ssh_unref_packet(PktIn *pkt) +{ + if (--pkt->refcount <= 0) + sfree(pkt); +} + +void ssh_free_pktout(PktOut *pkt) +{ + sfree(pkt->data); + sfree(pkt); +}