From 674a60748884dc55ee7091b7c23a41240e75f73c Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 1 Jun 2004 02:46:09 +0000 Subject: Makefile.in contains updated files required --HG-- extra : convert_revision : cc8a8c49dc70e632c352853a39801089b08149be --- common-kex.c | 458 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 common-kex.c (limited to 'common-kex.c') diff --git a/common-kex.c b/common-kex.c new file mode 100644 index 0000000..95f5db5 --- /dev/null +++ b/common-kex.c @@ -0,0 +1,458 @@ +/* + * Dropbear - a SSH2 server + * SSH client implementation + * + * This code is copied from the larger file "kex.c" + * some functions are verbatim, others are generalized --mihnea + * + * Copyright (c) 2002,2003 Matt Johnston + * Portions Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + +#include "includes.h" +#include "dbutil.h" +#include "algo.h" +#include "buffer.h" +#include "session.h" +#include "kex.h" +#include "ssh.h" +#include "packet.h" +#include "bignum.h" +#include "random.h" + +/* diffie-hellman-group1-sha1 value for p */ +const unsigned char dh_p_val[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +const int DH_G_VAL = 2; + +static void gen_new_keys(); +#ifndef DISABLE_ZLIB +static void gen_new_zstreams(); +#endif +/* helper function for gen_new_keys */ +static void hashkeys(unsigned char *out, int outlen, + const hash_state * hs, unsigned const char X); + + +/* Send our list of algorithms we can use */ +void send_msg_kexinit() { + + CHECKCLEARTOWRITE(); + buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT); + + /* cookie */ + genrandom(buf_getwriteptr(ses.writepayload, 16), 16); + buf_incrwritepos(ses.writepayload, 16); + + /* kex algos */ + buf_put_algolist(ses.writepayload, sshkex); + + /* server_host_key_algorithms */ + buf_put_algolist(ses.writepayload, sshhostkey); + + /* encryption_algorithms_client_to_server */ + buf_put_algolist(ses.writepayload, sshciphers); + + /* encryption_algorithms_server_to_client */ + buf_put_algolist(ses.writepayload, sshciphers); + + /* mac_algorithms_client_to_server */ + buf_put_algolist(ses.writepayload, sshhashes); + + /* mac_algorithms_server_to_client */ + buf_put_algolist(ses.writepayload, sshhashes); + + /* compression_algorithms_client_to_server */ + buf_put_algolist(ses.writepayload, sshcompress); + + /* compression_algorithms_server_to_client */ + buf_put_algolist(ses.writepayload, sshcompress); + + /* languages_client_to_server */ + buf_putstring(ses.writepayload, "", 0); + + /* languages_server_to_client */ + buf_putstring(ses.writepayload, "", 0); + + /* first_kex_packet_follows - unimplemented for now */ + buf_putbyte(ses.writepayload, 0x00); + + /* reserved unit32 */ + buf_putint(ses.writepayload, 0); + + /* set up transmitted kex packet buffer for hashing. + * This is freed after the end of the kex */ + ses.transkexinit = buf_newcopy(ses.writepayload); + + encrypt_packet(); + ses.dataallowed = 0; /* don't send other packets during kex */ + + TRACE(("DATAALLOWED=0")); + TRACE(("-> KEXINIT")); + ses.kexstate.sentkexinit = 1; +} + +/* *** NOTE regarding (send|recv)_msg_newkeys *** + * Changed by mihnea from the original kex.c to set dataallowed after a + * completed key exchange, no matter the order in which it was performed. + * This enables client mode without affecting server functionality. + */ + +/* Bring new keys into use after a key exchange, and let the client know*/ +void send_msg_newkeys() { + + TRACE(("enter send_msg_newkeys")); + + /* generate the kexinit request */ + CHECKCLEARTOWRITE(); + buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); + encrypt_packet(); + + + /* set up our state */ + if (ses.kexstate.recvnewkeys) { + TRACE(("while RECVNEWKEYS=1")); + gen_new_keys(); + kexinitialise(); /* we've finished with this kex */ + TRACE((" -> DATAALLOWED=1")); + ses.dataallowed = 1; /* we can send other packets again now */ + } else { + ses.kexstate.sentnewkeys = 1; + TRACE(("SENTNEWKEYS=1")); + } + + TRACE(("-> MSG_NEWKEYS")); + TRACE(("leave send_msg_newkeys")); +} + +/* Bring the new keys into use after a key exchange */ +void recv_msg_newkeys() { + + TRACE(("<- MSG_NEWKEYS")); + TRACE(("enter recv_msg_newkeys")); + + /* simply check if we've sent SSH_MSG_NEWKEYS, and if so, + * switch to the new keys */ + if (ses.kexstate.sentnewkeys) { + TRACE(("while SENTNEWKEYS=1")); + gen_new_keys(); + kexinitialise(); /* we've finished with this kex */ + TRACE((" -> DATAALLOWED=1")); + ses.dataallowed = 1; /* we can send other packets again now */ + } else { + TRACE(("RECVNEWKEYS=1")); + ses.kexstate.recvnewkeys = 1; + } + + TRACE(("leave recv_msg_newkeys")); +} + + +/* Duplicated verbatim from kex.c --mihnea */ +void kexinitialise() { + + struct timeval tv; + + TRACE(("kexinitialise()")); + + /* sent/recv'd MSG_KEXINIT */ + ses.kexstate.sentkexinit = 0; + ses.kexstate.recvkexinit = 0; + + /* sent/recv'd MSG_NEWKEYS */ + ses.kexstate.recvnewkeys = 0; + ses.kexstate.sentnewkeys = 0; + + /* first_packet_follows */ + /* TODO - currently not handled */ + ses.kexstate.firstfollows = 0; + + ses.kexstate.datatrans = 0; + ses.kexstate.datarecv = 0; + + if (gettimeofday(&tv, 0) < 0) { + dropbear_exit("Error getting time"); + } + ses.kexstate.lastkextime = tv.tv_sec; + +} + +/* Helper function for gen_new_keys, creates a hash. It makes a copy of the + * already initialised hash_state hs, which should already have processed + * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. + * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. + * The output will only be expanded once, since that is all that is required + * (for 3DES and SHA, with 24 and 20 bytes respectively). + * + * See Section 5.2 of the IETF secsh Transport Draft for details */ + +/* Duplicated verbatim from kex.c --mihnea */ +static void hashkeys(unsigned char *out, int outlen, + const hash_state * hs, const unsigned char X) { + + hash_state hs2; + unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */ + + memcpy(&hs2, hs, sizeof(hash_state)); + sha1_process(&hs2, &X, 1); + sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE); + sha1_done(&hs2, out); + if (SHA1_HASH_SIZE < outlen) { + /* need to extend */ + memcpy(&hs2, hs, sizeof(hash_state)); + sha1_process(&hs2, out, SHA1_HASH_SIZE); + sha1_done(&hs2, k2); + memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE); + } +} + +/* Generate the actual encryption/integrity keys, using the results of the + * key exchange, as specified in section 5.2 of the IETF secsh-transport + * draft. This occurs after the DH key-exchange. + * + * ses.newkeys is the new set of keys which are generated, these are only + * taken into use after both sides have sent a newkeys message */ + +/* Originally from kex.c, generalized for cli/svr mode --mihnea */ +static void gen_new_keys() { + + unsigned char C2S_IV[MAX_IV_LEN]; + unsigned char C2S_key[MAX_KEY_LEN]; + unsigned char S2C_IV[MAX_IV_LEN]; + unsigned char S2C_key[MAX_KEY_LEN]; + /* unsigned char key[MAX_KEY_LEN]; */ + unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; + + hash_state hs; + unsigned int C2S_keysize, S2C_keysize; + char mactransletter, macrecvletter; /* Client or server specific */ + + TRACE(("enter gen_new_keys")); + /* the dh_K and hash are the start of all hashes, we make use of that */ + + sha1_init(&hs); + sha1_process_mp(&hs, ses.dh_K); + mp_clear(ses.dh_K); + m_free(ses.dh_K); + sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); + m_burn(ses.hash, SHA1_HASH_SIZE); + + hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); + hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); + + if (IS_DROPBEAR_CLIENT) { + trans_IV = C2S_IV; + recv_IV = S2C_IV; + trans_key = C2S_key; + recv_key = S2C_key; + C2S_keysize = ses.newkeys->trans_algo_crypt->keysize; + S2C_keysize = ses.newkeys->recv_algo_crypt->keysize; + mactransletter = 'E'; + macrecvletter = 'F'; + } else { + trans_IV = S2C_IV; + recv_IV = C2S_IV; + trans_key = S2C_key; + recv_key = C2S_key; + C2S_keysize = ses.newkeys->recv_algo_crypt->keysize; + S2C_keysize = ses.newkeys->trans_algo_crypt->keysize; + mactransletter = 'F'; + macrecvletter = 'E'; + } + + hashkeys(C2S_key, C2S_keysize, &hs, 'C'); + hashkeys(S2C_key, S2C_keysize, &hs, 'D'); + + if (cbc_start( + find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name), + recv_IV, recv_key, + ses.newkeys->recv_algo_crypt->keysize, 0, + &ses.newkeys->recv_symmetric_struct) != CRYPT_OK) { + dropbear_exit("crypto error"); + } + + if (cbc_start( + find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name), + trans_IV, trans_key, + ses.newkeys->trans_algo_crypt->keysize, 0, + &ses.newkeys->trans_symmetric_struct) != CRYPT_OK) { + dropbear_exit("crypto error"); + } + + /* MAC keys */ + hashkeys(ses.newkeys->transmackey, + ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter); + hashkeys(ses.newkeys->recvmackey, + ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter); + +#ifndef DISABLE_ZLIB + gen_new_zstreams(); +#endif + + /* Switch over to the new keys */ + m_burn(ses.keys, sizeof(struct key_context)); + m_free(ses.keys); + ses.keys = ses.newkeys; + ses.newkeys = NULL; + + TRACE(("leave gen_new_keys")); +} + +#ifndef DISABLE_ZLIB +/* Set up new zlib compression streams, close the old ones. Only + * called from gen_new_keys() */ +static void gen_new_zstreams() { + + /* create new zstreams */ + if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) { + ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); + ses.newkeys->recv_zstream->zalloc = Z_NULL; + ses.newkeys->recv_zstream->zfree = Z_NULL; + + if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) { + dropbear_exit("zlib error"); + } + } else { + ses.newkeys->recv_zstream = NULL; + } + + if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) { + ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); + ses.newkeys->trans_zstream->zalloc = Z_NULL; + ses.newkeys->trans_zstream->zfree = Z_NULL; + + if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) + != Z_OK) { + dropbear_exit("zlib error"); + } + } else { + ses.newkeys->trans_zstream = NULL; + } + + /* clean up old keys */ + if (ses.keys->recv_zstream != NULL) { + if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { + /* Z_DATA_ERROR is ok, just means that stream isn't ended */ + dropbear_exit("crypto error"); + } + m_free(ses.keys->recv_zstream); + } + if (ses.keys->trans_zstream != NULL) { + if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) { + /* Z_DATA_ERROR is ok, just means that stream isn't ended */ + dropbear_exit("crypto error"); + } + m_free(ses.keys->trans_zstream); + } +} +#endif + + +/* Executed upon receiving a kexinit message from the client to initiate + * key exchange. If we haven't already done so, we send the list of our + * preferred algorithms. The client's requested algorithms are processed, + * and we calculate the first portion of the key-exchange-hash for used + * later in the key exchange. No response is sent, as the client should + * initiate the diffie-hellman key exchange */ + +/* Originally from kex.c, generalized for cli/svr mode --mihnea */ +/* Belongs in common_kex.c where it should be moved after review */ +void recv_msg_kexinit() { + + TRACE(("<- KEXINIT")); + TRACE(("enter recv_msg_kexinit")); + + /* start the kex hash */ + ses.kexhashbuf = buf_new(MAX_KEXHASHBUF); + + if (!ses.kexstate.sentkexinit) { + /* we need to send a kex packet */ + send_msg_kexinit(); + TRACE(("continue recv_msg_kexinit: sent kexinit")); + } + + + if (IS_DROPBEAR_CLIENT) { + + /* read the peer's choice of algos */ + cli_read_kex(); + + /* V_C, the client's version string (CR and NL excluded) */ + buf_putstring(ses.kexhashbuf, + (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); + /* V_S, the server's version string (CR and NL excluded) */ + buf_putstring(ses.kexhashbuf, + ses.remoteident, strlen((char*)ses.remoteident)); + + /* I_C, the payload of the client's SSH_MSG_KEXINIT */ + buf_putstring(ses.kexhashbuf, + buf_getptr(ses.transkexinit, ses.transkexinit->len), + ses.transkexinit->len); + /* I_S, the payload of the server's SSH_MSG_KEXINIT */ + buf_setpos(ses.payload, 0); + buf_putstring(ses.kexhashbuf, + buf_getptr(ses.payload, ses.payload->len), + ses.payload->len); + + } else { + + /* read the peer's choice of algos */ + svr_read_kex(); + /* V_C, the client's version string (CR and NL excluded) */ + buf_putstring(ses.kexhashbuf, + ses.remoteident, strlen((char*)ses.remoteident)); + /* V_S, the server's version string (CR and NL excluded) */ + buf_putstring(ses.kexhashbuf, + (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); + + /* I_C, the payload of the client's SSH_MSG_KEXINIT */ + buf_setpos(ses.payload, 0); + buf_putstring(ses.kexhashbuf, + buf_getptr(ses.payload, ses.payload->len), + ses.payload->len); + /* I_S, the payload of the server's SSH_MSG_KEXINIT */ + buf_putstring(ses.kexhashbuf, + buf_getptr(ses.transkexinit, ses.transkexinit->len), + ses.transkexinit->len); + } + + buf_free(ses.transkexinit); + ses.transkexinit = NULL; + /* the rest of ses.kexhashbuf will be done after DH exchange */ + + ses.kexstate.recvkexinit = 1; +// ses.expecting = SSH_MSG_KEXDH_INIT; + ses.expecting = 0; + + TRACE(("leave recv_msg_kexinit")); +} + -- cgit v1.2.3 From a9c38fb37f5fc8796435c2bcbcdecf35cf802ca6 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Mon, 26 Jul 2004 02:44:20 +0000 Subject: snapshot of stuff --HG-- extra : convert_revision : 2903853ba24669d01547710986ad531357602633 --- algo.h | 5 +- cli-algo.c | 9 +- cli-kex.c | 91 ++++++++++++++++++++ cli-main.c | 33 +++++++ cli-session.c | 101 ++++++++++++++++++++++ common-kex.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- common-session.c | 150 ++++++++++++++++++++++++-------- dbutil.c | 90 +++++++++++++++++++ dbutil.h | 5 ++ debug.h | 2 +- kex.h | 16 +++- main.c | 4 +- options.h | 5 +- process-packet.c | 2 + session.h | 23 ++++- signkey.c | 3 +- svr-algo.c | 4 +- svr-kex.c | 182 +-------------------------------------- svr-session.c | 82 ++---------------- tcpfwd-direct.c | 6 +- 20 files changed, 750 insertions(+), 321 deletions(-) create mode 100644 cli-kex.c create mode 100644 cli-main.c create mode 100644 cli-session.c (limited to 'common-kex.c') diff --git a/algo.h b/algo.h index 369f73c..3e8ebb5 100644 --- a/algo.h +++ b/algo.h @@ -66,10 +66,9 @@ void crypto_init(); int have_algo(char* algo, size_t algolen, algo_type algos[]); void buf_put_algolist(buffer * buf, algo_type localalgos[]); -algo_type * common_buf_match_algo(buffer* buf, algo_type localalgos[], - int *goodguess); algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[], int *goodguess); -algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]); +algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], + int *goodguess); #endif /* _ALGO_H_ */ diff --git a/cli-algo.c b/cli-algo.c index ba1ed85..5edd6a1 100644 --- a/cli-algo.c +++ b/cli-algo.c @@ -33,7 +33,8 @@ * direction MUST be the first algorithm on the client's list * that is also on the server's list. */ -algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]) { +algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], + int *goodguess) { unsigned char * algolist = NULL; unsigned char * remotealgos[MAX_PROPOSED_ALGO]; @@ -41,6 +42,8 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]) { unsigned int count, i, j; algo_type * ret = NULL; + *goodguess = 0; + /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ algolist = buf_getstring(buf, &len); TRACE(("cli_buf_match_algo: %s", algolist)); @@ -78,6 +81,10 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]) { if (len == strlen(remotealgos[i]) && strncmp(localalgos[j].name, remotealgos[i], len) == 0) { + if (i == 0 && j == 0) { + /* was a good guess */ + *goodguess = 1; + } ret = &localalgos[j]; goto out; } diff --git a/cli-kex.c b/cli-kex.c new file mode 100644 index 0000000..4d26332 --- /dev/null +++ b/cli-kex.c @@ -0,0 +1,91 @@ +/* + * Dropbear - a SSH2 server + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + +#include "includes.h" +#include "session.h" +#include "dbutil.h" +#include "algo.h" +#include "buffer.h" +#include "session.h" +#include "kex.h" +#include "ssh.h" +#include "packet.h" +#include "bignum.h" +#include "random.h" +#include "runopts.h" + + + +void send_msg_kexdh_init() { + + cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); + cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); + + m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x); + gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); + + CHECKCLEARTOWRITE(); + buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT); + buf_putmpint(ses.writepayload, cli_ses.dh_e); + encrypt_packet(); + ses.requirenext = SSH_MSG_KEXDH_REPLY; +} + +/* Handle a diffie-hellman key exchange reply. */ +void recv_msg_kexdh_reply() { + + mp_int dh_f; + sign_key *hostkey = NULL; + int type; + + type = ses.newkeys->algo_hostkey; + + hostkey = new_sign_key(); + if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { + dropbear_exit("Bad KEX packet"); + } + + m_mp_init(&dh_f); + if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { + dropbear_exit("Bad KEX packet"); + } + + kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey); + mp_clear(&dh_f); + + if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) + != DROPBEAR_SUCCESS) { + dropbear_exit("Bad hostkey signature"); + } + + /* XXX TODO */ + dropbear_log(LOG_WARNING,"Not checking hostkey fingerprint for the moment"); + + sign_key_free(hostkey); + hostkey = NULL; + + send_msg_newkeys(); + ses.requirenext = SSH_MSG_NEWKEYS; + TRACE(("leave recv_msg_kexdh_init")); +} diff --git a/cli-main.c b/cli-main.c new file mode 100644 index 0000000..2460060 --- /dev/null +++ b/cli-main.c @@ -0,0 +1,33 @@ +#include + +int main(int argc, char ** argv) { + + int sock; + char* error = NULL; + char* hostandport; + int len; + + _dropbear_exit = cli_dropbear_exit; + _dropbear_log = cli_dropbear_log; + + cli_getopts(argc, argv); + + sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport, + 0, &error); + + if (sock < 0) { + dropbear_exit("%s", error); + } + + /* Set up the host:port log */ + len = strlen(cli_opts.remotehost); + len += 10; /* 16 bit port and leeway*/ + hostandport = (char*)m_malloc(len); + snprintf(hostandport, len, "%s%d", + cli_opts.remotehost, cli_opts.remoteport); + + cli_session(sock, hostandport); + + /* not reached */ + return -1; +} diff --git a/cli-session.c b/cli-session.c new file mode 100644 index 0000000..d5afaf9 --- /dev/null +++ b/cli-session.c @@ -0,0 +1,101 @@ +#include "includes.h" +#include "session.h" +#include "dbutil.h" +#include "kex.h" +#include "ssh.h" +#include "packet.h" +#include "tcpfwd-direct.h" +#include "tcpfwd-remote.h" +#include "channel.h" +#include "random.h" + +static void cli_remoteclosed(); +static void cli_sessionloop(); + +struct clientsession cli_ses; /* GLOBAL */ + +static const packettype cli_packettypes[] = { + /* TYPE, AUTHREQUIRED, FUNCTION */ + {SSH_MSG_KEXINIT, recv_msg_kexinit}, + {SSH_MSG_KEXDH_REPLY, recv_msg_kexdh_reply}, // client + {SSH_MSG_NEWKEYS, recv_msg_newkeys}, + {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, + {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, + {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp}, + {SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request}, + {SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open}, + {SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof}, + {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close}, + {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, + {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, + {0, 0} /* End */ +}; + +static const struct ChanType *cli_chantypes[] = { +// &clichansess, + /* &chan_tcpdirect etc, though need to only allow if we've requested + * that forwarding */ + NULL /* Null termination */ +}; +void cli_session(int sock, char* remotehost) { + + crypto_init(); + common_session_init(sock, remotehost); + + chaninitialise(cli_chantypes); + + /* For printing "remote host closed" for the user */ + session_remoteclosed = cli_remoteclosed; + + /* packet handlers */ + ses.packettypes = cli_packettypes; + + /* Ready to go */ + sessinitdone = 1; + + /* Exchange identification */ + session_identification(); + + seedrandom(); + + send_msg_kexinit(); + + /* XXX here we do stuff differently */ + + session_loop(cli_sessionloop); + + /* Not reached */ + + +} + +static void cli_sessionloop() { + + switch (cli_ses.state) { + + KEXINIT_RCVD: + /* We initiate the KEX. If DH wasn't the correct type, the KEXINIT + * negotiation would have failed. */ + send_msg_kexdh_init(); + cli_ses.state = KEXDH_INIT_SENT; + break; + + default: + break; + } + + if (cli_ses.donefirstkex && !cli_ses.authdone) { + + + +} + +/* called when the remote side closes the connection */ +static void cli_remoteclosed() { + + /* XXX TODO perhaps print a friendlier message if we get this but have + * already sent/received disconnect message(s) ??? */ + close(ses.sock); + ses.sock = -1; + dropbear_exit("%s closed the connection", ses.remotehost); +} diff --git a/common-kex.c b/common-kex.c index e1ae91a..21accb6 100644 --- a/common-kex.c +++ b/common-kex.c @@ -193,7 +193,6 @@ void kexinitialise() { ses.kexstate.sentnewkeys = 0; /* first_packet_follows */ - /* TODO - currently not handled */ ses.kexstate.firstfollows = 0; ses.kexstate.datatrans = 0; @@ -402,47 +401,54 @@ void recv_msg_kexinit() { if (IS_DROPBEAR_CLIENT) { +#ifdef DROPBEAR_CLIENT - /* read the peer's choice of algos */ - cli_read_kex(); + /* read the peer's choice of algos */ + read_kex_algos(cli_buf_match_algo); - /* V_C, the client's version string (CR and NL excluded) */ + /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); - /* V_S, the server's version string (CR and NL excluded) */ + /* V_S, the server's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, ses.remoteident, strlen((char*)ses.remoteident)); - /* I_C, the payload of the client's SSH_MSG_KEXINIT */ + /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_putstring(ses.kexhashbuf, buf_getptr(ses.transkexinit, ses.transkexinit->len), ses.transkexinit->len); - /* I_S, the payload of the server's SSH_MSG_KEXINIT */ + /* I_S, the payload of the server's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, 0); buf_putstring(ses.kexhashbuf, buf_getptr(ses.payload, ses.payload->len), ses.payload->len); + cli_ses.state = KEXINIT_RCVD; +#endif } else { + /* SERVER */ +#ifdef DROPBEAR_SERVER - /* read the peer's choice of algos */ - svr_read_kex(); - /* V_C, the client's version string (CR and NL excluded) */ + /* read the peer's choice of algos */ + read_kex_algos(svr_buf_match_algo); + /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, ses.remoteident, strlen((char*)ses.remoteident)); - /* V_S, the server's version string (CR and NL excluded) */ + /* V_S, the server's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); - /* I_C, the payload of the client's SSH_MSG_KEXINIT */ + /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, 0); buf_putstring(ses.kexhashbuf, buf_getptr(ses.payload, ses.payload->len), ses.payload->len); - /* I_S, the payload of the server's SSH_MSG_KEXINIT */ + /* I_S, the payload of the server's SSH_MSG_KEXINIT */ buf_putstring(ses.kexhashbuf, buf_getptr(ses.transkexinit, ses.transkexinit->len), ses.transkexinit->len); + ses.requirenext = SSH_MSG_KEXDH_INIT; +#endif } buf_free(ses.transkexinit); @@ -450,9 +456,233 @@ void recv_msg_kexinit() { /* the rest of ses.kexhashbuf will be done after DH exchange */ ses.kexstate.recvkexinit = 1; - ses.requirenext = SSH_MSG_KEXDH_INIT; // ses.expecting = 0; // client matt TRACE(("leave recv_msg_kexinit")); } +/* Initialises and generate one side of the diffie-hellman key exchange values. + * See the ietf-secsh-transport draft, section 6, for details */ +void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { + + mp_int dh_p, dh_q, dh_g; + unsigned char randbuf[DH_P_LEN]; + int dh_q_len; + + TRACE(("enter send_msg_kexdh_reply")); + + m_mp_init_multi(&dh_g, &dh_p, &dh_q, dh_priv, dh_pub, NULL); + + /* read the prime and generator*/ + if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) + != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + + if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + + /* calculate q = (p-1)/2 */ + /* dh_priv is just a temp var here */ + if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + + dh_q_len = mp_unsigned_bin_size(&dh_q); + + /* calculate our random value dh_y */ + do { + assert((unsigned int)dh_q_len <= sizeof(randbuf)); + genrandom(randbuf, dh_q_len); + if (mp_read_unsigned_bin(dh_priv, randbuf, dh_q_len) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + } while (mp_cmp(dh_priv, &dh_q) == MP_GT || mp_cmp_d(dh_priv, 0) != MP_GT); + + /* f = g^y mod p */ + if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); +} + +/* This function is fairly common between client/server, with some substitution + * of dh_e/dh_f etc. Hence these arguments: + * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is + * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ +void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, + sign_key *hostkey) { + + mp_int dh_p; + mp_int *dh_e = NULL, *dh_f = NULL; + hash_state hs; + + /* read the prime and generator*/ + mp_init(&dh_p); + if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) + != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + + /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ + if (mp_cmp(dh_pub_them, &dh_p) != MP_LT + || mp_cmp_d(dh_pub_them, 0) != MP_GT) { + dropbear_exit("Diffie-Hellman error"); + } + + /* K = e^y mod p = f^x mod p */ + ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); + m_mp_init(ses.dh_K); + if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) { + dropbear_exit("Diffie-Hellman error"); + } + + /* clear no longer needed vars */ + mp_clear_multi(&dh_p, NULL); + + /* From here on, the code needs to work with the _same_ vars on each side, + * not vice-versaing for client/server */ + if (IS_DROPBEAR_CLIENT) { + dh_e = dh_pub_us; + dh_f = dh_pub_them; + } else { + dh_e = dh_pub_them; + dh_f = dh_pub_us; + } + + /* Create the remainder of the hash buffer, to generate the exchange hash */ + /* K_S, the host key */ + buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); + /* e, exchange value sent by the client */ + buf_putmpint(ses.kexhashbuf, dh_e); + /* f, exchange value sent by the server */ + buf_putmpint(ses.kexhashbuf, dh_f); + /* K, the shared secret */ + buf_putmpint(ses.kexhashbuf, ses.dh_K); + + /* calculate the hash H to sign */ + sha1_init(&hs); + buf_setpos(ses.kexhashbuf, 0); + sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), + ses.kexhashbuf->len); + sha1_done(&hs, ses.hash); + buf_free(ses.kexhashbuf); + ses.kexhashbuf = NULL; + + /* first time around, we set the session_id to H */ + if (ses.session_id == NULL) { + /* create the session_id, this never needs freeing */ + ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); + memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); + } +} + +/* read the other side's algo list. buf_match_algo is a callback to match + * algos for the client or server. */ +void read_kex_algos( + algo_type*(buf_match_algo)(buffer*buf, algo_type localalgos[], + int *goodguess)) { + + algo_type * algo; + char * erralgo = NULL; + + int goodguess = 0; + int allgood = 1; /* we AND this with each goodguess and see if its still + true after */ + + buf_incrpos(ses.payload, 16); /* start after the cookie */ + + ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); + + /* kex_algorithms */ + algo = buf_match_algo(ses.payload, sshkex, &goodguess); + allgood &= goodguess; + if (algo == NULL) { + erralgo = "kex"; + goto error; + } + ses.newkeys->algo_kex = algo->val; + + /* server_host_key_algorithms */ + algo = buf_match_algo(ses.payload, sshhostkey, &goodguess); + allgood &= goodguess; + if (algo == NULL) { + erralgo = "hostkey"; + goto error; + } + ses.newkeys->algo_hostkey = algo->val; + + /* encryption_algorithms_client_to_server */ + algo = buf_match_algo(ses.payload, sshciphers, &goodguess); + if (algo == NULL) { + erralgo = "enc c->s"; + goto error; + } + ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; + + /* encryption_algorithms_server_to_client */ + algo = buf_match_algo(ses.payload, sshciphers, &goodguess); + if (algo == NULL) { + erralgo = "enc s->c"; + goto error; + } + ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; + + /* mac_algorithms_client_to_server */ + algo = buf_match_algo(ses.payload, sshhashes, &goodguess); + if (algo == NULL) { + erralgo = "mac c->s"; + goto error; + } + ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; + + /* mac_algorithms_server_to_client */ + algo = buf_match_algo(ses.payload, sshhashes, &goodguess); + if (algo == NULL) { + erralgo = "mac s->c"; + goto error; + } + ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; + + /* compression_algorithms_client_to_server */ + algo = buf_match_algo(ses.payload, sshcompress, &goodguess); + if (algo == NULL) { + erralgo = "comp c->s"; + goto error; + } + ses.newkeys->recv_algo_comp = algo->val; + + /* compression_algorithms_server_to_client */ + algo = buf_match_algo(ses.payload, sshcompress, &goodguess); + if (algo == NULL) { + erralgo = "comp s->c"; + goto error; + } + ses.newkeys->trans_algo_comp = algo->val; + + /* languages_client_to_server */ + buf_eatstring(ses.payload); + + /* languages_server_to_client */ + buf_eatstring(ses.payload); + + /* first_kex_packet_follows */ + if (buf_getbyte(ses.payload)) { + ses.kexstate.firstfollows = 1; + /* if the guess wasn't good, we ignore the packet sent */ + if (!allgood) { + ses.ignorenext = 1; + } + } + + /* reserved for future extensions */ + buf_getint(ses.payload); + return; + +error: + dropbear_exit("no matching algo %s", erralgo); +} diff --git a/common-session.c b/common-session.c index 6e37e29..70ddbfe 100644 --- a/common-session.c +++ b/common-session.c @@ -35,6 +35,7 @@ #include "channel.h" #include "atomicio.h" + struct sshsession ses; /* GLOBAL */ /* need to know if the session struct has been initialised, this way isn't the @@ -44,19 +45,18 @@ int sessinitdone = 0; /* GLOBAL */ /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */ int exitflag = 0; /* GLOBAL */ -static int ident_readln(int fd, char* buf, int count); - - void(*session_remoteclosed)() = NULL; +static void checktimeouts(); +static int ident_readln(int fd, char* buf, int count); + /* called only at the start of a session, set up initial state */ -void common_session_init(int sock) { +void common_session_init(int sock, char* remotehost) { TRACE(("enter session_init")); - ses.remoteaddr = NULL; - ses.remotehost = NULL; + ses.remotehost = remotehost; ses.sock = sock; ses.maxfd = sock; @@ -114,6 +114,86 @@ void common_session_init(int sock) { TRACE(("leave session_init")); } +void session_loop(void(*loophandler)()) { + + fd_set readfd, writefd; + struct timeval timeout; + int val; + + /* main loop, select()s for all sockets in use */ + for(;;) { + + timeout.tv_sec = SELECT_TIMEOUT; + timeout.tv_usec = 0; + FD_ZERO(&writefd); + FD_ZERO(&readfd); + assert(ses.payload == NULL); + if (ses.sock != -1) { + FD_SET(ses.sock, &readfd); + if (!isempty(&ses.writequeue)) { + FD_SET(ses.sock, &writefd); + } + } + + /* set up for channels which require reading/writing */ + if (ses.dataallowed) { + setchannelfds(&readfd, &writefd); + } + val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); + + if (exitflag) { + dropbear_exit("Terminated by signal"); + } + + if (val < 0) { + if (errno == EINTR) { + continue; + } else { + dropbear_exit("Error in select"); + } + } + + /* check for auth timeout, rekeying required etc */ + checktimeouts(); + + if (val == 0) { + /* timeout */ + TRACE(("select timeout")); + continue; + } + + /* process session socket's incoming/outgoing data */ + if (ses.sock != -1) { + if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { + write_packet(); + } + + if (FD_ISSET(ses.sock, &readfd)) { + read_packet(); + } + + /* Process the decrypted packet. After this, the read buffer + * will be ready for a new packet */ + if (ses.payload != NULL) { + process_packet(); + } + } + + /* process pipes etc for the channels, ses.dataallowed == 0 + * during rekeying ) */ + if (ses.dataallowed) { + channelio(&readfd, &writefd); + } + + if (loophandler) { + loophandler(); + } + + } /* for(;;) */ + + /* Not reached */ +} + /* clean up a session on exit */ void common_session_cleanup() { @@ -134,35 +214,7 @@ void common_session_cleanup() { TRACE(("leave session_cleanup")); } -/* Check all timeouts which are required. Currently these are the time for - * user authentication, and the automatic rekeying. */ -void checktimeouts() { - - struct timeval tv; - long secs; - - if (gettimeofday(&tv, 0) < 0) { - dropbear_exit("Error getting time"); - } - - secs = tv.tv_sec; - - if (ses.connecttimeout != 0 && secs > ses.connecttimeout) { - dropbear_close("Timeout before auth"); - } - - /* we can't rekey if we haven't done remote ident exchange yet */ - if (ses.remoteident == NULL) { - return; - } - if (!ses.kexstate.sentkexinit - && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT - || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){ - TRACE(("rekeying after timeout or max data reached")); - send_msg_kexinit(); - } -} void session_identification() { /* max length of 255 chars */ @@ -268,3 +320,33 @@ static int ident_readln(int fd, char* buf, int count) { return pos+1; } +/* Check all timeouts which are required. Currently these are the time for + * user authentication, and the automatic rekeying. */ +static void checktimeouts() { + + struct timeval tv; + long secs; + + if (gettimeofday(&tv, 0) < 0) { + dropbear_exit("Error getting time"); + } + + secs = tv.tv_sec; + + if (ses.connecttimeout != 0 && secs > ses.connecttimeout) { + dropbear_close("Timeout before auth"); + } + + /* we can't rekey if we haven't done remote ident exchange yet */ + if (ses.remoteident == NULL) { + return; + } + + if (!ses.kexstate.sentkexinit + && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT + || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){ + TRACE(("rekeying after timeout or max data reached")); + send_msg_kexinit(); + } +} + diff --git a/dbutil.c b/dbutil.c index 2494f38..1c0648c 100644 --- a/dbutil.c +++ b/dbutil.c @@ -113,6 +113,95 @@ void dropbear_trace(const char* format, ...) { } #endif /* DEBUG_TRACE */ +/* Connect via TCP to a host. Connection will try ipv4 or ipv6, will + * return immediately if nonblocking is set */ +int connect_remote(const char* remotehost, const char* remoteport, + int nonblocking, char ** errstring) { + + struct addrinfo *res0 = NULL, *res = NULL, hints; + int sock; + int err; + + TRACE(("enter connect_remote")); + + if (errstring != NULL) { + *errstring = NULL; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = PF_UNSPEC; + + err = getaddrinfo(remotehost, remoteport, &hints, &res0); + if (err) { + if (errstring != NULL && *errstring == NULL) { + int len; + len = 20 + strlen(gai_strerror(err)); + *errstring = (char*)m_malloc(len); + snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); + } + TRACE(("Error resolving: %s", gai_strerror(err))); + return -1; + } + + sock = -1; + err = EADDRNOTAVAIL; + for (res = res0; res; res = res->ai_next) { + + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sock < 0) { + err = errno; + continue; + } + + if (nonblocking) { + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { + close(sock); + sock = -1; + if (errstring != NULL && *errstring == NULL) { + *errstring = m_strdup("Failed non-blocking"); + } + TRACE(("Failed non-blocking: %s", strerror(errno))); + continue; + } + } + + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { + if (errno == EINPROGRESS) { + TRACE(("Connect in progress")); + break; + } else { + err = errno; + close(sock); + sock = -1; + continue; + } + } + + break; /* Success */ + } + + if (sock < 0) { + /* Failed */ + if (errstring != NULL && *errstring == NULL) { + int len; + len = 20 + strlen(strerror(err)); + *errstring = (char*)m_malloc(len); + snprintf(*errstring, len, "Error connecting: %s", strerror(err)); + } + TRACE(("Error connecting: %s", strerror(err))); + } else { + /* Success */ + /* (err is used as a dummy var here) */ + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err)); + } + + freeaddrinfo(res0); + + TRACE(("leave connect_remote: sock %d", sock)); + return sock; +} + /* Return a string representation of the socket address passed. The return * value is allocated with malloc() */ unsigned char * getaddrstring(struct sockaddr * addr) { @@ -304,3 +393,4 @@ void m_burn(void *data, unsigned int len) { *p++ = 0x66; } } + diff --git a/dbutil.h b/dbutil.h index 3da6b2f..49b7466 100644 --- a/dbutil.h +++ b/dbutil.h @@ -45,6 +45,8 @@ void printhex(unsigned char* buf, int len); #endif char * stripcontrol(const char * text); unsigned char * getaddrstring(struct sockaddr * addr); +int connect_remote(const char* remotehost, const char* remoteport, + int nonblocking, char ** errstring); char* getaddrhostname(struct sockaddr * addr); int buf_readfile(buffer* buf, const char* filename); @@ -56,4 +58,7 @@ void * m_realloc(void* ptr, size_t size); void __m_free(void* ptr); void m_burn(void* data, unsigned int len); +/* Used to force mp_ints to be initialised */ +#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL} + #endif /* _DBUTIL_H_ */ diff --git a/debug.h b/debug.h index d619a58..736690a 100644 --- a/debug.h +++ b/debug.h @@ -36,7 +36,7 @@ /* Define this to print trace statements - very verbose */ /* Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing does not sanitise strings etc */ -#define DEBUG_TRACE +//#define DEBUG_TRACE /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're diff --git a/kex.h b/kex.h index 61b022e..e6c8ac1 100644 --- a/kex.h +++ b/kex.h @@ -26,17 +26,25 @@ #define _KEX_H_ #include "includes.h" +#include "algo.h" void send_msg_kexinit(); void recv_msg_kexinit(); -void send_dh_kex(); -void recv_msg_kexdh_init(); void send_msg_newkeys(); void recv_msg_newkeys(); void kexinitialise(); +void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv); +void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, + sign_key *hostkey); -void svr_read_kex(); -void cli_read_kex(); +void read_kex_algos( + algo_type*(buf_match_algo)(buffer*buf, algo_type localalgos[], + int *goodguess)); + +void recv_msg_kexdh_init(); // server + +void send_msg_kexdh_init(); // client +void recv_msg_kexdh_reply(); // client extern const unsigned char dh_p_val[]; #define DH_P_LEN 128 /* The length of the dh_p_val array */ diff --git a/main.c b/main.c index b9ff7aa..0ef1e62 100644 --- a/main.c +++ b/main.c @@ -240,8 +240,10 @@ int main(int argc, char ** argv) if (m_close(childpipe[0]) == DROPBEAR_FAILURE) { dropbear_exit("Couldn't close socket"); } + /* start the session */ - svr_session(childsock, childpipe[1], &remoteaddr); + svr_session(childsock, childpipe[1], + getaddrhostname(&remoteaddr)); /* don't return */ assert(0); } diff --git a/options.h b/options.h index c6b552a..3aeac0f 100644 --- a/options.h +++ b/options.h @@ -30,7 +30,7 @@ * parts are to allow for commandline -DDROPBEAR_XXX options etc. ******************************************************************/ #define DROPBEAR_SERVER -/* #define DROPBEAR_CLIENT */ +//#define DROPBEAR_CLIENT #ifndef DROPBEAR_PORT #define DROPBEAR_PORT 22 @@ -48,6 +48,7 @@ * perhaps 20% slower for pubkey operations (it is probably worth experimenting * if you want to use this) */ /*#define NO_FAST_EXPTMOD*/ +#define DROPBEAR_SMALL_CODE /* Enable X11 Forwarding */ #define ENABLE_X11FWD @@ -181,7 +182,7 @@ *******************************************************************/ #ifndef DROPBEAR_VERSION -#define DROPBEAR_VERSION "0.41" +#define DROPBEAR_VERSION "0.41-and-client" #endif #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION diff --git a/process-packet.c b/process-packet.c index 7b73cb7..afa45ef 100644 --- a/process-packet.c +++ b/process-packet.c @@ -104,9 +104,11 @@ void process_packet() { */ /* check that we aren't expecting a particular packet */ +#if 0 if (cli_ses.expecting && cli_ses.expecting == type) { cli_ses.expecting = 0; } +#endif } #endif diff --git a/session.h b/session.h index cc8340d..d929c1c 100644 --- a/session.h +++ b/session.h @@ -26,6 +26,7 @@ #define _SESSION_H_ #include "includes.h" +#include "options.h" #include "buffer.h" #include "signkey.h" #include "kex.h" @@ -38,7 +39,8 @@ extern int sessinitdone; /* Is set to 0 somewhere */ extern int exitflag; -void common_session_init(int sock); +void common_session_init(int sock, char* remotehost); +void session_loop(void(*loophandler)()); void common_session_cleanup(); void checktimeouts(); void session_identification(); @@ -46,10 +48,14 @@ void session_identification(); extern void(*session_remoteclosed)(); /* Server */ -void svr_session(int sock, int childpipe, struct sockaddr *remoteaddr); +void svr_session(int sock, int childpipe, char *remotehost); void svr_dropbear_exit(int exitcode, const char* format, va_list param); void svr_dropbear_log(int priority, const char* format, va_list param); +/* Client */ +void cli_session(int sock, char *remotehost); +void cli_dropbear_exit(int exitcode, const char* format, va_list param); +void cli_dropbear_log(int priority, const char* format, va_list param); struct key_context { @@ -85,8 +91,8 @@ struct sshsession { int sock; - struct sockaddr *remoteaddr; unsigned char *remotehost; /* the peer hostname */ + unsigned char *remoteident; int maxfd; /* the maximum file descriptor to check with select() */ @@ -166,11 +172,20 @@ struct serversession { }; +typedef enum { + NOTHING, + KEXINIT_RCVD, + KEXDH_INIT_SENT, + KEXDH_REPLY_RCVD, +} cli_state; struct clientsession { + mp_int *dh_e, *dh_x; /* Used during KEX */ + cli_state state; /* Used to progress the KEX/auth/channelsession etc */ int something; /* XXX */ + unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */ }; @@ -182,7 +197,7 @@ extern struct serversession svr_ses; #endif /* DROPBEAR_SERVER */ #ifdef DROPBEAR_CLIENT -extern struct serversession cli_ses; +extern struct clientsession cli_ses; #endif /* DROPBEAR_CLIENT */ #endif /* _SESSION_H_ */ diff --git a/signkey.c b/signkey.c index c529c8c..5fcdbbf 100644 --- a/signkey.c +++ b/signkey.c @@ -45,7 +45,8 @@ sign_key * new_sign_key() { } /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail. - * type is set to hold the type returned */ + * type should be set by the caller to specify the type to read, and + * on return is set to the type read (useful when type = _ANY) */ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { unsigned char* ident; diff --git a/svr-algo.c b/svr-algo.c index 33b9471..dc6565a 100644 --- a/svr-algo.c +++ b/svr-algo.c @@ -16,6 +16,8 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[], unsigned int count, i, j; algo_type * ret = NULL; + *goodguess = 0; + /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ algolist = buf_getstring(buf, &len); /* Debug this */ @@ -57,8 +59,6 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[], /* set if it was a good guess */ if (i == 0 && j == 0) { *goodguess = 1; - } else { - *goodguess = 0; } /* set the algo to return */ ret = &localalgos[j]; diff --git a/svr-kex.c b/svr-kex.c index 4dfa6a7..35b50a6 100644 --- a/svr-kex.c +++ b/svr-kex.c @@ -70,87 +70,15 @@ void recv_msg_kexdh_init() { * See the ietf-secsh-transport draft, section 6, for details */ static void send_msg_kexdh_reply(mp_int *dh_e) { - mp_int dh_p, dh_q, dh_g, dh_y, dh_f; - unsigned char randbuf[DH_P_LEN]; - int dh_q_len; - hash_state hs; + mp_int dh_y, dh_f; TRACE(("enter send_msg_kexdh_reply")); - m_mp_init_multi(&dh_g, &dh_p, &dh_q, &dh_y, &dh_f, NULL); + gen_kexdh_vals(&dh_f, &dh_y); - /* read the prime and generator*/ - if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) - != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - - if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - - /* calculate q = (p-1)/2 */ - if (mp_sub_d(&dh_p, 1, &dh_y) != MP_OKAY) { /*dh_y is just a temp var here*/ - dropbear_exit("Diffie-Hellman error"); - } - if (mp_div_2(&dh_y, &dh_q) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - - dh_q_len = mp_unsigned_bin_size(&dh_q); - - /* calculate our random value dh_y */ - do { - assert((unsigned int)dh_q_len <= sizeof(randbuf)); - genrandom(randbuf, dh_q_len); - if (mp_read_unsigned_bin(&dh_y, randbuf, dh_q_len) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - } while (mp_cmp(&dh_y, &dh_q) == MP_GT || mp_cmp_d(&dh_y, 0) != MP_GT); - - /* f = g^y mod p */ - if (mp_exptmod(&dh_g, &dh_y, &dh_p, &dh_f) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - mp_clear(&dh_g); - - /* K = e^y mod p */ - ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init(ses.dh_K); - if (mp_exptmod(dh_e, &dh_y, &dh_p, ses.dh_K) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } + kexdh_comb_key(&dh_f, &dh_y, dh_e, svr_opts.hostkey); + mp_clear(&dh_y); - /* clear no longer needed vars */ - mp_clear_multi(&dh_y, &dh_p, &dh_q, NULL); - - /* Create the remainder of the hash buffer, to generate the exchange hash */ - /* K_S, the host key */ - buf_put_pub_key(ses.kexhashbuf, svr_opts.hostkey, - ses.newkeys->algo_hostkey); - /* e, exchange value sent by the client */ - buf_putmpint(ses.kexhashbuf, dh_e); - /* f, exchange value sent by the server */ - buf_putmpint(ses.kexhashbuf, &dh_f); - /* K, the shared secret */ - buf_putmpint(ses.kexhashbuf, ses.dh_K); - - /* calculate the hash H to sign */ - sha1_init(&hs); - buf_setpos(ses.kexhashbuf, 0); - sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), - ses.kexhashbuf->len); - sha1_done(&hs, ses.hash); - buf_free(ses.kexhashbuf); - ses.kexhashbuf = NULL; - - /* first time around, we set the session_id to H */ - if (ses.session_id == NULL) { - /* create the session_id, this never needs freeing */ - ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); - memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); - } - /* we can start creating the kexdh_reply packet */ CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY); @@ -171,105 +99,3 @@ static void send_msg_kexdh_reply(mp_int *dh_e) { TRACE(("leave send_msg_kexdh_reply")); } -/* read the client's choice of algorithms */ -void svr_read_kex() { - - algo_type * algo; - char * erralgo = NULL; - - int goodguess = 0; - int allgood = 1; /* we AND this with each goodguess and see if its still - true after */ - - buf_incrpos(ses.payload, 16); /* start after the cookie */ - - ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); - - /* kex_algorithms */ - algo = svr_buf_match_algo(ses.payload, sshkex, &goodguess); - allgood &= goodguess; - if (algo == NULL) { - erralgo = "kex"; - goto error; - } - ses.newkeys->algo_kex = algo->val; - - /* server_host_key_algorithms */ - algo = svr_buf_match_algo(ses.payload, sshhostkey, &goodguess); - allgood &= goodguess; - if (algo == NULL) { - erralgo = "hostkey"; - goto error; - } - ses.newkeys->algo_hostkey = algo->val; - - /* encryption_algorithms_client_to_server */ - algo = svr_buf_match_algo(ses.payload, sshciphers, &goodguess); - if (algo == NULL) { - erralgo = "enc c->s"; - goto error; - } - ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; - - /* encryption_algorithms_server_to_client */ - algo = svr_buf_match_algo(ses.payload, sshciphers, &goodguess); - if (algo == NULL) { - erralgo = "enc s->c"; - goto error; - } - ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; - - /* mac_algorithms_client_to_server */ - algo = svr_buf_match_algo(ses.payload, sshhashes, &goodguess); - if (algo == NULL) { - erralgo = "mac c->s"; - goto error; - } - ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; - - /* mac_algorithms_server_to_client */ - algo = svr_buf_match_algo(ses.payload, sshhashes, &goodguess); - if (algo == NULL) { - erralgo = "mac s->c"; - goto error; - } - ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; - - /* compression_algorithms_client_to_server */ - algo = svr_buf_match_algo(ses.payload, sshcompress, &goodguess); - if (algo == NULL) { - erralgo = "comp c->s"; - goto error; - } - ses.newkeys->recv_algo_comp = algo->val; - - /* compression_algorithms_server_to_client */ - algo = svr_buf_match_algo(ses.payload, sshcompress, &goodguess); - if (algo == NULL) { - erralgo = "comp s->c"; - goto error; - } - ses.newkeys->trans_algo_comp = algo->val; - - /* languages_client_to_server */ - buf_eatstring(ses.payload); - - /* languages_server_to_client */ - buf_eatstring(ses.payload); - - /* first_kex_packet_follows */ - if (buf_getbyte(ses.payload)) { - ses.kexstate.firstfollows = 1; - /* if the guess wasn't good, we ignore the packet sent */ - if (!allgood) { - ses.ignorenext = 1; - } - } - - /* reserved for future extensions */ - buf_getint(ses.payload); - return; - -error: - dropbear_exit("no matching algo %s", erralgo); -} diff --git a/svr-session.c b/svr-session.c index 927a1c1..cb309fe 100644 --- a/svr-session.c +++ b/svr-session.c @@ -50,7 +50,7 @@ static const packettype svr_packettypes[] = { {SSH_MSG_SERVICE_REQUEST, recv_msg_service_request}, // server {SSH_MSG_USERAUTH_REQUEST, recv_msg_userauth_request}, //server {SSH_MSG_KEXINIT, recv_msg_kexinit}, - {SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init}, + {SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init}, // server {SSH_MSG_NEWKEYS, recv_msg_newkeys}, {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, @@ -70,17 +70,12 @@ static const struct ChanType *svr_chantypes[] = { NULL /* Null termination is mandatory. */ }; -void svr_session(int sock, int childpipe, struct sockaddr* remoteaddr) { +void svr_session(int sock, int childpipe, char* remotehost) { - fd_set readfd, writefd; struct timeval timeout; - int val; crypto_init(); - common_session_init(sock); - - ses.remoteaddr = remoteaddr; - ses.remotehost = getaddrhostname(remoteaddr); + common_session_init(sock, remotehost); /* Initialise server specific parts of the session */ svr_ses.childpipe = childpipe; @@ -111,75 +106,12 @@ void svr_session(int sock, int childpipe, struct sockaddr* remoteaddr) { /* start off with key exchange */ send_msg_kexinit(); - FD_ZERO(&readfd); - FD_ZERO(&writefd); - - /* main loop, select()s for all sockets in use */ - for(;;) { - - timeout.tv_sec = SELECT_TIMEOUT; - timeout.tv_usec = 0; - FD_ZERO(&writefd); - FD_ZERO(&readfd); - assert(ses.payload == NULL); - if (ses.sock != -1) { - FD_SET(ses.sock, &readfd); - if (!isempty(&ses.writequeue)) { - FD_SET(ses.sock, &writefd); - } - } - - /* set up for channels which require reading/writing */ - if (ses.dataallowed) { - setchannelfds(&readfd, &writefd); - } - val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); - - if (exitflag) { - dropbear_exit("Terminated by signal"); - } - - if (val < 0) { - if (errno == EINTR) { - continue; - } else { - dropbear_exit("Error in select"); - } - } - - /* check for auth timeout, rekeying required etc */ - checktimeouts(); - - if (val == 0) { - /* timeout */ - TRACE(("select timeout")); - continue; - } - - /* process session socket's incoming/outgoing data */ - if (ses.sock != -1) { - if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { - write_packet(); - } - - if (FD_ISSET(ses.sock, &readfd)) { - read_packet(); - } - - /* Process the decrypted packet. After this, the read buffer - * will be ready for a new packet */ - if (ses.payload != NULL) { - process_packet(); - } - } + /* Run the main for loop. NULL is for the dispatcher - only the client + * code makes use of it */ + session_loop(NULL); - /* process pipes etc for the channels, ses.dataallowed == 0 - * during rekeying ) */ - if (ses.dataallowed) { - channelio(&readfd, &writefd); - } + /* Not reached */ - } /* for(;;) */ } /* failure exit - format must be <= 100 chars */ diff --git a/tcpfwd-direct.c b/tcpfwd-direct.c index b6a2178..b611283 100644 --- a/tcpfwd-direct.c +++ b/tcpfwd-direct.c @@ -27,6 +27,7 @@ static int newtcpdirect(struct Channel * channel) { unsigned int destport; unsigned char* orighost = NULL; unsigned int origport; + char portstring[6]; int sock; int len; int ret = DROPBEAR_FAILURE; @@ -58,7 +59,8 @@ static int newtcpdirect(struct Channel * channel) { goto out; } - sock = newtcp(desthost, destport); + snprintf(portstring, sizeof(portstring), "%d", destport); + sock = connect_remote(desthost, portstring, 1, NULL); if (sock < 0) { TRACE(("leave newtcpdirect: sock failed")); goto out; @@ -86,6 +88,7 @@ out: * returned will need to be checked for success when it is first written. * Similarities with OpenSSH's connect_to() are not coincidental. * Returns -1 on failure */ +#if 0 static int newtcp(const char * host, int port) { int sock = -1; @@ -152,4 +155,5 @@ static int newtcp(const char * host, int port) { setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); return sock; } +#endif #endif /* DISABLE_TCPFWD_DIRECT */ -- cgit v1.2.3 From a76b1ba06868c1743837a5267efcbf2e07c9d81d Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 27 Jul 2004 16:30:46 +0000 Subject: Progressing client support --HG-- extra : convert_revision : 48946be1cef774d1c33b0f78689962b18720c627 --- Makefile.in | 13 ++--- auth.h | 30 +++++++++-- cli-auth.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cli-authpasswd.c | 36 +++++++++++++ cli-kex.c | 1 + cli-main.c | 49 +++++++++++++++++- cli-service.c | 62 +++++++++++++++++++++++ cli-session.c | 92 +++++++++++++++++++++++++++------ common-kex.c | 42 +++++++++------- common-runopts.c | 28 +++++++++++ common-session.c | 6 +-- dbmulti.c | 8 +++ debug.h | 2 +- kex.h | 9 ++-- options.h | 23 ++------- packet.c | 6 +-- runopts.h | 6 ++- scp.c | 7 ++- service.h | 3 +- session.h | 38 ++++++++++---- svr-agentfwd.c | 8 +-- svr-auth.c | 72 +++++++++++++------------- svr-authpasswd.c | 12 ++--- svr-authpubkey.c | 22 ++++---- svr-chansession.c | 32 ++++++------ svr-runopts.c | 4 +- svr-service.c | 3 +- svr-session.c | 13 ++--- 28 files changed, 599 insertions(+), 176 deletions(-) create mode 100644 cli-auth.c create mode 100644 cli-authpasswd.c create mode 100644 cli-service.c create mode 100644 common-runopts.c (limited to 'common-kex.c') diff --git a/Makefile.in b/Makefile.in index 645da6d..b8de23e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -27,7 +27,7 @@ SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \ svr-chansession.o svr-runopts.o svr-agentfwd.o svr-main.o svr-x11fwd.o CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \ - cli-session.o cli-service.o + cli-session.o cli-service.o cli-runopts.o CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \ common-channel.o common-chansession.o termcodes.o loginrec.o \ @@ -140,11 +140,12 @@ dbclient: $(dbclientobjs) dropbearkey: $(dropbearkeyobjs) dropbearconvert: $(dropbearconvertobjs) -dropbear dbclient dropbearkey dropbearconvert: $(HEADERS) $(LTC) $(LTM) +dropbear dbclient dropbearkey dropbearconvert: $(HEADERS) $(LTC) $(LTM) \ + Makefile $(LD) $(LDFLAGS) -o $(SPREFIX)$@$(EXEEXT) $($@objs) $(LIBS) # scp doesn't use the libs so is special. -scp: $(SCPOBJS) $(HEADERS) +scp: $(SCPOBJS) $(HEADERS) Makefile $(LD) $(LDFLAGS) -o $(SPREFIX)$@$(EXEEXT) $(SCPOBJS) @@ -155,16 +156,16 @@ ifeq ($(MULTI),1) CFLAGS+=$(addprefix -DDBMULTI_, $(PROGRAMS)) -DDROPBEAR_MULTI endif -dropbearmulti: $(HEADERS) $(MULTIOBJS) $(LTC) $(LTM) +dropbearmulti: $(HEADERS) $(MULTIOBJS) $(LTC) $(LTM) Makefile $(LD) $(LDFLAGS) -o $(SPREFIX)$@$(EXEEXT) $(MULTIOBJS) $(LIBS) @echo @echo "You should now create symlinks to the programs you have included" @echo "ie 'ln -s dropbearmulti dropbear'" -$(LTC): $(HEADERS) +$(LTC): options.h cd libtomcrypt && $(MAKE) clean && $(MAKE) -$(LTM): $(HEADERS) +$(LTM): options.h cd libtommath && $(MAKE) ltc-clean: diff --git a/auth.h b/auth.h index 8d2db3e..df8ae0c 100644 --- a/auth.h +++ b/auth.h @@ -27,12 +27,28 @@ #include "includes.h" -void authinitialise(); +void svr_authinitialise(); +void cli_authinitialise(); +void svr_auth_password(); +void svr_auth_pubkey(); + +int cli_auth_password(); +int cli_auth_pubkey(); + +/* Server functions */ void recv_msg_userauth_request(); void send_msg_userauth_failure(int partial, int incrfail); void send_msg_userauth_success(); +/* Client functions */ +void recv_msg_userauth_failure(); +void recv_msg_userauth_success(); +void cli_get_user(); +void cli_auth_getmethods(); +void cli_auth_try(); + + #define MAX_USERNAME_LEN 25 /* arbitrary for the moment */ #define AUTH_TYPE_PUBKEY 1 << 0 @@ -46,17 +62,23 @@ void send_msg_userauth_success(); #define AUTH_METHOD_PASSWORD "password" #define AUTH_METHOD_PASSWORD_LEN 8 +/* This structure is shared between server and client - it contains + * relatively little extraneous bits when used for the client rather than the + * server */ struct AuthState { char *username; /* This is the username the client presents to check. It is updated each run through, used for auth checking */ - char *printableuser; /* stripped of control chars, used for logs etc */ - struct passwd * pw; unsigned char authtypes; /* Flags indicating which auth types are still valid */ unsigned int failcount; /* Number of (failed) authentication attempts.*/ - unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have */ + unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for + client and server (though has differing [obvious] + meanings). */ + /* These are only used for the server */ + char *printableuser; /* stripped of control chars, used for logs etc */ + struct passwd * pw; }; diff --git a/cli-auth.c b/cli-auth.c new file mode 100644 index 0000000..952546e --- /dev/null +++ b/cli-auth.c @@ -0,0 +1,148 @@ +#include "includes.h" +#include "session.h" +#include "auth.h" +#include "dbutil.h" +#include "buffer.h" +#include "ssh.h" +#include "packet.h" +#include "runopts.h" + +void cli_authinitialise() { + + memset(&ses.authstate, 0, sizeof(ses.authstate)); +} + + +void cli_get_user() { + + uid_t uid; + struct passwd *pw; + + TRACE(("enter cli_get_user")); + if (cli_opts.username != NULL) { + ses.authstate.username = cli_opts.username; + } else { + uid = getuid(); + + pw = getpwuid(uid); + if (pw == NULL || pw->pw_name == NULL) { + dropbear_exit("Couldn't find username for current user"); + } + + ses.authstate.username = m_strdup(pw->pw_name); + } + TRACE(("leave cli_get_user: %s", cli_ses.username)); +} + +/* Send a "none" auth request to get available methods */ +void cli_auth_getmethods() { + + TRACE(("enter cli_auth_getmethods")); + + CHECKCLEARTOWRITE(); + + buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); + buf_putstring(ses.writepayload, ses.authstate.username, + strlen(ses.authstate.username)); + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + SSH_SERVICE_CONNECTION_LEN); + buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ + + encrypt_packet(); + cli_ses.state = USERAUTH_METHODS_SENT; + TRACE(("leave cli_auth_getmethods")); + +} + +void recv_msg_userauth_failure() { + + unsigned char * methods = NULL; + unsigned char * tok = NULL; + unsigned int methlen = 0; + unsigned int partial = 0; + unsigned int i = 0; + + TRACE(("<- MSG_USERAUTH_FAILURE")); + TRACE(("enter recv_msg_userauth_failure")); + + methods = buf_getstring(ses.payload, &methlen); + + partial = buf_getbyte(ses.payload); + + if (partial) { + dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required"); + } else { + ses.authstate.failcount++; + } + + TRACE(("Methods (len %d): '%s'", methlen, methods)); + + ses.authstate.authdone=0; + ses.authstate.authtypes=0; + + /* Split with nulls rather than commas */ + for (i = 0; i < methlen; i++) { + if (methods[i] == ',') { + methods[i] = '\0'; + } + } + + tok = methods; /* tok stores the next method we'll compare */ + for (i = 0; i <= methlen; i++) { + if (methods[i] == '\0') { + TRACE(("auth method '%s'\n", tok)); +#ifdef DROPBEAR_PUBKEY_AUTH + if (strncmp(AUTH_METHOD_PUBKEY, tok, + AUTH_METHOD_PUBKEY_LEN) == 0) { + ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; + } +#endif +#ifdef DROPBEAR_PASSWORD_AUTH + if (strncmp(AUTH_METHOD_PASSWORD, tok, + AUTH_METHOD_PASSWORD_LEN) == 0) { + ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; + } +#endif + tok = &methods[i]; /* Must make sure we don't use it after + the last loop, since it'll point + to something undefined */ + } + } + + cli_ses.state = USERAUTH_FAIL_RCVD; + + TRACE(("leave recv_msg_userauth_failure")); +} + +void recv_msg_userauth_success() { + TRACE(("received msg_userauth_success")); + ses.authstate.authdone = 1; +} + +void cli_auth_try() { + + TRACE(("enter cli_auth_try")); + int finished = 0; + + CHECKCLEARTOWRITE(); + + /* XXX We hardcode that we try a pubkey first */ +#ifdef DROPBEAR_PUBKEY_AUTH + if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { + finished = cli_auth_pubkey(); + } +#endif + +#ifdef DROPBEAR_PASSWORD_AUTH + if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { + finished = cli_auth_password(); + } +#endif + + if (!finished) { + dropbear_exit("No auth methods could be used."); + } + + cli_ses.state = USERAUTH_REQ_SENT; + TRACE(("leave cli_auth_try")); +} diff --git a/cli-authpasswd.c b/cli-authpasswd.c new file mode 100644 index 0000000..6185334 --- /dev/null +++ b/cli-authpasswd.c @@ -0,0 +1,36 @@ +#include "includes.h" +#include "buffer.h" +#include "dbutil.h" +#include "session.h" +#include "ssh.h" + +int cli_auth_password() { + + char* password = NULL; + TRACE(("enter cli_auth_password")); + + CHECKCLEARTOWRITE(); + password = getpass("Password: "); + + buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); + + buf_putstring(ses.writepayload, ses.authstate.username, + strlen(ses.authstate.username)); + + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + SSH_SERVICE_CONNECTION_LEN); + + buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD, + AUTH_METHOD_PASSWORD_LEN); + + buf_putbyte(ses.writepayload, 0); /* FALSE - so says the spec */ + + buf_putstring(ses.writepayload, password, strlen(password)); + + encrypt_packet(); + m_burn(password, strlen(password)); + + TRACE(("leave cli_auth_password")); + return 1; /* Password auth can always be tried */ + +} diff --git a/cli-kex.c b/cli-kex.c index 4d26332..2577caf 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -34,6 +34,7 @@ #include "bignum.h" #include "random.h" #include "runopts.h" +#include "signkey.h" diff --git a/cli-main.c b/cli-main.c index 2460060..c5d5b3e 100644 --- a/cli-main.c +++ b/cli-main.c @@ -1,6 +1,17 @@ -#include +#include "includes.h" +#include "dbutil.h" +#include "runopts.h" +#include "session.h" +static void cli_dropbear_exit(int exitcode, const char* format, va_list param); +static void cli_dropbear_log(int priority, const char* format, va_list param); + +#if defined(DBMULTI_dbclient) || !defined(DROPBEAR_MULTI) +#if defined(DBMULTI_dbclient) && defined(DROPBEAR_MULTI) +int cli_main(int argc, char ** argv) { +#else int main(int argc, char ** argv) { +#endif int sock; char* error = NULL; @@ -12,6 +23,9 @@ int main(int argc, char ** argv) { cli_getopts(argc, argv); + TRACE(("user='%s' host='%s' port='%s'", cli_opts.username, + cli_opts.remotehost, cli_opts.remoteport)); + sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport, 0, &error); @@ -23,7 +37,7 @@ int main(int argc, char ** argv) { len = strlen(cli_opts.remotehost); len += 10; /* 16 bit port and leeway*/ hostandport = (char*)m_malloc(len); - snprintf(hostandport, len, "%s%d", + snprintf(hostandport, len, "%s:%s", cli_opts.remotehost, cli_opts.remoteport); cli_session(sock, hostandport); @@ -31,3 +45,34 @@ int main(int argc, char ** argv) { /* not reached */ return -1; } +#endif /* DBMULTI stuff */ + +static void cli_dropbear_exit(int exitcode, const char* format, va_list param) { + + char fmtbuf[300]; + + if (!sessinitdone) { + snprintf(fmtbuf, sizeof(fmtbuf), "exited: %s", + format); + } else { + snprintf(fmtbuf, sizeof(fmtbuf), + "connection to %s@%s:%s exited: %s", + cli_opts.username, cli_opts.remotehost, + cli_opts.remoteport, format); + } + + _dropbear_log(LOG_INFO, fmtbuf, param); + + common_session_cleanup(); + exit(exitcode); +} + +static void cli_dropbear_log(int priority, const char* format, va_list param) { + + char printbuf[1024]; + + vsnprintf(printbuf, sizeof(printbuf), format, param); + + fprintf(stderr, "Dropbear: %s\n", printbuf); + +} diff --git a/cli-service.c b/cli-service.c new file mode 100644 index 0000000..c873919 --- /dev/null +++ b/cli-service.c @@ -0,0 +1,62 @@ +#include "includes.h" +#include "service.h" +#include "dbutil.h" +#include "packet.h" +#include "buffer.h" +#include "session.h" +#include "ssh.h" + +void send_msg_service_request(char* servicename) { + + TRACE(("enter send_msg_service_request: servicename='%s'", servicename)); + + CHECKCLEARTOWRITE(); + + buf_putbyte(ses.payload, SSH_MSG_SERVICE_REQUEST); + buf_putstring(ses.payload, servicename, strlen(servicename)); + + encrypt_packet(); + TRACE(("leave send_msg_service_request")); +} + +/* This just sets up the state variables right for the main client session loop + * to deal with */ +void recv_msg_service_accept() { + + unsigned char* servicename; + unsigned int len; + + TRACE(("enter recv_msg_service_accept")); + + servicename = buf_getstring(ses.payload, &len); + + /* ssh-userauth */ + if (cli_ses.state = SERVICE_AUTH_REQ_SENT + && len == SSH_SERVICE_USERAUTH_LEN + && strncmp(SSH_SERVICE_USERAUTH, servicename, len) == 0) { + + cli_ses.state = SERVICE_AUTH_ACCEPT_RCVD; + m_free(servicename); + TRACE(("leave recv_msg_service_accept: done ssh-userauth")); + return; + } + + /* ssh-connection */ + if (cli_ses.state = SERVICE_CONN_REQ_SENT + && len == SSH_SERVICE_CONNECTION_LEN + && strncmp(SSH_SERVICE_CONNECTION, servicename, len) == 0) { + + if (ses.authstate.authdone != 1) { + dropbear_exit("request for connection before auth"); + } + + cli_ses.state = SERVICE_CONN_ACCEPT_RCVD; + m_free(servicename); + TRACE(("leave recv_msg_service_accept: done ssh-connection")); + return; + } + + dropbear_exit("unrecognised service accept"); + /* m_free(servicename); not reached */ + +} diff --git a/cli-session.c b/cli-session.c index d5afaf9..9f80bd1 100644 --- a/cli-session.c +++ b/cli-session.c @@ -8,9 +8,11 @@ #include "tcpfwd-remote.h" #include "channel.h" #include "random.h" +#include "service.h" static void cli_remoteclosed(); static void cli_sessionloop(); +static void cli_session_init(); struct clientsession cli_ses; /* GLOBAL */ @@ -28,6 +30,8 @@ static const packettype cli_packettypes[] = { {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close}, {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, + {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, + {SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, {0, 0} /* End */ }; @@ -37,6 +41,7 @@ static const struct ChanType *cli_chantypes[] = { * that forwarding */ NULL /* Null termination */ }; + void cli_session(int sock, char* remotehost) { crypto_init(); @@ -44,11 +49,9 @@ void cli_session(int sock, char* remotehost) { chaninitialise(cli_chantypes); - /* For printing "remote host closed" for the user */ - session_remoteclosed = cli_remoteclosed; - /* packet handlers */ - ses.packettypes = cli_packettypes; + /* Set up cli_ses vars */ + cli_session_init(); /* Ready to go */ sessinitdone = 1; @@ -66,26 +69,85 @@ void cli_session(int sock, char* remotehost) { /* Not reached */ +} + +static void cli_session_init() { + cli_ses.state = STATE_NOTHING; + cli_ses.kex_state = KEX_NOTHING; + + /* For printing "remote host closed" for the user */ + ses.remoteclosed = cli_remoteclosed; + ses.buf_match_algo = cli_buf_match_algo; + + /* packet handlers */ + ses.packettypes = cli_packettypes; } +/* This function drives the progress of the session - it initiates KEX, + * service, userauth and channel requests */ static void cli_sessionloop() { - switch (cli_ses.state) { + TRACE(("enter cli_sessionloop")); + + if (cli_ses.kex_state == KEX_NOTHING && ses.kexstate.recvkexinit) { + cli_ses.state = KEXINIT_RCVD; + } - KEXINIT_RCVD: - /* We initiate the KEX. If DH wasn't the correct type, the KEXINIT - * negotiation would have failed. */ - send_msg_kexdh_init(); - cli_ses.state = KEXDH_INIT_SENT; - break; + if (cli_ses.state == KEXINIT_RCVD) { - default: - break; + /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT + * negotiation would have failed. */ + send_msg_kexdh_init(); + cli_ses.kex_state = KEXDH_INIT_SENT; + TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD")); + return; } - if (cli_ses.donefirstkex && !cli_ses.authdone) { + /* A KEX has finished, so we should go back to our KEX_NOTHING state */ + if (cli_ses.kex_state != KEX_NOTHING && ses.kexstate.recvkexinit == 0 + && ses.kexstate.sentkexinit == 0) { + cli_ses.kex_state = KEX_NOTHING; + } + + /* We shouldn't do anything else if a KEX is in progress */ + if (cli_ses.kex_state != KEX_NOTHING) { + TRACE(("leave cli_sessionloop: kex_state != KEX_NOTHING")); + return; + } + /* We should exit if we haven't donefirstkex: we shouldn't reach here + * in normal operation */ + if (ses.kexstate.donefirstkex == 0) { + TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")); + } + + switch (cli_ses.state) { + + case STATE_NOTHING: + /* We've got the transport layer sorted, we now need to request + * userauth */ + send_msg_service_request(SSH_SERVICE_USERAUTH); + cli_ses.state = SERVICE_AUTH_REQ_SENT; + return; + + /* userauth code */ + case SERVICE_AUTH_ACCEPT_RCVD: + cli_get_user(); + cli_auth_getmethods(); + cli_ses.state = USERAUTH_METHODS_SENT; + return; + + case USERAUTH_FAIL_RCVD: + cli_auth_try(); + return; + + /* XXX more here needed */ + + + default: + break; + } } @@ -97,5 +159,5 @@ static void cli_remoteclosed() { * already sent/received disconnect message(s) ??? */ close(ses.sock); ses.sock = -1; - dropbear_exit("%s closed the connection", ses.remotehost); + dropbear_exit("remote closed the connection"); } diff --git a/common-kex.c b/common-kex.c index 21accb6..9847a48 100644 --- a/common-kex.c +++ b/common-kex.c @@ -5,7 +5,7 @@ * This code is copied from the larger file "kex.c" * some functions are verbatim, others are generalized --mihnea * - * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2002-2004 Matt Johnston * Portions Copyright (c) 2004 by Mihnea Stoenescu * All rights reserved. * @@ -54,10 +54,12 @@ const unsigned char dh_p_val[] = { const int DH_G_VAL = 2; +static void kexinitialise(); static void gen_new_keys(); #ifndef DISABLE_ZLIB static void gen_new_zstreams(); #endif +static void read_kex_algos(); /* helper function for gen_new_keys */ static void hashkeys(unsigned char *out, int outlen, const hash_state * hs, unsigned const char X); @@ -145,6 +147,7 @@ void send_msg_newkeys() { kexinitialise(); /* we've finished with this kex */ TRACE((" -> DATAALLOWED=1")); ses.dataallowed = 1; /* we can send other packets again now */ + ses.kexstate.donefirstkex = 1; } else { ses.kexstate.sentnewkeys = 1; TRACE(("SENTNEWKEYS=1")); @@ -168,6 +171,7 @@ void recv_msg_newkeys() { kexinitialise(); /* we've finished with this kex */ TRACE((" -> DATAALLOWED=1")); ses.dataallowed = 1; /* we can send other packets again now */ + ses.kexstate.donefirstkex = 1; } else { TRACE(("RECVNEWKEYS=1")); ses.kexstate.recvnewkeys = 1; @@ -177,8 +181,15 @@ void recv_msg_newkeys() { } -/* Duplicated verbatim from kex.c --mihnea */ -void kexinitialise() { +/* Set up the kex for the first time */ +void kexfirstinitialise() { + + ses.kexstate.donefirstkex = 0; + kexinitialise(); +} + +/* Reset the kex state, ready for a new negotiation */ +static void kexinitialise() { struct timeval tv; @@ -404,7 +415,7 @@ void recv_msg_kexinit() { #ifdef DROPBEAR_CLIENT /* read the peer's choice of algos */ - read_kex_algos(cli_buf_match_algo); + read_kex_algos(); /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, @@ -423,14 +434,13 @@ void recv_msg_kexinit() { buf_getptr(ses.payload, ses.payload->len), ses.payload->len); - cli_ses.state = KEXINIT_RCVD; #endif } else { /* SERVER */ #ifdef DROPBEAR_SERVER /* read the peer's choice of algos */ - read_kex_algos(svr_buf_match_algo); + read_kex_algos(); /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, ses.remoteident, strlen((char*)ses.remoteident)); @@ -583,9 +593,7 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, /* read the other side's algo list. buf_match_algo is a callback to match * algos for the client or server. */ -void read_kex_algos( - algo_type*(buf_match_algo)(buffer*buf, algo_type localalgos[], - int *goodguess)) { +static void read_kex_algos() { algo_type * algo; char * erralgo = NULL; @@ -599,7 +607,7 @@ void read_kex_algos( ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); /* kex_algorithms */ - algo = buf_match_algo(ses.payload, sshkex, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess); allgood &= goodguess; if (algo == NULL) { erralgo = "kex"; @@ -608,7 +616,7 @@ void read_kex_algos( ses.newkeys->algo_kex = algo->val; /* server_host_key_algorithms */ - algo = buf_match_algo(ses.payload, sshhostkey, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshhostkey, &goodguess); allgood &= goodguess; if (algo == NULL) { erralgo = "hostkey"; @@ -617,7 +625,7 @@ void read_kex_algos( ses.newkeys->algo_hostkey = algo->val; /* encryption_algorithms_client_to_server */ - algo = buf_match_algo(ses.payload, sshciphers, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc c->s"; goto error; @@ -625,7 +633,7 @@ void read_kex_algos( ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; /* encryption_algorithms_server_to_client */ - algo = buf_match_algo(ses.payload, sshciphers, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc s->c"; goto error; @@ -633,7 +641,7 @@ void read_kex_algos( ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; /* mac_algorithms_client_to_server */ - algo = buf_match_algo(ses.payload, sshhashes, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac c->s"; goto error; @@ -641,7 +649,7 @@ void read_kex_algos( ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; /* mac_algorithms_server_to_client */ - algo = buf_match_algo(ses.payload, sshhashes, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac s->c"; goto error; @@ -649,7 +657,7 @@ void read_kex_algos( ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; /* compression_algorithms_client_to_server */ - algo = buf_match_algo(ses.payload, sshcompress, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp c->s"; goto error; @@ -657,7 +665,7 @@ void read_kex_algos( ses.newkeys->recv_algo_comp = algo->val; /* compression_algorithms_server_to_client */ - algo = buf_match_algo(ses.payload, sshcompress, &goodguess); + algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp s->c"; goto error; diff --git a/common-runopts.c b/common-runopts.c new file mode 100644 index 0000000..097ab12 --- /dev/null +++ b/common-runopts.c @@ -0,0 +1,28 @@ +/* + * Dropbear - a SSH2 server + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + +#include "includes.h" +#include "runopts.h" + +runopts opts; /* GLOBAL */ diff --git a/common-session.c b/common-session.c index 70ddbfe..93e7c74 100644 --- a/common-session.c +++ b/common-session.c @@ -45,8 +45,6 @@ int sessinitdone = 0; /* GLOBAL */ /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */ int exitflag = 0; /* GLOBAL */ -void(*session_remoteclosed)() = NULL; - static void checktimeouts(); static int ident_readln(int fd, char* buf, int count); @@ -63,7 +61,7 @@ void common_session_init(int sock, char* remotehost) { ses.connecttimeout = 0; - kexinitialise(); /* initialise the kex state */ + kexfirstinitialise(); /* initialise the kex state */ chaninitialise(); /* initialise the channel state */ ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN); @@ -104,8 +102,6 @@ void common_session_init(int sock, char* remotehost) { ses.dh_K = NULL; ses.remoteident = NULL; - ses.authdone = 0; - ses.chantypes = NULL; ses.allowprivport = 0; diff --git a/dbmulti.c b/dbmulti.c index 8f39227..24adce1 100644 --- a/dbmulti.c +++ b/dbmulti.c @@ -19,6 +19,11 @@ int main(int argc, char ** argv) { return dropbear_main(argc, argv); } #endif +#ifdef DBMULTI_dbclient + if (strcmp(progname, "dbclient") == 0) { + return cli_main(argc, argv); + } +#endif #ifdef DBMULTI_dropbearkey if (strcmp(progname, "dropbearkey") == 0) { return dropbearkey_main(argc, argv); @@ -41,6 +46,9 @@ int main(int argc, char ** argv) { #ifdef DBMULTI_dropbear "'dropbear' - the Dropbear server\n" #endif +#ifdef DBMULTI_dbclient + "'dbclient' - the Dropbear client\n" +#endif #ifdef DBMULTI_dropbearkey "'dropbearkey' - the key generator\n" #endif diff --git a/debug.h b/debug.h index 736690a..d619a58 100644 --- a/debug.h +++ b/debug.h @@ -36,7 +36,7 @@ /* Define this to print trace statements - very verbose */ /* Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing does not sanitise strings etc */ -//#define DEBUG_TRACE +#define DEBUG_TRACE /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're diff --git a/kex.h b/kex.h index e6c8ac1..01626ed 100644 --- a/kex.h +++ b/kex.h @@ -32,15 +32,11 @@ void send_msg_kexinit(); void recv_msg_kexinit(); void send_msg_newkeys(); void recv_msg_newkeys(); -void kexinitialise(); +void kexfirstinitialise(); void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv); void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, sign_key *hostkey); -void read_kex_algos( - algo_type*(buf_match_algo)(buffer*buf, algo_type localalgos[], - int *goodguess)); - void recv_msg_kexdh_init(); // server void send_msg_kexdh_init(); // client @@ -59,6 +55,9 @@ struct KEXState { unsigned sentnewkeys : 1; /* set once we've send/recv'ed MSG_NEWKEYS*/ unsigned recvnewkeys : 1; + unsigned donefirstkex : 1; /* Set to 1 after the first kex has completed, + ie the transport layer has been set up */ + long lastkextime; /* time of the last kex */ unsigned int datatrans; /* data transmitted since last kex */ unsigned int datarecv; /* data received since last kex */ diff --git a/options.h b/options.h index 3aeac0f..ee0ee60 100644 --- a/options.h +++ b/options.h @@ -29,8 +29,6 @@ * Define compile-time options below - the "#ifndef DROPBEAR_XXX .... #endif" * parts are to allow for commandline -DDROPBEAR_XXX options etc. ******************************************************************/ -#define DROPBEAR_SERVER -//#define DROPBEAR_CLIENT #ifndef DROPBEAR_PORT #define DROPBEAR_PORT 22 @@ -48,7 +46,6 @@ * perhaps 20% slower for pubkey operations (it is probably worth experimenting * if you want to use this) */ /*#define NO_FAST_EXPTMOD*/ -#define DROPBEAR_SMALL_CODE /* Enable X11 Forwarding */ #define ENABLE_X11FWD @@ -114,7 +111,7 @@ /* Authentication types to enable, at least one required. RFC Draft requires pubkey auth, and recommends password */ #define DROPBEAR_PASSWORD_AUTH -#define DROPBEAR_PUBKEY_AUTH +//#define DROPBEAR_PUBKEY_AUTH /* Random device to use - you must specify _one only_. * DEV_RANDOM is recommended on hosts with a good /dev/urandom, otherwise use @@ -162,20 +159,8 @@ /* This is used by the scp binary when used as a client binary */ #define _PATH_SSH_PROGRAM "/usr/bin/ssh" -/* Multi-purpose binary configuration - if you want to make the combined - * binary, first define DROPBEAR_MULTI, and then define which of the three - * components you want. You should then compile Dropbear with - * "make clean; make dropbearmulti". You'll need to install the binary - * manually, see MULTI for details */ - -/* #define DROPBEAR_MULTI */ - -/* The three multi binaries: dropbear, dropbearkey, dropbearconvert - * Comment out these if you don't want some of them */ -#define DBMULTI_DROPBEAR -#define DBMULTI_KEY -#define DBMULTI_CONVERT - +/* Multi-purpose binary configuration has now moved. Look at the top + * of the Makefile for instructions, or INSTALL */ /******************************************************************* * You shouldn't edit below here unless you know you need to. @@ -246,7 +231,7 @@ #define DROPBEAR_COMP_ZLIB 1 /* Required for pubkey auth */ -#ifdef DROPBEAR_PUBKEY_AUTH +#if defined(DROPBEAR_PUBKEY_AUTH) || defined(DROPBEAR_CLIENT) #define DROPBEAR_SIGNKEY_VERIFY #endif diff --git a/packet.c b/packet.c index 886fe67..997bc6f 100644 --- a/packet.c +++ b/packet.c @@ -73,7 +73,7 @@ void write_packet() { } if (written == 0) { - session_remoteclosed(); + ses.remoteclosed(); } if (written == len) { @@ -122,7 +122,7 @@ void read_packet() { len = read(ses.sock, buf_getptr(ses.readbuf, maxlen), maxlen); if (len == 0) { - session_remoteclosed(); + ses.remoteclosed(); } if (len < 0) { @@ -171,7 +171,7 @@ static void read_packet_init() { len = read(ses.sock, buf_getwriteptr(ses.readbuf, maxlen), maxlen); if (len == 0) { - session_remoteclosed(); + ses.remoteclosed(); } if (len < 0) { if (errno == EINTR) { diff --git a/runopts.h b/runopts.h index 1bf1539..125d737 100644 --- a/runopts.h +++ b/runopts.h @@ -79,7 +79,11 @@ void svr_getopts(int argc, char ** argv); /* Uncompleted XXX matt */ typedef struct cli_runopts { - int todo; + char *remotehost; + char *remoteport; + + char *username; + /* XXX TODO */ } cli_runopts; diff --git a/scp.c b/scp.c index b23dec6..b6eec88 100644 --- a/scp.c +++ b/scp.c @@ -229,8 +229,12 @@ void tolocal(int, char *[]); void toremote(char *, int, char *[]); void usage(void); -int +#if defined(DBMULTI_scp) || !defined(DROPBEAR_MULTI) +#if defined(DBMULTI_scp) && defined(DROPBEAR_MULTI) +int scp_main(int argc, char **argv) +#else main(int argc, char **argv) +#endif { int ch, fflag, tflag, status; double speed; @@ -379,6 +383,7 @@ main(int argc, char **argv) } exit(errs != 0); } +#endif /* DBMULTI stuff */ void toremote(char *targ, int argc, char **argv) diff --git a/service.h b/service.h index 0dfcd6e..5f50347 100644 --- a/service.h +++ b/service.h @@ -25,6 +25,7 @@ #ifndef _SERVICE_H_ #define _SERVICE_H_ -void recv_msg_service_request(); +void recv_msg_service_request(); /* Server */ +void send_msg_service_request(); /* Client */ #endif /* _SERVICE_H_ */ diff --git a/session.h b/session.h index d929c1c..4a7e0ac 100644 --- a/session.h +++ b/session.h @@ -45,7 +45,6 @@ void common_session_cleanup(); void checktimeouts(); void session_identification(); -extern void(*session_remoteclosed)(); /* Server */ void svr_session(int sock, int childpipe, char *remotehost); @@ -135,13 +134,18 @@ struct sshsession { buffer* transkexinit; /* the kexinit packet we send should be kept so we can add it to the hash when generating keys */ + algo_type*(*buf_match_algo)(buffer*buf, algo_type localalgos[], + int *goodguess); /* The function to use to choose which algorithm + to use from the ones presented by the remote + side. Is specific to the client/server mode, + hence the function-pointer callback.*/ - unsigned char authdone; /* Indicates when authentication has been - completed. This applies to both client and - server - in the server it gets set to 1 when - authentication is successful, in the client it - is set when the server has told us that auth - succeeded */ + void(*remoteclosed)(); /* A callback to handle closure of the + remote connection */ + + + struct AuthState authstate; /* Common amongst client and server, since most + struct elements are common */ /* Channel related */ struct Channel ** channels; /* these pointers may be null */ @@ -165,7 +169,6 @@ struct serversession { /* Server specific options */ int childpipe; /* kept open until we successfully authenticate */ /* userauth */ - struct AuthState authstate; struct ChildPid * childpids; /* array of mappings childpid<->channel */ unsigned int childpidsize; @@ -173,17 +176,30 @@ struct serversession { }; typedef enum { - NOTHING, + KEX_NOTHING, KEXINIT_RCVD, KEXDH_INIT_SENT, - KEXDH_REPLY_RCVD, + KEXDONE, + +} cli_kex_state; + +typedef enum { + STATE_NOTHING, + SERVICE_AUTH_REQ_SENT, + SERVICE_AUTH_ACCEPT_RCVD, + SERVICE_CONN_REQ_SENT, + SERVICE_CONN_ACCEPT_RCVD, + USERAUTH_METHODS_SENT, + USERAUTH_REQ_SENT, + USERAUTH_FAIL_RCVD, } cli_state; struct clientsession { mp_int *dh_e, *dh_x; /* Used during KEX */ - cli_state state; /* Used to progress the KEX/auth/channelsession etc */ + cli_kex_state kex_state; /* Used for progressing KEX */ + cli_state state; /* Used to progress auth/channelsession etc */ int something; /* XXX */ unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */ diff --git a/svr-agentfwd.c b/svr-agentfwd.c index fd068fe..0dad2a4 100644 --- a/svr-agentfwd.c +++ b/svr-agentfwd.c @@ -152,8 +152,8 @@ void agentcleanup(struct ChanSess * chansess) { * for themselves */ uid = getuid(); gid = getgid(); - if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 || - (seteuid(svr_ses.authstate.pw->pw_uid)) < 0) { + if ((setegid(ses.authstate.pw->pw_gid)) < 0 || + (seteuid(ses.authstate.pw->pw_uid)) < 0) { dropbear_exit("failed to set euid"); } @@ -215,8 +215,8 @@ static int bindagent(int fd, struct ChanSess * chansess) { /* drop to user privs to make the dir/file */ uid = getuid(); gid = getgid(); - if ((setegid(svr_ses.authstate.pw->pw_gid)) < 0 || - (seteuid(svr_ses.authstate.pw->pw_uid)) < 0) { + if ((setegid(ses.authstate.pw->pw_gid)) < 0 || + (seteuid(ses.authstate.pw->pw_uid)) < 0) { dropbear_exit("failed to set euid"); } diff --git a/svr-auth.c b/svr-auth.c index 7b588c0..0f0ef67 100644 --- a/svr-auth.c +++ b/svr-auth.c @@ -41,9 +41,9 @@ static int checkusername(unsigned char *username, unsigned int userlen); static void send_msg_userauth_banner(); /* initialise the first time for a session, resetting all parameters */ -void authinitialise() { +void svr_authinitialise() { - svr_ses.authstate.failcount = 0; + ses.authstate.failcount = 0; authclear(); } @@ -53,17 +53,13 @@ void authinitialise() { * on initialisation */ static void authclear() { - ses.authdone = 0; - svr_ses.authstate.pw = NULL; - svr_ses.authstate.username = NULL; - svr_ses.authstate.printableuser = NULL; - svr_ses.authstate.authtypes = 0; + memset(&ses.authstate, 0, sizeof(ses.authstate)); #ifdef DROPBEAR_PUBKEY_AUTH - svr_ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; + ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; #endif #ifdef DROPBEAR_PASSWORD_AUTH if (svr_opts.noauthpass) { - svr_ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; + ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; } #endif @@ -103,7 +99,7 @@ void recv_msg_userauth_request() { TRACE(("enter recv_msg_userauth_request")); /* ignore packets if auth is already done */ - if (ses.authdone == 1) { + if (ses.authstate.authdone == 1) { return; } @@ -147,12 +143,12 @@ void recv_msg_userauth_request() { #ifdef DROPBEAR_PASSWORD_AUTH if (!svr_opts.noauthpass && - !(svr_opts.norootpass && svr_ses.authstate.pw->pw_uid == 0) ) { + !(svr_opts.norootpass && ses.authstate.pw->pw_uid == 0) ) { /* user wants to try password auth */ if (methodlen == AUTH_METHOD_PASSWORD_LEN && strncmp(methodname, AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN) == 0) { - passwordauth(); + svr_auth_password(); goto out; } } @@ -163,7 +159,7 @@ void recv_msg_userauth_request() { if (methodlen == AUTH_METHOD_PUBKEY_LEN && strncmp(methodname, AUTH_METHOD_PUBKEY, AUTH_METHOD_PUBKEY_LEN) == 0) { - pubkeyauth(); + svr_auth_pubkey(); goto out; } #endif @@ -192,21 +188,21 @@ static int checkusername(unsigned char *username, unsigned int userlen) { } /* new user or username has changed */ - if (svr_ses.authstate.username == NULL || - strcmp(username, svr_ses.authstate.username) != 0) { + if (ses.authstate.username == NULL || + strcmp(username, ses.authstate.username) != 0) { /* the username needs resetting */ - if (svr_ses.authstate.username != NULL) { + if (ses.authstate.username != NULL) { dropbear_log(LOG_WARNING, "client trying multiple usernames"); - m_free(svr_ses.authstate.username); + m_free(ses.authstate.username); } authclear(); - svr_ses.authstate.pw = getpwnam((char*)username); - svr_ses.authstate.username = m_strdup(username); - m_free(svr_ses.authstate.printableuser); + ses.authstate.pw = getpwnam((char*)username); + ses.authstate.username = m_strdup(username); + m_free(ses.authstate.printableuser); } /* check that user exists */ - if (svr_ses.authstate.pw == NULL) { + if (ses.authstate.pw == NULL) { TRACE(("leave checkusername: user '%s' doesn't exist", username)); dropbear_log(LOG_WARNING, "login attempt for nonexistent user"); @@ -215,10 +211,10 @@ static int checkusername(unsigned char *username, unsigned int userlen) { } /* We can set it once we know its a real user */ - svr_ses.authstate.printableuser = m_strdup(svr_ses.authstate.pw->pw_name); + ses.authstate.printableuser = m_strdup(ses.authstate.pw->pw_name); /* check for non-root if desired */ - if (svr_opts.norootlogin && svr_ses.authstate.pw->pw_uid == 0) { + if (svr_opts.norootlogin && ses.authstate.pw->pw_uid == 0) { TRACE(("leave checkusername: root login disabled")); dropbear_log(LOG_WARNING, "root login rejected"); send_msg_userauth_failure(0, 1); @@ -226,18 +222,18 @@ static int checkusername(unsigned char *username, unsigned int userlen) { } /* check for an empty password */ - if (svr_ses.authstate.pw->pw_passwd[0] == '\0') { + if (ses.authstate.pw->pw_passwd[0] == '\0') { TRACE(("leave checkusername: empty pword")); dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); send_msg_userauth_failure(0, 1); return DROPBEAR_FAILURE; } - TRACE(("shell is %s", svr_ses.authstate.pw->pw_shell)); + TRACE(("shell is %s", ses.authstate.pw->pw_shell)); /* check that the shell is set */ - usershell = svr_ses.authstate.pw->pw_shell; + usershell = ses.authstate.pw->pw_shell; if (usershell[0] == '\0') { /* empty shell in /etc/passwd means /bin/sh according to passwd(5) */ usershell = "/bin/sh"; @@ -258,7 +254,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { endusershell(); TRACE(("no matching shell")); dropbear_log(LOG_WARNING, "user '%s' has invalid shell, rejected", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); send_msg_userauth_failure(0, 1); return DROPBEAR_FAILURE; @@ -266,7 +262,7 @@ goodshell: endusershell(); TRACE(("matching shell")); - TRACE(("uid = %d", svr_ses.authstate.pw->pw_uid)); + TRACE(("uid = %d", ses.authstate.pw->pw_uid)); TRACE(("leave checkusername")); return DROPBEAR_SUCCESS; @@ -290,14 +286,14 @@ void send_msg_userauth_failure(int partial, int incrfail) { /* put a list of allowed types */ typebuf = buf_new(30); /* long enough for PUBKEY and PASSWORD */ - if (svr_ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { + if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { buf_putbytes(typebuf, AUTH_METHOD_PUBKEY, AUTH_METHOD_PUBKEY_LEN); - if (svr_ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { + if (ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { buf_putbyte(typebuf, ','); } } - if (svr_ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { + if (ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { buf_putbytes(typebuf, AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN); } @@ -311,18 +307,18 @@ void send_msg_userauth_failure(int partial, int incrfail) { if (incrfail) { usleep(300000); /* XXX improve this */ - svr_ses.authstate.failcount++; + ses.authstate.failcount++; } - if (svr_ses.authstate.failcount >= MAX_AUTH_TRIES) { + if (ses.authstate.failcount >= MAX_AUTH_TRIES) { char * userstr; /* XXX - send disconnect ? */ TRACE(("Max auth tries reached, exiting")); - if (svr_ses.authstate.printableuser == NULL) { + if (ses.authstate.printableuser == NULL) { userstr = "is invalid"; } else { - userstr = svr_ses.authstate.printableuser; + userstr = ses.authstate.printableuser; } dropbear_exit("Max auth tries reached - user %s", userstr); } @@ -340,9 +336,9 @@ void send_msg_userauth_success() { buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS); encrypt_packet(); - ses.authdone = 1; + ses.authstate.authdone = 1; - if (svr_ses.authstate.pw->pw_uid == 0) { + if (ses.authstate.pw->pw_uid == 0) { ses.allowprivport = 1; } diff --git a/svr-authpasswd.c b/svr-authpasswd.c index 859cfd5..f161b69 100644 --- a/svr-authpasswd.c +++ b/svr-authpasswd.c @@ -35,7 +35,7 @@ /* Process a password auth request, sending success or failure messages as * appropriate */ -void passwordauth() { +void svr_auth_password() { #ifdef HAVE_SHADOW_H struct spwd *spasswd; @@ -47,10 +47,10 @@ void passwordauth() { unsigned char changepw; - passwdcrypt = svr_ses.authstate.pw->pw_passwd; + passwdcrypt = ses.authstate.pw->pw_passwd; #ifdef HAVE_SHADOW_H /* get the shadow password if possible */ - spasswd = getspnam(svr_ses.authstate.pw->pw_name); + spasswd = getspnam(ses.authstate.pw->pw_name); if (spasswd != NULL && spasswd->sp_pwdp != NULL) { passwdcrypt = spasswd->sp_pwdp; } @@ -66,7 +66,7 @@ void passwordauth() { * in auth.c */ if (passwdcrypt[0] == '\0') { dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); send_msg_userauth_failure(0, 1); return; } @@ -92,12 +92,12 @@ void passwordauth() { /* successful authentication */ dropbear_log(LOG_NOTICE, "password auth succeeded for '%s'", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); send_msg_userauth_success(); } else { dropbear_log(LOG_WARNING, "bad password attempt for '%s'", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); send_msg_userauth_failure(0, 1); } diff --git a/svr-authpubkey.c b/svr-authpubkey.c index e3e6947..9c58a8d 100644 --- a/svr-authpubkey.c +++ b/svr-authpubkey.c @@ -50,7 +50,7 @@ static int getauthline(buffer * line, FILE * authfile); /* process a pubkey auth request, sending success or failure message as * appropriate */ -void pubkeyauth() { +void svr_auth_pubkey() { unsigned char testkey; /* whether we're just checking if a key is usable */ unsigned char* algo = NULL; /* pubkey algo */ @@ -113,12 +113,12 @@ void pubkeyauth() { signbuf->len) == DROPBEAR_SUCCESS) { dropbear_log(LOG_NOTICE, "pubkey auth succeeded for '%s' with key %s", - svr_ses.authstate.printableuser, fp); + ses.authstate.printableuser, fp); send_msg_userauth_success(); } else { dropbear_log(LOG_WARNING, "pubkey auth bad signature for '%s' with key %s", - svr_ses.authstate.printableuser, fp); + ses.authstate.printableuser, fp); send_msg_userauth_failure(0, 1); } m_free(fp); @@ -178,7 +178,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, if (have_algo(algo, algolen, sshhostkey) == DROPBEAR_FAILURE) { dropbear_log(LOG_WARNING, "pubkey auth attempt with unknown algo for '%s'", - svr_ses.authstate.printableuser); + ses.authstate.printableuser); goto out; } @@ -190,12 +190,12 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, /* we don't need to check pw and pw_dir for validity, since * its been done in checkpubkeyperms. */ - len = strlen(svr_ses.authstate.pw->pw_dir); + len = strlen(ses.authstate.pw->pw_dir); /* allocate max required pathname storage, * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */ filename = m_malloc(len + 22); snprintf(filename, len + 22, "%s/.ssh/authorized_keys", - svr_ses.authstate.pw->pw_dir); + ses.authstate.pw->pw_dir); /* open the file */ authfile = fopen(filename, "r"); @@ -352,19 +352,19 @@ static int checkpubkeyperms() { TRACE(("enter checkpubkeyperms")); - assert(svr_ses.authstate.pw); - if (svr_ses.authstate.pw->pw_dir == NULL) { + assert(ses.authstate.pw); + if (ses.authstate.pw->pw_dir == NULL) { goto out; } - if ((len = strlen(svr_ses.authstate.pw->pw_dir)) == 0) { + if ((len = strlen(ses.authstate.pw->pw_dir)) == 0) { goto out; } /* allocate max required pathname storage, * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */ filename = m_malloc(len + 22); - strncpy(filename, svr_ses.authstate.pw->pw_dir, len+1); + strncpy(filename, ses.authstate.pw->pw_dir, len+1); /* check ~ */ if (checkfileperm(filename) != DROPBEAR_SUCCESS) { @@ -406,7 +406,7 @@ static int checkfileperm(char * filename) { return DROPBEAR_FAILURE; } /* check ownership - user or root only*/ - if (filestat.st_uid != svr_ses.authstate.pw->pw_uid + if (filestat.st_uid != ses.authstate.pw->pw_uid && filestat.st_uid != 0) { TRACE(("leave checkfileperm: wrong ownership")); return DROPBEAR_FAILURE; diff --git a/svr-chansession.c b/svr-chansession.c index cbc7ebe..50e0a5e 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -239,7 +239,7 @@ static void closechansess(struct Channel *channel) { if (chansess->tty) { /* write the utmp/wtmp login record */ - li = login_alloc_entry(chansess->pid, svr_ses.authstate.username, + li = login_alloc_entry(chansess->pid, ses.authstate.username, ses.remotehost, chansess->tty); login_logout(li); login_free_entry(li); @@ -425,7 +425,7 @@ static int sessionpty(struct ChanSess * chansess) { dropbear_exit("out of memory"); /* TODO disconnect */ } - pty_setowner(svr_ses.authstate.pw, chansess->tty); + pty_setowner(ses.authstate.pw, chansess->tty); pty_change_window_size(chansess->master, chansess->termr, chansess->termc, chansess->termw, chansess->termh); @@ -683,7 +683,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { /* write the utmp/wtmp login record - must be after changing the * terminal used for stdout with the dup2 above */ - li= login_alloc_entry(getpid(), svr_ses.authstate.username, + li= login_alloc_entry(getpid(), ses.authstate.username, ses.remotehost, chansess->tty); login_login(li); login_free_entry(li); @@ -695,10 +695,10 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { /* don't show the motd if ~/.hushlogin exists */ /* 11 == strlen("/hushlogin\0") */ - len = strlen(svr_ses.authstate.pw->pw_dir) + 11; + len = strlen(ses.authstate.pw->pw_dir) + 11; hushpath = m_malloc(len); - snprintf(hushpath, len, "%s/hushlogin", svr_ses.authstate.pw->pw_dir); + snprintf(hushpath, len, "%s/hushlogin", ses.authstate.pw->pw_dir); if (stat(hushpath, &sb) < 0) { /* more than a screenful is stupid IMHO */ @@ -808,10 +808,10 @@ static void execchild(struct ChanSess *chansess) { /* We can only change uid/gid as root ... */ if (getuid() == 0) { - if ((setgid(svr_ses.authstate.pw->pw_gid) < 0) || - (initgroups(svr_ses.authstate.pw->pw_name, - svr_ses.authstate.pw->pw_gid) < 0) || - (setuid(svr_ses.authstate.pw->pw_uid) < 0)) { + if ((setgid(ses.authstate.pw->pw_gid) < 0) || + (initgroups(ses.authstate.pw->pw_name, + ses.authstate.pw->pw_gid) < 0) || + (setuid(ses.authstate.pw->pw_uid) < 0)) { dropbear_exit("error changing user"); } } else { @@ -822,29 +822,29 @@ static void execchild(struct ChanSess *chansess) { * usernames with the same uid, but differing groups, then the * differing groups won't be set (as with initgroups()). The solution * is for the sysadmin not to give out the UID twice */ - if (getuid() != svr_ses.authstate.pw->pw_uid) { + if (getuid() != ses.authstate.pw->pw_uid) { dropbear_exit("couldn't change user as non-root"); } } /* an empty shell should be interpreted as "/bin/sh" */ - if (svr_ses.authstate.pw->pw_shell[0] == '\0') { + if (ses.authstate.pw->pw_shell[0] == '\0') { usershell = "/bin/sh"; } else { - usershell = svr_ses.authstate.pw->pw_shell; + usershell = ses.authstate.pw->pw_shell; } /* set env vars */ - addnewvar("USER", svr_ses.authstate.pw->pw_name); - addnewvar("LOGNAME", svr_ses.authstate.pw->pw_name); - addnewvar("HOME", svr_ses.authstate.pw->pw_dir); + addnewvar("USER", ses.authstate.pw->pw_name); + addnewvar("LOGNAME", ses.authstate.pw->pw_name); + addnewvar("HOME", ses.authstate.pw->pw_dir); addnewvar("SHELL", usershell); if (chansess->term != NULL) { addnewvar("TERM", chansess->term); } /* change directory */ - if (chdir(svr_ses.authstate.pw->pw_dir) < 0) { + if (chdir(ses.authstate.pw->pw_dir) < 0) { dropbear_exit("error changing directory"); } diff --git a/svr-runopts.c b/svr-runopts.c index 1f5b0c6..c79208c 100644 --- a/svr-runopts.c +++ b/svr-runopts.c @@ -106,8 +106,8 @@ void svr_getopts(int argc, char ** argv) { opts.nolocaltcp = 0; opts.noremotetcp = 0; /* not yet - svr_opts.ipv4 = 1; - svr_opts.ipv6 = 1; + opts.ipv4 = 1; + opts.ipv6 = 1; */ #ifdef DO_MOTD svr_opts.domotd = 1; diff --git a/svr-service.c b/svr-service.c index 7b717bf..e823490 100644 --- a/svr-service.c +++ b/svr-service.c @@ -56,7 +56,7 @@ void recv_msg_service_request() { /* ssh-connection */ if (len == SSH_SERVICE_CONNECTION_LEN && (strncmp(SSH_SERVICE_CONNECTION, name, len) == 0)) { - if (ses.authdone != 1) { + if (ses.authstate.authdone != 1) { dropbear_exit("request for connection before auth"); } @@ -70,7 +70,6 @@ void recv_msg_service_request() { /* TODO this should be a MSG_DISCONNECT */ dropbear_exit("unrecognised SSH_MSG_SERVICE_REQUEST"); - TRACE(("leave recv_msg_service_request")); } diff --git a/svr-session.c b/svr-session.c index cb309fe..80c622a 100644 --- a/svr-session.c +++ b/svr-session.c @@ -79,7 +79,7 @@ void svr_session(int sock, int childpipe, char* remotehost) { /* Initialise server specific parts of the session */ svr_ses.childpipe = childpipe; - authinitialise(); + svr_authinitialise(); chaninitialise(svr_chantypes); svr_chansessinitialise(); @@ -90,10 +90,11 @@ void svr_session(int sock, int childpipe, char* remotehost) { ses.connecttimeout = timeout.tv_sec + AUTH_TIMEOUT; /* set up messages etc */ - session_remoteclosed = svr_remoteclosed; + ses.remoteclosed = svr_remoteclosed; /* packet handlers */ ses.packettypes = svr_packettypes; + ses.buf_match_algo = svr_buf_match_algo; /* We're ready to go now */ sessinitdone = 1; @@ -123,16 +124,16 @@ void svr_dropbear_exit(int exitcode, const char* format, va_list param) { /* before session init */ snprintf(fmtbuf, sizeof(fmtbuf), "premature exit: %s", format); - } else if (svr_ses.authstate.authdone) { + } else if (ses.authstate.authdone) { /* user has authenticated */ snprintf(fmtbuf, sizeof(fmtbuf), "exit after auth (%s): %s", - svr_ses.authstate.printableuser, format); - } else if (svr_ses.authstate.printableuser) { + ses.authstate.printableuser, format); + } else if (ses.authstate.printableuser) { /* we have a potential user */ snprintf(fmtbuf, sizeof(fmtbuf), "exit before auth (user '%s', %d fails): %s", - svr_ses.authstate.printableuser, svr_ses.authstate.failcount, format); + ses.authstate.printableuser, ses.authstate.failcount, format); } else { /* before userauth */ snprintf(fmtbuf, sizeof(fmtbuf), -- cgit v1.2.3 From 2d82f73484e588e9367657a25331afd4aa0bf976 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 28 Jul 2004 16:44:16 +0000 Subject: Client mostly works up to password auth Need to rework algo-choosing etc, since server is now broken. --HG-- extra : convert_revision : 458dc4eed0e885e7c91633d4781d3348213a0e19 --- cli-auth.c | 10 +++++----- cli-kex.c | 10 ++++++++-- cli-service.c | 4 ++-- cli-session.c | 16 +++++++++++----- common-kex.c | 8 ++++++++ common-session.c | 1 + dss.c | 4 ++++ process-packet.c | 2 ++ rsa.c | 6 ++++++ service.h | 1 + session.h | 2 ++ signkey.c | 7 +++++++ 12 files changed, 57 insertions(+), 14 deletions(-) (limited to 'common-kex.c') diff --git a/cli-auth.c b/cli-auth.c index 952546e..d222d7e 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -31,7 +31,7 @@ void cli_get_user() { ses.authstate.username = m_strdup(pw->pw_name); } - TRACE(("leave cli_get_user: %s", cli_ses.username)); + TRACE(("leave cli_get_user: %s", ses.authstate.username)); } /* Send a "none" auth request to get available methods */ @@ -90,7 +90,7 @@ void recv_msg_userauth_failure() { tok = methods; /* tok stores the next method we'll compare */ for (i = 0; i <= methlen; i++) { if (methods[i] == '\0') { - TRACE(("auth method '%s'\n", tok)); + TRACE(("auth method '%s'", tok)); #ifdef DROPBEAR_PUBKEY_AUTH if (strncmp(AUTH_METHOD_PUBKEY, tok, AUTH_METHOD_PUBKEY_LEN) == 0) { @@ -103,9 +103,9 @@ void recv_msg_userauth_failure() { ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; } #endif - tok = &methods[i]; /* Must make sure we don't use it after - the last loop, since it'll point - to something undefined */ + tok = &methods[i+1]; /* Must make sure we don't use it after the + last loop, since it'll point to something + undefined */ } } diff --git a/cli-kex.c b/cli-kex.c index 2577caf..d882423 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -43,7 +43,7 @@ void send_msg_kexdh_init() { cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x); + m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); CHECKCLEARTOWRITE(); @@ -58,17 +58,23 @@ void recv_msg_kexdh_reply() { mp_int dh_f; sign_key *hostkey = NULL; - int type; + int type, keylen; + TRACE(("enter recv_msg_kexdh_reply")); type = ses.newkeys->algo_hostkey; + TRACE(("type is %d", type)); hostkey = new_sign_key(); + keylen = buf_getint(ses.payload); + if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { + TRACE(("failed getting pubkey")); dropbear_exit("Bad KEX packet"); } m_mp_init(&dh_f); if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { + TRACE(("failed getting mpint")); dropbear_exit("Bad KEX packet"); } diff --git a/cli-service.c b/cli-service.c index c873919..8ba06c6 100644 --- a/cli-service.c +++ b/cli-service.c @@ -12,8 +12,8 @@ void send_msg_service_request(char* servicename) { CHECKCLEARTOWRITE(); - buf_putbyte(ses.payload, SSH_MSG_SERVICE_REQUEST); - buf_putstring(ses.payload, servicename, strlen(servicename)); + buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST); + buf_putstring(ses.writepayload, servicename, strlen(servicename)); encrypt_packet(); TRACE(("leave send_msg_service_request")); diff --git a/cli-session.c b/cli-session.c index 9f80bd1..2ae2719 100644 --- a/cli-session.c +++ b/cli-session.c @@ -21,6 +21,7 @@ static const packettype cli_packettypes[] = { {SSH_MSG_KEXINIT, recv_msg_kexinit}, {SSH_MSG_KEXDH_REPLY, recv_msg_kexdh_reply}, // client {SSH_MSG_NEWKEYS, recv_msg_newkeys}, + {SSH_MSG_SERVICE_ACCEPT, recv_msg_service_accept}, // client {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp}, @@ -30,8 +31,8 @@ static const packettype cli_packettypes[] = { {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close}, {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, - {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, - {SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, + {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, // client + {SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, // client {0, 0} /* End */ }; @@ -90,11 +91,11 @@ static void cli_sessionloop() { TRACE(("enter cli_sessionloop")); - if (cli_ses.kex_state == KEX_NOTHING && ses.kexstate.recvkexinit) { - cli_ses.state = KEXINIT_RCVD; + if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { + cli_ses.kex_state = KEXINIT_RCVD; } - if (cli_ses.state == KEXINIT_RCVD) { + if (cli_ses.kex_state == KEXINIT_RCVD) { /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT * negotiation would have failed. */ @@ -120,6 +121,7 @@ static void cli_sessionloop() { * in normal operation */ if (ses.kexstate.donefirstkex == 0) { TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")); + return; } switch (cli_ses.state) { @@ -129,6 +131,7 @@ static void cli_sessionloop() { * userauth */ send_msg_service_request(SSH_SERVICE_USERAUTH); cli_ses.state = SERVICE_AUTH_REQ_SENT; + TRACE(("leave cli_sessionloop: sent userauth service req")); return; /* userauth code */ @@ -136,10 +139,12 @@ static void cli_sessionloop() { cli_get_user(); cli_auth_getmethods(); cli_ses.state = USERAUTH_METHODS_SENT; + TRACE(("leave cli_sessionloop: sent userauth methods req")); return; case USERAUTH_FAIL_RCVD: cli_auth_try(); + TRACE(("leave cli_sessionloop: cli_auth_try")); return; /* XXX more here needed */ @@ -149,6 +154,7 @@ static void cli_sessionloop() { break; } + TRACE(("leave cli_sessionloop: fell out")); } diff --git a/common-kex.c b/common-kex.c index 9847a48..07b221b 100644 --- a/common-kex.c +++ b/common-kex.c @@ -613,6 +613,7 @@ static void read_kex_algos() { erralgo = "kex"; goto error; } + TRACE(("kex algo %s", algo->name)); ses.newkeys->algo_kex = algo->val; /* server_host_key_algorithms */ @@ -622,6 +623,7 @@ static void read_kex_algos() { erralgo = "hostkey"; goto error; } + TRACE(("hostkey algo %s", algo->name)); ses.newkeys->algo_hostkey = algo->val; /* encryption_algorithms_client_to_server */ @@ -631,6 +633,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; + TRACE(("enc algo recv %s", algo->name)); /* encryption_algorithms_server_to_client */ algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); @@ -639,6 +642,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; + TRACE(("enc algo trans %s", algo->name)); /* mac_algorithms_client_to_server */ algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -647,6 +651,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; + TRACE(("mac algo recv %s", algo->name)); /* mac_algorithms_server_to_client */ algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -655,6 +660,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; + TRACE(("mac algo trans %s", algo->name)); /* compression_algorithms_client_to_server */ algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -663,6 +669,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->recv_algo_comp = algo->val; + TRACE(("comp algo recv %s", algo->name)); /* compression_algorithms_server_to_client */ algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -671,6 +678,7 @@ static void read_kex_algos() { goto error; } ses.newkeys->trans_algo_comp = algo->val; + TRACE(("comp algo trans %s", algo->name)); /* languages_client_to_server */ buf_eatstring(ses.payload); diff --git a/common-session.c b/common-session.c index 93e7c74..79166f4 100644 --- a/common-session.c +++ b/common-session.c @@ -75,6 +75,7 @@ void common_session_init(int sock, char* remotehost) { ses.requirenext = SSH_MSG_KEXINIT; ses.dataallowed = 0; /* don't send data yet, we'll wait until after kex */ ses.ignorenext = 0; + ses.lastpacket = 0; /* set all the algos to none */ ses.keys = (struct key_context*)m_malloc(sizeof(struct key_context)); diff --git a/dss.c b/dss.c index ebe80c6..74b92c7 100644 --- a/dss.c +++ b/dss.c @@ -45,6 +45,7 @@ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_get_dss_pub_key(buffer* buf, dss_key *key) { + TRACE(("enter buf_get_dss_pub_key")); assert(key != NULL); key->p = m_malloc(sizeof(mp_int)); key->q = m_malloc(sizeof(mp_int)); @@ -58,14 +59,17 @@ int buf_get_dss_pub_key(buffer* buf, dss_key *key) { || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) { + TRACE(("leave buf_get_dss_pub_key: failed reading mpints")); return DROPBEAR_FAILURE; } if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) { dropbear_log(LOG_WARNING, "DSS key too short"); + TRACE(("leave buf_get_dss_pub_key: short key")); return DROPBEAR_FAILURE; } + TRACE(("leave buf_get_dss_pub_key: success")); return DROPBEAR_SUCCESS; } diff --git a/process-packet.c b/process-packet.c index f9f6dee..3e6b79c 100644 --- a/process-packet.c +++ b/process-packet.c @@ -50,6 +50,8 @@ void process_packet() { type = buf_getbyte(ses.payload); TRACE(("process_packet: packet type = %d", type)); + ses.lastpacket = type; + /* These packets we can receive at any time */ switch(type) { diff --git a/rsa.c b/rsa.c index 936b2c8..2d63c02 100644 --- a/rsa.c +++ b/rsa.c @@ -205,6 +205,8 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, mp_int *rsa_em = NULL; int ret = DROPBEAR_FAILURE; + TRACE(("enter buf_rsa_verify")); + assert(key != NULL); m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); @@ -217,6 +219,7 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos), buf->len - buf->pos) != MP_OKAY) { + TRACE(("failed reading rsa_s")); goto out; } @@ -230,17 +233,20 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, rsa_em = rsa_pad_em(key, data, len); if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { + TRACE(("failed exptmod rsa_s")); goto out; } if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { /* signature is valid */ + TRACE(("success!")); ret = DROPBEAR_SUCCESS; } out: mp_clear_multi(rsa_em, &rsa_mdash, &rsa_s, NULL); m_free(rsa_em); + TRACE(("leave buf_rsa_verify: ret %d", ret)); return ret; } diff --git a/service.h b/service.h index 5f50347..197d8d1 100644 --- a/service.h +++ b/service.h @@ -27,5 +27,6 @@ void recv_msg_service_request(); /* Server */ void send_msg_service_request(); /* Client */ +void recv_msg_service_accept(); /* Client */ #endif /* _SERVICE_H_ */ diff --git a/session.h b/session.h index 4a7e0ac..bf6adb3 100644 --- a/session.h +++ b/session.h @@ -119,6 +119,8 @@ struct sshsession { unsigned char ignorenext; /* whether to ignore the next packet, used for kex_follows stuff */ + + unsigned char lastpacket; /* What the last received packet type was */ diff --git a/signkey.c b/signkey.c index 5fcdbbf..faf3739 100644 --- a/signkey.c +++ b/signkey.c @@ -52,8 +52,12 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { unsigned char* ident; unsigned int len; + TRACE(("enter buf_get_pub_key")); + printhex(buf_getptr(buf, 0x99), 0x99); + ident = buf_getstring(buf, &len); + #ifdef DROPBEAR_DSS if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0 && (*type == DROPBEAR_SIGNKEY_ANY @@ -78,6 +82,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { return buf_get_rsa_pub_key(buf, key->rsakey); } #endif + TRACE(("leave buf_get_pub_key: didn't match the type we want (%d versus '%s'len %d)", *type, ident, len)); m_free(ident); @@ -352,6 +357,8 @@ int buf_verify(buffer * buf, sign_key *key, const unsigned char *data, unsigned char * ident = NULL; unsigned int identlen = 0; + TRACE(("enter buf_verify")); + bloblen = buf_getint(buf); ident = buf_getstring(buf, &identlen); -- cgit v1.2.3 From e1491b8ec67e0e24b93a7b2997172d57b23a933c Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 29 Jul 2004 02:19:03 +0000 Subject: set the isserver flag (oops) fix password auth for the server --HG-- extra : convert_revision : 234eb604aabaef9ed0dd496ff8db8ecc212ca18c --- cli-auth.c | 25 ++----------------------- cli-authpasswd.c | 5 +++-- cli-session.c | 3 ++- common-kex.c | 11 ++++++----- svr-auth.c | 7 ++++++- svr-session.c | 2 ++ 6 files changed, 21 insertions(+), 32 deletions(-) (limited to 'common-kex.c') diff --git a/cli-auth.c b/cli-auth.c index d222d7e..3759ff5 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -13,27 +13,6 @@ void cli_authinitialise() { } -void cli_get_user() { - - uid_t uid; - struct passwd *pw; - - TRACE(("enter cli_get_user")); - if (cli_opts.username != NULL) { - ses.authstate.username = cli_opts.username; - } else { - uid = getuid(); - - pw = getpwuid(uid); - if (pw == NULL || pw->pw_name == NULL) { - dropbear_exit("Couldn't find username for current user"); - } - - ses.authstate.username = m_strdup(pw->pw_name); - } - TRACE(("leave cli_get_user: %s", ses.authstate.username)); -} - /* Send a "none" auth request to get available methods */ void cli_auth_getmethods() { @@ -42,8 +21,8 @@ void cli_auth_getmethods() { CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); - buf_putstring(ses.writepayload, ses.authstate.username, - strlen(ses.authstate.username)); + buf_putstring(ses.writepayload, cli_opts.username, + strlen(cli_opts.username)); buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ diff --git a/cli-authpasswd.c b/cli-authpasswd.c index 6185334..c04d240 100644 --- a/cli-authpasswd.c +++ b/cli-authpasswd.c @@ -3,6 +3,7 @@ #include "dbutil.h" #include "session.h" #include "ssh.h" +#include "runopts.h" int cli_auth_password() { @@ -14,8 +15,8 @@ int cli_auth_password() { buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); - buf_putstring(ses.writepayload, ses.authstate.username, - strlen(ses.authstate.username)); + buf_putstring(ses.writepayload, cli_opts.username, + strlen(cli_opts.username)); buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); diff --git a/cli-session.c b/cli-session.c index 2ae2719..c999aed 100644 --- a/cli-session.c +++ b/cli-session.c @@ -83,6 +83,8 @@ static void cli_session_init() { /* packet handlers */ ses.packettypes = cli_packettypes; + + ses.isserver = 0; } /* This function drives the progress of the session - it initiates KEX, @@ -136,7 +138,6 @@ static void cli_sessionloop() { /* userauth code */ case SERVICE_AUTH_ACCEPT_RCVD: - cli_get_user(); cli_auth_getmethods(); cli_ses.state = USERAUTH_METHODS_SENT; TRACE(("leave cli_sessionloop: sent userauth methods req")); diff --git a/common-kex.c b/common-kex.c index 07b221b..49cbfa4 100644 --- a/common-kex.c +++ b/common-kex.c @@ -55,7 +55,7 @@ const unsigned char dh_p_val[] = { const int DH_G_VAL = 2; static void kexinitialise(); -static void gen_new_keys(); +void gen_new_keys(); #ifndef DISABLE_ZLIB static void gen_new_zstreams(); #endif @@ -253,7 +253,7 @@ static void hashkeys(unsigned char *out, int outlen, * taken into use after both sides have sent a newkeys message */ /* Originally from kex.c, generalized for cli/svr mode --mihnea */ -static void gen_new_keys() { +void gen_new_keys() { unsigned char C2S_IV[MAX_IV_LEN]; unsigned char C2S_key[MAX_KEY_LEN]; @@ -276,9 +276,6 @@ static void gen_new_keys() { sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); m_burn(ses.hash, SHA1_HASH_SIZE); - hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); - hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); - if (IS_DROPBEAR_CLIENT) { trans_IV = C2S_IV; recv_IV = S2C_IV; @@ -299,6 +296,8 @@ static void gen_new_keys() { macrecvletter = 'E'; } + hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); + hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); hashkeys(C2S_key, C2S_keysize, &hs, 'C'); hashkeys(S2C_key, S2C_keysize, &hs, 'D'); @@ -580,6 +579,8 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), ses.kexhashbuf->len); sha1_done(&hs, ses.hash); + + buf_burn(ses.kexhashbuf); buf_free(ses.kexhashbuf); ses.kexhashbuf = NULL; diff --git a/svr-auth.c b/svr-auth.c index 0f0ef67..db1d6a4 100644 --- a/svr-auth.c +++ b/svr-auth.c @@ -58,7 +58,7 @@ static void authclear() { ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; #endif #ifdef DROPBEAR_PASSWORD_AUTH - if (svr_opts.noauthpass) { + if (!svr_opts.noauthpass) { ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; } #endif @@ -100,6 +100,7 @@ void recv_msg_userauth_request() { /* ignore packets if auth is already done */ if (ses.authstate.authdone == 1) { + TRACE(("leave recv_msg_userauth_request: authdone already")); return; } @@ -129,6 +130,7 @@ void recv_msg_userauth_request() { if (methodlen == AUTH_METHOD_NONE_LEN && strncmp(methodname, AUTH_METHOD_NONE, AUTH_METHOD_NONE_LEN) == 0) { + TRACE(("recv_msg_userauth_request: 'none' request")); send_msg_userauth_failure(0, 0); goto out; } @@ -305,6 +307,9 @@ void send_msg_userauth_failure(int partial, int incrfail) { buf_putbyte(ses.writepayload, partial ? 1 : 0); encrypt_packet(); + TRACE(("auth fail: methods %d, '%s'", ses.authstate.authtypes, + buf_getptr(typebuf, typebuf->len))); + if (incrfail) { usleep(300000); /* XXX improve this */ ses.authstate.failcount++; diff --git a/svr-session.c b/svr-session.c index 80c622a..c9aed49 100644 --- a/svr-session.c +++ b/svr-session.c @@ -96,6 +96,8 @@ void svr_session(int sock, int childpipe, char* remotehost) { ses.packettypes = svr_packettypes; ses.buf_match_algo = svr_buf_match_algo; + ses.isserver = 1; + /* We're ready to go now */ sessinitdone = 1; -- cgit v1.2.3 From bf785cbcec2857110a70fa0f86db7afd83f58e05 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 29 Jul 2004 15:43:26 +0000 Subject: Handle differing c2s and s2c algorithms properly --HG-- extra : convert_revision : 5a8d0e105df84e50bc3e9d80486d6986634ff900 --- common-kex.c | 73 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'common-kex.c') diff --git a/common-kex.c b/common-kex.c index 49cbfa4..b9b8ba3 100644 --- a/common-kex.c +++ b/common-kex.c @@ -411,7 +411,6 @@ void recv_msg_kexinit() { if (IS_DROPBEAR_CLIENT) { -#ifdef DROPBEAR_CLIENT /* read the peer's choice of algos */ read_kex_algos(); @@ -433,10 +432,8 @@ void recv_msg_kexinit() { buf_getptr(ses.payload, ses.payload->len), ses.payload->len); -#endif } else { /* SERVER */ -#ifdef DROPBEAR_SERVER /* read the peer's choice of algos */ read_kex_algos(); @@ -457,7 +454,6 @@ void recv_msg_kexinit() { buf_getptr(ses.transkexinit, ses.transkexinit->len), ses.transkexinit->len); ses.requirenext = SSH_MSG_KEXDH_INIT; -#endif } buf_free(ses.transkexinit); @@ -596,7 +592,17 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, * algos for the client or server. */ static void read_kex_algos() { - algo_type * algo; + /* for asymmetry */ + algo_type * c2s_hash_algo = NULL; + algo_type * s2c_hash_algo = NULL; + algo_type * c2s_cipher_algo = NULL; + algo_type * s2c_cipher_algo = NULL; + algo_type * c2s_comp_algo = NULL; + algo_type * s2c_comp_algo = NULL; + /* the generic one */ + algo_type * algo = NULL; + + /* which algo couldn't match */ char * erralgo = NULL; int goodguess = 0; @@ -628,58 +634,46 @@ static void read_kex_algos() { ses.newkeys->algo_hostkey = algo->val; /* encryption_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); + c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc c->s"; goto error; } - ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; - TRACE(("enc algo recv %s", algo->name)); /* encryption_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); + s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc s->c"; goto error; } - ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; - TRACE(("enc algo trans %s", algo->name)); /* mac_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); + c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac c->s"; goto error; } - ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; - TRACE(("mac algo recv %s", algo->name)); /* mac_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); + s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac s->c"; goto error; } - ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; - TRACE(("mac algo trans %s", algo->name)); /* compression_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); + c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp c->s"; goto error; } - ses.newkeys->recv_algo_comp = algo->val; - TRACE(("comp algo recv %s", algo->name)); /* compression_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); + s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp s->c"; goto error; } - ses.newkeys->trans_algo_comp = algo->val; - TRACE(("comp algo trans %s", algo->name)); /* languages_client_to_server */ buf_eatstring(ses.payload); @@ -696,6 +690,39 @@ static void read_kex_algos() { } } + /* Handle the asymmetry */ + if (IS_DROPBEAR_CLIENT) { + ses.newkeys->recv_algo_crypt = + (struct dropbear_cipher*)s2c_cipher_algo->data; + ses.newkeys->trans_algo_crypt = + (struct dropbear_cipher*)c2s_cipher_algo->data; + ses.newkeys->recv_algo_mac = + (struct dropbear_hash*)s2c_hash_algo->data; + ses.newkeys->trans_algo_mac = + (struct dropbear_hash*)c2s_hash_algo->data; + ses.newkeys->recv_algo_comp = s2c_comp_algo->val; + ses.newkeys->trans_algo_comp = c2s_comp_algo->val; + } else { + /* SERVER */ + ses.newkeys->recv_algo_crypt = + (struct dropbear_cipher*)c2s_cipher_algo->data; + ses.newkeys->trans_algo_crypt = + (struct dropbear_cipher*)s2c_cipher_algo->data; + ses.newkeys->recv_algo_mac = + (struct dropbear_hash*)c2s_hash_algo->data; + ses.newkeys->trans_algo_mac = + (struct dropbear_hash*)s2c_hash_algo->data; + ses.newkeys->recv_algo_comp = c2s_comp_algo->val; + ses.newkeys->trans_algo_comp = s2c_comp_algo->val; + } + + TRACE(("enc algo recv %s", algo->name)); + TRACE(("enc algo trans %s", algo->name)); + TRACE(("mac algo recv %s", algo->name)); + TRACE(("mac algo trans %s", algo->name)); + TRACE(("comp algo recv %s", algo->name)); + TRACE(("comp algo trans %s", algo->name)); + /* reserved for future extensions */ buf_getint(ses.payload); return; -- cgit v1.2.3 From 703c9a7370f856af030873562a89cccdb71fed8f Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sat, 14 Aug 2004 17:54:20 +0000 Subject: License boilerplate etc, add Mihnea as an author to some of the files --HG-- extra : convert_revision : 75c02f80c4ed25bd4697e7f17ffac6eded54c148 --- LICENSE | 14 +++++++++++--- cli-auth.c | 25 +++++++++++++++++++++++++ cli-authpasswd.c | 24 ++++++++++++++++++++++++ cli-authpubkey.c | 25 +++++++++++++++++++++++++ cli-chansession.c | 25 +++++++++++++++++++++++++ cli-kex.c | 3 ++- cli-main.c | 26 ++++++++++++++++++++++++++ cli-service.c | 25 +++++++++++++++++++++++++ cli-session.c | 27 ++++++++++++++++++++++++++- cli-tcpfwd.c | 24 ++++++++++++++++++++++++ common-algo.c | 3 ++- common-kex.c | 6 +----- compat.h | 24 ++++++++++++++++++++++++ dbmulti.c | 24 ++++++++++++++++++++++++ keyimport.h | 24 ++++++++++++++++++++++++ listener.c | 26 +++++++++++++++++++++++++- listener.h | 24 ++++++++++++++++++++++++ svr-algo.c | 26 ++++++++++++++++++++++++++ svr-kex.c | 1 + svr-tcpfwd.c | 25 +++++++++++++++++++++++++ tcp-accept.c | 24 ++++++++++++++++++++++++ 21 files changed, 413 insertions(+), 12 deletions(-) (limited to 'common-kex.c') diff --git a/LICENSE b/LICENSE index 9dfc16d..e0a11ac 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,15 @@ -The majority of code is written by Matt Johnston, under the following license: +Dropbear contains a number of components from different sources, hence there +are a few licenses and authors involved. All licenses are fairly +non-restrictive. -Copyright (c) 2002,2003 Matt Johnston + +The majority of code is written by Matt Johnston, under the license below. + +Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the +same license: + +Copyright (c) 2002-2004 Matt Johnston +Portions copyright (c) 2004 Mihnea Stoenescu All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,7 +33,6 @@ SOFTWARE. ===== LibTomCrypt and LibTomMath are written by Tom St Denis, and are Public Domain. -Some files are from other public domain sources, see libtomcrypt/legal.txt ===== diff --git a/cli-auth.c b/cli-auth.c index 39a336e..2dd0281 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "session.h" #include "auth.h" diff --git a/cli-authpasswd.c b/cli-authpasswd.c index 2a66a06..724203b 100644 --- a/cli-authpasswd.c +++ b/cli-authpasswd.c @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "buffer.h" #include "dbutil.h" diff --git a/cli-authpubkey.c b/cli-authpubkey.c index 7e380e1..d308dc3 100644 --- a/cli-authpubkey.c +++ b/cli-authpubkey.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "buffer.h" #include "dbutil.h" diff --git a/cli-chansession.c b/cli-chansession.c index 6c48f05..c6855a3 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "packet.h" #include "buffer.h" diff --git a/cli-kex.c b/cli-kex.c index c07588a..dc05501 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -1,7 +1,8 @@ /* * Dropbear - a SSH2 server * - * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2002-2004 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/cli-main.c b/cli-main.c index 106cc64..659177e 100644 --- a/cli-main.c +++ b/cli-main.c @@ -1,3 +1,29 @@ +/* + * Dropbear - a SSH2 server + * SSH client implementation + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "dbutil.h" #include "runopts.h" diff --git a/cli-service.c b/cli-service.c index 8fbbad4..d14c77f 100644 --- a/cli-service.c +++ b/cli-service.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "service.h" #include "dbutil.h" diff --git a/cli-session.c b/cli-session.c index 07a5ba8..764b874 100644 --- a/cli-session.c +++ b/cli-session.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "session.h" #include "dbutil.h" @@ -21,7 +46,7 @@ struct clientsession cli_ses; /* GLOBAL */ /* Sorted in decreasing frequency will be more efficient - data and window * should be first */ static const packettype cli_packettypes[] = { - /* TYPE, AUTHREQUIRED, FUNCTION */ + /* TYPE, FUNCTION */ {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, /* client */ diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c index 8d8e605..747d8db 100644 --- a/cli-tcpfwd.c +++ b/cli-tcpfwd.c @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "options.h" #include "dbutil.h" diff --git a/common-algo.c b/common-algo.c index f71fd33..e1d22e1 100644 --- a/common-algo.c +++ b/common-algo.c @@ -1,7 +1,8 @@ /* - * Dropbear - a SSH2 server + * Dropbear SSH * * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/common-kex.c b/common-kex.c index b9b8ba3..0654b19 100644 --- a/common-kex.c +++ b/common-kex.c @@ -1,9 +1,5 @@ /* - * Dropbear - a SSH2 server - * SSH client implementation - * - * This code is copied from the larger file "kex.c" - * some functions are verbatim, others are generalized --mihnea + * Dropbear SSH * * Copyright (c) 2002-2004 Matt Johnston * Portions Copyright (c) 2004 by Mihnea Stoenescu diff --git a/compat.h b/compat.h index f4ac823..1ab344f 100644 --- a/compat.h +++ b/compat.h @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #ifndef _COMPAT_H_ #define _COMPAT_H_ diff --git a/dbmulti.c b/dbmulti.c index 24adce1..8d61c5c 100644 --- a/dbmulti.c +++ b/dbmulti.c @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" /* definitions are cleanest if we just put them here */ diff --git a/keyimport.h b/keyimport.h index f8c7b64..19f212f 100644 --- a/keyimport.h +++ b/keyimport.h @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #ifndef _KEYIMPORT_H_ #define _KEYIMPORT_H_ diff --git a/listener.c b/listener.c index 9424c6a..1a6da04 100644 --- a/listener.c +++ b/listener.c @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "listener.h" #include "session.h" @@ -47,7 +71,7 @@ void handle_listeners(fd_set * readfds) { } } } -} +} /* Woo brace matching */ /* acceptor(int fd, void* typedata) is a function to accept connections, diff --git a/listener.h b/listener.h index 11f9dc4..5092efd 100644 --- a/listener.h +++ b/listener.h @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #ifndef _LISTENER_H #define _LISTENER_H diff --git a/svr-algo.c b/svr-algo.c index dc6565a..5559da6 100644 --- a/svr-algo.c +++ b/svr-algo.c @@ -1,3 +1,29 @@ +/* + * Dropbear - a SSH2 server + * SSH client implementation + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "algo.h" #include "dbutil.h" diff --git a/svr-kex.c b/svr-kex.c index 35b50a6..816779c 100644 --- a/svr-kex.c +++ b/svr-kex.c @@ -2,6 +2,7 @@ * Dropbear - a SSH2 server * * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c index 0f22a23..7e2ee8b 100644 --- a/svr-tcpfwd.c +++ b/svr-tcpfwd.c @@ -1,3 +1,28 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 by Mihnea Stoenescu + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "ssh.h" #include "tcpfwd.h" diff --git a/tcp-accept.c b/tcp-accept.c index 63d9775..c143319 100644 --- a/tcp-accept.c +++ b/tcp-accept.c @@ -1,3 +1,27 @@ +/* + * Dropbear SSH + * + * Copyright (c) 2002,2003 Matt Johnston + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ + #include "includes.h" #include "ssh.h" #include "tcpfwd.h" -- cgit v1.2.3 From fdfc95df8b1d5c7c889e56a1028671a77f6cff5a Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Mon, 16 Aug 2004 08:59:11 +0000 Subject: - don't crash when trying to add to known_hosts if it doesn't exist - comments --HG-- extra : convert_revision : ffafd48c7494fee17a98d901e30c3372e1a092e9 --- cli-kex.c | 4 +++- common-kex.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'common-kex.c') diff --git a/cli-kex.c b/cli-kex.c index dc05501..bad559c 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -255,5 +255,7 @@ out: fclose(hostsfile); } m_free(filename); - buf_free(line); + if (line != NULL) { + buf_free(line); + } } diff --git a/common-kex.c b/common-kex.c index 0654b19..f8bfe97 100644 --- a/common-kex.c +++ b/common-kex.c @@ -464,6 +464,8 @@ void recv_msg_kexinit() { /* Initialises and generate one side of the diffie-hellman key exchange values. * See the ietf-secsh-transport draft, section 6, for details */ +/* dh_pub and dh_priv will be initialised by this function, and should be + * mp_clear()ed after finished */ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { mp_int dh_p, dh_q, dh_g; -- cgit v1.2.3 From 4a52217ed410dfbfdceee4688688d756fa0d097e Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 17 Aug 2004 10:20:20 +0000 Subject: default initialisers for mp_ints --HG-- extra : convert_revision : af69bacb50a31523e383e8f73844d04681f9e394 --- cli-kex.c | 13 ++++++++++--- common-kex.c | 9 +++++---- dss.c | 16 +++++++++++----- gendss.c | 11 ++++++++--- genrsa.c | 6 ++++-- options.h | 2 +- rsa.c | 5 +++-- svr-kex.c | 6 ++++-- 8 files changed, 46 insertions(+), 22 deletions(-) (limited to 'common-kex.c') diff --git a/cli-kex.c b/cli-kex.c index ca29e7d..90c8d29 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -45,8 +45,8 @@ void send_msg_kexdh_init() { cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); CHECKCLEARTOWRITE(); @@ -59,13 +59,18 @@ void send_msg_kexdh_init() { /* Handle a diffie-hellman key exchange reply. */ void recv_msg_kexdh_reply() { - mp_int dh_f; + DEF_MP_INT(dh_f); sign_key *hostkey = NULL; unsigned int type, keybloblen; unsigned char* keyblob = NULL; TRACE(("enter recv_msg_kexdh_reply")); + + if (cli_ses.kex_state != KEXDH_INIT_SENT) { + dropbear_exit("Received out-of-order kexdhreply"); + } + m_mp_init(&dh_f); type = ses.newkeys->algo_hostkey; TRACE(("type is %d", type)); @@ -83,7 +88,6 @@ void recv_msg_kexdh_reply() { dropbear_exit("Bad KEX packet"); } - m_mp_init(&dh_f); if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { TRACE(("failed getting mpint")); dropbear_exit("Bad KEX packet"); @@ -91,6 +95,9 @@ void recv_msg_kexdh_reply() { kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey); mp_clear(&dh_f); + mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + m_free(cli_ses.dh_e); + m_free(cli_ses.dh_x); if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) != DROPBEAR_SUCCESS) { diff --git a/common-kex.c b/common-kex.c index f8bfe97..7bb0c82 100644 --- a/common-kex.c +++ b/common-kex.c @@ -464,17 +464,18 @@ void recv_msg_kexinit() { /* Initialises and generate one side of the diffie-hellman key exchange values. * See the ietf-secsh-transport draft, section 6, for details */ -/* dh_pub and dh_priv will be initialised by this function, and should be - * mp_clear()ed after finished */ +/* dh_pub and dh_priv MUST be already initialised */ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { - mp_int dh_p, dh_q, dh_g; + DEF_MP_INT(dh_p); + DEF_MP_INT(dh_q); + DEF_MP_INT(dh_g); unsigned char randbuf[DH_P_LEN]; int dh_q_len; TRACE(("enter send_msg_kexdh_reply")); - m_mp_init_multi(&dh_g, &dh_p, &dh_q, dh_priv, dh_pub, NULL); + m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); /* read the prime and generator*/ if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) diff --git a/dss.c b/dss.c index 9b56f10..5bd358a 100644 --- a/dss.c +++ b/dss.c @@ -164,7 +164,10 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, unsigned char msghash[SHA1_HASH_SIZE]; hash_state hs; int ret = DROPBEAR_FAILURE; - mp_int val1, val2, val3, val4; + DEF_MP_INT(val1); + DEF_MP_INT(val2); + DEF_MP_INT(val3); + DEF_MP_INT(val4); char * string = NULL; int stringlen; @@ -281,13 +284,16 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, unsigned char privkeyhash[SHA512_HASH_SIZE]; unsigned char *privkeytmp; unsigned char proto_k[SHA512_HASH_SIZE]; - mp_int dss_protok; + DEF_MP_INT(dss_protok); #else unsigned char kbuf[SHA1_HASH_SIZE]; #endif - mp_int dss_k, dss_m; - mp_int dss_temp1, dss_temp2; - mp_int dss_r, dss_s; + DEF_MP_INT(dss_k); + DEF_MP_INT(dss_m); + DEF_MP_INT(dss_temp1); + DEF_MP_INT(dss_temp2); + DEF_MP_INT(dss_r); + DEF_MP_INT(dss_s); hash_state hs; TRACE(("enter buf_put_dss_sign")); diff --git a/gendss.c b/gendss.c index 5a440a1..e1b502d 100644 --- a/gendss.c +++ b/gendss.c @@ -89,7 +89,10 @@ static void getq(dss_key *key) { static void getp(dss_key *key, unsigned int size) { - mp_int tempX, tempC, tempP, temp2q; + DEF_MP_INT(tempX); + DEF_MP_INT(tempC); + DEF_MP_INT(tempP); + DEF_MP_INT(temp2q); int result; unsigned char *buf; @@ -148,7 +151,9 @@ static void getp(dss_key *key, unsigned int size) { static void getg(dss_key * key) { char printbuf[1000]; - mp_int div, h, val; + DEF_MP_INT(div); + DEF_MP_INT(h); + DEF_MP_INT(val); m_mp_init_multi(&div, &h, &val, NULL); @@ -185,7 +190,7 @@ static void getg(dss_key * key) { static void getx(dss_key *key) { - mp_int val; + DEF_MP_INT(val); char buf[QSIZE]; m_mp_init(&val); diff --git a/genrsa.c b/genrsa.c index 330ebf2..5711519 100644 --- a/genrsa.c +++ b/genrsa.c @@ -40,7 +40,9 @@ static void getrsaprime(mp_int* prime, mp_int *primeminus, rsa_key * gen_rsa_priv_key(unsigned int size) { rsa_key * key; - mp_int pminus, qminus, lcm; + DEF_MP_INT(pminus); + DEF_MP_INT(qminus); + DEF_MP_INT(lcm); key = (rsa_key*)m_malloc(sizeof(rsa_key)); @@ -95,7 +97,7 @@ static void getrsaprime(mp_int* prime, mp_int *primeminus, mp_int* rsa_e, unsigned int size) { unsigned char *buf; - mp_int temp_gcd; + DEF_MP_INT(temp_gcd); buf = (unsigned char*)m_malloc(size+1); diff --git a/options.h b/options.h index 2887c59..9e7d1ee 100644 --- a/options.h +++ b/options.h @@ -139,7 +139,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ #define ENABLE_CLI_PUBKEY_AUTH /* Random device to use - you must specify _one only_. - * DEV_RANDOM is recommended on hosts with a good /dev/urandom, otherwise use + * DEV_URANDOM is recommended on hosts with a good /dev/urandom, otherwise use * PRNGD and run prngd, specifying the socket. This device must be able to * produce a large amount of random data, so using /dev/random or Entropy * Gathering Daemon (egd) may result in halting, as it waits for more random diff --git a/rsa.c b/rsa.c index 1130e93..7e891e0 100644 --- a/rsa.c +++ b/rsa.c @@ -201,7 +201,8 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, unsigned int len) { unsigned int slen; - mp_int rsa_s, rsa_mdash; + DEF_MP_INT(rsa_s); + DEF_MP_INT(rsa_mdash); mp_int *rsa_em = NULL; int ret = DROPBEAR_FAILURE; @@ -262,7 +263,7 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, unsigned int nsize, ssize; unsigned int i; - mp_int rsa_s; + DEF_MP_INT(rsa_s); mp_int *rsa_em = NULL; TRACE(("enter buf_put_rsa_sign")); diff --git a/svr-kex.c b/svr-kex.c index 816779c..47c540e 100644 --- a/svr-kex.c +++ b/svr-kex.c @@ -44,7 +44,7 @@ static void send_msg_kexdh_reply(mp_int *dh_e); * that function, then brings the new keys into use */ void recv_msg_kexdh_init() { - mp_int dh_e; + DEF_MP_INT(dh_e); TRACE(("enter recv_msg_kexdh_init")); if (!ses.kexstate.recvkexinit) { @@ -71,9 +71,11 @@ void recv_msg_kexdh_init() { * See the ietf-secsh-transport draft, section 6, for details */ static void send_msg_kexdh_reply(mp_int *dh_e) { - mp_int dh_y, dh_f; + DEF_MP_INT(dh_y); + DEF_MP_INT(dh_f); TRACE(("enter send_msg_kexdh_reply")); + m_mp_init_multi(&dh_y, &dh_f, NULL); gen_kexdh_vals(&dh_f, &dh_y); -- cgit v1.2.3 From 8559be015aa7a5fca3598047716b8b795e855584 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 2 Sep 2004 15:24:17 +0000 Subject: Check for non-matching algos properly --HG-- extra : convert_revision : 20ab9edd3f3f714ecc4630bb97912185d88aa376 --- common-kex.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'common-kex.c') diff --git a/common-kex.c b/common-kex.c index 7bb0c82..38ce090 100644 --- a/common-kex.c +++ b/common-kex.c @@ -634,42 +634,44 @@ static void read_kex_algos() { /* encryption_algorithms_client_to_server */ c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); - if (algo == NULL) { + if (c2s_cipher_algo == NULL) { erralgo = "enc c->s"; goto error; } + TRACE(("c2s is %s", c2s_cipher_algo->name)); /* encryption_algorithms_server_to_client */ s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); - if (algo == NULL) { + if (s2c_cipher_algo == NULL) { erralgo = "enc s->c"; goto error; } + TRACE(("s2c is %s", s2c_cipher_algo->name)); /* mac_algorithms_client_to_server */ c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); - if (algo == NULL) { + if (c2s_hash_algo == NULL) { erralgo = "mac c->s"; goto error; } /* mac_algorithms_server_to_client */ s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); - if (algo == NULL) { + if (s2c_hash_algo == NULL) { erralgo = "mac s->c"; goto error; } /* compression_algorithms_client_to_server */ c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); - if (algo == NULL) { + if (c2s_comp_algo == NULL) { erralgo = "comp c->s"; goto error; } /* compression_algorithms_server_to_client */ s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); - if (algo == NULL) { + if (s2c_comp_algo == NULL) { erralgo = "comp s->c"; goto error; } -- cgit v1.2.3 From 8c1a429c446d00ad2030814e9f3d7afccc08ddf8 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sun, 2 Jan 2005 20:25:56 +0000 Subject: Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place --HG-- extra : convert_revision : d928bc851e32be7bd429bf7504b148c0e4bf7e2f --- buffer.c | 4 +- circbuffer.c | 4 +- cli-algo.c | 2 +- cli-auth.c | 30 ++++++------ cli-authpasswd.c | 4 +- cli-authpubkey.c | 32 ++++++------- cli-channel.c | 8 ++-- cli-chansession.c | 34 +++++++------- cli-kex.c | 34 +++++++------- cli-main.c | 2 +- cli-runopts.c | 22 ++++----- cli-service.c | 10 ++-- cli-session.c | 22 ++++----- cli-tcpfwd.c | 22 ++++----- common-algo.c | 2 +- common-channel.c | 136 +++++++++++++++++++++++++++--------------------------- common-kex.c | 64 ++++++++++++------------- common-session.c | 28 +++++------ dbutil.c | 42 ++++++++--------- debug.h | 4 +- dropbearkey.c | 4 +- dss.c | 24 +++++----- listener.c | 4 +- packet.c | 34 +++++++------- process-packet.c | 14 +++--- queue.c | 6 +-- rsa.c | 50 ++++++++++---------- signkey.c | 36 +++++++-------- svr-agentfwd.c | 2 +- svr-algo.c | 2 +- svr-auth.c | 44 +++++++++--------- svr-authpam.c | 20 ++++---- svr-authpubkey.c | 38 +++++++-------- svr-chansession.c | 54 +++++++++++----------- svr-kex.c | 8 ++-- svr-main.c | 6 +-- svr-runopts.c | 4 +- svr-service.c | 8 ++-- svr-tcpfwd.c | 38 +++++++-------- svr-x11fwd.c | 2 +- tcp-accept.c | 8 ++-- 41 files changed, 456 insertions(+), 456 deletions(-) (limited to 'common-kex.c') diff --git a/buffer.c b/buffer.c index 793eee1..dff861f 100644 --- a/buffer.c +++ b/buffer.c @@ -258,7 +258,7 @@ void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len) { void buf_putmpint(buffer* buf, mp_int * mp) { unsigned int len, pad = 0; - TRACE(("enter buf_putmpint")); + TRACE(("enter buf_putmpint")) assert(mp != NULL); @@ -294,7 +294,7 @@ void buf_putmpint(buffer* buf, mp_int * mp) { buf_incrwritepos(buf, len-pad); } - TRACE(("leave buf_putmpint")); + TRACE(("leave buf_putmpint")) } /* Retrieve an mp_int from the buffer. diff --git a/circbuffer.c b/circbuffer.c index a2edcbb..6dc9179 100644 --- a/circbuffer.c +++ b/circbuffer.c @@ -70,7 +70,7 @@ unsigned int cbuf_readlen(circbuffer *cbuf) { assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); if (cbuf->used == 0) { - TRACE(("cbuf_readlen: unused buffer")); + TRACE(("cbuf_readlen: unused buffer")) return 0; } @@ -88,7 +88,7 @@ unsigned int cbuf_writelen(circbuffer *cbuf) { assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); if (cbuf->used == cbuf->size) { - TRACE(("cbuf_writelen: full buffer")); + TRACE(("cbuf_writelen: full buffer")) return 0; /* full */ } diff --git a/cli-algo.c b/cli-algo.c index 5edd6a1..ec3a1ff 100644 --- a/cli-algo.c +++ b/cli-algo.c @@ -46,7 +46,7 @@ algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[], /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ algolist = buf_getstring(buf, &len); - TRACE(("cli_buf_match_algo: %s", algolist)); + TRACE(("cli_buf_match_algo: %s", algolist)) if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { goto out; /* just a sanity check, no other use */ } diff --git a/cli-auth.c b/cli-auth.c index 9dedfa8..dfd9bbb 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -42,7 +42,7 @@ void cli_authinitialise() { /* Send a "none" auth request to get available methods */ void cli_auth_getmethods() { - TRACE(("enter cli_auth_getmethods")); + TRACE(("enter cli_auth_getmethods")) CHECKCLEARTOWRITE(); @@ -54,7 +54,7 @@ void cli_auth_getmethods() { buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ encrypt_packet(); - TRACE(("leave cli_auth_getmethods")); + TRACE(("leave cli_auth_getmethods")) } @@ -64,9 +64,9 @@ void recv_msg_userauth_banner() { unsigned int bannerlen; unsigned int i, linecount; - TRACE(("enter recv_msg_userauth_banner")); + TRACE(("enter recv_msg_userauth_banner")) if (ses.authstate.authdone) { - TRACE(("leave recv_msg_userauth_banner: banner after auth done")); + TRACE(("leave recv_msg_userauth_banner: banner after auth done")) return; } @@ -74,7 +74,7 @@ void recv_msg_userauth_banner() { buf_eatstring(ses.payload); /* The language string */ if (bannerlen > MAX_BANNER_SIZE) { - TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)); + TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)) goto out; } @@ -96,7 +96,7 @@ void recv_msg_userauth_banner() { out: m_free(banner); - TRACE(("leave recv_msg_userauth_banner")); + TRACE(("leave recv_msg_userauth_banner")) } @@ -108,12 +108,12 @@ void recv_msg_userauth_failure() { unsigned int partial = 0; unsigned int i = 0; - TRACE(("<- MSG_USERAUTH_FAILURE")); - TRACE(("enter recv_msg_userauth_failure")); + TRACE(("<- MSG_USERAUTH_FAILURE")) + TRACE(("enter recv_msg_userauth_failure")) if (cli_ses.state != USERAUTH_REQ_SENT) { /* Perhaps we should be more fatal? */ - TRACE(("But we didn't send a userauth request!!!!!!")); + TRACE(("But we didn't send a userauth request!!!!!!")) return; } @@ -135,7 +135,7 @@ void recv_msg_userauth_failure() { ses.authstate.failcount++; } - TRACE(("Methods (len %d): '%s'", methlen, methods)); + TRACE(("Methods (len %d): '%s'", methlen, methods)) ses.authstate.authdone=0; ses.authstate.authtypes=0; @@ -150,7 +150,7 @@ void recv_msg_userauth_failure() { tok = methods; /* tok stores the next method we'll compare */ for (i = 0; i <= methlen; i++) { if (methods[i] == '\0') { - TRACE(("auth method '%s'", tok)); + TRACE(("auth method '%s'", tok)) #ifdef ENABLE_CLI_PUBKEY_AUTH if (strncmp(AUTH_METHOD_PUBKEY, tok, AUTH_METHOD_PUBKEY_LEN) == 0) { @@ -173,18 +173,18 @@ void recv_msg_userauth_failure() { cli_ses.state = USERAUTH_FAIL_RCVD; - TRACE(("leave recv_msg_userauth_failure")); + TRACE(("leave recv_msg_userauth_failure")) } void recv_msg_userauth_success() { - TRACE(("received msg_userauth_success")); + TRACE(("received msg_userauth_success")) ses.authstate.authdone = 1; cli_ses.state = USERAUTH_SUCCESS_RCVD; } void cli_auth_try() { - TRACE(("enter cli_auth_try")); + TRACE(("enter cli_auth_try")) int finished = 0; CHECKCLEARTOWRITE(); @@ -208,5 +208,5 @@ void cli_auth_try() { dropbear_exit("No auth methods could be used."); } - TRACE(("leave cli_auth_try")); + TRACE(("leave cli_auth_try")) } diff --git a/cli-authpasswd.c b/cli-authpasswd.c index 724203b..02bce18 100644 --- a/cli-authpasswd.c +++ b/cli-authpasswd.c @@ -33,7 +33,7 @@ int cli_auth_password() { char* password = NULL; - TRACE(("enter cli_auth_password")); + TRACE(("enter cli_auth_password")) CHECKCLEARTOWRITE(); password = getpass("Password: "); @@ -56,7 +56,7 @@ int cli_auth_password() { encrypt_packet(); m_burn(password, strlen(password)); - TRACE(("leave cli_auth_password")); + TRACE(("leave cli_auth_password")) return 1; /* Password auth can always be tried */ } diff --git a/cli-authpubkey.c b/cli-authpubkey.c index d308dc3..61b17d9 100644 --- a/cli-authpubkey.c +++ b/cli-authpubkey.c @@ -41,7 +41,7 @@ void cli_pubkeyfail() { struct PubkeyList *keyitem; struct PubkeyList **previtem; - TRACE(("enter cli_pubkeyfail")); + TRACE(("enter cli_pubkeyfail")) previtem = &cli_opts.pubkeys; /* Find the key we failed with, and remove it */ @@ -55,7 +55,7 @@ void cli_pubkeyfail() { sign_key_free(cli_ses.lastpubkey->key); /* It won't be used again */ m_free(cli_ses.lastpubkey); - TRACE(("leave cli_pubkeyfail")); + TRACE(("leave cli_pubkeyfail")) } void recv_msg_userauth_pk_ok() { @@ -67,11 +67,11 @@ void recv_msg_userauth_pk_ok() { int keytype; unsigned int remotelen; - TRACE(("enter recv_msg_userauth_pk_ok")); + TRACE(("enter recv_msg_userauth_pk_ok")) algotype = buf_getstring(ses.payload, &algolen); keytype = signkey_type_from_name(algotype, algolen); - TRACE(("recv_msg_userauth_pk_ok: type %d", keytype)); + TRACE(("recv_msg_userauth_pk_ok: type %d", keytype)) m_free(algotype); keybuf = buf_new(MAX_PUBKEY_SIZE); @@ -84,7 +84,7 @@ void recv_msg_userauth_pk_ok() { if (keyitem->type != keytype) { /* Types differed */ - TRACE(("types differed")); + TRACE(("types differed")) continue; } @@ -98,14 +98,14 @@ void recv_msg_userauth_pk_ok() { if (keybuf->len-4 != remotelen) { - TRACE(("lengths differed: localh %d remote %d", keybuf->len, remotelen)); + TRACE(("lengths differed: localh %d remote %d", keybuf->len, remotelen)) /* Lengths differed */ continue; } if (memcmp(buf_getptr(keybuf, remotelen), buf_getptr(ses.payload, remotelen), remotelen) != 0) { /* Data didn't match this key */ - TRACE(("data differed")); + TRACE(("data differed")) continue; } @@ -114,15 +114,15 @@ void recv_msg_userauth_pk_ok() { } if (keyitem != NULL) { - TRACE(("matching key")); + 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); } 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")); + 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")) } - TRACE(("leave recv_msg_userauth_pk_ok")); + TRACE(("leave recv_msg_userauth_pk_ok")) } /* TODO: make it take an agent reference to use as well */ @@ -132,7 +132,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { int algolen; buffer* sigbuf = NULL; - TRACE(("enter send_msg_userauth_pubkey")); + TRACE(("enter send_msg_userauth_pubkey")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); @@ -154,7 +154,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { buf_put_pub_key(ses.writepayload, key, type); if (realsign) { - TRACE(("realsign")); + TRACE(("realsign")) /* We put the signature as well - this contains string(session id), then * the contents of the write payload to this point */ sigbuf = buf_new(4 + SHA1_HASH_SIZE + ses.writepayload->len); @@ -165,22 +165,22 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { } encrypt_packet(); - TRACE(("leave send_msg_userauth_pubkey")); + TRACE(("leave send_msg_userauth_pubkey")) } int cli_auth_pubkey() { - TRACE(("enter cli_auth_pubkey")); + TRACE(("enter cli_auth_pubkey")) if (cli_opts.pubkeys != NULL) { /* Send a trial request */ send_msg_userauth_pubkey(cli_opts.pubkeys->key, cli_opts.pubkeys->type, 0); cli_ses.lastpubkey = cli_opts.pubkeys; - TRACE(("leave cli_auth_pubkey-success")); + TRACE(("leave cli_auth_pubkey-success")) return 1; } else { - TRACE(("leave cli_auth_pubkey-failure")); + TRACE(("leave cli_auth_pubkey-failure")) return 0; } } diff --git a/cli-channel.c b/cli-channel.c index ea4af69..42e165b 100644 --- a/cli-channel.c +++ b/cli-channel.c @@ -37,7 +37,7 @@ void recv_msg_channel_extended_data() { struct Channel *channel; unsigned int datatype; - TRACE(("enter recv_msg_channel_extended_data")); + TRACE(("enter recv_msg_channel_extended_data")) chan = buf_getint(ses.payload); channel = getchannel(chan); @@ -47,7 +47,7 @@ void recv_msg_channel_extended_data() { } if (channel->type != &clichansess) { - TRACE(("leave recv_msg_channel_extended_data: chantype is wrong")); + TRACE(("leave recv_msg_channel_extended_data: chantype is wrong")) return; /* we just ignore it */ } @@ -55,11 +55,11 @@ void recv_msg_channel_extended_data() { if (datatype != SSH_EXTENDED_DATA_STDERR) { TRACE(("leave recv_msg_channel_extended_data: wrong datatype: %d", - datatype)); + datatype)) return; } common_recv_msg_channel_data(channel, channel->errfd, channel->extrabuf); - TRACE(("leave recv_msg_channel_extended_data")); + TRACE(("leave recv_msg_channel_extended_data")) } diff --git a/cli-chansession.c b/cli-chansession.c index 35be671..76e9dfa 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -59,20 +59,20 @@ static void cli_chansessreq(struct Channel *channel) { unsigned char* type = NULL; int wantreply; - TRACE(("enter cli_chansessreq")); + TRACE(("enter cli_chansessreq")) type = buf_getstring(ses.payload, NULL); wantreply = buf_getbyte(ses.payload); if (strcmp(type, "exit-status") != 0) { - TRACE(("unknown request '%s'", type)); + TRACE(("unknown request '%s'", type)) send_msg_channel_failure(channel); goto out; } /* We'll just trust what they tell us */ cli_ses.retval = buf_getint(ses.payload); - TRACE(("got exit-status of '%d'", cli_ses.retval)); + TRACE(("got exit-status of '%d'", cli_ses.retval)) out: m_free(type); @@ -108,10 +108,10 @@ static void cli_tty_setup() { struct termios tio; - TRACE(("enter cli_pty_setup")); + TRACE(("enter cli_pty_setup")) if (cli_ses.tty_raw_mode == 1) { - TRACE(("leave cli_tty_setup: already in raw mode!")); + TRACE(("leave cli_tty_setup: already in raw mode!")) return; } @@ -139,15 +139,15 @@ static void cli_tty_setup() { } cli_ses.tty_raw_mode = 1; - TRACE(("leave cli_tty_setup")); + TRACE(("leave cli_tty_setup")) } void cli_tty_cleanup() { - TRACE(("enter cli_tty_cleanup")); + TRACE(("enter cli_tty_cleanup")) if (cli_ses.tty_raw_mode == 0) { - TRACE(("leave cli_tty_cleanup: not in raw mode")); + TRACE(("leave cli_tty_cleanup: not in raw mode")) return; } @@ -157,12 +157,12 @@ void cli_tty_cleanup() { cli_ses.tty_raw_mode = 0; } - TRACE(("leave cli_tty_cleanup")); + TRACE(("leave cli_tty_cleanup")) } static void put_termcodes() { - TRACE(("enter put_termcodes")); + TRACE(("enter put_termcodes")) struct termios tio; unsigned int sshcode; @@ -232,7 +232,7 @@ static void put_termcodes() { buf_putint(ses.writepayload, bufpos2 - bufpos1 - 4); /* len(termcodes) */ buf_setpos(ses.writepayload, bufpos2); /* Back where we were */ - TRACE(("leave put_termcodes")); + TRACE(("leave put_termcodes")) } static void put_winsize() { @@ -284,7 +284,7 @@ static void send_chansess_pty_req(struct Channel *channel) { unsigned char* term = NULL; - TRACE(("enter send_chansess_pty_req")); + TRACE(("enter send_chansess_pty_req")) start_channel_request(channel, "pty-req"); @@ -310,14 +310,14 @@ static void send_chansess_pty_req(struct Channel *channel) { if (signal(SIGWINCH, sigwinch_handler) == SIG_ERR) { dropbear_exit("signal error"); } - TRACE(("leave send_chansess_pty_req")); + TRACE(("leave send_chansess_pty_req")) } static void send_chansess_shell_req(struct Channel *channel) { unsigned char* reqtype = NULL; - TRACE(("enter send_chansess_shell_req")); + TRACE(("enter send_chansess_shell_req")) if (cli_opts.cmd) { reqtype = "exec"; @@ -334,7 +334,7 @@ static void send_chansess_shell_req(struct Channel *channel) { } encrypt_packet(); - TRACE(("leave send_chansess_shell_req")); + TRACE(("leave send_chansess_shell_req")) } static int cli_initchansess(struct Channel *channel) { @@ -367,7 +367,7 @@ static int cli_initchansess(struct Channel *channel) { void cli_send_chansess_request() { - TRACE(("enter cli_send_chansess_request")); + TRACE(("enter cli_send_chansess_request")) if (send_msg_channel_open_init(STDIN_FILENO, &clichansess) == DROPBEAR_FAILURE) { dropbear_exit("Couldn't open initial channel"); @@ -375,6 +375,6 @@ void cli_send_chansess_request() { /* No special channel request data */ encrypt_packet(); - TRACE(("leave cli_send_chansess_request")); + TRACE(("leave cli_send_chansess_request")) } diff --git a/cli-kex.c b/cli-kex.c index c8949ef..03a0670 100644 --- a/cli-kex.c +++ b/cli-kex.c @@ -65,14 +65,14 @@ void recv_msg_kexdh_reply() { unsigned char* keyblob = NULL; - TRACE(("enter recv_msg_kexdh_reply")); + TRACE(("enter recv_msg_kexdh_reply")) if (cli_ses.kex_state != KEXDH_INIT_SENT) { dropbear_exit("Received out-of-order kexdhreply"); } m_mp_init(&dh_f); type = ses.newkeys->algo_hostkey; - TRACE(("type is %d", type)); + TRACE(("type is %d", type)) hostkey = new_sign_key(); keybloblen = buf_getint(ses.payload); @@ -84,12 +84,12 @@ void recv_msg_kexdh_reply() { } if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { - TRACE(("failed getting pubkey")); + TRACE(("failed getting pubkey")) dropbear_exit("Bad KEX packet"); } if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { - TRACE(("failed getting mpint")); + TRACE(("failed getting mpint")) dropbear_exit("Bad KEX packet"); } @@ -109,7 +109,7 @@ void recv_msg_kexdh_reply() { send_msg_newkeys(); ses.requirenext = SSH_MSG_NEWKEYS; - TRACE(("leave recv_msg_kexdh_init")); + TRACE(("leave recv_msg_kexdh_init")) } static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) { @@ -156,7 +156,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { if (errno != EEXIST) { dropbear_log(LOG_INFO, "Warning: failed creating ~/.ssh: %s", strerror(errno)); - TRACE(("mkdir didn't work: %s", strerror(errno))); + TRACE(("mkdir didn't work: %s", strerror(errno))) ask_to_confirm(keyblob, keybloblen); goto out; /* only get here on success */ } @@ -170,14 +170,14 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { } else { /* We mightn't have been able to open it if it was read-only */ if (errno == EACCES || errno == EROFS) { - TRACE(("trying readonly: %s", strerror(errno))); + TRACE(("trying readonly: %s", strerror(errno))) readonly = 1; hostsfile = fopen(filename, "r"); } } if (hostsfile == NULL) { - TRACE(("hostsfile didn't open: %s", strerror(errno))); + TRACE(("hostsfile didn't open: %s", strerror(errno))) ask_to_confirm(keyblob, keybloblen); goto out; /* We only get here on success */ } @@ -188,7 +188,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { do { if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) { - TRACE(("failed reading line: prob EOF")); + TRACE(("failed reading line: prob EOF")) break; } @@ -197,32 +197,32 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { * buf_getfoo() past the end and die horribly - the base64 parsing * code is what tiptoes up to the end nicely */ if (line->len < (hostlen+30) ) { - TRACE(("line is too short to be sensible")); + TRACE(("line is too short to be sensible")) continue; } /* Compare hostnames */ if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen), hostlen) != 0) { - TRACE(("hosts don't match")); + TRACE(("hosts don't match")) continue; } buf_incrpos(line, hostlen); if (buf_getbyte(line) != ' ') { /* there wasn't a space after the hostname, something dodgy */ - TRACE(("missing space afte matching hostname")); + TRACE(("missing space afte matching hostname")) continue; } if ( strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) { - TRACE(("algo doesn't match")); + TRACE(("algo doesn't match")) continue; } buf_incrpos(line, algolen); if (buf_getbyte(line) != ' ') { - TRACE(("missing space after algo")); + TRACE(("missing space after algo")) continue; } @@ -231,7 +231,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { if (ret == DROPBEAR_SUCCESS) { /* Good matching key */ - TRACE(("good matching key")); + TRACE(("good matching key")) goto out; } @@ -244,7 +244,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { /* If we get here, they said yes */ if (readonly) { - TRACE(("readonly")); + TRACE(("readonly")) goto out; } @@ -257,7 +257,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { buf_putbytes(line, algoname, algolen); buf_putbyte(line, ' '); len = line->size - line->pos; - TRACE(("keybloblen %d, len %d", keybloblen, len)); + TRACE(("keybloblen %d, len %d", keybloblen, len)) /* The only failure with base64 is buffer_overflow, but buf_getwriteptr * will die horribly in the case anyway */ base64_encode(keyblob, keybloblen, buf_getwriteptr(line, len), &len); diff --git a/cli-main.c b/cli-main.c index def2c72..3f767c9 100644 --- a/cli-main.c +++ b/cli-main.c @@ -50,7 +50,7 @@ int main(int argc, char ** argv) { cli_getopts(argc, argv); TRACE(("user='%s' host='%s' port='%s'", cli_opts.username, - cli_opts.remotehost, cli_opts.remoteport)); + cli_opts.remotehost, cli_opts.remoteport)) if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { dropbear_exit("signal() error"); diff --git a/cli-runopts.c b/cli-runopts.c index b8ecdc0..3ac5c2b 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -116,7 +116,7 @@ void cli_getopts(int argc, char ** argv) { #endif #ifdef ENABLE_CLI_REMOTETCPFWD if (nextisremote) { - TRACE(("nextisremote true")); + TRACE(("nextisremote true")) addforward(argv[i], &cli_opts.remotefwds); nextisremote = 0; continue; @@ -124,7 +124,7 @@ void cli_getopts(int argc, char ** argv) { #endif #ifdef ENABLE_CLI_LOCALTCPFWD if (nextislocal) { - TRACE(("nextislocal true")); + TRACE(("nextislocal true")) addforward(argv[i], &cli_opts.localfwds); nextislocal = 0; continue; @@ -214,7 +214,7 @@ void cli_getopts(int argc, char ** argv) { continue; /* next argument */ } else { - TRACE(("non-flag arg: '%s'", argv[i])); + TRACE(("non-flag arg: '%s'", argv[i])) /* Either the hostname or commands */ @@ -343,7 +343,7 @@ static void addforward(char* origstr, struct TCPFwdList** fwdlist) { struct TCPFwdList* newfwd = NULL; char * str = NULL; - TRACE(("enter addforward")); + TRACE(("enter addforward")) /* We probably don't want to be editing argvs */ str = m_strdup(origstr); @@ -352,7 +352,7 @@ static void addforward(char* origstr, struct TCPFwdList** fwdlist) { connectaddr = strchr(str, ':'); if (connectaddr == NULL) { - TRACE(("connectaddr == NULL")); + TRACE(("connectaddr == NULL")) goto fail; } @@ -361,7 +361,7 @@ static void addforward(char* origstr, struct TCPFwdList** fwdlist) { connectport = strchr(connectaddr, ':'); if (connectport == NULL) { - TRACE(("connectport == NULL")); + TRACE(("connectport == NULL")) goto fail; } @@ -374,32 +374,32 @@ static void addforward(char* origstr, struct TCPFwdList** fwdlist) { * the check later only checks for >= MAX_PORT */ newfwd->listenport = strtol(listenport, NULL, 10); if (errno != 0) { - TRACE(("bad listenport strtol")); + TRACE(("bad listenport strtol")) goto fail; } newfwd->connectport = strtol(connectport, NULL, 10); if (errno != 0) { - TRACE(("bad connectport strtol")); + TRACE(("bad connectport strtol")) goto fail; } newfwd->connectaddr = connectaddr; if (newfwd->listenport > 65535) { - TRACE(("listenport > 65535")); + TRACE(("listenport > 65535")) goto badport; } if (newfwd->connectport > 65535) { - TRACE(("connectport > 65535")); + TRACE(("connectport > 65535")) goto badport; } newfwd->next = *fwdlist; *fwdlist = newfwd; - TRACE(("leave addforward: done")); + TRACE(("leave addforward: done")) return; fail: diff --git a/cli-service.c b/cli-service.c index d14c77f..87b6ed2 100644 --- a/cli-service.c +++ b/cli-service.c @@ -33,7 +33,7 @@ void send_msg_service_request(char* servicename) { - TRACE(("enter send_msg_service_request: servicename='%s'", servicename)); + TRACE(("enter send_msg_service_request: servicename='%s'", servicename)) CHECKCLEARTOWRITE(); @@ -41,7 +41,7 @@ void send_msg_service_request(char* servicename) { buf_putstring(ses.writepayload, servicename, strlen(servicename)); encrypt_packet(); - TRACE(("leave send_msg_service_request")); + TRACE(("leave send_msg_service_request")) } /* This just sets up the state variables right for the main client session loop @@ -51,7 +51,7 @@ void recv_msg_service_accept() { unsigned char* servicename; unsigned int len; - TRACE(("enter recv_msg_service_accept")); + TRACE(("enter recv_msg_service_accept")) servicename = buf_getstring(ses.payload, &len); @@ -62,7 +62,7 @@ void recv_msg_service_accept() { cli_ses.state = SERVICE_AUTH_ACCEPT_RCVD; m_free(servicename); - TRACE(("leave recv_msg_service_accept: done ssh-userauth")); + TRACE(("leave recv_msg_service_accept: done ssh-userauth")) return; } @@ -77,7 +77,7 @@ void recv_msg_service_accept() { cli_ses.state = SERVICE_CONN_ACCEPT_RCVD; m_free(servicename); - TRACE(("leave recv_msg_service_accept: done ssh-connection")); + TRACE(("leave recv_msg_service_accept: done ssh-connection")) return; } diff --git a/cli-session.c b/cli-session.c index 0ea33af..4d6a645 100644 --- a/cli-session.c +++ b/cli-session.c @@ -139,7 +139,7 @@ static void cli_session_init() { * service, userauth and channel requests */ static void cli_sessionloop() { - TRACE(("enter cli_sessionloop")); + TRACE(("enter cli_sessionloop")) if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { cli_ses.kex_state = KEXINIT_RCVD; @@ -151,7 +151,7 @@ static void cli_sessionloop() { * negotiation would have failed. */ send_msg_kexdh_init(); cli_ses.kex_state = KEXDH_INIT_SENT; - TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD")); + TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD")) return; } @@ -163,14 +163,14 @@ static void cli_sessionloop() { /* We shouldn't do anything else if a KEX is in progress */ if (cli_ses.kex_state != KEX_NOTHING) { - TRACE(("leave cli_sessionloop: kex_state != KEX_NOTHING")); + TRACE(("leave cli_sessionloop: kex_state != KEX_NOTHING")) return; } /* We should exit if we haven't donefirstkex: we shouldn't reach here * in normal operation */ if (ses.kexstate.donefirstkex == 0) { - TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")); + TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")) return; } @@ -181,32 +181,32 @@ static void cli_sessionloop() { * userauth */ send_msg_service_request(SSH_SERVICE_USERAUTH); cli_ses.state = SERVICE_AUTH_REQ_SENT; - TRACE(("leave cli_sessionloop: sent userauth service req")); + TRACE(("leave cli_sessionloop: sent userauth service req")) return; /* userauth code */ case SERVICE_AUTH_ACCEPT_RCVD: cli_auth_getmethods(); cli_ses.state = USERAUTH_REQ_SENT; - TRACE(("leave cli_sessionloop: sent userauth methods req")); + TRACE(("leave cli_sessionloop: sent userauth methods req")) return; case USERAUTH_FAIL_RCVD: cli_auth_try(); cli_ses.state = USERAUTH_REQ_SENT; - TRACE(("leave cli_sessionloop: cli_auth_try")); + TRACE(("leave cli_sessionloop: cli_auth_try")) return; /* case USERAUTH_SUCCESS_RCVD: send_msg_service_request(SSH_SERVICE_CONNECTION); cli_ses.state = SERVICE_CONN_REQ_SENT; - TRACE(("leave cli_sessionloop: sent ssh-connection service req")); + TRACE(("leave cli_sessionloop: sent ssh-connection service req")) return; case SERVICE_CONN_ACCEPT_RCVD: cli_send_chansess_request(); - TRACE(("leave cli_sessionloop: cli_send_chansess_request")); + TRACE(("leave cli_sessionloop: cli_send_chansess_request")) cli_ses.state = SESSION_RUNNING; return; */ @@ -219,7 +219,7 @@ static void cli_sessionloop() { setup_remotetcp(); #endif cli_send_chansess_request(); - TRACE(("leave cli_sessionloop: cli_send_chansess_request")); + TRACE(("leave cli_sessionloop: cli_send_chansess_request")) cli_ses.state = SESSION_RUNNING; return; @@ -240,7 +240,7 @@ static void cli_sessionloop() { break; } - TRACE(("leave cli_sessionloop: fell out")); + TRACE(("leave cli_sessionloop: fell out")) } diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c index b4d99e9..aa5b720 100644 --- a/cli-tcpfwd.c +++ b/cli-tcpfwd.c @@ -62,10 +62,10 @@ void setup_localtcp() { int ret; - TRACE(("enter setup_localtcp")); + TRACE(("enter setup_localtcp")) if (cli_opts.localfwds == NULL) { - TRACE(("cli_opts.localfwds == NULL")); + TRACE(("cli_opts.localfwds == NULL")) } while (cli_opts.localfwds != NULL) { @@ -81,7 +81,7 @@ void setup_localtcp() { cli_opts.localfwds = cli_opts.localfwds->next; } - TRACE(("leave setup_localtcp")); + TRACE(("leave setup_localtcp")) } @@ -105,7 +105,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, if (ret == DROPBEAR_FAILURE) { m_free(tcpinfo); } - TRACE(("leave cli_localtcp: %d", ret)); + TRACE(("leave cli_localtcp: %d", ret)) return ret; } #endif /* ENABLE_CLI_LOCALTCPFWD */ @@ -113,7 +113,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, #ifdef ENABLE_CLI_REMOTETCPFWD static void send_msg_global_request_remotetcp(int port) { - TRACE(("enter send_msg_global_request_remotetcp")); + TRACE(("enter send_msg_global_request_remotetcp")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); @@ -124,17 +124,17 @@ static void send_msg_global_request_remotetcp(int port) { encrypt_packet(); - TRACE(("leave send_msg_global_request_remotetcp")); + TRACE(("leave send_msg_global_request_remotetcp")) } void setup_remotetcp() { struct TCPFwdList * iter = NULL; - TRACE(("enter setup_remotetcp")); + TRACE(("enter setup_remotetcp")) if (cli_opts.remotefwds == NULL) { - TRACE(("cli_opts.remotefwds == NULL")); + TRACE(("cli_opts.remotefwds == NULL")) } iter = cli_opts.remotefwds; @@ -143,7 +143,7 @@ void setup_remotetcp() { send_msg_global_request_remotetcp(iter->listenport); iter = iter->next; } - TRACE(("leave setup_remotetcp")); + TRACE(("leave setup_remotetcp")) } static int newtcpforwarded(struct Channel * channel) { @@ -179,7 +179,7 @@ static int newtcpforwarded(struct Channel * channel) { snprintf(portstring, sizeof(portstring), "%d", iter->connectport); sock = connect_remote(iter->connectaddr, portstring, 1, NULL); if (sock < 0) { - TRACE(("leave newtcpdirect: sock failed")); + TRACE(("leave newtcpdirect: sock failed")) err = SSH_OPEN_CONNECT_FAILED; goto out; } @@ -196,7 +196,7 @@ static int newtcpforwarded(struct Channel * channel) { err = SSH_OPEN_IN_PROGRESS; out: - TRACE(("leave newtcpdirect: err %d", err)); + TRACE(("leave newtcpdirect: err %d", err)) return err; } #endif /* ENABLE_CLI_REMOTETCPFWD */ diff --git a/common-algo.c b/common-algo.c index 22cdc70..1975864 100644 --- a/common-algo.c +++ b/common-algo.c @@ -202,6 +202,6 @@ void buf_put_algolist(buffer * buf, algo_type localalgos[]) { } str[pos]=0; /* Debug this */ - TRACE(("buf_put_algolist: %s", str)); + TRACE(("buf_put_algolist: %s", str)) buf_putstring(buf, str, pos); } diff --git a/common-channel.c b/common-channel.c index 1d703a2..6f73fab 100644 --- a/common-channel.c +++ b/common-channel.c @@ -81,15 +81,15 @@ void chancleanup() { unsigned int i; - TRACE(("enter chancleanup")); + TRACE(("enter chancleanup")) for (i = 0; i < ses.chansize; i++) { if (ses.channels[i] != NULL) { - TRACE(("channel %d closing", i)); + TRACE(("channel %d closing", i)) removechannel(ses.channels[i]); } } m_free(ses.channels); - TRACE(("leave chancleanup")); + TRACE(("leave chancleanup")) } /* Create a new channel entry, send a reply confirm or failure */ @@ -103,7 +103,7 @@ struct Channel* newchannel(unsigned int remotechan, struct Channel * newchan; unsigned int i, j; - TRACE(("enter newchannel")); + TRACE(("enter newchannel")) /* first see if we can use existing channels */ for (i = 0; i < ses.chansize; i++) { @@ -115,7 +115,7 @@ struct Channel* newchannel(unsigned int remotechan, /* otherwise extend the list */ if (i == ses.chansize) { if (ses.chansize >= MAX_CHANNELS) { - TRACE(("leave newchannel: max chans reached")); + TRACE(("leave newchannel: max chans reached")) return NULL; } @@ -157,7 +157,7 @@ struct Channel* newchannel(unsigned int remotechan, ses.channels[i] = newchan; ses.chancount++; - TRACE(("leave newchannel")); + TRACE(("leave newchannel")) return newchan; } @@ -246,13 +246,13 @@ void channelio(fd_set *readfd, fd_set *writefd) { /* do all the EOF/close type stuff checking for a channel */ static void checkclose(struct Channel *channel) { - TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d", + TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d", channel->infd, channel->outfd, - channel->errfd, channel->sentclosed, channel->recvclosed)); + channel->errfd, channel->sentclosed, channel->recvclosed)) TRACE(("writebuf %d extrabuf %s extrabuf %d", cbuf_getused(channel->writebuf), channel->writebuf, - channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))); + channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) if (!channel->sentclosed) { @@ -289,7 +289,7 @@ static void checkclose(struct Channel *channel) { */ if (channel->recvclosed) { if (! channel->sentclosed) { - TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")); + TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) send_msg_channel_close(channel); } removechannel(channel); @@ -306,7 +306,7 @@ static void checkinitdone(struct Channel *channel) { int val; socklen_t vallen = sizeof(val); - TRACE(("enter checkinitdone")); + TRACE(("enter checkinitdone")) if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen) || val != 0) { @@ -314,13 +314,13 @@ static void checkinitdone(struct Channel *channel) { SSH_OPEN_CONNECT_FAILED, "", ""); close(channel->infd); deletechannel(channel); - TRACE(("leave checkinitdone: fail")); + TRACE(("leave checkinitdone: fail")) } else { send_msg_channel_open_confirmation(channel, channel->recvwindow, channel->recvmaxpacket); channel->outfd = channel->infd; channel->initconn = 0; - TRACE(("leave checkinitdone: success")); + TRACE(("leave checkinitdone: success")) } } @@ -329,7 +329,7 @@ static void checkinitdone(struct Channel *channel) { /* Send the close message and set the channel as closed */ static void send_msg_channel_close(struct Channel *channel) { - TRACE(("enter send_msg_channel_close")); + TRACE(("enter send_msg_channel_close")) /* XXX server */ if (channel->type->closehandler) { channel->type->closehandler(channel); @@ -344,13 +344,13 @@ static void send_msg_channel_close(struct Channel *channel) { channel->senteof = 1; channel->sentclosed = 1; - TRACE(("leave send_msg_channel_close")); + TRACE(("leave send_msg_channel_close")) } /* call this when trans/eof channels are closed */ static void send_msg_channel_eof(struct Channel *channel) { - TRACE(("enter send_msg_channel_eof")); + TRACE(("enter send_msg_channel_eof")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF); @@ -360,7 +360,7 @@ static void send_msg_channel_eof(struct Channel *channel) { channel->senteof = 1; - TRACE(("leave send_msg_channel_eof")); + TRACE(("leave send_msg_channel_eof")) } /* Called to write data out to the local side of the channel. @@ -370,7 +370,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { int len, maxlen; - TRACE(("enter writechannel")); + TRACE(("enter writechannel")) maxlen = cbuf_readlen(cbuf); @@ -382,7 +382,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { * that's a nasty failure too */ closeinfd(channel); } - TRACE(("leave writechannel: len <= 0")); + TRACE(("leave writechannel: len <= 0")) return; } @@ -392,7 +392,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { if (fd == channel->infd && len == maxlen && channel->recveof) { /* Check if we're closing up */ closeinfd(channel); - TRACE(("leave writechannel: recveof set")); + TRACE(("leave writechannel: recveof set")) return; } @@ -410,7 +410,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { channel->recvwindow <= cbuf_getavail(channel->extrabuf)); - TRACE(("leave writechannel")); + TRACE(("leave writechannel")) } /* Set the file descriptors for the main select in session.c @@ -444,7 +444,7 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) { TRACE(("infd = %d, outfd %d, errfd %d, bufused %d", channel->infd, channel->outfd, channel->errfd, - cbuf_getused(channel->writebuf) )); + cbuf_getused(channel->writebuf) )) if (channel->infd >= 0 && channel->infd != channel->outfd) { FD_SET(channel->infd, readfd); } @@ -477,7 +477,7 @@ void recv_msg_channel_eof() { unsigned int chan; struct Channel * channel; - TRACE(("enter recv_msg_channel_eof")); + TRACE(("enter recv_msg_channel_eof")) chan = buf_getint(ses.payload); channel = getchannel(chan); @@ -493,7 +493,7 @@ void recv_msg_channel_eof() { closeinfd(channel); } - TRACE(("leave recv_msg_channel_eof")); + TRACE(("leave recv_msg_channel_eof")) } @@ -503,10 +503,10 @@ void recv_msg_channel_close() { unsigned int chan; struct Channel * channel; - TRACE(("enter recv_msg_channel_close")); + TRACE(("enter recv_msg_channel_close")) chan = buf_getint(ses.payload); - TRACE(("close channel = %d", chan)); + TRACE(("close channel = %d", chan)) channel = getchannel(chan); if (channel == NULL) { @@ -521,15 +521,15 @@ void recv_msg_channel_close() { removechannel(channel); } - TRACE(("leave recv_msg_channel_close")); + TRACE(("leave recv_msg_channel_close")) } /* Remove a channel entry, this is only executed after both sides have sent * channel close */ static void removechannel(struct Channel * channel) { - TRACE(("enter removechannel")); - TRACE(("channel index is %d", channel->index)); + TRACE(("enter removechannel")) + TRACE(("channel index is %d", channel->index)) cbuf_free(channel->writebuf); channel->writebuf = NULL; @@ -550,7 +550,7 @@ static void removechannel(struct Channel * channel) { deletechannel(channel); - TRACE(("leave removechannel")); + TRACE(("leave removechannel")) } /* Remove a channel entry */ @@ -570,7 +570,7 @@ void recv_msg_channel_request() { unsigned int chan; struct Channel *channel; - TRACE(("enter recv_msg_channel_request")); + TRACE(("enter recv_msg_channel_request")) chan = buf_getint(ses.payload); channel = getchannel(chan); @@ -586,7 +586,7 @@ void recv_msg_channel_request() { send_msg_channel_failure(channel); } - TRACE(("leave recv_msg_channel_request")); + TRACE(("leave recv_msg_channel_request")) } @@ -603,8 +603,8 @@ static void send_msg_channel_data(struct Channel *channel, int isextended, unsigned int maxlen; int fd; -/* TRACE(("enter send_msg_channel_data")); - TRACE(("extended = %d type = %d", isextended, exttype));*/ +/* TRACE(("enter send_msg_channel_data")) + TRACE(("extended = %d type = %d", isextended, exttype))*/ CHECKCLEARTOWRITE(); @@ -623,14 +623,14 @@ static void send_msg_channel_data(struct Channel *channel, int isextended, maxlen = MIN(maxlen, ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0)); if (maxlen == 0) { - TRACE(("leave send_msg_channel_data: no window")); + TRACE(("leave send_msg_channel_data: no window")) return; /* the data will get written later */ } /* read the data */ - TRACE(("maxlen %d", maxlen)); + TRACE(("maxlen %d", maxlen)) buf = buf_new(maxlen); - TRACE(("buf pos %d data %x", buf->pos, buf->data)); + TRACE(("buf pos %d data %x", buf->pos, buf->data)) len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); if (len <= 0) { /* on error/eof, send eof */ @@ -660,7 +660,7 @@ static void send_msg_channel_data(struct Channel *channel, int isextended, channel->transwindow -= len; encrypt_packet(); - TRACE(("leave send_msg_channel_data")); + TRACE(("leave send_msg_channel_data")) } /* We receive channel data */ @@ -689,7 +689,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, unsigned int buflen; unsigned int len; - TRACE(("enter recv_msg_channel_data")); + TRACE(("enter recv_msg_channel_data")) if (channel->recveof) { dropbear_exit("received data after eof"); @@ -730,7 +730,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, channel->recvwindow -= datalen; assert(channel->recvwindow <= RECV_MAXWINDOW); - TRACE(("leave recv_msg_channel_data")); + TRACE(("leave recv_msg_channel_data")) } /* Increment the outgoing data window for a channel - the remote end limits @@ -750,7 +750,7 @@ void recv_msg_channel_window_adjust() { } incr = buf_getint(ses.payload); - TRACE(("received window increment %d", incr)); + TRACE(("received window increment %d", incr)) incr = MIN(incr, MAX_TRANS_WIN_INCR); channel->transwindow += incr; @@ -763,7 +763,7 @@ void recv_msg_channel_window_adjust() { static void send_msg_channel_window_adjust(struct Channel* channel, unsigned int incr) { - TRACE(("sending window adjust %d", incr)); + TRACE(("sending window adjust %d", incr)) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST); @@ -787,7 +787,7 @@ void recv_msg_channel_open() { int ret; - TRACE(("enter recv_msg_channel_open")); + TRACE(("enter recv_msg_channel_open")) /* get the packet contents */ type = buf_getstring(ses.payload, &typelen); @@ -815,17 +815,17 @@ void recv_msg_channel_open() { } if (chantype == NULL) { - TRACE(("No matching type for '%s'", type)); + TRACE(("No matching type for '%s'", type)) goto failure; } - TRACE(("matched type '%s'", type)); + TRACE(("matched type '%s'", type)) /* create the channel */ channel = newchannel(remotechan, chantype, transwindow, transmaxpacket); if (channel == NULL) { - TRACE(("newchannel returned NULL")); + TRACE(("newchannel returned NULL")) goto failure; } @@ -838,7 +838,7 @@ void recv_msg_channel_open() { } errtype = ret; deletechannel(channel); - TRACE(("inithandler returned failure %d", ret)); + TRACE(("inithandler returned failure %d", ret)) goto failure; } } @@ -849,39 +849,39 @@ void recv_msg_channel_open() { goto cleanup; failure: - TRACE(("recv_msg_channel_open failure")); + TRACE(("recv_msg_channel_open failure")) send_msg_channel_open_failure(remotechan, errtype, "", ""); cleanup: m_free(type); - TRACE(("leave recv_msg_channel_open")); + TRACE(("leave recv_msg_channel_open")) } /* Send a failure message */ void send_msg_channel_failure(struct Channel *channel) { - TRACE(("enter send_msg_channel_failure")); + TRACE(("enter send_msg_channel_failure")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE); buf_putint(ses.writepayload, channel->remotechan); encrypt_packet(); - TRACE(("leave send_msg_channel_failure")); + TRACE(("leave send_msg_channel_failure")) } /* Send a success message */ void send_msg_channel_success(struct Channel *channel) { - TRACE(("enter send_msg_channel_success")); + TRACE(("enter send_msg_channel_success")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS); buf_putint(ses.writepayload, channel->remotechan); encrypt_packet(); - TRACE(("leave send_msg_channel_success")); + TRACE(("leave send_msg_channel_success")) } /* Send a channel open failure message, with a corresponding reason @@ -889,7 +889,7 @@ void send_msg_channel_success(struct Channel *channel) { static void send_msg_channel_open_failure(unsigned int remotechan, int reason, const unsigned char *text, const unsigned char *lang) { - TRACE(("enter send_msg_channel_open_failure")); + TRACE(("enter send_msg_channel_open_failure")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE); @@ -899,7 +899,7 @@ static void send_msg_channel_open_failure(unsigned int remotechan, buf_putstring(ses.writepayload, lang, strlen((char*)lang)); encrypt_packet(); - TRACE(("leave send_msg_channel_open_failure")); + TRACE(("leave send_msg_channel_open_failure")) } /* Confirm a channel open, and let the remote end know what number we've @@ -908,7 +908,7 @@ static void send_msg_channel_open_confirmation(struct Channel* channel, unsigned int recvwindow, unsigned int recvmaxpacket) { - TRACE(("enter send_msg_channel_open_confirmation")); + TRACE(("enter send_msg_channel_open_confirmation")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION); @@ -918,7 +918,7 @@ static void send_msg_channel_open_confirmation(struct Channel* channel, buf_putint(ses.writepayload, recvmaxpacket); encrypt_packet(); - TRACE(("leave send_msg_channel_open_confirmation")); + TRACE(("leave send_msg_channel_open_confirmation")) } #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT) @@ -931,10 +931,10 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) { struct Channel* chan; - TRACE(("enter send_msg_channel_open_init()")); + TRACE(("enter send_msg_channel_open_init()")) chan = newchannel(0, type, 0, 0); if (!chan) { - TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()")); + TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()")) return DROPBEAR_FAILURE; } @@ -953,7 +953,7 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) { buf_putint(ses.writepayload, RECV_MAXWINDOW); buf_putint(ses.writepayload, RECV_MAXPACKET); - TRACE(("leave send_msg_channel_open_init()")); + TRACE(("leave send_msg_channel_open_init()")) return DROPBEAR_SUCCESS; } @@ -965,7 +965,7 @@ void recv_msg_channel_open_confirmation() { struct Channel * channel; int ret; - TRACE(("enter recv_msg_channel_open_confirmation")); + TRACE(("enter recv_msg_channel_open_confirmation")) chan = buf_getint(ses.payload); channel = getchannel(chan); @@ -977,19 +977,19 @@ void recv_msg_channel_open_confirmation() { channel->transwindow = buf_getint(ses.payload); channel->transmaxpacket = buf_getint(ses.payload); - TRACE(("new chan remote %d localho %d", channel->remotechan, chan)); + TRACE(("new chan remote %d localho %d", channel->remotechan, chan)) /* Run the inithandler callback */ if (channel->type->inithandler) { ret = channel->type->inithandler(channel); if (ret > 0) { removechannel(channel); - TRACE(("inithandler returned failure %d", ret)); + TRACE(("inithandler returned failure %d", ret)) } } - TRACE(("leave recv_msg_channel_open_confirmation")); + TRACE(("leave recv_msg_channel_open_confirmation")) } /* Notification that our channel open request failed */ @@ -1013,17 +1013,17 @@ static void closeoutfd(struct Channel * channel, int fd) { /* don't close it if it is the same as infd, * unless infd is already set -1 */ - TRACE(("enter closeoutfd")); + TRACE(("enter closeoutfd")) closechanfd(channel, fd, 0); - TRACE(("leave closeoutfd")); + TRACE(("leave closeoutfd")) } /* close a stdin fd */ static void closeinfd(struct Channel * channel) { - TRACE(("enter closeinfd")); + TRACE(("enter closeinfd")) closechanfd(channel, channel->infd, 1); - TRACE(("leave closeinfd")); + TRACE(("leave closeinfd")) } /* close a fd, how is 0 for stdout/stderr, 1 for stdin */ diff --git a/common-kex.c b/common-kex.c index 38ce090..97e341d 100644 --- a/common-kex.c +++ b/common-kex.c @@ -114,8 +114,8 @@ void send_msg_kexinit() { encrypt_packet(); ses.dataallowed = 0; /* don't send other packets during kex */ - TRACE(("DATAALLOWED=0")); - TRACE(("-> KEXINIT")); + TRACE(("DATAALLOWED=0")) + TRACE(("-> KEXINIT")) ses.kexstate.sentkexinit = 1; } @@ -128,7 +128,7 @@ void send_msg_kexinit() { /* Bring new keys into use after a key exchange, and let the client know*/ void send_msg_newkeys() { - TRACE(("enter send_msg_newkeys")); + TRACE(("enter send_msg_newkeys")) /* generate the kexinit request */ CHECKCLEARTOWRITE(); @@ -138,42 +138,42 @@ void send_msg_newkeys() { /* set up our state */ if (ses.kexstate.recvnewkeys) { - TRACE(("while RECVNEWKEYS=1")); + TRACE(("while RECVNEWKEYS=1")) gen_new_keys(); kexinitialise(); /* we've finished with this kex */ - TRACE((" -> DATAALLOWED=1")); + TRACE((" -> DATAALLOWED=1")) ses.dataallowed = 1; /* we can send other packets again now */ ses.kexstate.donefirstkex = 1; } else { ses.kexstate.sentnewkeys = 1; - TRACE(("SENTNEWKEYS=1")); + TRACE(("SENTNEWKEYS=1")) } - TRACE(("-> MSG_NEWKEYS")); - TRACE(("leave send_msg_newkeys")); + TRACE(("-> MSG_NEWKEYS")) + TRACE(("leave send_msg_newkeys")) } /* Bring the new keys into use after a key exchange */ void recv_msg_newkeys() { - TRACE(("<- MSG_NEWKEYS")); - TRACE(("enter recv_msg_newkeys")); + TRACE(("<- MSG_NEWKEYS")) + TRACE(("enter recv_msg_newkeys")) /* simply check if we've sent SSH_MSG_NEWKEYS, and if so, * switch to the new keys */ if (ses.kexstate.sentnewkeys) { - TRACE(("while SENTNEWKEYS=1")); + TRACE(("while SENTNEWKEYS=1")) gen_new_keys(); kexinitialise(); /* we've finished with this kex */ - TRACE((" -> DATAALLOWED=1")); + TRACE((" -> DATAALLOWED=1")) ses.dataallowed = 1; /* we can send other packets again now */ ses.kexstate.donefirstkex = 1; } else { - TRACE(("RECVNEWKEYS=1")); + TRACE(("RECVNEWKEYS=1")) ses.kexstate.recvnewkeys = 1; } - TRACE(("leave recv_msg_newkeys")); + TRACE(("leave recv_msg_newkeys")) } @@ -189,7 +189,7 @@ static void kexinitialise() { struct timeval tv; - TRACE(("kexinitialise()")); + TRACE(("kexinitialise()")) /* sent/recv'd MSG_KEXINIT */ ses.kexstate.sentkexinit = 0; @@ -262,7 +262,7 @@ void gen_new_keys() { unsigned int C2S_keysize, S2C_keysize; char mactransletter, macrecvletter; /* Client or server specific */ - TRACE(("enter gen_new_keys")); + TRACE(("enter gen_new_keys")) /* the dh_K and hash are the start of all hashes, we make use of that */ sha1_init(&hs); @@ -329,7 +329,7 @@ void gen_new_keys() { ses.keys = ses.newkeys; ses.newkeys = NULL; - TRACE(("leave gen_new_keys")); + TRACE(("leave gen_new_keys")) } #ifndef DISABLE_ZLIB @@ -393,8 +393,8 @@ static void gen_new_zstreams() { /* Belongs in common_kex.c where it should be moved after review */ void recv_msg_kexinit() { - TRACE(("<- KEXINIT")); - TRACE(("enter recv_msg_kexinit")); + TRACE(("<- KEXINIT")) + TRACE(("enter recv_msg_kexinit")) /* start the kex hash */ ses.kexhashbuf = buf_new(MAX_KEXHASHBUF); @@ -402,7 +402,7 @@ void recv_msg_kexinit() { if (!ses.kexstate.sentkexinit) { /* we need to send a kex packet */ send_msg_kexinit(); - TRACE(("continue recv_msg_kexinit: sent kexinit")); + TRACE(("continue recv_msg_kexinit: sent kexinit")) } @@ -459,7 +459,7 @@ void recv_msg_kexinit() { ses.kexstate.recvkexinit = 1; // ses.expecting = 0; // client matt - TRACE(("leave recv_msg_kexinit")); + TRACE(("leave recv_msg_kexinit")) } /* Initialises and generate one side of the diffie-hellman key exchange values. @@ -473,7 +473,7 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { unsigned char randbuf[DH_P_LEN]; int dh_q_len; - TRACE(("enter send_msg_kexdh_reply")); + TRACE(("enter send_msg_kexdh_reply")) m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); @@ -619,7 +619,7 @@ static void read_kex_algos() { erralgo = "kex"; goto error; } - TRACE(("kex algo %s", algo->name)); + TRACE(("kex algo %s", algo->name)) ses.newkeys->algo_kex = algo->val; /* server_host_key_algorithms */ @@ -629,7 +629,7 @@ static void read_kex_algos() { erralgo = "hostkey"; goto error; } - TRACE(("hostkey algo %s", algo->name)); + TRACE(("hostkey algo %s", algo->name)) ses.newkeys->algo_hostkey = algo->val; /* encryption_algorithms_client_to_server */ @@ -638,7 +638,7 @@ static void read_kex_algos() { erralgo = "enc c->s"; goto error; } - TRACE(("c2s is %s", c2s_cipher_algo->name)); + TRACE(("c2s is %s", c2s_cipher_algo->name)) /* encryption_algorithms_server_to_client */ s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); @@ -646,7 +646,7 @@ static void read_kex_algos() { erralgo = "enc s->c"; goto error; } - TRACE(("s2c is %s", s2c_cipher_algo->name)); + TRACE(("s2c is %s", s2c_cipher_algo->name)) /* mac_algorithms_client_to_server */ c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -717,12 +717,12 @@ static void read_kex_algos() { ses.newkeys->trans_algo_comp = s2c_comp_algo->val; } - TRACE(("enc algo recv %s", algo->name)); - TRACE(("enc algo trans %s", algo->name)); - TRACE(("mac algo recv %s", algo->name)); - TRACE(("mac algo trans %s", algo->name)); - TRACE(("comp algo recv %s", algo->name)); - TRACE(("comp algo trans %s", algo->name)); + TRACE(("enc algo recv %s", algo->name)) + TRACE(("enc algo trans %s", algo->name)) + TRACE(("mac algo recv %s", algo->name)) + TRACE(("mac algo trans %s", algo->name)) + TRACE(("comp algo recv %s", algo->name)) + TRACE(("comp algo trans %s", algo->name)) /* reserved for future extensions */ buf_getint(ses.payload); diff --git a/common-session.c b/common-session.c index 2914069..06cdbd1 100644 --- a/common-session.c +++ b/common-session.c @@ -52,7 +52,7 @@ int exitflag = 0; /* GLOBAL */ /* called only at the start of a session, set up initial state */ void common_session_init(int sock, char* remotehost) { - TRACE(("enter session_init")); + TRACE(("enter session_init")) ses.remotehost = remotehost; @@ -110,7 +110,7 @@ void common_session_init(int sock, char* remotehost) { ses.allowprivport = 0; - TRACE(("leave session_init")); + TRACE(("leave session_init")) } void session_loop(void(*loophandler)()) { @@ -162,7 +162,7 @@ void session_loop(void(*loophandler)()) { if (val == 0) { /* timeout */ - TRACE(("select timeout")); + TRACE(("select timeout")) continue; } @@ -201,11 +201,11 @@ void session_loop(void(*loophandler)()) { /* clean up a session on exit */ void common_session_cleanup() { - TRACE(("enter session_cleanup")); + TRACE(("enter session_cleanup")) /* we can't cleanup if we don't know the session state */ if (!sessinitdone) { - TRACE(("leave session_cleanup: !sessinitdone")); + TRACE(("leave session_cleanup: !sessinitdone")) return; } @@ -215,7 +215,7 @@ void common_session_cleanup() { chancleanup(); - TRACE(("leave session_cleanup")); + TRACE(("leave session_cleanup")) } @@ -252,7 +252,7 @@ void session_identification() { } if (!done) { - TRACE(("err: %s for '%s'\n", strerror(errno), linebuf)); + TRACE(("err: %s for '%s'\n", strerror(errno), linebuf)) dropbear_exit("Failed to get remote version"); } else { /* linebuf is already null terminated */ @@ -260,7 +260,7 @@ void session_identification() { memcpy(ses.remoteident, linebuf, len); } - TRACE(("remoteident: %s", ses.remoteident)); + TRACE(("remoteident: %s", ses.remoteident)) } @@ -274,7 +274,7 @@ static int ident_readln(int fd, char* buf, int count) { fd_set fds; struct timeval timeout; - TRACE(("enter ident_readln")); + TRACE(("enter ident_readln")) if (count < 1) { return -1; @@ -295,7 +295,7 @@ static int ident_readln(int fd, char* buf, int count) { if (errno == EINTR) { continue; } - TRACE(("leave ident_readln: select error")); + TRACE(("leave ident_readln: select error")) return -1; } @@ -313,12 +313,12 @@ static int ident_readln(int fd, char* buf, int count) { if (errno == EINTR) { continue; /* not a real error */ } - TRACE(("leave ident_readln: read error")); + TRACE(("leave ident_readln: read error")) return -1; } if (num == 0) { /* EOF */ - TRACE(("leave ident_readln: EOF")); + TRACE(("leave ident_readln: EOF")) return -1; } if (in == '\n') { @@ -334,7 +334,7 @@ static int ident_readln(int fd, char* buf, int count) { } buf[pos] = '\0'; - TRACE(("leave ident_readln: return %d", pos+1)); + TRACE(("leave ident_readln: return %d", pos+1)) return pos+1; } @@ -363,7 +363,7 @@ static void checktimeouts() { if (!ses.kexstate.sentkexinit && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){ - TRACE(("rekeying after timeout or max data reached")); + TRACE(("rekeying after timeout or max data reached")) send_msg_kexinit(); } } diff --git a/dbutil.c b/dbutil.c index c77386f..3ead979 100644 --- a/dbutil.c +++ b/dbutil.c @@ -164,17 +164,17 @@ int dropbear_listen(const char* address, const char* port, int val; int sock; - TRACE(("enter dropbear_listen")); + TRACE(("enter dropbear_listen")) memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */ hints.ai_socktype = SOCK_STREAM; if (address && address[0] == '\0') { - TRACE(("dropbear_listen: local loopback")); + TRACE(("dropbear_listen: local loopback")) address = NULL; } else { - TRACE(("dropbear_listen: not local loopback")); + TRACE(("dropbear_listen: not local loopback")) hints.ai_flags = AI_PASSIVE; } err = getaddrinfo(address, port, &hints, &res0); @@ -186,7 +186,7 @@ int dropbear_listen(const char* address, const char* port, *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); } - TRACE(("leave dropbear_listen: failed resolving")); + TRACE(("leave dropbear_listen: failed resolving")) return -1; } @@ -203,7 +203,7 @@ int dropbear_listen(const char* address, const char* port, if (sock < 0) { err = errno; - TRACE(("socket() failed")); + TRACE(("socket() failed")) continue; } @@ -221,14 +221,14 @@ int dropbear_listen(const char* address, const char* port, if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { err = errno; close(sock); - TRACE(("bind(%s) failed", port)); + TRACE(("bind(%s) failed", port)) continue; } if (listen(sock, 20) < 0) { err = errno; close(sock); - TRACE(("listen() failed")); + TRACE(("listen() failed")) continue; } @@ -243,12 +243,12 @@ int dropbear_listen(const char* address, const char* port, len = 20 + strlen(strerror(err)); *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error listening: %s", strerror(err)); - TRACE(("leave dropbear_listen: failure, %s", strerror(err))); + TRACE(("leave dropbear_listen: failure, %s", strerror(err))) return -1; } } - TRACE(("leave dropbear_listen: success, %d socks bound", nsock)); + TRACE(("leave dropbear_listen: success, %d socks bound", nsock)) return nsock; } @@ -264,7 +264,7 @@ int connect_remote(const char* remotehost, const char* remoteport, int sock; int err; - TRACE(("enter connect_remote")); + TRACE(("enter connect_remote")) if (errstring != NULL) { *errstring = NULL; @@ -282,7 +282,7 @@ int connect_remote(const char* remotehost, const char* remoteport, *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); } - TRACE(("Error resolving: %s", gai_strerror(err))); + TRACE(("Error resolving: %s", gai_strerror(err))) return -1; } @@ -303,14 +303,14 @@ int connect_remote(const char* remotehost, const char* remoteport, if (errstring != NULL && *errstring == NULL) { *errstring = m_strdup("Failed non-blocking"); } - TRACE(("Failed non-blocking: %s", strerror(errno))); + TRACE(("Failed non-blocking: %s", strerror(errno))) continue; } } if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { if (errno == EINPROGRESS && nonblocking) { - TRACE(("Connect in progress")); + TRACE(("Connect in progress")) break; } else { err = errno; @@ -331,7 +331,7 @@ int connect_remote(const char* remotehost, const char* remoteport, *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error connecting: %s", strerror(err)); } - TRACE(("Error connecting: %s", strerror(err))); + TRACE(("Error connecting: %s", strerror(err))) } else { /* Success */ /* (err is used as a dummy var here) */ @@ -343,7 +343,7 @@ int connect_remote(const char* remotehost, const char* remoteport, m_free(*errstring); } - TRACE(("leave connect_remote: sock %d\n", sock)); + TRACE(("leave connect_remote: sock %d\n", sock)) return sock; } @@ -503,7 +503,7 @@ int buf_getline(buffer * line, FILE * authfile) { int c = EOF; - TRACE(("enter buf_getline")); + TRACE(("enter buf_getline")) buf_setpos(line, 0); buf_setlen(line, 0); @@ -518,7 +518,7 @@ int buf_getline(buffer * line, FILE * authfile) { buf_putbyte(line, (unsigned char)c); } - TRACE(("leave getauthline: line too long")); + TRACE(("leave getauthline: line too long")) /* We return success, but the line length will be zeroed - ie we just * ignore that line */ buf_setlen(line, 0); @@ -528,10 +528,10 @@ out: /* if we didn't read anything before EOF or error, exit */ if (c == EOF && line->pos == 0) { - TRACE(("leave buf_getline: failure")); + TRACE(("leave buf_getline: failure")) return DROPBEAR_FAILURE; } else { - TRACE(("leave buf_getline: success")); + TRACE(("leave buf_getline: success")) buf_setpos(line, 0); return DROPBEAR_SUCCESS; } @@ -618,10 +618,10 @@ void m_burn(void *data, unsigned int len) { void setnonblocking(int fd) { - TRACE(("setnonblocking: %d", fd)); + TRACE(("setnonblocking: %d", fd)) if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { dropbear_exit("Couldn't set nonblocking"); } - TRACE(("leave setnonblocking")); + TRACE(("leave setnonblocking")) } diff --git a/debug.h b/debug.h index 37f51ac..7b1e2b5 100644 --- a/debug.h +++ b/debug.h @@ -39,7 +39,7 @@ * Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing may not sanitise strings etc. This will add a reasonable * amount to your executable size. */ -/* #define DEBUG_TRACE */ + //#define DEBUG_TRACE /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're @@ -60,7 +60,7 @@ /* you don't need to touch this block */ #ifdef DEBUG_TRACE -#define TRACE(X) (dropbear_trace X) +#define TRACE(X) dropbear_trace X; #else /*DEBUG_TRACE*/ #define TRACE(X) #endif /*DEBUG_TRACE*/ diff --git a/dropbearkey.c b/dropbearkey.c index 364b765..8ceefdc 100644 --- a/dropbearkey.c +++ b/dropbearkey.c @@ -166,13 +166,13 @@ int main(int argc, char ** argv) { #ifdef DROPBEAR_RSA if (strncmp(typetext, "rsa", 3) == 0) { keytype = DROPBEAR_SIGNKEY_RSA; - TRACE(("type is rsa")); + TRACE(("type is rsa")) } #endif #ifdef DROPBEAR_DSS if (strncmp(typetext, "dss", 3) == 0) { keytype = DROPBEAR_SIGNKEY_DSS; - TRACE(("type is dss")); + TRACE(("type is dss")) } #endif } diff --git a/dss.c b/dss.c index 0cb437c..6429ede 100644 --- a/dss.c +++ b/dss.c @@ -45,7 +45,7 @@ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_get_dss_pub_key(buffer* buf, dss_key *key) { - TRACE(("enter buf_get_dss_pub_key")); + TRACE(("enter buf_get_dss_pub_key")) assert(key != NULL); key->p = m_malloc(sizeof(mp_int)); key->q = m_malloc(sizeof(mp_int)); @@ -59,17 +59,17 @@ int buf_get_dss_pub_key(buffer* buf, dss_key *key) { || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_dss_pub_key: failed reading mpints")); + TRACE(("leave buf_get_dss_pub_key: failed reading mpints")) return DROPBEAR_FAILURE; } if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) { dropbear_log(LOG_WARNING, "DSS key too short"); - TRACE(("leave buf_get_dss_pub_key: short key")); + TRACE(("leave buf_get_dss_pub_key: short key")) return DROPBEAR_FAILURE; } - TRACE(("leave buf_get_dss_pub_key: success")); + TRACE(("leave buf_get_dss_pub_key: success")) return DROPBEAR_SUCCESS; } @@ -98,9 +98,9 @@ int buf_get_dss_priv_key(buffer* buf, dss_key *key) { /* Clear and free the memory used by a public or private key */ void dss_key_free(dss_key *key) { - TRACE(("enter dsa_key_free")); + TRACE(("enter dsa_key_free")) if (key == NULL) { - TRACE(("enter dsa_key_free: key == NULL")); + TRACE(("enter dsa_key_free: key == NULL")) return; } if (key->p) { @@ -124,7 +124,7 @@ void dss_key_free(dss_key *key) { m_free(key->x); } m_free(key); - TRACE(("leave dsa_key_free")); + TRACE(("leave dsa_key_free")) } /* put the dss public key into the buffer in the required format: @@ -171,7 +171,7 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, char * string = NULL; int stringlen; - TRACE(("enter buf_dss_verify")); + TRACE(("enter buf_dss_verify")) assert(key != NULL); m_mp_init_multi(&val1, &val2, &val3, &val4, NULL); @@ -195,7 +195,7 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, goto out; } if (mp_cmp(&val1, key->q) != MP_LT) { - TRACE(("verify failed, s' >= q")); + TRACE(("verify failed, s' >= q")) goto out; } /* let val2 = w = (s')^-1 mod q*/ @@ -220,7 +220,7 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, goto out; } if (mp_cmp(&val1, key->q) != MP_LT) { - TRACE(("verify failed, r' >= q")); + TRACE(("verify failed, r' >= q")) goto out; } /* let val4 = u2 = ((r')w) mod q */ @@ -315,7 +315,7 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, DEF_MP_INT(dss_s); hash_state hs; - TRACE(("enter buf_put_dss_sign")); + TRACE(("enter buf_put_dss_sign")) assert(key != NULL); /* hash the data */ @@ -422,7 +422,7 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, /* create the signature to return */ - TRACE(("leave buf_put_dss_sign")); + TRACE(("leave buf_put_dss_sign")) } #endif /* DROPBEAR_DSS */ diff --git a/listener.c b/listener.c index 1a6da04..dd90c6b 100644 --- a/listener.c +++ b/listener.c @@ -93,7 +93,7 @@ struct Listener* new_listener(int socks[], unsigned int nsocks, /* or create a new one */ if (i == ses.listensize) { if (ses.listensize > MAX_LISTENERS) { - TRACE(("leave newlistener: too many already")); + TRACE(("leave newlistener: too many already")) for (j = 0; j < nsocks; j++) { close(socks[i]); } @@ -115,7 +115,7 @@ struct Listener* new_listener(int socks[], unsigned int nsocks, ses.maxfd = MAX(ses.maxfd, socks[j]); } - TRACE(("new listener num %d ", i)); + TRACE(("new listener num %d ", i)) newlisten = (struct Listener*)m_malloc(sizeof(struct Listener)); newlisten->index = i; diff --git a/packet.c b/packet.c index 5e8e14d..56b31c2 100644 --- a/packet.c +++ b/packet.c @@ -52,7 +52,7 @@ void write_packet() { int len, written; buffer * writebuf = NULL; - TRACE(("enter write_packet")); + TRACE(("enter write_packet")) assert(!isempty(&ses.writequeue)); /* Get the next buffer in the queue of encrypted packets to write*/ @@ -65,7 +65,7 @@ void write_packet() { if (written < 0) { if (errno == EINTR) { - TRACE(("leave writepacket: EINTR")); + TRACE(("leave writepacket: EINTR")) return; } else { dropbear_exit("error writing"); @@ -86,7 +86,7 @@ void write_packet() { buf_incrpos(writebuf, written); } - TRACE(("leave write_packet")); + TRACE(("leave write_packet")) } /* Non-blocking function reading available portion of a packet into the @@ -98,7 +98,7 @@ void read_packet() { unsigned int maxlen; unsigned char blocksize; - TRACE(("enter read_packet")); + TRACE(("enter read_packet")) blocksize = ses.keys->recv_algo_crypt->blocksize; if (ses.readbuf == NULL || ses.readbuf->len < blocksize) { @@ -111,7 +111,7 @@ void read_packet() { /* If we don't have the length of decryptreadbuf, we didn't read * a whole blocksize and should exit */ if (ses.decryptreadbuf->len == 0) { - TRACE(("leave read_packet: packetinit done")); + TRACE(("leave read_packet: packetinit done")) return; } } @@ -128,7 +128,7 @@ void read_packet() { if (len < 0) { if (errno == EINTR || errno == EAGAIN) { - TRACE(("leave read_packet: EINTR or EAGAIN")); + TRACE(("leave read_packet: EINTR or EAGAIN")) return; } else { dropbear_exit("error reading: %s", strerror(errno)); @@ -143,7 +143,7 @@ void read_packet() { /* The main select() loop process_packet() to * handle the packet contents... */ } - TRACE(("leave read_packet")); + TRACE(("leave read_packet")) } /* Function used to read the initial portion of a packet, and determine the @@ -176,7 +176,7 @@ static void read_packet_init() { } if (len < 0) { if (errno == EINTR) { - TRACE(("leave read_packet_init: EINTR")); + TRACE(("leave read_packet_init: EINTR")) return; } dropbear_exit("error reading: %s", strerror(errno)); @@ -230,7 +230,7 @@ void decrypt_packet() { unsigned int padlen; unsigned int len; - TRACE(("enter decrypt_packet")); + TRACE(("enter decrypt_packet")) blocksize = ses.keys->recv_algo_crypt->blocksize; macsize = ses.keys->recv_algo_mac->hashsize; @@ -305,7 +305,7 @@ void decrypt_packet() { ses.recvseq++; - TRACE(("leave decrypt_packet")); + TRACE(("leave decrypt_packet")) } /* Checks the mac in hashbuf, for the data in readbuf. @@ -413,8 +413,8 @@ void encrypt_packet() { buffer * writebuf; /* the packet which will go on the wire */ buffer * clearwritebuf; /* unencrypted, possibly compressed */ - TRACE(("enter encrypt_packet()")); - TRACE(("encrypt_packet type is %d", ses.writepayload->data[0])); + TRACE(("enter encrypt_packet()")) + TRACE(("encrypt_packet type is %d", ses.writepayload->data[0])) blocksize = ses.keys->trans_algo_crypt->blocksize; macsize = ses.keys->trans_algo_mac->hashsize; @@ -514,7 +514,7 @@ void encrypt_packet() { ses.kexstate.datatrans += writebuf->len; ses.transseq++; - TRACE(("leave encrypt_packet()")); + TRACE(("leave encrypt_packet()")) } @@ -526,7 +526,7 @@ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { unsigned long hashsize; hmac_state hmac; - TRACE(("enter writemac")); + TRACE(("enter writemac")) macsize = ses.keys->trans_algo_mac->hashsize; @@ -561,7 +561,7 @@ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { } buf_incrwritepos(outputbuffer, macsize); } - TRACE(("leave writemac")); + TRACE(("leave writemac")) } #ifndef DISABLE_ZLIB @@ -572,7 +572,7 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len) { unsigned int endpos = src->pos + len; int result; - TRACE(("enter buf_compress")); + TRACE(("enter buf_compress")) while (1) { @@ -606,6 +606,6 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len) { buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR); } - TRACE(("leave buf_compress")); + TRACE(("leave buf_compress")) } #endif diff --git a/process-packet.c b/process-packet.c index bdec032..07fc130 100644 --- a/process-packet.c +++ b/process-packet.c @@ -45,10 +45,10 @@ void process_packet() { unsigned char type; unsigned int i; - TRACE(("enter process_packet")); + TRACE(("enter process_packet")) type = buf_getbyte(ses.payload); - TRACE(("process_packet: packet type = %d", type)); + TRACE(("process_packet: packet type = %d", type)) ses.lastpacket = type; @@ -57,12 +57,12 @@ void process_packet() { case SSH_MSG_IGNORE: case SSH_MSG_DEBUG: - TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG")); + TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG")) goto out; case SSH_MSG_UNIMPLEMENTED: /* debugging XXX */ - TRACE(("SSH_MSG_UNIMPLEMENTED")); + TRACE(("SSH_MSG_UNIMPLEMENTED")) dropbear_exit("received SSH_MSG_UNIMPLEMENTED"); case SSH_MSG_DISCONNECT: @@ -87,7 +87,7 @@ void process_packet() { /* Check if we should ignore this packet. Used currently only for * KEX code, with first_kex_packet_follows */ if (ses.ignorenext) { - TRACE(("Ignoring packet, type = %d", type)); + TRACE(("Ignoring packet, type = %d", type)) ses.ignorenext = 0; goto out; } @@ -115,7 +115,7 @@ void process_packet() { /* TODO do something more here? */ - TRACE(("preauth unknown packet")); + TRACE(("preauth unknown packet")) recv_unimplemented(); out: @@ -123,7 +123,7 @@ out: buf_free(ses.payload); ses.payload = NULL; - TRACE(("leave process_packet")); + TRACE(("leave process_packet")) } diff --git a/queue.c b/queue.c index a1352dc..caf6145 100644 --- a/queue.c +++ b/queue.c @@ -52,7 +52,7 @@ void* dequeue(struct Queue* queue) { } else { queue->head = NULL; queue->tail = NULL; - TRACE(("empty queue dequeing")); + TRACE(("empty queue dequeing")) } m_free(oldhead); @@ -70,7 +70,7 @@ void enqueue(struct Queue* queue, void* item) { struct Link* newlink; - TRACE(("enter enqueue")); + TRACE(("enter enqueue")) newlink = (struct Link*)m_malloc(sizeof(struct Link)); newlink->item = item; @@ -85,5 +85,5 @@ void enqueue(struct Queue* queue, void* item) { queue->head = newlink; } queue->count++; - TRACE(("leave enqueue")); + TRACE(("leave enqueue")) } diff --git a/rsa.c b/rsa.c index 7e891e0..1ac0357 100644 --- a/rsa.c +++ b/rsa.c @@ -47,7 +47,7 @@ static mp_int * rsa_pad_em(rsa_key * key, * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { - TRACE(("enter buf_get_rsa_pub_key")); + TRACE(("enter buf_get_rsa_pub_key")) assert(key != NULL); key->e = m_malloc(sizeof(mp_int)); key->n = m_malloc(sizeof(mp_int)); @@ -60,7 +60,7 @@ int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_rsa_pub_key: failure")); + TRACE(("leave buf_get_rsa_pub_key: failure")) return DROPBEAR_FAILURE; } @@ -69,7 +69,7 @@ int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { return DROPBEAR_FAILURE; } - TRACE(("leave buf_get_rsa_pub_key: success")); + TRACE(("leave buf_get_rsa_pub_key: success")) return DROPBEAR_SUCCESS; } @@ -81,17 +81,17 @@ int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { assert(key != NULL); - TRACE(("enter buf_get_rsa_priv_key")); + TRACE(("enter buf_get_rsa_priv_key")) if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")); + TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) return DROPBEAR_FAILURE; } key->d = m_malloc(sizeof(mp_int)); m_mp_init(key->d); if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")); + TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) return DROPBEAR_FAILURE; } @@ -105,17 +105,17 @@ int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { m_mp_init_multi(key->p, key->q, NULL); if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")); + TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) return DROPBEAR_FAILURE; } if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { - TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")); + TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) return DROPBEAR_FAILURE; } } - TRACE(("leave buf_get_rsa_priv_key")); + TRACE(("leave buf_get_rsa_priv_key")) return DROPBEAR_SUCCESS; } @@ -123,10 +123,10 @@ int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { /* Clear and free the memory used by a public or private key */ void rsa_key_free(rsa_key *key) { - TRACE(("enter rsa_key_free")); + TRACE(("enter rsa_key_free")) if (key == NULL) { - TRACE(("leave rsa_key_free: key == NULL")); + TRACE(("leave rsa_key_free: key == NULL")) return; } if (key->d) { @@ -150,7 +150,7 @@ void rsa_key_free(rsa_key *key) { m_free(key->q); } m_free(key); - TRACE(("leave rsa_key_free")); + TRACE(("leave rsa_key_free")) } /* Put the public rsa key into the buffer in the required format: @@ -161,21 +161,21 @@ void rsa_key_free(rsa_key *key) { */ void buf_put_rsa_pub_key(buffer* buf, rsa_key *key) { - TRACE(("enter buf_put_rsa_pub_key")); + TRACE(("enter buf_put_rsa_pub_key")) assert(key != NULL); buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); buf_putmpint(buf, key->e); buf_putmpint(buf, key->n); - TRACE(("leave buf_put_rsa_pub_key")); + TRACE(("leave buf_put_rsa_pub_key")) } /* Same as buf_put_rsa_pub_key, but with the private "x" key appended */ void buf_put_rsa_priv_key(buffer* buf, rsa_key *key) { - TRACE(("enter buf_put_rsa_priv_key")); + TRACE(("enter buf_put_rsa_priv_key")) assert(key != NULL); buf_put_rsa_pub_key(buf, key); @@ -190,7 +190,7 @@ void buf_put_rsa_priv_key(buffer* buf, rsa_key *key) { } - TRACE(("leave buf_put_rsa_priv_key")); + TRACE(("leave buf_put_rsa_priv_key")) } @@ -206,7 +206,7 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, mp_int *rsa_em = NULL; int ret = DROPBEAR_FAILURE; - TRACE(("enter buf_rsa_verify")); + TRACE(("enter buf_rsa_verify")) assert(key != NULL); @@ -214,19 +214,19 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, slen = buf_getint(buf); if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { - TRACE(("bad size")); + TRACE(("bad size")) goto out; } if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos), buf->len - buf->pos) != MP_OKAY) { - TRACE(("failed reading rsa_s")); + TRACE(("failed reading rsa_s")) goto out; } /* check that s <= n-1 */ if (mp_cmp(&rsa_s, key->n) != MP_LT) { - TRACE(("s > n-1")); + TRACE(("s > n-1")) goto out; } @@ -234,13 +234,13 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, rsa_em = rsa_pad_em(key, data, len); if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { - TRACE(("failed exptmod rsa_s")); + TRACE(("failed exptmod rsa_s")) goto out; } if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { /* signature is valid */ - TRACE(("success!")); + TRACE(("success!")) ret = DROPBEAR_SUCCESS; } @@ -250,7 +250,7 @@ out: m_free(rsa_em); } mp_clear_multi(&rsa_mdash, &rsa_s, NULL); - TRACE(("leave buf_rsa_verify: ret %d", ret)); + TRACE(("leave buf_rsa_verify: ret %d", ret)) return ret; } @@ -266,7 +266,7 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, DEF_MP_INT(rsa_s); mp_int *rsa_em = NULL; - TRACE(("enter buf_put_rsa_sign")); + TRACE(("enter buf_put_rsa_sign")) assert(key != NULL); rsa_em = rsa_pad_em(key, data, len); @@ -306,7 +306,7 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, #endif - TRACE(("leave buf_put_rsa_sign")); + TRACE(("leave buf_put_rsa_sign")) } /* Creates the message value as expected by PKCS, see rfc2437 etc */ diff --git a/signkey.c b/signkey.c index 2c8da55..b6b8bdc 100644 --- a/signkey.c +++ b/signkey.c @@ -94,7 +94,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { int keytype; int ret = DROPBEAR_FAILURE; - TRACE(("enter buf_get_pub_key")); + TRACE(("enter buf_get_pub_key")) ident = buf_getstring(buf, &len); keytype = signkey_type_from_name(ident, len); @@ -130,7 +130,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { } #endif - TRACE(("leave buf_get_pub_key")); + TRACE(("leave buf_get_pub_key")) return ret; @@ -146,14 +146,14 @@ int buf_get_priv_key(buffer *buf, sign_key *key, int *type) { int keytype; int ret = DROPBEAR_FAILURE; - TRACE(("enter buf_get_priv_key")); + TRACE(("enter buf_get_priv_key")) ident = buf_getstring(buf, &len); keytype = signkey_type_from_name(ident, len); m_free(ident); if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) { - TRACE(("wrong key type: %d %d", *type, keytype)); + TRACE(("wrong key type: %d %d", *type, keytype)) return DROPBEAR_FAILURE; } @@ -183,7 +183,7 @@ int buf_get_priv_key(buffer *buf, sign_key *key, int *type) { } #endif - TRACE(("leave buf_get_priv_key")); + TRACE(("leave buf_get_priv_key")) return ret; @@ -194,7 +194,7 @@ void buf_put_pub_key(buffer* buf, sign_key *key, int type) { buffer *pubkeys; - TRACE(("enter buf_put_pub_key")); + TRACE(("enter buf_put_pub_key")) pubkeys = buf_new(MAX_PUBKEY_SIZE); #ifdef DROPBEAR_DSS @@ -216,26 +216,26 @@ void buf_put_pub_key(buffer* buf, sign_key *key, int type) { pubkeys->len); buf_free(pubkeys); - TRACE(("leave buf_put_pub_key")); + TRACE(("leave buf_put_pub_key")) } /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */ void buf_put_priv_key(buffer* buf, sign_key *key, int type) { - TRACE(("enter buf_put_priv_key")); - TRACE(("type is %d", type)); + TRACE(("enter buf_put_priv_key")) + TRACE(("type is %d", type)) #ifdef DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { buf_put_dss_priv_key(buf, key->dsskey); - TRACE(("leave buf_put_priv_key: dss done")); + TRACE(("leave buf_put_priv_key: dss done")) return; } #endif #ifdef DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { buf_put_rsa_priv_key(buf, key->rsakey); - TRACE(("leave buf_put_priv_key: rsa done")); + TRACE(("leave buf_put_priv_key: rsa done")) return; } #endif @@ -244,7 +244,7 @@ void buf_put_priv_key(buffer* buf, sign_key *key, int type) { void sign_key_free(sign_key *key) { - TRACE(("enter sign_key_free")); + TRACE(("enter sign_key_free")) #ifdef DROPBEAR_DSS dss_key_free(key->dsskey); @@ -256,7 +256,7 @@ void sign_key_free(sign_key *key) { #endif m_free(key); - TRACE(("leave sign_key_free")); + TRACE(("leave sign_key_free")) } static char hexdig(unsigned char x) { @@ -393,7 +393,7 @@ int buf_verify(buffer * buf, sign_key *key, const unsigned char *data, unsigned char * ident = NULL; unsigned int identlen = 0; - TRACE(("enter buf_verify")); + TRACE(("enter buf_verify")) bloblen = buf_getint(buf); ident = buf_getstring(buf, &identlen); @@ -442,17 +442,17 @@ int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen, if (base64_decode(buf_getptr(line, len), len, buf_getwriteptr(decodekey, decodekey->size), &decodekeylen) != CRYPT_OK) { - TRACE(("checkpubkey: base64 decode failed")); + TRACE(("checkpubkey: base64 decode failed")) goto out; } - TRACE(("checkpubkey: base64_decode success")); + TRACE(("checkpubkey: base64_decode success")) buf_incrlen(decodekey, decodekeylen); /* compare the keys */ if ( ( decodekeylen != keybloblen ) || memcmp( buf_getptr(decodekey, decodekey->len), keyblob, decodekey->len) != 0) { - TRACE(("checkpubkey: compare failed")); + TRACE(("checkpubkey: compare failed")) goto out; } @@ -461,7 +461,7 @@ int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen, filealgolen = buf_getint(decodekey); filealgo = buf_getptr(decodekey, filealgolen); if (filealgolen != algolen || memcmp(filealgo, algoname, algolen) != 0) { - TRACE(("checkpubkey: algo match failed")); + TRACE(("checkpubkey: algo match failed")) goto out; } diff --git a/svr-agentfwd.c b/svr-agentfwd.c index 60c23f7..5127158 100644 --- a/svr-agentfwd.c +++ b/svr-agentfwd.c @@ -101,7 +101,7 @@ static void agentaccept(struct Listener *UNUSED(listener), int sock) { fd = accept(sock, NULL, NULL); if (fd < 0) { - TRACE(("accept failed")); + TRACE(("accept failed")) return; } diff --git a/svr-algo.c b/svr-algo.c index 5559da6..c0b7823 100644 --- a/svr-algo.c +++ b/svr-algo.c @@ -47,7 +47,7 @@ algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[], /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ algolist = buf_getstring(buf, &len); /* Debug this */ - TRACE(("buf_match_algo: %s", algolist)); + TRACE(("buf_match_algo: %s", algolist)) if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { goto out; /* just a sanity check, no other use */ } diff --git a/svr-auth.c b/svr-auth.c index 5eb3e27..f0fca38 100644 --- a/svr-auth.c +++ b/svr-auth.c @@ -67,9 +67,9 @@ static void authclear() { * ignore this, but possibly serves as a legal "no trespassing" sign */ static void send_msg_userauth_banner() { - TRACE(("enter send_msg_userauth_banner")); + TRACE(("enter send_msg_userauth_banner")) if (svr_opts.banner == NULL) { - TRACE(("leave send_msg_userauth_banner: banner is NULL")); + TRACE(("leave send_msg_userauth_banner: banner is NULL")) return; } @@ -84,7 +84,7 @@ static void send_msg_userauth_banner() { buf_free(svr_opts.banner); svr_opts.banner = NULL; - TRACE(("leave send_msg_userauth_banner")); + TRACE(("leave send_msg_userauth_banner")) } /* handle a userauth request, check validity, pass to password or pubkey @@ -94,11 +94,11 @@ void recv_msg_userauth_request() { unsigned char *username = NULL, *servicename = NULL, *methodname = NULL; unsigned int userlen, servicelen, methodlen; - TRACE(("enter recv_msg_userauth_request")); + TRACE(("enter recv_msg_userauth_request")) /* ignore packets if auth is already done */ if (ses.authstate.authdone == 1) { - TRACE(("leave recv_msg_userauth_request: authdone already")); + TRACE(("leave recv_msg_userauth_request: authdone already")) return; } @@ -128,7 +128,7 @@ void recv_msg_userauth_request() { if (methodlen == AUTH_METHOD_NONE_LEN && strncmp(methodname, AUTH_METHOD_NONE, AUTH_METHOD_NONE_LEN) == 0) { - TRACE(("recv_msg_userauth_request: 'none' request")); + TRACE(("recv_msg_userauth_request: 'none' request")) send_msg_userauth_failure(0, 0); goto out; } @@ -136,7 +136,7 @@ void recv_msg_userauth_request() { /* check username is good before continuing */ if (checkusername(username, userlen) == DROPBEAR_FAILURE) { /* username is invalid/no shell/etc - send failure */ - TRACE(("sending checkusername failure")); + TRACE(("sending checkusername failure")) send_msg_userauth_failure(0, 1); goto out; } @@ -195,7 +195,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { char* listshell = NULL; char* usershell = NULL; - TRACE(("enter checkusername")); + TRACE(("enter checkusername")) if (userlen > MAX_USERNAME_LEN) { return DROPBEAR_FAILURE; } @@ -217,7 +217,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { /* check that user exists */ if (ses.authstate.pw == NULL) { - TRACE(("leave checkusername: user '%s' doesn't exist", username)); + TRACE(("leave checkusername: user '%s' doesn't exist", username)) dropbear_log(LOG_WARNING, "login attempt for nonexistent user from %s", svr_ses.addrstring); @@ -230,7 +230,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { /* check for non-root if desired */ if (svr_opts.norootlogin && ses.authstate.pw->pw_uid == 0) { - TRACE(("leave checkusername: root login disabled")); + TRACE(("leave checkusername: root login disabled")) dropbear_log(LOG_WARNING, "root login rejected"); send_msg_userauth_failure(0, 1); return DROPBEAR_FAILURE; @@ -238,14 +238,14 @@ static int checkusername(unsigned char *username, unsigned int userlen) { /* check for an empty password */ if (ses.authstate.pw->pw_passwd[0] == '\0') { - TRACE(("leave checkusername: empty pword")); + TRACE(("leave checkusername: empty pword")) dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected", ses.authstate.printableuser); send_msg_userauth_failure(0, 1); return DROPBEAR_FAILURE; } - TRACE(("shell is %s", ses.authstate.pw->pw_shell)); + TRACE(("shell is %s", ses.authstate.pw->pw_shell)) /* check that the shell is set */ usershell = ses.authstate.pw->pw_shell; @@ -259,7 +259,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { * is platform-specific) */ setusershell(); while ((listshell = getusershell()) != NULL) { - TRACE(("test shell is '%s'", listshell)); + TRACE(("test shell is '%s'", listshell)) if (strcmp(listshell, usershell) == 0) { /* have a match */ goto goodshell; @@ -267,7 +267,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) { } /* no matching shell */ endusershell(); - TRACE(("no matching shell")); + TRACE(("no matching shell")) dropbear_log(LOG_WARNING, "user '%s' has invalid shell, rejected", ses.authstate.printableuser); send_msg_userauth_failure(0, 1); @@ -275,10 +275,10 @@ static int checkusername(unsigned char *username, unsigned int userlen) { goodshell: endusershell(); - TRACE(("matching shell")); + TRACE(("matching shell")) - TRACE(("uid = %d", ses.authstate.pw->pw_uid)); - TRACE(("leave checkusername")); + TRACE(("uid = %d", ses.authstate.pw->pw_uid)) + TRACE(("leave checkusername")) return DROPBEAR_SUCCESS; } @@ -292,7 +292,7 @@ void send_msg_userauth_failure(int partial, int incrfail) { buffer *typebuf = NULL; - TRACE(("enter send_msg_userauth_failure")); + TRACE(("enter send_msg_userauth_failure")) CHECKCLEARTOWRITE(); @@ -331,7 +331,7 @@ void send_msg_userauth_failure(int partial, int incrfail) { if (ses.authstate.failcount >= MAX_AUTH_TRIES) { char * userstr; /* XXX - send disconnect ? */ - TRACE(("Max auth tries reached, exiting")); + TRACE(("Max auth tries reached, exiting")) if (ses.authstate.printableuser == NULL) { userstr = "is invalid"; @@ -342,13 +342,13 @@ void send_msg_userauth_failure(int partial, int incrfail) { userstr, svr_ses.addrstring); } - TRACE(("leave send_msg_userauth_failure")); + TRACE(("leave send_msg_userauth_failure")) } /* Send a success message to the user, and set the "authdone" flag */ void send_msg_userauth_success() { - TRACE(("enter send_msg_userauth_success")); + TRACE(("enter send_msg_userauth_success")) CHECKCLEARTOWRITE(); @@ -368,6 +368,6 @@ void send_msg_userauth_success() { * logins - a nasty situation. */ m_close(svr_ses.childpipe); - TRACE(("leave send_msg_userauth_success")); + TRACE(("leave send_msg_userauth_success")) } diff --git a/svr-authpam.c b/svr-authpam.c index 4937fa6..4b16616 100644 --- a/svr-authpam.c +++ b/svr-authpam.c @@ -57,7 +57,7 @@ pamConvFunc(int num_msg, const char* message = (*msg)->msg; - TRACE(("enter pamConvFunc")); + TRACE(("enter pamConvFunc")) if (num_msg != 1) { /* If you're getting here - Dropbear probably can't support your pam @@ -67,11 +67,11 @@ pamConvFunc(int num_msg, return PAM_CONV_ERR; } - TRACE(("msg_style is %d", (*msg)->msg_style)); + TRACE(("msg_style is %d", (*msg)->msg_style)) if (message) { - TRACE(("message is '%s'", message)); + TRACE(("message is '%s'", message)) } else { - TRACE(("null message")); + TRACE(("null message")) } switch((*msg)->msg_style) { @@ -79,7 +79,7 @@ pamConvFunc(int num_msg, case PAM_PROMPT_ECHO_OFF: if (strcmp(message, "Password:") != 0) { - TRACE(("PAM_PROMPT_ECHO_OFF: unrecognized prompt")); + TRACE(("PAM_PROMPT_ECHO_OFF: unrecognized prompt")) rc = PAM_CONV_ERR; break; } @@ -102,7 +102,7 @@ pamConvFunc(int num_msg, if ((strcmp(message, "login: " ) != 0) && (strcmp(message, "login:" ) != 0) && (strcmp(message, "Please enter username: " ) != 0)) { - TRACE(("PAM_PROMPT_ECHO_ON: unrecognized prompt")); + TRACE(("PAM_PROMPT_ECHO_ON: unrecognized prompt")) rc = PAM_CONV_ERR; break; } @@ -117,17 +117,17 @@ pamConvFunc(int num_msg, /* Safe to just use the direct pointer (no strdup) since * it shouldn't be getting munged at all */ resp->resp = m_strdup(userDatap->user); - TRACE(("userDatap->user='%s'", userDatap->user)); + TRACE(("userDatap->user='%s'", userDatap->user)) (*respp) = resp; break; default: - TRACE(("Unknown message type")); + TRACE(("Unknown message type")) rc = PAM_CONV_ERR; break; } - TRACE(("leave pamConvFunc, rc %d", rc)); + TRACE(("leave pamConvFunc, rc %d", rc)) return rc; } @@ -224,7 +224,7 @@ cleanup: m_free(password); } if (pamHandlep != NULL) { - TRACE(("pam_end")); + TRACE(("pam_end")) (void) pam_end(pamHandlep, 0 /* pam_status */); } } diff --git a/svr-authpubkey.c b/svr-authpubkey.c index 5052b10..5daba0f 100644 --- a/svr-authpubkey.c +++ b/svr-authpubkey.c @@ -60,7 +60,7 @@ void svr_auth_pubkey() { char* fp = NULL; int type = -1; - TRACE(("enter pubkeyauth")); + TRACE(("enter pubkeyauth")) /* 0 indicates user just wants to check if key can be used, 1 is an * actual attempt*/ @@ -127,7 +127,7 @@ out: sign_key_free(key); key = NULL; } - TRACE(("leave pubkeyauth")); + TRACE(("leave pubkeyauth")) } /* Reply that the key is valid for auth, this is sent when the user sends @@ -136,7 +136,7 @@ out: static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen, unsigned char* keyblob, unsigned int keybloblen) { - TRACE(("enter send_msg_userauth_pk_ok")); + TRACE(("enter send_msg_userauth_pk_ok")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_PK_OK); @@ -144,7 +144,7 @@ static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen, buf_putstring(ses.writepayload, keyblob, keybloblen); encrypt_packet(); - TRACE(("leave send_msg_userauth_pk_ok")); + TRACE(("leave send_msg_userauth_pk_ok")) } @@ -160,7 +160,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, buffer * line = NULL; unsigned int len, pos; - TRACE(("enter checkpubkey")); + TRACE(("enter checkpubkey")) /* check that we can use the algo */ if (have_algo(algo, algolen, sshhostkey) == DROPBEAR_FAILURE) { @@ -172,7 +172,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, /* check file permissions, also whether file exists */ if (checkpubkeyperms() == DROPBEAR_FAILURE) { - TRACE(("bad authorized_keys permissions, or file doesn't exist")); + TRACE(("bad authorized_keys permissions, or file doesn't exist")) goto out; } @@ -190,7 +190,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, if (authfile == NULL) { goto out; } - TRACE(("checkpubkey: opened authorized_keys OK")); + TRACE(("checkpubkey: opened authorized_keys OK")) line = buf_new(MAX_AUTHKEYS_LINE); @@ -199,12 +199,12 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, if (buf_getline(line, authfile) == DROPBEAR_FAILURE) { /* EOF reached */ - TRACE(("checkpubkey: authorized_keys EOF reached")); + TRACE(("checkpubkey: authorized_keys EOF reached")) break; } if (line->len < MIN_AUTHKEYS_LINE) { - TRACE(("checkpubkey: line too short")); + TRACE(("checkpubkey: line too short")) continue; /* line is too short for it to be a valid key */ } @@ -217,7 +217,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, /* check for space (' ') character */ if (buf_getbyte(line) != ' ') { - TRACE(("checkpubkey: space character expected, isn't there")); + TRACE(("checkpubkey: space character expected, isn't there")) continue; } @@ -229,7 +229,7 @@ static int checkpubkey(unsigned char* algo, unsigned int algolen, buf_setpos(line, pos); buf_setlen(line, line->pos + len); - TRACE(("checkpubkey: line pos = %d len = %d", line->pos, line->len)); + TRACE(("checkpubkey: line pos = %d len = %d", line->pos, line->len)) ret = cmp_base64_key(keyblob, keybloblen, algo, algolen, line); if (ret == DROPBEAR_SUCCESS) { @@ -248,7 +248,7 @@ out: buf_free(line); } m_free(filename); - TRACE(("leave checkpubkey: ret=%d", ret)); + TRACE(("leave checkpubkey: ret=%d", ret)) return ret; } @@ -264,7 +264,7 @@ static int checkpubkeyperms() { int ret = DROPBEAR_FAILURE; unsigned int len; - TRACE(("enter checkpubkeyperms")); + TRACE(("enter checkpubkeyperms")) assert(ses.authstate.pw); if (ses.authstate.pw->pw_dir == NULL) { @@ -303,7 +303,7 @@ static int checkpubkeyperms() { out: m_free(filename); - TRACE(("leave checkpubkeyperms")); + TRACE(("leave checkpubkeyperms")) return ret; } @@ -313,24 +313,24 @@ out: static int checkfileperm(char * filename) { struct stat filestat; - TRACE(("enter checkfileperm(%s)", filename)); + TRACE(("enter checkfileperm(%s)", filename)) if (stat(filename, &filestat) != 0) { - TRACE(("leave checkfileperm: stat() != 0")); + TRACE(("leave checkfileperm: stat() != 0")) return DROPBEAR_FAILURE; } /* check ownership - user or root only*/ if (filestat.st_uid != ses.authstate.pw->pw_uid && filestat.st_uid != 0) { - TRACE(("leave checkfileperm: wrong ownership")); + TRACE(("leave checkfileperm: wrong ownership")) return DROPBEAR_FAILURE; } /* check permissions - don't want group or others +w */ if (filestat.st_mode & (S_IWGRP | S_IWOTH)) { - TRACE(("leave checkfileperm: wrong perms")); + TRACE(("leave checkfileperm: wrong perms")) return DROPBEAR_FAILURE; } - TRACE(("leave checkfileperm: success")); + TRACE(("leave checkfileperm: success")) return DROPBEAR_SUCCESS; } diff --git a/svr-chansession.c b/svr-chansession.c index f1e9c88..c365114 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -87,7 +87,7 @@ static void sesssigchild_handler(int UNUSED(dummy)) { struct sigaction sa_chld; struct exitinfo *exit = NULL; - TRACE(("enter sigchld handler")); + TRACE(("enter sigchld handler")) while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { /* find the corresponding chansess */ for (i = 0; i < svr_ses.childpidsize; i++) { @@ -126,7 +126,7 @@ static void sesssigchild_handler(int UNUSED(dummy)) { sa_chld.sa_handler = sesssigchild_handler; sa_chld.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sa_chld, NULL); - TRACE(("leave sigchld handler")); + TRACE(("leave sigchld handler")) } /* send the exit status or the signal causing termination for a session */ @@ -248,9 +248,9 @@ static void closechansess(struct Channel *channel) { send_exitsignalstatus(channel); - TRACE(("enter closechansess")); + TRACE(("enter closechansess")) if (chansess == NULL) { - TRACE(("leave closechansess: chansess == NULL")); + TRACE(("leave closechansess: chansess == NULL")) return; } @@ -280,8 +280,8 @@ static void closechansess(struct Channel *channel) { for (i = 0; i < svr_ses.childpidsize; i++) { if (svr_ses.childpids[i].chansess == chansess) { assert(svr_ses.childpids[i].pid > 0); - TRACE(("closing pid %d", svr_ses.childpids[i].pid)); - TRACE(("exitpid = %d", chansess->exit.exitpid)); + TRACE(("closing pid %d", svr_ses.childpids[i].pid)) + TRACE(("exitpid = %d", chansess->exit.exitpid)) svr_ses.childpids[i].pid = -1; svr_ses.childpids[i].chansess = NULL; } @@ -289,7 +289,7 @@ static void closechansess(struct Channel *channel) { m_free(chansess); - TRACE(("leave closechansess")); + TRACE(("leave closechansess")) } /* Handle requests for a channel. These can be execution requests, @@ -302,19 +302,19 @@ static void chansessionrequest(struct Channel *channel) { int ret = 1; struct ChanSess *chansess; - TRACE(("enter chansessionrequest")); + TRACE(("enter chansessionrequest")) type = buf_getstring(ses.payload, &typelen); wantreply = buf_getbyte(ses.payload); if (typelen > MAX_NAME_LEN) { - TRACE(("leave chansessionrequest: type too long")); /* XXX send error?*/ + TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/ goto out; } chansess = (struct ChanSess*)channel->typedata; assert(chansess != NULL); - TRACE(("type is %s", type)); + TRACE(("type is %s", type)) if (strcmp(type, "window-change") == 0) { ret = sessionwinchange(chansess); @@ -351,7 +351,7 @@ out: } m_free(type); - TRACE(("leave chansessionrequest")); + TRACE(("leave chansessionrequest")) } @@ -421,7 +421,7 @@ static void get_termmodes(struct ChanSess *chansess) { const struct TermCode * termcode; unsigned int len; - TRACE(("enter get_termmodes")); + TRACE(("enter get_termmodes")) /* Term modes */ /* We'll ignore errors and continue if we can't set modes. @@ -438,7 +438,7 @@ static void get_termmodes(struct ChanSess *chansess) { } if (len == 0) { - TRACE(("leave get_termmodes: empty terminal modes string")); + TRACE(("leave get_termmodes: empty terminal modes string")) } while (((opcode = buf_getbyte(ses.payload)) != 0x00) && opcode <= 159) { @@ -500,7 +500,7 @@ static void get_termmodes(struct ChanSess *chansess) { if (tcsetattr(chansess->master, TCSANOW, &termio) < 0) { dropbear_log(LOG_INFO, "error setting terminal attributes"); } - TRACE(("leave get_termmodes")); + TRACE(("leave get_termmodes")) } /* Set up a session pty which will be used to execute the shell or program. @@ -511,11 +511,11 @@ static int sessionpty(struct ChanSess * chansess) { unsigned int termlen; unsigned char namebuf[65]; - TRACE(("enter sessionpty")); + TRACE(("enter sessionpty")) chansess->term = buf_getstring(ses.payload, &termlen); if (termlen > MAX_TERM_LEN) { /* TODO send disconnect ? */ - TRACE(("leave sessionpty: term len too long")); + TRACE(("leave sessionpty: term len too long")) return DROPBEAR_FAILURE; } @@ -524,7 +524,7 @@ static int sessionpty(struct ChanSess * chansess) { dropbear_exit("multiple pty requests"); } if (pty_allocate(&chansess->master, &chansess->slave, namebuf, 64) == 0) { - TRACE(("leave sessionpty: failed to allocate pty")); + TRACE(("leave sessionpty: failed to allocate pty")) return DROPBEAR_FAILURE; } @@ -541,7 +541,7 @@ static int sessionpty(struct ChanSess * chansess) { /* Read the terminal modes */ get_termmodes(chansess); - TRACE(("leave sessionpty")); + TRACE(("leave sessionpty")) return DROPBEAR_SUCCESS; } @@ -555,7 +555,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, unsigned int cmdlen; int ret; - TRACE(("enter sessioncommand")); + TRACE(("enter sessioncommand")) if (chansess->cmd != NULL) { /* Note that only one command can _succeed_. The client might try @@ -612,7 +612,7 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) { pid_t pid; unsigned int i; - TRACE(("enter noptycommand")); + TRACE(("enter noptycommand")) /* redirect stdin/stdout/stderr */ if (pipe(infds) != 0) @@ -635,7 +635,7 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) { if ((dup2(infds[FDIN], STDIN_FILENO) < 0) || (dup2(outfds[FDOUT], STDOUT_FILENO) < 0) || (dup2(errfds[FDOUT], STDERR_FILENO) < 0)) { - TRACE(("leave noptycommand: error redirecting FDs")); + TRACE(("leave noptycommand: error redirecting FDs")) return DROPBEAR_FAILURE; } @@ -651,7 +651,7 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) { } else { /* parent */ - TRACE(("continue noptycommand: parent")); + TRACE(("continue noptycommand: parent")) chansess->pid = pid; addchildpid(chansess, pid); @@ -687,7 +687,7 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) { #undef FDIN #undef FDOUT - TRACE(("leave noptycommand")); + TRACE(("leave noptycommand")) return DROPBEAR_SUCCESS; } @@ -705,7 +705,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { char *hushpath = NULL; #endif - TRACE(("enter ptycommand")); + TRACE(("enter ptycommand")) /* we need to have a pty allocated */ if (chansess->master == -1 || chansess->tty == NULL) { @@ -728,7 +728,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { if ((dup2(chansess->slave, STDIN_FILENO) < 0) || (dup2(chansess->slave, STDERR_FILENO) < 0) || (dup2(chansess->slave, STDOUT_FILENO) < 0)) { - TRACE(("leave ptycommand: error redirecting filedesc")); + TRACE(("leave ptycommand: error redirecting filedesc")) return DROPBEAR_FAILURE; } @@ -776,7 +776,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { } else { /* parent */ - TRACE(("continue ptycommand: parent")); + TRACE(("continue ptycommand: parent")) chansess->pid = pid; /* add a child pid */ @@ -792,7 +792,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { } - TRACE(("leave ptycommand")); + TRACE(("leave ptycommand")) return DROPBEAR_SUCCESS; } diff --git a/svr-kex.c b/svr-kex.c index 47c540e..a9954bb 100644 --- a/svr-kex.c +++ b/svr-kex.c @@ -46,7 +46,7 @@ void recv_msg_kexdh_init() { DEF_MP_INT(dh_e); - TRACE(("enter recv_msg_kexdh_init")); + TRACE(("enter recv_msg_kexdh_init")) if (!ses.kexstate.recvkexinit) { dropbear_exit("Premature kexdh_init message received"); } @@ -60,7 +60,7 @@ void recv_msg_kexdh_init() { send_msg_newkeys(); ses.requirenext = SSH_MSG_NEWKEYS; - TRACE(("leave recv_msg_kexdh_init")); + TRACE(("leave recv_msg_kexdh_init")) } /* Generate our side of the diffie-hellman key exchange value (dh_f), and @@ -74,7 +74,7 @@ static void send_msg_kexdh_reply(mp_int *dh_e) { DEF_MP_INT(dh_y); DEF_MP_INT(dh_f); - TRACE(("enter send_msg_kexdh_reply")); + TRACE(("enter send_msg_kexdh_reply")) m_mp_init_multi(&dh_y, &dh_f, NULL); gen_kexdh_vals(&dh_f, &dh_y); @@ -99,6 +99,6 @@ static void send_msg_kexdh_reply(mp_int *dh_e) { /* the SSH_MSG_KEXDH_REPLY is done */ encrypt_packet(); - TRACE(("leave send_msg_kexdh_reply")); + TRACE(("leave send_msg_kexdh_reply")) } diff --git a/svr-main.c b/svr-main.c index 48e6042..e39f3d9 100644 --- a/svr-main.c +++ b/svr-main.c @@ -247,7 +247,7 @@ void main_noinetd() { } if (pipe(childpipe) < 0) { - TRACE(("error creating child pipe")); + TRACE(("error creating child pipe")) close(childsock); continue; } @@ -369,11 +369,11 @@ static int listensockets(int *sock, int sockcount, int *maxfd) { unsigned int sockpos = 0; int nsock; - TRACE(("listensockets: %d to try\n", svr_opts.portcount)); + TRACE(("listensockets: %d to try\n", svr_opts.portcount)) for (i = 0; i < svr_opts.portcount; i++) { - TRACE(("listening on '%s'", svr_opts.ports[i])); + TRACE(("listening on '%s'", svr_opts.ports[i])) nsock = dropbear_listen(NULL, svr_opts.ports[i], &sock[sockpos], sockcount - sockpos, diff --git a/svr-runopts.c b/svr-runopts.c index 06ffafc..375797b 100644 --- a/svr-runopts.c +++ b/svr-runopts.c @@ -270,7 +270,7 @@ void loadhostkeys() { int ret; int type; - TRACE(("enter loadhostkeys")); + TRACE(("enter loadhostkeys")) svr_opts.hostkey = new_sign_key(); @@ -300,5 +300,5 @@ void loadhostkeys() { dropbear_exit("No hostkeys available"); } - TRACE(("leave loadhostkeys")); + TRACE(("leave loadhostkeys")) } diff --git a/svr-service.c b/svr-service.c index e823490..2c78e7d 100644 --- a/svr-service.c +++ b/svr-service.c @@ -39,7 +39,7 @@ void recv_msg_service_request() { unsigned char * name; unsigned int len; - TRACE(("enter recv_msg_service_request")); + TRACE(("enter recv_msg_service_request")) name = buf_getstring(ses.payload, &len); @@ -49,7 +49,7 @@ void recv_msg_service_request() { send_msg_service_accept(name, len); m_free(name); - TRACE(("leave recv_msg_service_request: done ssh-userauth")); + TRACE(("leave recv_msg_service_request: done ssh-userauth")) return; } @@ -62,7 +62,7 @@ void recv_msg_service_request() { send_msg_service_accept(name, len); m_free(name); - TRACE(("leave recv_msg_service_request: done ssh-connection")); + TRACE(("leave recv_msg_service_request: done ssh-connection")) return; } @@ -75,7 +75,7 @@ void recv_msg_service_request() { static void send_msg_service_accept(unsigned char *name, int len) { - TRACE(("accepting service %s", name)); + TRACE(("accepting service %s", name)) CHECKCLEARTOWRITE(); diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c index 68ceba5..7fbc609 100644 --- a/svr-tcpfwd.c +++ b/svr-tcpfwd.c @@ -70,10 +70,10 @@ void recv_msg_global_request_remotetcp() { unsigned int wantreply = 0; int ret = DROPBEAR_FAILURE; - TRACE(("enter recv_msg_global_request_remotetcp")); + TRACE(("enter recv_msg_global_request_remotetcp")) if (opts.noremotetcp) { - TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled")); + TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled")) goto out; } @@ -81,7 +81,7 @@ void recv_msg_global_request_remotetcp() { wantreply = buf_getbyte(ses.payload); if (namelen > MAXNAMLEN) { - TRACE(("name len is wrong: %d", namelen)); + TRACE(("name len is wrong: %d", namelen)) goto out; } @@ -90,7 +90,7 @@ void recv_msg_global_request_remotetcp() { } else if (strcmp("cancel-tcpip-forward", reqname) == 0) { ret = svr_cancelremotetcp(); } else { - TRACE(("reqname isn't tcpip-forward: '%s'", reqname)); + TRACE(("reqname isn't tcpip-forward: '%s'", reqname)) } out: @@ -104,7 +104,7 @@ out: m_free(reqname); - TRACE(("leave recv_msg_global_request")); + TRACE(("leave recv_msg_global_request")) } @@ -143,11 +143,11 @@ static int svr_cancelremotetcp() { struct Listener * listener = NULL; struct TCPListener tcpinfo; - TRACE(("enter cancelremotetcp")); + TRACE(("enter cancelremotetcp")) bindaddr = buf_getstring(ses.payload, &addrlen); if (addrlen > MAX_IP_LEN) { - TRACE(("addr len too long: %d", addrlen)); + TRACE(("addr len too long: %d", addrlen)) goto out; } @@ -163,7 +163,7 @@ static int svr_cancelremotetcp() { out: m_free(bindaddr); - TRACE(("leave cancelremotetcp")); + TRACE(("leave cancelremotetcp")) return ret; } @@ -175,12 +175,12 @@ static int svr_remotetcpreq() { struct TCPListener *tcpinfo = NULL; unsigned int port; - TRACE(("enter remotetcpreq")); + TRACE(("enter remotetcpreq")) /* NOTE: at this stage, we ignore bindaddr. see below and listen_tcpfwd */ bindaddr = buf_getstring(ses.payload, &addrlen); if (addrlen > MAX_IP_LEN) { - TRACE(("addr len too long: %d", addrlen)); + TRACE(("addr len too long: %d", addrlen)) goto out; } @@ -192,12 +192,12 @@ static int svr_remotetcpreq() { } if (port < 1 || port > 65535) { - TRACE(("invalid port: %d", port)); + TRACE(("invalid port: %d", port)) goto out; } if (!ses.allowprivport && port < IPPORT_RESERVED) { - TRACE(("can't assign port < 1024 for non-root")); + TRACE(("can't assign port < 1024 for non-root")) goto out; } @@ -218,7 +218,7 @@ out: m_free(tcpinfo->sendaddr); m_free(tcpinfo); } - TRACE(("leave remotetcpreq")); + TRACE(("leave remotetcpreq")) return ret; } @@ -236,13 +236,13 @@ static int newtcpdirect(struct Channel * channel) { int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; if (opts.nolocaltcp) { - TRACE(("leave newtcpdirect: local tcp forwarding disabled")); + TRACE(("leave newtcpdirect: local tcp forwarding disabled")) goto out; } desthost = buf_getstring(ses.payload, &len); if (len > MAX_HOST_LEN) { - TRACE(("leave newtcpdirect: desthost too long")); + TRACE(("leave newtcpdirect: desthost too long")) goto out; } @@ -250,7 +250,7 @@ static int newtcpdirect(struct Channel * channel) { orighost = buf_getstring(ses.payload, &len); if (len > MAX_HOST_LEN) { - TRACE(("leave newtcpdirect: orighost too long")); + TRACE(("leave newtcpdirect: orighost too long")) goto out; } @@ -258,7 +258,7 @@ static int newtcpdirect(struct Channel * channel) { /* best be sure */ if (origport > 65535 || destport > 65535) { - TRACE(("leave newtcpdirect: port > 65535")); + TRACE(("leave newtcpdirect: port > 65535")) goto out; } @@ -266,7 +266,7 @@ static int newtcpdirect(struct Channel * channel) { sock = connect_remote(desthost, portstring, 1, NULL); if (sock < 0) { err = SSH_OPEN_CONNECT_FAILED; - TRACE(("leave newtcpdirect: sock failed")); + TRACE(("leave newtcpdirect: sock failed")) goto out; } @@ -284,7 +284,7 @@ static int newtcpdirect(struct Channel * channel) { out: m_free(desthost); m_free(orighost); - TRACE(("leave newtcpdirect: err %d", err)); + TRACE(("leave newtcpdirect: err %d", err)) return err; } diff --git a/svr-x11fwd.c b/svr-x11fwd.c index 45c9060..e15fb82 100644 --- a/svr-x11fwd.c +++ b/svr-x11fwd.c @@ -170,7 +170,7 @@ void x11cleanup(struct ChanSess *chansess) { m_free(chansess->x11authprot); m_free(chansess->x11authcookie); - TRACE(("chansess %s", chansess)); + TRACE(("chansess %s", chansess)) if (chansess->x11listener != NULL) { remove_listener(chansess->x11listener); chansess->x11listener = NULL; diff --git a/tcp-accept.c b/tcp-accept.c index c143319..e75224e 100644 --- a/tcp-accept.c +++ b/tcp-accept.c @@ -87,7 +87,7 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) { int nsocks; char* errstring = NULL; - TRACE(("enter listen_tcpfwd")); + TRACE(("enter listen_tcpfwd")) /* first we try to bind, so don't need to do so much cleanup on failure */ snprintf(portstring, sizeof(portstring), "%d", tcpinfo->listenport); @@ -100,7 +100,7 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) { if (nsocks < 0) { dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring); m_free(errstring); - TRACE(("leave listen_tcpfwd: dropbear_listen failed")); + TRACE(("leave listen_tcpfwd: dropbear_listen failed")) return DROPBEAR_FAILURE; } @@ -109,11 +109,11 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) { if (listener == NULL) { m_free(tcpinfo); - TRACE(("leave listen_tcpfwd: listener failed")); + TRACE(("leave listen_tcpfwd: listener failed")) return DROPBEAR_FAILURE; } - TRACE(("leave listen_tcpfwd: success")); + TRACE(("leave listen_tcpfwd: success")) return DROPBEAR_SUCCESS; } -- cgit v1.2.3 From f45eafe342aa07dfdc7a83e865b642f9b8ef2fa0 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sun, 13 Mar 2005 13:58:14 +0000 Subject: * fix longstanding bug with connections being closed on failure to connect to auth socket (server) * differentiate between get_byte and get_bool * get rid of some // comments * general tidying --HG-- extra : convert_revision : fb8d188ce33b6b45804a5ce51b9f601f83bdf3d7 --- buffer.c | 10 ++++++++++ buffer.h | 1 + channel.h | 2 +- cli-auth.c | 2 +- cli-channel.c | 5 +---- cli-chansession.c | 2 +- common-channel.c | 43 ++++++++++++++----------------------------- common-kex.c | 3 +-- debug.h | 2 +- dss.c | 2 ++ kex.h | 6 +++--- scp.c | 3 --- svr-authpam.c | 2 +- svr-authpasswd.c | 2 +- svr-authpubkey.c | 2 +- svr-chansession.c | 2 +- svr-tcpfwd.c | 2 +- svr-x11fwd.c | 2 +- 18 files changed, 42 insertions(+), 51 deletions(-) (limited to 'common-kex.c') diff --git a/buffer.c b/buffer.c index dff861f..97045ff 100644 --- a/buffer.c +++ b/buffer.c @@ -160,6 +160,16 @@ unsigned char buf_getbyte(buffer* buf) { return buf->data[buf->pos++]; } +/* Get a bool from the buffer and increment the pos */ +unsigned char buf_getbool(buffer* buf) { + + unsigned char b; + b = buf_getbyte(buf); + if (b != 0) + b = 1; + return b; +} + /* put a byte, incrementing the length if required */ void buf_putbyte(buffer* buf, unsigned char val) { diff --git a/buffer.h b/buffer.h index e1031a1..f9aa6fa 100644 --- a/buffer.h +++ b/buffer.h @@ -50,6 +50,7 @@ void buf_setpos(buffer* buf, unsigned int pos); void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */ void buf_incrwritepos(buffer* buf, unsigned int incr); unsigned char buf_getbyte(buffer* buf); +unsigned char buf_getbool(buffer* buf); 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); diff --git a/channel.h b/channel.h index 225fafb..a2fe87a 100644 --- a/channel.h +++ b/channel.h @@ -100,7 +100,7 @@ void chaninitialise(); void chancleanup(); void setchannelfds(fd_set *readfd, fd_set *writefd); void channelio(fd_set *readfd, fd_set *writefd); -struct Channel* getchannel(unsigned int chan); +struct Channel* getchannel(); struct Channel* newchannel(unsigned int remotechan, const struct ChanType *type, unsigned int transwindow, unsigned int transmaxpacket); diff --git a/cli-auth.c b/cli-auth.c index dfd9bbb..fc51061 100644 --- a/cli-auth.c +++ b/cli-auth.c @@ -127,7 +127,7 @@ void recv_msg_userauth_failure() { methods = buf_getstring(ses.payload, &methlen); - partial = buf_getbyte(ses.payload); + partial = buf_getbool(ses.payload); if (partial) { dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required"); diff --git a/cli-channel.c b/cli-channel.c index 42e165b..1bd49ab 100644 --- a/cli-channel.c +++ b/cli-channel.c @@ -33,15 +33,12 @@ /* We receive channel data - only used by the client chansession code*/ void recv_msg_channel_extended_data() { - unsigned int chan; struct Channel *channel; unsigned int datatype; TRACE(("enter recv_msg_channel_extended_data")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } diff --git a/cli-chansession.c b/cli-chansession.c index 76e9dfa..a8363ac 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -62,7 +62,7 @@ static void cli_chansessreq(struct Channel *channel) { TRACE(("enter cli_chansessreq")) type = buf_getstring(ses.payload, NULL); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (strcmp(type, "exit-status") != 0) { TRACE(("unknown request '%s'", type)) diff --git a/common-channel.c b/common-channel.c index 6f73fab..bb7928c 100644 --- a/common-channel.c +++ b/common-channel.c @@ -162,8 +162,13 @@ struct Channel* newchannel(unsigned int remotechan, return newchan; } -/* Get the channel structure corresponding to a channel number */ -struct Channel* getchannel(unsigned int chan) { +/* Returns the channel structure corresponding to the channel in the current + * data packet (ses.payload must be positioned appropriately) */ +struct Channel* getchannel() { + + unsigned int chan; + + chan = buf_getint(ses.payload); if (chan >= ses.chansize || ses.channels[chan] == NULL) { return NULL; } @@ -474,14 +479,11 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) { * etc) FD is also EOF */ void recv_msg_channel_eof() { - unsigned int chan; struct Channel * channel; TRACE(("enter recv_msg_channel_eof")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("EOF for unknown channel"); } @@ -500,15 +502,11 @@ void recv_msg_channel_eof() { /* Handle channel closure(), respond in kind and close the channels */ void recv_msg_channel_close() { - unsigned int chan; struct Channel * channel; TRACE(("enter recv_msg_channel_close")) - chan = buf_getint(ses.payload); - TRACE(("close channel = %d", chan)) - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { /* disconnect ? */ dropbear_exit("Close for unknown channel"); @@ -567,14 +565,11 @@ static void deletechannel(struct Channel *channel) { * such as chansession or x11fwd */ void recv_msg_channel_request() { - unsigned int chan; struct Channel *channel; TRACE(("enter recv_msg_channel_request")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { /* disconnect ? */ dropbear_exit("Unknown channel"); @@ -666,12 +661,9 @@ static void send_msg_channel_data(struct Channel *channel, int isextended, /* We receive channel data */ void recv_msg_channel_data() { - unsigned int chan; struct Channel *channel; - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -738,13 +730,10 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, * as data is sent, and incremented upon receiving window-adjust messages */ void recv_msg_channel_window_adjust() { - unsigned int chan; struct Channel * channel; unsigned int incr; - chan = buf_getint(ses.payload); - channel = getchannel(chan); - + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -961,14 +950,12 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) { * successful*/ void recv_msg_channel_open_confirmation() { - unsigned int chan; struct Channel * channel; int ret; TRACE(("enter recv_msg_channel_open_confirmation")) - chan = buf_getint(ses.payload); - channel = getchannel(chan); + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } @@ -995,11 +982,9 @@ void recv_msg_channel_open_confirmation() { /* Notification that our channel open request failed */ void recv_msg_channel_open_failure() { - unsigned int chan; struct Channel * channel; - chan = buf_getbyte(ses.payload); - channel = getchannel(chan); + channel = getchannel(); if (channel == NULL) { dropbear_exit("Unknown channel"); } diff --git a/common-kex.c b/common-kex.c index 97e341d..a2336c5 100644 --- a/common-kex.c +++ b/common-kex.c @@ -457,7 +457,6 @@ void recv_msg_kexinit() { /* the rest of ses.kexhashbuf will be done after DH exchange */ ses.kexstate.recvkexinit = 1; -// ses.expecting = 0; // client matt TRACE(("leave recv_msg_kexinit")) } @@ -683,7 +682,7 @@ static void read_kex_algos() { buf_eatstring(ses.payload); /* first_kex_packet_follows */ - if (buf_getbyte(ses.payload)) { + if (buf_getbool(ses.payload)) { ses.kexstate.firstfollows = 1; /* if the guess wasn't good, we ignore the packet sent */ if (!allgood) { diff --git a/debug.h b/debug.h index 7b1e2b5..93cb891 100644 --- a/debug.h +++ b/debug.h @@ -39,7 +39,7 @@ * Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing may not sanitise strings etc. This will add a reasonable * amount to your executable size. */ - //#define DEBUG_TRACE +/*#define DEBUG_TRACE */ /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're diff --git a/dss.c b/dss.c index 6429ede..7b3d9d4 100644 --- a/dss.c +++ b/dss.c @@ -261,6 +261,7 @@ out: } #endif /* DROPBEAR_SIGNKEY_VERIFY */ +#ifdef DSS_PROTOK /* convert an unsigned mp into an array of bytes, malloced. * This array must be freed after use, len contains the length of the array, * if len != NULL */ @@ -279,6 +280,7 @@ static unsigned char* mptobytes(mp_int *mp, int *len) { } return ret; } +#endif /* Sign the data presented with key, writing the signature contents * to the buffer diff --git a/kex.h b/kex.h index 01626ed..92b6c42 100644 --- a/kex.h +++ b/kex.h @@ -37,10 +37,10 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv); void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, sign_key *hostkey); -void recv_msg_kexdh_init(); // server +void recv_msg_kexdh_init(); /* server */ -void send_msg_kexdh_init(); // client -void recv_msg_kexdh_reply(); // client +void send_msg_kexdh_init(); /* client */ +void recv_msg_kexdh_reply(); /* client */ extern const unsigned char dh_p_val[]; #define DH_P_LEN 128 /* The length of the dh_p_val array */ diff --git a/scp.c b/scp.c index e356b8b..ccb6c2a 100644 --- a/scp.c +++ b/scp.c @@ -244,9 +244,6 @@ main(int argc, char **argv) extern char *optarg; extern int optind; - /* hack, seems to work */ -// __progname = argv[0]; - args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); diff --git a/svr-authpam.c b/svr-authpam.c index e045b74..fe1f123 100644 --- a/svr-authpam.c +++ b/svr-authpam.c @@ -155,7 +155,7 @@ void svr_auth_pam() { unsigned char changepw; /* check if client wants to change password */ - changepw = buf_getbyte(ses.payload); + changepw = buf_getbool(ses.payload); if (changepw) { /* not implemented by this server */ send_msg_userauth_failure(0, 1); diff --git a/svr-authpasswd.c b/svr-authpasswd.c index 4348817..5be1e2a 100644 --- a/svr-authpasswd.c +++ b/svr-authpasswd.c @@ -71,7 +71,7 @@ void svr_auth_password() { } /* check if client wants to change password */ - changepw = buf_getbyte(ses.payload); + changepw = buf_getbool(ses.payload); if (changepw) { /* not implemented by this server */ send_msg_userauth_failure(0, 1); diff --git a/svr-authpubkey.c b/svr-authpubkey.c index 5daba0f..dcd59f0 100644 --- a/svr-authpubkey.c +++ b/svr-authpubkey.c @@ -64,7 +64,7 @@ void svr_auth_pubkey() { /* 0 indicates user just wants to check if key can be used, 1 is an * actual attempt*/ - testkey = (buf_getbyte(ses.payload) == 0); + testkey = (buf_getbool(ses.payload) == 0); algo = buf_getstring(ses.payload, &algolen); keybloblen = buf_getint(ses.payload); diff --git a/svr-chansession.c b/svr-chansession.c index c04d592..90c82a7 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -305,7 +305,7 @@ static void chansessionrequest(struct Channel *channel) { TRACE(("enter chansessionrequest")) type = buf_getstring(ses.payload, &typelen); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (typelen > MAX_NAME_LEN) { TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/ diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c index 7fbc609..3acc4ff 100644 --- a/svr-tcpfwd.c +++ b/svr-tcpfwd.c @@ -78,7 +78,7 @@ void recv_msg_global_request_remotetcp() { } reqname = buf_getstring(ses.payload, &namelen); - wantreply = buf_getbyte(ses.payload); + wantreply = buf_getbool(ses.payload); if (namelen > MAXNAMLEN) { TRACE(("name len is wrong: %d", namelen)) diff --git a/svr-x11fwd.c b/svr-x11fwd.c index e15fb82..cbc8a79 100644 --- a/svr-x11fwd.c +++ b/svr-x11fwd.c @@ -52,7 +52,7 @@ int x11req(struct ChanSess * chansess) { return DROPBEAR_FAILURE; } - chansess->x11singleconn = buf_getbyte(ses.payload); + chansess->x11singleconn = buf_getbool(ses.payload); chansess->x11authprot = buf_getstring(ses.payload, NULL); chansess->x11authcookie = buf_getstring(ses.payload, NULL); chansess->x11screennum = buf_getint(ses.payload); -- cgit v1.2.3 From cf585ba1dee7a7e1f2fbc90d2251d99b7da66a7e Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 5 May 2005 03:58:21 +0000 Subject: - refactored random mp_int generation and byte->mp_int code - added RSA blinding --HG-- extra : convert_revision : 5d5b4657a24a1c8f53c6fc45d5ec29ddb85fb45a --- bignum.c | 4 +-- bignum.h | 2 +- common-kex.c | 24 +++-------------- dss.c | 30 ++++++--------------- gendss.c | 28 +++----------------- genrsa.c | 5 +--- random.c | 36 +++++++++++++++++++++++++ random.h | 3 +++ rsa.c | 86 +++++++++++++++++++++++++++++++++++++++--------------------- 9 files changed, 115 insertions(+), 103 deletions(-) (limited to 'common-kex.c') diff --git a/bignum.c b/bignum.c index 97901fb..60b5220 100644 --- a/bignum.c +++ b/bignum.c @@ -52,9 +52,9 @@ void m_mp_init_multi(mp_int *mp, ...) va_end(args); } -void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len) { +void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) { - if (mp_read_unsigned_bin(mp, bytes, len) != MP_OKAY) { + if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) { dropbear_exit("mem alloc error"); } } diff --git a/bignum.h b/bignum.h index 2a807af..042f811 100644 --- a/bignum.h +++ b/bignum.h @@ -29,7 +29,7 @@ void m_mp_init(mp_int *mp); void m_mp_init_multi(mp_int *mp, ...); -void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len); +void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len); void sha1_process_mp(hash_state *hs, mp_int *mp); #endif /* _BIGNUM_H_ */ diff --git a/common-kex.c b/common-kex.c index a2336c5..8a8aa93 100644 --- a/common-kex.c +++ b/common-kex.c @@ -469,18 +469,13 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { DEF_MP_INT(dh_p); DEF_MP_INT(dh_q); DEF_MP_INT(dh_g); - unsigned char randbuf[DH_P_LEN]; - int dh_q_len; TRACE(("enter send_msg_kexdh_reply")) m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); /* read the prime and generator*/ - if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) - != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } + bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN); if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); @@ -495,16 +490,8 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { dropbear_exit("Diffie-Hellman error"); } - dh_q_len = mp_unsigned_bin_size(&dh_q); - - /* calculate our random value dh_y */ - do { - assert((unsigned int)dh_q_len <= sizeof(randbuf)); - genrandom(randbuf, dh_q_len); - if (mp_read_unsigned_bin(dh_priv, randbuf, dh_q_len) != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } - } while (mp_cmp(dh_priv, &dh_q) == MP_GT || mp_cmp_d(dh_priv, 0) != MP_GT); + /* Generate a private portion 0 < dh_priv < dh_q */ + gen_random_mpint(&dh_q, dh_priv); /* f = g^y mod p */ if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { @@ -526,10 +513,7 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, /* read the prime and generator*/ mp_init(&dh_p); - if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) - != MP_OKAY) { - dropbear_exit("Diffie-Hellman error"); - } + bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ if (mp_cmp(dh_pub_them, &dh_p) != MP_LT diff --git a/dss.c b/dss.c index 5cf018d..cb877ca 100644 --- a/dss.c +++ b/dss.c @@ -190,10 +190,8 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, /* create the signature - s' and r' are the received signatures in buf */ /* w = (s')-1 mod q */ /* let val1 = s' */ - if (mp_read_unsigned_bin(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE) - != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE); + if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, s' >= q")) goto out; @@ -205,9 +203,8 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, /* u1 = ((SHA(M')w) mod q */ /* let val1 = SHA(M') = msghash */ - if (mp_read_unsigned_bin(&val1, msghash, SHA1_HASH_SIZE) != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, msghash, SHA1_HASH_SIZE); + /* let val3 = u1 = ((SHA(M')w) mod q */ if (mp_mulmod(&val1, &val2, key->q, &val3) != MP_OKAY) { goto out; @@ -215,10 +212,7 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, /* u2 = ((r')w) mod q */ /* let val1 = r' */ - if (mp_read_unsigned_bin(&val1, &string[0], SHA1_HASH_SIZE) - != MP_OKAY) { - goto out; - } + bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE); if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, r' >= q")) goto out; @@ -306,8 +300,6 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, unsigned char *privkeytmp; unsigned char proto_k[SHA512_HASH_SIZE]; DEF_MP_INT(dss_protok); -#else - unsigned char kbuf[SHA1_HASH_SIZE]; #endif DEF_MP_INT(dss_k); DEF_MP_INT(dss_m); @@ -345,22 +337,16 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, /* generate k */ m_mp_init(&dss_protok); - bytestomp(&dss_protok, proto_k, SHA512_HASH_SIZE); + bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE); mp_mod(&dss_protok, key->q, &dss_k); mp_clear(&dss_protok); m_burn(proto_k, SHA512_HASH_SIZE); #else /* DSS_PROTOK not defined*/ - do { - genrandom(kbuf, SHA1_HASH_SIZE); - if (mp_read_unsigned_bin(&dss_k, kbuf, SHA1_HASH_SIZE) != MP_OKAY) { - dropbear_exit("dss error"); - } - } while (mp_cmp(&dss_k, key->q) == MP_GT || mp_cmp_d(&dss_k, 0) != MP_GT); - m_burn(kbuf, SHA1_HASH_SIZE); + gen_random_mpint(key->q, &dss_k); #endif /* now generate the actual signature */ - bytestomp(&dss_m, msghash, SHA1_HASH_SIZE); + bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE); /* g^k mod p */ if (mp_exptmod(key->g, &dss_k, key->p, &dss_temp1) != MP_OKAY) { diff --git a/gendss.c b/gendss.c index d589722..bf46d3d 100644 --- a/gendss.c +++ b/gendss.c @@ -77,10 +77,7 @@ static void getq(dss_key *key) { buf[0] |= 0x80; /* top bit high */ buf[QSIZE-1] |= 0x01; /* bottom bit high */ - if (mp_read_unsigned_bin(key->q, buf, QSIZE) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - exit(1); - } + bytes_to_mp(key->q, buf, QSIZE); /* 18 rounds are required according to HAC */ if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) { @@ -116,10 +113,7 @@ static void getp(dss_key *key, unsigned int size) { buf[0] |= 0x80; /* set the top bit high */ /* X is a random mp_int */ - if (mp_read_unsigned_bin(&tempX, buf, size) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - exit(1); - } + bytes_to_mp(&tempX, buf, size); /* C = X mod 2q */ if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) { @@ -147,6 +141,7 @@ static void getp(dss_key *key, unsigned int size) { } while (!result); mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL); + m_burn(buf, size); m_free(buf); } @@ -189,22 +184,7 @@ static void getg(dss_key * key) { static void getx(dss_key *key) { - DEF_MP_INT(val); - char buf[QSIZE]; - - m_mp_init(&val); - - do { - genrandom(buf, QSIZE); - - if (mp_read_unsigned_bin(&val, buf, QSIZE) != MP_OKAY) { - fprintf(stderr, "dss key generation failed\n"); - } - } while ((mp_cmp_d(&val, 1) == MP_GT) && (mp_cmp(&val, key->q) == MP_LT)); - - mp_copy(&val, key->x); - mp_clear(&val); - + gen_random_mpint(key->q, key->x); } static void gety(dss_key *key) { diff --git a/genrsa.c b/genrsa.c index 5711519..73a7984 100644 --- a/genrsa.c +++ b/genrsa.c @@ -108,10 +108,7 @@ static void getrsaprime(mp_int* prime, mp_int *primeminus, genrandom(buf, size+1); buf[0] |= 0x80; /* MSB set */ - if (mp_read_unsigned_bin(prime, buf, size+1) != MP_OKAY) { - fprintf(stderr, "rsa generation failed\n"); - exit(1); - } + bytes_to_mp(prime, buf, size+1); /* find the next integer which is prime, 8 round of miller-rabin */ if (mp_prime_next_prime(prime, 8, 0) != MP_OKAY) { diff --git a/random.c b/random.c index c69f641..2b2777a 100644 --- a/random.c +++ b/random.c @@ -25,6 +25,7 @@ #include "includes.h" #include "buffer.h" #include "dbutil.h" +#include "bignum.h" int donerandinit = 0; @@ -159,3 +160,38 @@ void genrandom(unsigned char* buf, unsigned int len) { } m_burn(hash, sizeof(hash)); } + +/* Generates a random mp_int. + * max is a *mp_int specifying an upper bound. + * rand must be an initialised *mp_int for the result. + * the result rand satisfies: 0 < rand < max + * */ +void gen_random_mpint(mp_int *max, mp_int *rand) { + + unsigned char *randbuf = NULL; + unsigned int len = 0; + const char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; + + const int size_bits = mp_count_bits(max); + + len = size_bits / 8; + if ((size_bits % 8) != 0) { + len += 1; + } + + randbuf = (unsigned char*)m_malloc(len); + do { + genrandom(randbuf, len); + /* Mask out the unrequired bits - mp_read_unsigned_bin expects + * MSB first.*/ + randbuf[0] &= masks[size_bits % 8]; + + bytes_to_mp(rand, randbuf, len); + + /* keep regenerating until we get one satisfying + * 0 < rand < max */ + } while ( ( (max != NULL) && (mp_cmp(rand, max) != MP_LT) ) + || (mp_cmp_d(rand, 0) != MP_GT) ); + m_burn(randbuf, len); + m_free(randbuf); +} diff --git a/random.h b/random.h index 91aa342..5ec1f24 100644 --- a/random.h +++ b/random.h @@ -25,8 +25,11 @@ #ifndef _RANDOM_H_ #define _RANDOM_H_ +struct mp_int; + void seedrandom(); void genrandom(unsigned char* buf, int len); void addrandom(unsigned char* buf, int len); +void gen_random_mpint(mp_int *max, mp_int *rand); #endif /* _RANDOM_H_ */ diff --git a/rsa.c b/rsa.c index 1ac0357..8b24360 100644 --- a/rsa.c +++ b/rsa.c @@ -38,8 +38,9 @@ #ifdef DROPBEAR_RSA -static mp_int * rsa_pad_em(rsa_key * key, - const unsigned char * data, unsigned int len); +static void rsa_pad_em(rsa_key * key, + const unsigned char * data, unsigned int len, + mp_int * rsa_em); /* Load a public rsa key from a buffer, initialising the values. * The key will have the same format as buf_put_rsa_key. @@ -203,14 +204,14 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, unsigned int slen; DEF_MP_INT(rsa_s); DEF_MP_INT(rsa_mdash); - mp_int *rsa_em = NULL; + DEF_MP_INT(rsa_em); int ret = DROPBEAR_FAILURE; TRACE(("enter buf_rsa_verify")) assert(key != NULL); - m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); + m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); slen = buf_getint(buf); if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { @@ -231,29 +232,25 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data, } /* create the magic PKCS padded value */ - rsa_em = rsa_pad_em(key, data, len); + rsa_pad_em(key, data, len, &rsa_em); if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { TRACE(("failed exptmod rsa_s")) goto out; } - if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { + if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) { /* signature is valid */ TRACE(("success!")) ret = DROPBEAR_SUCCESS; } out: - if (rsa_em) { - mp_clear(rsa_em); - m_free(rsa_em); - } - mp_clear_multi(&rsa_mdash, &rsa_s, NULL); + mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL); TRACE(("leave buf_rsa_verify: ret %d", ret)) return ret; - } + #endif /* DROPBEAR_SIGNKEY_VERIFY */ /* Sign the data presented with key, writing the signature contents @@ -264,22 +261,56 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, unsigned int nsize, ssize; unsigned int i; DEF_MP_INT(rsa_s); - mp_int *rsa_em = NULL; + DEF_MP_INT(rsa_tmp1); + DEF_MP_INT(rsa_tmp2); + DEF_MP_INT(rsa_tmp3); + unsigned char *tmpbuf; TRACE(("enter buf_put_rsa_sign")) assert(key != NULL); - rsa_em = rsa_pad_em(key, data, len); + m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); - m_mp_init(&rsa_s); + rsa_pad_em(key, data, len, &rsa_tmp1); /* the actual signing of the padded data */ + +#define RSA_BLINDING +#ifdef RSA_BLINDING + + /* With blinding, s = (r^(-1))((em)*r^e)^d mod n */ + + /* generate the r blinding value */ + /* rsa_tmp2 is r */ + gen_random_mpint(key->n, &rsa_tmp2); + + /* rsa_tmp1 is em */ + /* em' = em * r^e mod n */ + + mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/ + mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3); + mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2); + + /* rsa_tmp2 is em' */ + /* s' = (em')^d mod n */ + mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1); + + /* rsa_tmp1 is s' */ + /* rsa_tmp3 is r^(-1) mod n */ + /* s = (s')r^(-1) mod n */ + mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s); + +#else + /* s = em^d mod n */ - if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) { + /* rsa_tmp1 is em */ + if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) { dropbear_exit("rsa error"); } - mp_clear(rsa_em); - m_free(rsa_em); + +#endif /* RSA_BLINDING */ + + mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL); /* create the signature to return */ buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); @@ -318,9 +349,12 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data, * * prefix is the ASN1 designator prefix, * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 + * + * rsa_em must be a pointer to an initialised mp_int. */ -static mp_int * rsa_pad_em(rsa_key * key, - const unsigned char * data, unsigned int len) { +static void rsa_pad_em(rsa_key * key, + const unsigned char * data, unsigned int len, + mp_int * rsa_em) { /* ASN1 designator (including the 0x00 preceding) */ const char rsa_asn1_magic[] = @@ -330,7 +364,6 @@ static mp_int * rsa_pad_em(rsa_key * key, buffer * rsa_EM = NULL; hash_state hs; unsigned int nsize; - mp_int * rsa_em = NULL; assert(key != NULL); assert(data != NULL); @@ -358,16 +391,9 @@ static mp_int * rsa_pad_em(rsa_key * key, /* Create the mp_int from the encoded bytes */ buf_setpos(rsa_EM, 0); - rsa_em = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init(rsa_em); - if (mp_read_unsigned_bin(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), - rsa_EM->size) != MP_OKAY) { - dropbear_exit("rsa error"); - } + bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size), + rsa_EM->size); buf_free(rsa_EM); - - return rsa_em; - } #endif /* DROPBEAR_RSA */ -- cgit v1.2.3 From 71c07ed930e0e8c9402c7dc259650e08dd36eb4d Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 24 Aug 2005 16:43:29 +0000 Subject: Make a variables static - Patch from Andreas Mohr --HG-- extra : convert_revision : de230e99968203f63995d49e9123b3ac45feab71 --- common-algo.c | 12 ++++++------ common-kex.c | 5 +++-- kex.h | 5 ----- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'common-kex.c') diff --git a/common-algo.c b/common-algo.c index ea9c311..31902d1 100644 --- a/common-algo.c +++ b/common-algo.c @@ -33,19 +33,19 @@ {&cipher_desc, keysize, blocksize} */ #ifdef DROPBEAR_AES128_CBC -const struct dropbear_cipher dropbear_aes128 = +static const struct dropbear_cipher dropbear_aes128 = {&aes_desc, 16, 16}; #endif #ifdef DROPBEAR_BLOWFISH_CBC -const struct dropbear_cipher dropbear_blowfish = +static const struct dropbear_cipher dropbear_blowfish = {&blowfish_desc, 16, 8}; #endif #ifdef DROPBEAR_TWOFISH128_CBC -const struct dropbear_cipher dropbear_twofish128 = +static const struct dropbear_cipher dropbear_twofish128 = {&twofish_desc, 16, 16}; #endif #ifdef DROPBEAR_3DES_CBC -const struct dropbear_cipher dropbear_3des = +static const struct dropbear_cipher dropbear_3des = {&des3_desc, 24, 8}; #endif @@ -57,11 +57,11 @@ const struct dropbear_cipher dropbear_nocipher = {&hash_desc, keysize, hashsize} */ #ifdef DROPBEAR_SHA1_HMAC -const struct dropbear_hash dropbear_sha1 = +static const struct dropbear_hash dropbear_sha1 = {&sha1_desc, 20, 20}; #endif #ifdef DROPBEAR_MD5_HMAC -const struct dropbear_hash dropbear_md5 = +static const struct dropbear_hash dropbear_md5 = {&md5_desc, 16, 16}; #endif diff --git a/common-kex.c b/common-kex.c index 8a8aa93..a0c7b7e 100644 --- a/common-kex.c +++ b/common-kex.c @@ -35,7 +35,7 @@ #include "random.h" /* diffie-hellman-group1-sha1 value for p */ -const unsigned char dh_p_val[] = { +static const unsigned char dh_p_val[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, @@ -47,8 +47,9 @@ const unsigned char dh_p_val[] = { 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +#define DH_P_LEN sizeof(dh_p_val) -const int DH_G_VAL = 2; +static const int DH_G_VAL = 2; static void kexinitialise(); void gen_new_keys(); diff --git a/kex.h b/kex.h index 92b6c42..448ad1b 100644 --- a/kex.h +++ b/kex.h @@ -42,11 +42,6 @@ void recv_msg_kexdh_init(); /* server */ void send_msg_kexdh_init(); /* client */ void recv_msg_kexdh_reply(); /* client */ -extern const unsigned char dh_p_val[]; -#define DH_P_LEN 128 /* The length of the dh_p_val array */ - -extern const int DH_G_VAL; /* == 2 */ - struct KEXState { unsigned sentkexinit : 1; /*set when we've sent/recv kexinit packet */ -- cgit v1.2.3 From ca77392bd1bde7e42b8254f82ca9b0b569b4f74d Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 30 Aug 2005 16:58:57 +0000 Subject: - Fixed twofish algorithm naming so it actually works. - Added support for aes256, twofish256 and sha1-96 - Fixed some debugging statements --HG-- extra : convert_revision : 598835dadaddb1e95d4ac99f8a1be4ba51639000 --- common-algo.c | 29 +++++++++++++++++++++++++---- common-kex.c | 15 ++++++--------- options.h | 31 ++++++++++++++++++++++--------- packet.c | 27 +++++++++++++-------------- 4 files changed, 66 insertions(+), 36 deletions(-) (limited to 'common-kex.c') diff --git a/common-algo.c b/common-algo.c index 31902d1..4a8f49c 100644 --- a/common-algo.c +++ b/common-algo.c @@ -32,6 +32,10 @@ /* Mappings for ciphers, parameters are {&cipher_desc, keysize, blocksize} */ +#ifdef DROPBEAR_AES256_CBC +static const struct dropbear_cipher dropbear_aes256 = + {&aes_desc, 32, 16}; +#endif #ifdef DROPBEAR_AES128_CBC static const struct dropbear_cipher dropbear_aes128 = {&aes_desc, 16, 16}; @@ -40,6 +44,10 @@ static const struct dropbear_cipher dropbear_aes128 = static const struct dropbear_cipher dropbear_blowfish = {&blowfish_desc, 16, 8}; #endif +#ifdef DROPBEAR_TWOFISH256_CBC +static const struct dropbear_cipher dropbear_twofish256 = + {&twofish_desc, 32, 16}; +#endif #ifdef DROPBEAR_TWOFISH128_CBC static const struct dropbear_cipher dropbear_twofish128 = {&twofish_desc, 16, 16}; @@ -60,6 +68,10 @@ const struct dropbear_cipher dropbear_nocipher = static const struct dropbear_hash dropbear_sha1 = {&sha1_desc, 20, 20}; #endif +#ifdef DROPBEAR_SHA1_96_HMAC +static const struct dropbear_hash dropbear_sha1_96 = + {&sha1_desc, 20, 12}; +#endif #ifdef DROPBEAR_MD5_HMAC static const struct dropbear_hash dropbear_md5 = {&md5_desc, 16, 16}; @@ -75,19 +87,28 @@ algo_type sshciphers[] = { #ifdef DROPBEAR_AES128_CBC {"aes128-cbc", 0, (void*)&dropbear_aes128, 1}, #endif +#ifdef DROPBEAR_3DES_CBC + {"3des-cbc", 0, (void*)&dropbear_3des, 1}, +#endif +#ifdef DROPBEAR_AES256_CBC + {"aes256-cbc", 0, (void*)&dropbear_aes256, 1}, +#endif #ifdef DROPBEAR_BLOWFISH_CBC {"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1}, #endif -#ifdef DROPBEAR_TWOFISH128_CBC - {"twofish-cbc", 0, (void*)&dropbear_twofish128, 1}, +#ifdef DROPBEAR_TWOFISH256_CBC + {"twofish256-cbc", 0, (void*)&dropbear_twofish256, 1}, #endif -#ifdef DROPBEAR_3DES_CBC - {"3des-cbc", 0, (void*)&dropbear_3des, 1}, +#ifdef DROPBEAR_TWOFISH128_CBC + {"twofish128-cbc", 0, (void*)&dropbear_twofish128, 1}, #endif {NULL, 0, NULL, 0} }; algo_type sshhashes[] = { +#ifdef DROPBEAR_SHA1_96_HMAC + {"hmac-sha1-96", 0, (void*)&dropbear_sha1_96, 1}, +#endif #ifdef DROPBEAR_SHA1_HMAC {"hmac-sha1", 0, (void*)&dropbear_sha1, 1}, #endif diff --git a/common-kex.c b/common-kex.c index a0c7b7e..f325329 100644 --- a/common-kex.c +++ b/common-kex.c @@ -622,7 +622,7 @@ static void read_kex_algos() { erralgo = "enc c->s"; goto error; } - TRACE(("c2s is %s", c2s_cipher_algo->name)) + TRACE(("enc c2s is %s", c2s_cipher_algo->name)) /* encryption_algorithms_server_to_client */ s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); @@ -630,7 +630,7 @@ static void read_kex_algos() { erralgo = "enc s->c"; goto error; } - TRACE(("s2c is %s", s2c_cipher_algo->name)) + TRACE(("enc s2c is %s", s2c_cipher_algo->name)) /* mac_algorithms_client_to_server */ c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -638,6 +638,7 @@ static void read_kex_algos() { erralgo = "mac c->s"; goto error; } + TRACE(("hash c2s is %s", c2s_hash_algo->name)) /* mac_algorithms_server_to_client */ s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); @@ -645,6 +646,7 @@ static void read_kex_algos() { erralgo = "mac s->c"; goto error; } + TRACE(("hash s2c is %s", s2c_hash_algo->name)) /* compression_algorithms_client_to_server */ c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -652,6 +654,7 @@ static void read_kex_algos() { erralgo = "comp c->s"; goto error; } + TRACE(("hash c2s is %s", c2s_comp_algo->name)) /* compression_algorithms_server_to_client */ s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); @@ -659,6 +662,7 @@ static void read_kex_algos() { erralgo = "comp s->c"; goto error; } + TRACE(("hash s2c is %s", s2c_comp_algo->name)) /* languages_client_to_server */ buf_eatstring(ses.payload); @@ -701,13 +705,6 @@ static void read_kex_algos() { ses.newkeys->trans_algo_comp = s2c_comp_algo->val; } - TRACE(("enc algo recv %s", algo->name)) - TRACE(("enc algo trans %s", algo->name)) - TRACE(("mac algo recv %s", algo->name)) - TRACE(("mac algo trans %s", algo->name)) - TRACE(("comp algo recv %s", algo->name)) - TRACE(("comp algo trans %s", algo->name)) - /* reserved for future extensions */ buf_getint(ses.payload); return; diff --git a/options.h b/options.h index 5211c77..adfcb44 100644 --- a/options.h +++ b/options.h @@ -62,25 +62,30 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ #define ENABLE_AGENTFWD /* Encryption - at least one required. - * RFC Draft requires 3DES, and recommends Blowfish, AES128 & Twofish128 */ + * RFC Draft requires 3DES and recommends AES128 for interoperability. + * Including multiple keysize variants the same cipher + * (eg AES256 as well as AES128) will result in a minimal size increase.*/ #define DROPBEAR_AES128_CBC +#define DROPBEAR_3DES_CBC +#define DROPBEAR_AES256_CBC #define DROPBEAR_BLOWFISH_CBC +#define DROPBEAR_TWOFISH256_CBC #define DROPBEAR_TWOFISH128_CBC -#define DROPBEAR_3DES_CBC -/* Integrity - at least one required. - * RFC Draft requires sha1-hmac, and recommends md5-hmac. +/* Message Integrity - at least one required. + * RFC Draft requires sha1 and recommends sha1-96. + * sha1-96 may be of use for slow links, as it has a smaller overhead. * - * Note: there's no point disabling sha1 to save space, since it's used in the + * Note: there's no point disabling sha1 to save space, since it's used * for the random number generator and public-key cryptography anyway. * Disabling it here will just stop it from being used as the integrity portion * of the ssh protocol. * - * These are also used for key fingerprints in logs (when pubkey auth is used), - * MD5 fingerprints are printed if available, however SHA1 fingerprints will be - * generated otherwise. This isn't exactly optimal, although SHA1 fingerprints - * are not too hard to create from pubkeys if required. */ + * These hashes are also used for public key fingerprints in logs. + * If you disable MD5, Dropbear will fall back to SHA1 fingerprints, + * which are not the standard form. */ #define DROPBEAR_SHA1_HMAC +#define DROPBEAR_SHA1_96_HMAC #define DROPBEAR_MD5_HMAC /* Hostkey/public key algorithms - at least one required, these are used @@ -310,6 +315,14 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ #define DROPBEAR_MAX_CLI_PASS 1024 +#if defined(DROPBEAR_AES256_CBC) || defined(DROPBEAR_AES128_CBC) +#define DROPBEAR_AES_CBC +#endif + +#if defined(DROPBEAR_TWOFISH256_CBC) || defined(DROPBEAR_TWOFISH128_CBC) +#define DROPBEAR_TWOFISH_CBC +#endif + #ifndef ENABLE_X11FWD #define DISABLE_X11FWD #endif diff --git a/packet.c b/packet.c index ecda410..ab4d70a 100644 --- a/packet.c +++ b/packet.c @@ -215,7 +215,7 @@ static void read_packet_init() { if ((len > MAX_PACKET_LEN) || (len < MIN_PACKET_LEN + macsize) || ((len - macsize) % blocksize != 0)) { - dropbear_exit("bad packet size"); + dropbear_exit("bad packet size %d", len); } buf_resize(ses.readbuf, len); @@ -314,14 +314,13 @@ void decrypt_packet() { * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int checkmac(buffer* macbuf, buffer* sourcebuf) { - unsigned char macsize; + unsigned int macsize; hmac_state hmac; unsigned char tempbuf[MAX_MAC_LEN]; - unsigned long hashsize; - int len; + unsigned long bufsize; + unsigned int len; macsize = ses.keys->recv_algo_mac->hashsize; - if (macsize == 0) { return DROPBEAR_SUCCESS; } @@ -347,8 +346,8 @@ static int checkmac(buffer* macbuf, buffer* sourcebuf) { dropbear_exit("HMAC error"); } - hashsize = sizeof(tempbuf); - if (hmac_done(&hmac, tempbuf, &hashsize) != CRYPT_OK) { + bufsize = sizeof(tempbuf); + if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } @@ -524,15 +523,15 @@ void encrypt_packet() { /* Create the packet mac, and append H(seqno|clearbuf) to the output */ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { - int macsize; + unsigned int macsize; unsigned char seqbuf[4]; - unsigned long hashsize; + unsigned char tempbuf[MAX_MAC_LEN]; + unsigned long bufsize; hmac_state hmac; TRACE(("enter writemac")) - macsize = ses.keys->trans_algo_mac->hashsize; - + macsize = ses.keys->recv_algo_mac->hashsize; if (macsize > 0) { /* calculate the mac */ if (hmac_init(&hmac, @@ -557,12 +556,12 @@ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { dropbear_exit("HMAC error"); } - hashsize = macsize; - if (hmac_done(&hmac, buf_getwriteptr(outputbuffer, macsize), &hashsize) + bufsize = sizeof(tempbuf); + if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } - buf_incrwritepos(outputbuffer, macsize); + buf_putbytes(outputbuffer, tempbuf, macsize); } TRACE(("leave writemac")) } -- cgit v1.2.3 From 736f370dce614b717193f45d084e9e009de723ce Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 30 Nov 2005 10:11:24 +0000 Subject: * options.h, common-kex.c: fix support of 4096 byte host keys --HG-- extra : convert_revision : 096f29c430c23f0140f0cf272942a13046483ec6 --- common-kex.c | 44 ++++++++++++++++++++++++-------------------- options.h | 12 ++++++++---- 2 files changed, 32 insertions(+), 24 deletions(-) (limited to 'common-kex.c') diff --git a/common-kex.c b/common-kex.c index f325329..5db8e52 100644 --- a/common-kex.c +++ b/common-kex.c @@ -394,18 +394,28 @@ static void gen_new_zstreams() { /* Belongs in common_kex.c where it should be moved after review */ void recv_msg_kexinit() { + unsigned int kexhashbuf_len = 0; + unsigned int remote_ident_len = 0; + unsigned int local_ident_len = 0; + TRACE(("<- KEXINIT")) TRACE(("enter recv_msg_kexinit")) - /* start the kex hash */ - ses.kexhashbuf = buf_new(MAX_KEXHASHBUF); - if (!ses.kexstate.sentkexinit) { /* we need to send a kex packet */ send_msg_kexinit(); TRACE(("continue recv_msg_kexinit: sent kexinit")) } + /* start the kex hash */ + local_ident_len = strlen(LOCAL_IDENT); + remote_ident_len = strlen((char*)ses.remoteident); + + kexhashbuf_len = local_ident_len + remote_ident_len + + ses.transkexinit->len + ses.payload->len + + KEXHASHBUF_MAX_INTS; + + ses.kexhashbuf = buf_new(kexhashbuf_len); if (IS_DROPBEAR_CLIENT) { @@ -414,20 +424,16 @@ void recv_msg_kexinit() { /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, - (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); + (unsigned char*)LOCAL_IDENT, local_ident_len); /* V_S, the server's version string (CR and NL excluded) */ - buf_putstring(ses.kexhashbuf, - ses.remoteident, strlen((char*)ses.remoteident)); + buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_putstring(ses.kexhashbuf, - buf_getptr(ses.transkexinit, ses.transkexinit->len), - ses.transkexinit->len); + ses.transkexinit->data, ses.transkexinit->len); /* I_S, the payload of the server's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, 0); - buf_putstring(ses.kexhashbuf, - buf_getptr(ses.payload, ses.payload->len), - ses.payload->len); + buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); } else { /* SERVER */ @@ -435,21 +441,19 @@ void recv_msg_kexinit() { /* read the peer's choice of algos */ read_kex_algos(); /* V_C, the client's version string (CR and NL excluded) */ - buf_putstring(ses.kexhashbuf, - ses.remoteident, strlen((char*)ses.remoteident)); + buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); /* V_S, the server's version string (CR and NL excluded) */ - buf_putstring(ses.kexhashbuf, - (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); + buf_putstring(ses.kexhashbuf, + (unsigned char*)LOCAL_IDENT, local_ident_len); /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, 0); - buf_putstring(ses.kexhashbuf, - buf_getptr(ses.payload, ses.payload->len), - ses.payload->len); + buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); + /* I_S, the payload of the server's SSH_MSG_KEXINIT */ buf_putstring(ses.kexhashbuf, - buf_getptr(ses.transkexinit, ses.transkexinit->len), - ses.transkexinit->len); + ses.transkexinit->data, ses.transkexinit->len); + ses.requirenext = SSH_MSG_KEXDH_INIT; } diff --git a/options.h b/options.h index 6285756..baba472 100644 --- a/options.h +++ b/options.h @@ -306,10 +306,14 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ #define MAX_STRING_LEN 1400 /* ~= MAX_PROPOSED_ALGO * MAX_NAME_LEN, also is the max length for a password etc */ -/* For a 4096 bit DSS key, empirically determined to be 1590 bytes */ -#define MAX_PUBKEY_SIZE 1600 -/* For a 4096 bit DSS key, empirically determined to be 1590 bytes */ -#define MAX_PRIVKEY_SIZE 1600 +/* For a 4096 bit DSS key, empirically determined */ +#define MAX_PUBKEY_SIZE 1700 +/* For a 4096 bit DSS key, empirically determined */ +#define MAX_PRIVKEY_SIZE 1700 + +/* The maximum size of the bignum portion of the kexhash buffer */ +/* Sect. 8 of the transport draft, K_S + e + f + K */ +#define KEXHASHBUF_MAX_INTS (1700 + 130 + 130 + 130) #define DROPBEAR_MAX_SOCKS 2 /* IPv4, IPv6 are all we'll get for now. Revisit in a few years time.... */ -- cgit v1.2.3