changeset 391:00fcf5045160

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head c1db4398d56c56c6d06ae1e20c1e0d04dbb598ed) to branch 'au.asn.ucc.matt.dropbear' (head d26d5eb2837f46b56a33fb0e7573aa0201abd4d5)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 04:29:08 +0000
parents d8e44bef7917 (current diff) 5ff8218bcee9 (diff)
children 24b425be5718
files Doxyfile build.sh changes crypt.lof crypt.tex demos/encrypt.c demos/hashsum.c demos/multi.c demos/small.c demos/test.c demos/timing.c demos/tv_gen.c doc/footer.html doc/header.html filter.pl fixupind.pl genlist.sh libtomcrypt/src/headers/tomcrypt_custom.h makefile.icc makefile.msvc makefile.shared makefile.unix mess.sh notes/base64_tv.txt notes/ccm_tv.txt notes/cipher_tv.txt notes/eax_tv.txt notes/ecc_tv.txt notes/etc/saferp_optimizer.c notes/etc/whirlgen.c notes/etc/whirltest.c notes/gcm_tv.txt notes/hash_tv.txt notes/hmac_tv.txt notes/lrw_tv.txt notes/ocb_tv.txt notes/omac_tv.txt notes/pmac_tv.txt notes/tech0001.txt notes/tech0002.txt notes/tech0003.txt notes/tech0004.txt notes/tech0005.txt notes/tech0006.txt notes/tech0007.txt parsenames.pl run.sh src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/anubis.c src/ciphers/blowfish.c src/ciphers/cast5.c src/ciphers/des.c src/ciphers/kasumi.c src/ciphers/khazad.c src/ciphers/kseed.c src/ciphers/noekeon.c src/ciphers/rc2.c src/ciphers/rc5.c src/ciphers/rc6.c src/ciphers/safer/safer.c src/ciphers/safer/safer_tab.c src/ciphers/safer/saferp.c src/ciphers/skipjack.c src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c src/ciphers/xtea.c src/encauth/ccm/ccm_memory.c src/encauth/ccm/ccm_test.c src/encauth/eax/eax_addheader.c src/encauth/eax/eax_decrypt.c src/encauth/eax/eax_decrypt_verify_memory.c src/encauth/eax/eax_done.c src/encauth/eax/eax_encrypt.c src/encauth/eax/eax_encrypt_authenticate_memory.c src/encauth/eax/eax_init.c src/encauth/eax/eax_test.c src/encauth/gcm/gcm_add_aad.c src/encauth/gcm/gcm_add_iv.c src/encauth/gcm/gcm_done.c src/encauth/gcm/gcm_gf_mult.c src/encauth/gcm/gcm_init.c src/encauth/gcm/gcm_memory.c src/encauth/gcm/gcm_mult_h.c src/encauth/gcm/gcm_process.c src/encauth/gcm/gcm_reset.c src/encauth/gcm/gcm_test.c src/encauth/ocb/ocb_decrypt.c src/encauth/ocb/ocb_decrypt_verify_memory.c src/encauth/ocb/ocb_done_decrypt.c src/encauth/ocb/ocb_done_encrypt.c src/encauth/ocb/ocb_encrypt.c src/encauth/ocb/ocb_encrypt_authenticate_memory.c src/encauth/ocb/ocb_init.c src/encauth/ocb/ocb_ntz.c src/encauth/ocb/ocb_shift_xor.c src/encauth/ocb/ocb_test.c src/encauth/ocb/s_ocb_done.c src/hashes/chc/chc.c src/hashes/helper/hash_file.c src/hashes/helper/hash_filehandle.c src/hashes/helper/hash_memory.c src/hashes/helper/hash_memory_multi.c src/hashes/md2.c src/hashes/md4.c src/hashes/md5.c src/hashes/rmd128.c src/hashes/rmd160.c src/hashes/rmd256.c src/hashes/rmd320.c src/hashes/sha1.c src/hashes/sha2/sha224.c src/hashes/sha2/sha256.c src/hashes/sha2/sha384.c src/hashes/sha2/sha512.c src/hashes/tiger.c src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h src/headers/tomcrypt_math.h src/headers/tomcrypt_misc.h src/headers/tomcrypt_pk.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h src/mac/f9/f9_done.c src/mac/f9/f9_file.c src/mac/f9/f9_init.c src/mac/f9/f9_memory.c src/mac/f9/f9_memory_multi.c src/mac/f9/f9_process.c src/mac/f9/f9_test.c src/mac/hmac/hmac_done.c src/mac/hmac/hmac_file.c src/mac/hmac/hmac_init.c src/mac/hmac/hmac_memory.c src/mac/hmac/hmac_memory_multi.c src/mac/hmac/hmac_process.c src/mac/hmac/hmac_test.c src/mac/omac/omac_done.c src/mac/omac/omac_file.c src/mac/omac/omac_init.c src/mac/omac/omac_memory.c src/mac/omac/omac_memory_multi.c src/mac/omac/omac_process.c src/mac/omac/omac_test.c src/mac/pelican/pelican.c src/mac/pelican/pelican_memory.c src/mac/pelican/pelican_test.c src/mac/pmac/pmac_done.c src/mac/pmac/pmac_file.c src/mac/pmac/pmac_init.c src/mac/pmac/pmac_memory.c src/mac/pmac/pmac_memory_multi.c src/mac/pmac/pmac_ntz.c src/mac/pmac/pmac_process.c src/mac/pmac/pmac_shift_xor.c src/mac/pmac/pmac_test.c src/mac/xcbc/xcbc_done.c src/mac/xcbc/xcbc_file.c src/mac/xcbc/xcbc_init.c src/mac/xcbc/xcbc_memory.c src/mac/xcbc/xcbc_memory_multi.c src/mac/xcbc/xcbc_process.c src/mac/xcbc/xcbc_test.c src/math/fp/ltc_ecc_fp_mulmod.c src/math/gmp_desc.c src/math/ltm_desc.c src/math/multi.c src/math/rand_prime.c src/math/tfm_desc.c src/misc/base64/base64_decode.c src/misc/base64/base64_encode.c src/misc/burn_stack.c src/misc/crypt/crypt.c src/misc/crypt/crypt_argchk.c src/misc/crypt/crypt_cipher_descriptor.c src/misc/crypt/crypt_cipher_is_valid.c src/misc/crypt/crypt_find_cipher.c src/misc/crypt/crypt_find_cipher_any.c src/misc/crypt/crypt_find_cipher_id.c src/misc/crypt/crypt_find_hash.c src/misc/crypt/crypt_find_hash_any.c src/misc/crypt/crypt_find_hash_id.c src/misc/crypt/crypt_find_hash_oid.c src/misc/crypt/crypt_find_prng.c src/misc/crypt/crypt_fsa.c src/misc/crypt/crypt_hash_descriptor.c src/misc/crypt/crypt_hash_is_valid.c src/misc/crypt/crypt_ltc_mp_descriptor.c src/misc/crypt/crypt_prng_descriptor.c src/misc/crypt/crypt_prng_is_valid.c src/misc/crypt/crypt_register_cipher.c src/misc/crypt/crypt_register_hash.c src/misc/crypt/crypt_register_prng.c src/misc/crypt/crypt_unregister_cipher.c src/misc/crypt/crypt_unregister_hash.c src/misc/crypt/crypt_unregister_prng.c src/misc/error_to_string.c src/misc/pkcs5/pkcs_5_1.c src/misc/pkcs5/pkcs_5_2.c src/misc/zeromem.c src/modes/cbc/cbc_decrypt.c src/modes/cbc/cbc_done.c src/modes/cbc/cbc_encrypt.c src/modes/cbc/cbc_getiv.c src/modes/cbc/cbc_setiv.c src/modes/cbc/cbc_start.c src/modes/cfb/cfb_decrypt.c src/modes/cfb/cfb_done.c src/modes/cfb/cfb_encrypt.c src/modes/cfb/cfb_getiv.c src/modes/cfb/cfb_setiv.c src/modes/cfb/cfb_start.c src/modes/ctr/ctr_decrypt.c src/modes/ctr/ctr_done.c src/modes/ctr/ctr_encrypt.c src/modes/ctr/ctr_getiv.c src/modes/ctr/ctr_setiv.c src/modes/ctr/ctr_start.c src/modes/ctr/ctr_test.c src/modes/ecb/ecb_decrypt.c src/modes/ecb/ecb_done.c src/modes/ecb/ecb_encrypt.c src/modes/ecb/ecb_start.c src/modes/f8/f8_decrypt.c src/modes/f8/f8_done.c src/modes/f8/f8_encrypt.c src/modes/f8/f8_getiv.c src/modes/f8/f8_setiv.c src/modes/f8/f8_start.c src/modes/f8/f8_test_mode.c src/modes/lrw/lrw_decrypt.c src/modes/lrw/lrw_done.c src/modes/lrw/lrw_encrypt.c src/modes/lrw/lrw_getiv.c src/modes/lrw/lrw_process.c src/modes/lrw/lrw_setiv.c src/modes/lrw/lrw_start.c src/modes/lrw/lrw_test.c src/modes/ofb/ofb_decrypt.c src/modes/ofb/ofb_done.c src/modes/ofb/ofb_encrypt.c src/modes/ofb/ofb_getiv.c src/modes/ofb/ofb_setiv.c src/modes/ofb/ofb_start.c src/pk/asn1/der/bit/der_decode_bit_string.c src/pk/asn1/der/bit/der_encode_bit_string.c src/pk/asn1/der/bit/der_length_bit_string.c src/pk/asn1/der/boolean/der_decode_boolean.c src/pk/asn1/der/boolean/der_encode_boolean.c src/pk/asn1/der/boolean/der_length_boolean.c src/pk/asn1/der/choice/der_decode_choice.c src/pk/asn1/der/ia5/der_decode_ia5_string.c src/pk/asn1/der/ia5/der_encode_ia5_string.c src/pk/asn1/der/ia5/der_length_ia5_string.c src/pk/asn1/der/integer/der_decode_integer.c src/pk/asn1/der/integer/der_encode_integer.c src/pk/asn1/der/integer/der_length_integer.c src/pk/asn1/der/object_identifier/der_decode_object_identifier.c src/pk/asn1/der/object_identifier/der_encode_object_identifier.c src/pk/asn1/der/object_identifier/der_length_object_identifier.c src/pk/asn1/der/octet/der_decode_octet_string.c src/pk/asn1/der/octet/der_encode_octet_string.c src/pk/asn1/der/octet/der_length_octet_string.c src/pk/asn1/der/printable_string/der_decode_printable_string.c src/pk/asn1/der/printable_string/der_encode_printable_string.c src/pk/asn1/der/printable_string/der_length_printable_string.c src/pk/asn1/der/sequence/der_decode_sequence_ex.c src/pk/asn1/der/sequence/der_decode_sequence_flexi.c src/pk/asn1/der/sequence/der_decode_sequence_multi.c src/pk/asn1/der/sequence/der_encode_sequence_ex.c src/pk/asn1/der/sequence/der_encode_sequence_multi.c src/pk/asn1/der/sequence/der_length_sequence.c src/pk/asn1/der/sequence/der_sequence_free.c src/pk/asn1/der/set/der_encode_set.c src/pk/asn1/der/set/der_encode_setof.c src/pk/asn1/der/short_integer/der_decode_short_integer.c src/pk/asn1/der/short_integer/der_encode_short_integer.c src/pk/asn1/der/short_integer/der_length_short_integer.c src/pk/asn1/der/utctime/der_decode_utctime.c src/pk/asn1/der/utctime/der_encode_utctime.c src/pk/asn1/der/utctime/der_length_utctime.c src/pk/asn1/der/utf8/der_decode_utf8_string.c src/pk/asn1/der/utf8/der_encode_utf8_string.c src/pk/asn1/der/utf8/der_length_utf8_string.c src/pk/dsa/dsa_decrypt_key.c src/pk/dsa/dsa_encrypt_key.c src/pk/dsa/dsa_export.c src/pk/dsa/dsa_free.c src/pk/dsa/dsa_import.c src/pk/dsa/dsa_make_key.c src/pk/dsa/dsa_shared_secret.c src/pk/dsa/dsa_sign_hash.c src/pk/dsa/dsa_verify_hash.c src/pk/dsa/dsa_verify_key.c src/pk/ecc/ecc.c src/pk/ecc/ecc_ansi_x963_export.c src/pk/ecc/ecc_ansi_x963_import.c src/pk/ecc/ecc_decrypt_key.c src/pk/ecc/ecc_encrypt_key.c src/pk/ecc/ecc_export.c src/pk/ecc/ecc_free.c src/pk/ecc/ecc_get_size.c src/pk/ecc/ecc_import.c src/pk/ecc/ecc_make_key.c src/pk/ecc/ecc_shared_secret.c src/pk/ecc/ecc_sign_hash.c src/pk/ecc/ecc_sizes.c src/pk/ecc/ecc_test.c src/pk/ecc/ecc_verify_hash.c src/pk/ecc/ltc_ecc_is_valid_idx.c src/pk/ecc/ltc_ecc_map.c src/pk/ecc/ltc_ecc_mul2add.c src/pk/ecc/ltc_ecc_mulmod.c src/pk/ecc/ltc_ecc_mulmod_timing.c src/pk/ecc/ltc_ecc_points.c src/pk/ecc/ltc_ecc_projective_add_point.c src/pk/ecc/ltc_ecc_projective_dbl_point.c src/pk/katja/katja_decrypt_key.c src/pk/katja/katja_encrypt_key.c src/pk/katja/katja_export.c src/pk/katja/katja_exptmod.c src/pk/katja/katja_free.c src/pk/katja/katja_import.c src/pk/katja/katja_make_key.c src/pk/pkcs1/pkcs_1_i2osp.c src/pk/pkcs1/pkcs_1_mgf1.c src/pk/pkcs1/pkcs_1_oaep_decode.c src/pk/pkcs1/pkcs_1_oaep_encode.c src/pk/pkcs1/pkcs_1_os2ip.c src/pk/pkcs1/pkcs_1_pss_decode.c src/pk/pkcs1/pkcs_1_pss_encode.c src/pk/pkcs1/pkcs_1_v1_5_decode.c src/pk/pkcs1/pkcs_1_v1_5_encode.c src/pk/rsa/rsa_decrypt_key.c src/pk/rsa/rsa_encrypt_key.c src/pk/rsa/rsa_export.c src/pk/rsa/rsa_exptmod.c src/pk/rsa/rsa_free.c src/pk/rsa/rsa_import.c src/pk/rsa/rsa_make_key.c src/pk/rsa/rsa_sign_hash.c src/pk/rsa/rsa_verify_hash.c src/prngs/fortuna.c src/prngs/rc4.c src/prngs/rng_get_bytes.c src/prngs/rng_make_prng.c src/prngs/sober128.c src/prngs/sober128tab.c src/prngs/sprng.c src/prngs/yarrow.c testbuild.sh testme.sh testprof/base64_test.c testprof/cipher_hash_test.c testprof/der_tests.c testprof/dsa_test.c testprof/ecc_test.c testprof/katja_test.c testprof/mac_test.c testprof/makefile testprof/makefile.icc testprof/makefile.msvc testprof/makefile.shared testprof/modes_test.c testprof/pkcs_1_test.c testprof/rsa_test.c testprof/store_test.c testprof/test.der testprof/test.key testprof/test_driver.c testprof/tomcrypt_test.h testprof/x86_prof.c updatemakes.sh
diffstat 1084 files changed, 138004 insertions(+), 76889 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGES	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,565 @@
+0.49 - Tues 13 June 2003
+
+- Return immediately for "sleep 10 & echo foo", rather than waiting
+  for the sleep to return (pointed out by Rob Landley)
+
+- Added -P pidfile argument to the server (from Swen Schillig)
+
+- Compile fixes, make sure that all variable definitions are at the start
+  of a scope.
+
+- Use $HOME in preference to that from /etc/passwd, so that it
+  dbclient can still work on systems with a broken setup.
+
+- Add -N dbclient option for "no command"
+
+- Add -f dbclient option for "background after auth"
+
+- Try to finally fix ss_family compilation problems
+
+0.48.1 - Sat 11 March 2006
+
+- Compile fix for scp
+
+0.48 - Thurs 9 March 2006
+
+- Check that the circular buffer is properly empty before
+  closing a channel, which could cause truncated transfers
+  (thanks to Tomas Vanek for helping track it down)
+
+- Implement per-IP pre-authentication connection limits 
+  (after some poking from Pablo Fernandez)
+
+- Exit gracefully if trying to connect to as SSH v1 server 
+  (reported by Rushi Lala)
+
+- Only read /dev/random once at startup when in non-inetd mode
+
+- Allow ctrl-c to close a dbclient password prompt (may
+  still have to press enter on some platforms)
+
+- Merged in uClinux patch for inetd mode
+
+- Updated to scp from OpenSSH 4.3p2 - fixes a security issue
+  where use of system() could cause users to execute arbitrary
+  code through malformed filenames, ref CVE-2006-0225
+
+0.47 - Thurs Dec 8 2005
+
+- SECURITY: fix for buffer allocation error in server code, could potentially
+  allow authenticated users to gain elevated privileges. All multi-user systems
+  running the server should upgrade (or apply the patch available on the
+  Dropbear webpage).
+
+- Fix channel handling code so that redirecting to /dev/null doesn't use
+  100% CPU.
+
+- Turn on zlib compression for dbclient.
+
+- Set "low delay" TOS bit, can significantly improve interactivity
+  over some links.
+
+- Added client keyboard-interactive mode support, allows operation with
+  newer OpenSSH servers in default config.
+
+- Log when pubkey auth fails because of bad ~/.ssh/authorized_keys permissions
+
+- Improve logging of assertions
+
+- Added aes-256 cipher and sha1-96 hmac.
+
+- Fix twofish so that it actually works.
+
+- Improve PAM prompt comparison.
+
+- Added -g (dbclient) and -a (dropbear server) options to allow
+  connections to listening forwarded ports from remote machines.
+
+- Various other minor fixes
+
+- Compile fixes for glibc 2.1 (ss_family vs __ss_family) and NetBSD
+  (netinet/in_systm.h needs to be included).
+
+0.46 - Sat July 9 2005
+
+- Fix long-standing bug which caused connections to be closed if an ssh-agent
+  socket was no longer available
+
+- Print a warning if we seem to be blocking on /dev/random 
+  (suggested by Paul Fox)
+
+- Fixed a memory leak in DSS code (thanks to Boris Berezovsky for the patch)
+
+- dbclient -L no longer segfaults, allocate correct buffer size (thanks
+  to David Cook for reporting it, and Christopher Faylor for independently
+  sending in a patch)
+
+- Added RSA blinding to signing code (suggested by Dan Kaminsky)
+
+- Rearranged bignum reading/random generation code
+
+- Reset the non-blocking status on stderr and stdout as well as stdin,
+  fixes a problem where the shell running dbclient will exit (thanks to 
+  Brent Roman for reporting it)
+
+- Fix so that all file descriptors are closed so the child shell doesn't
+  inherit descriptors (thanks to Linden May for the patch)
+
+- Change signkey.c to avoid gcc 4 generating incorrect code
+
+- After both sides of a file descriptor have been shutdown(), close()
+  it to avoid leaking descriptors (thanks to Ari Hyttinen for a patch)
+
+- Update to LibTomCrypt 1.05 and LibTomMath 0.35
+
+0.45 - Mon March 7 2005
+
+- Makefile no longer appends 'static' to statically linked binaries
+
+- Add optional SSH_ASKPASS support to the client
+
+- Respect HOST_LOOKUP option
+
+- Fix accidentally removed "return;" statement which was removed in 0.44
+  (causing clients which sent an empty terminal-modes string to fail to
+  connect - including pssh, ssh.com, danger hiptop). (patches
+  independently from Paul Fox, David Horwitt and Sven-Ola Tuecke)
+
+- Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
+  will work with scp.
+
+0.44 - Mon Jan 3 2005
+
+- SECURITY: Fix for PAM auth so that usernames are logged and conversation
+  function responses are allocated correctly - all 0.44test4 users with PAM
+  compiled in (not default) are advised to upgrade.
+
+- Fix calls to getnameinfo() for compatibility with Solaris
+
+- Pristine compilation works (run 'configure' from a fresh dir and make it
+  there)
+
+- Fixes for compiling with most options disabled.
+
+- Upgraded to LibTomCrypt 0.99 and LibTomMath 0.32
+
+- Make sure that zeroing out of values in LTM and LTC won't get optimised away
+
+- Removed unused functions from loginrec.c
+
+- /dev/random is now the default entropy source rather than /dev/urandom
+
+- Logging of IPs in auth success/failure messages for improved greppability
+
+- Fix dbclient so that "scp -i keyfile" works. (It can handle "-ikeyfile
+  properly)
+
+- Avoid a race in server shell-handling code which prevents the exit-code
+  from being returned to the client in some circumstances.
+
+- Makefile modified so that install target works correctly (doesn't try
+  to install "all" binary) - patch from Juergen Daubert
+
+- Various minor fixes and compile warnings.
+
+0.44test4 - Tue Sept 14 2004 21:15:54 +0800
+
+- Fix inetd mode so it actually loads the hostkeys (oops)
+
+- Changed DROPBEAR_DEFPORT properly everywhere
+
+- Fix a small memory leak in the auth code
+
+- WCOREDUMP is only used on systems which support it (ie not cygwin or AIX)
+
+- Check (and fail for) cases when we can't negotiate algorithms with the
+  remote side successfully (rather than bombing out ungracefully)
+
+- Handle authorized_keys files without a terminating newline
+
+- Fiddle the channel receive window size for possibly better performance
+
+- Added in the PAM authentication code (finally! thanks to Martin Carlsson)
+
+0.44test3 - Fri Aug 27 22:20:54 +0800
+
+- Fixed a bunch of warnings.
+
+- scp works correctly when passed a username (fix for the dbclient program
+  itself as well, "-lmatt" works as well as "-l matt").
+
+- Remove unrequired debian files
+
+- Exit with the remote process's return code for dbclient
+
+- Display stderr messages from the server in the client
+
+- Add circular buffering to the channel code. This should dramatically reduce
+  the amount of backtraffic sent in response to traffic incoming to the
+  Dropbear end - improves high-latency performance (ie dialup).
+
+- Various other related channel-handling fixups.
+
+- Allow leading lines in the banner when connecting to servers
+
+- Fixed printing out errors onto the network socket with stderr (for inetd
+  mode when using xinetd)
+
+- Remove obselete documentation
+
+- Fix a null-pointer exception when trying to free non-existant listeners
+  at cleanup.
+
+- DEBUG_TRACE now only works if you add "-v" to the program commandline
+
+- Don't leave stdin non-blocking on exit - this caused the parent shell
+  of dbclient to close when dbclient exited, for some shells in BusyBox
+
+- Server connections no longer timeout after 5 minutes
+
+- Fixed stupid DSS hostkey typo (server couldn't load host keys)
+
+0.44test2 - Tues Aug 17 2004 17:43:54 +0800
+
+- Fix up dropbearmulti targets in the Makefile - symlinks are now created
+
+- Compile fake-rfc2553 even with dropbearconvert/dropbearkey - this 
+  allows them to work on platforms without a native getaddrinfo()
+
+- Create ~/.ssh/known_hosts properly if it doesn't exist
+
+- Fix basename() function prototype
+
+- Backport some local changes (more #ifdefs for termcodes.c, a fix for missing
+  defines on AIX).
+
+- Let dbclient be run as "ssh"
+
+- Initialise mp_ints by default
+
+0.44test1 - Sun Aug 16 2005 17:43:54 +0800
+
+- TESTING RELEASE - this is the first public release of the client codebase,
+  so there are sure to be bugs to be found. In addition, if you're just using
+  the server portion, the final binary size probably will increase - I'll
+  be trying to get it back down in future releases.
+
+- Dropbear client added - lots of changes to the server code as well to 
+  generalise things
+
+- IPv6 support added for client, server, and forwarding
+
+- New makefile with more generic support for multiple-program binaries
+
+0.43 - Fri Jul 16 2004 17:44:54 +0800
+
+- SECURITY: Don't try to free() uninitialised variables in DSS verification
+  code. Thanks to Arne Bernin for pointing out this bug. This is possibly
+  exploitable, all users with DSS and pubkey-auth compiled in are advised to
+  upgrade.
+
+- Clean up agent forwarding socket files correctly, patch from Gerrit Pape.
+
+- Don't go into an infinite loop when portforwarding to servers which don't
+  send any initial data/banner. Patch from Nikola Vladov
+
+- Fix for network vs. host byte order in logging remote TCP ports, also
+  from Gerrit Pape.
+
+- Initialise many pointers to NULL, for general safety. Also checked cleanup
+  code for mp_ints (related to security issues above).
+
+0.42 - Wed Jun 16 2004 12:44:54 +0800
+
+- Updated to Gerrit Pape's official Debian subdirectory
+
+- Fixed bad check when opening /dev/urandom - thanks to Danny Sung.
+
+- Added -i inetd mode flag, and associated options in options.h . Dropbear
+  can be compiled with either normal mode, inetd, or both modes. Thanks
+  to Gerrit Pape for basic patch and motivation.
+
+- Use <dirent.h> rather than <sys/dir.h> for POSIX compliance. Thanks to Bill
+  Sommerfield.
+
+- Fixed a TCP forwarding (client-local, -L style) bug which caused the whole
+  session to close if the TCP connection failed. Thanks to Andrew Braund for
+  reporting it and helping track it down.
+
+- Re-enable sigpipe for child processes. Thanks to Gerrit Pape for some
+  suggestions, and BSD manpages for a clearer explanation of the behaviour.
+
+- Added manpages, thanks to Gerrit Pape.
+
+- Changed license text for LibTomCrypt and LibTomMath.
+
+- Added strip-static target
+
+- Fixed a bug in agent-forwarding cleanup handler - would segfault
+  (dereferencing a null pointer) if agent forwarding had failed.
+
+- Fix behaviour of authorized_keys parsing, so larger (>1024 bit) DSA keys will
+  work. Thanks to Dr. Markus Waldeck for the report. 
+
+- Fixed local port forwarding code so that the "-j" option will make forwarding
+  attempts fail more gracefully.
+
+- Allow repeated requests in a single session if previous ones fail - this fixes  PuTTY and some other SCP clients, which try SFTP, then fall-back to SCP if it
+  isn't available. Thanks to Stirling Westrup for the report.
+
+- Updated to LibTomCrypt 0.96 and LibTomMath 0.30. The AES code now uses
+  smaller non-precomputed tables if DROPBEAR_SMALL_CODE is defined in
+  options.h, leading to a significant reduction in the binary size.
+
+0.41 - Mon Jan 19 2004 22:40:19 +0800
+
+- Fix in configure so that cross-compiling works, thanks to numerous people for
+  reporting and testing
+
+- Terminal mode parsing now handles empty terminal mode strings (sent by
+  Windows ssh.com clients), thanks to Ricardo Derbes for the report
+
+- Handling is improved for users with no shell specified in /etc/passwd,
+  thanks again to Ricardo Derbes
+
+- Fix for compiling with --disable-syslog, thanks to gordonfh
+
+- Various minor fixes allow scp to work with irix, thanks to Paul Marinceu for
+  fixing it up
+
+- Use <stropts.h> not <sys/stropts.h>, since the former seems more common
+
+0.40 - Tue Jan 13 2004 21:05:19 +0800
+
+- Remote TCP forwarding (-R) style implemented
+
+- Local and remote TCP forwarding can each be disabled at runtime (-k and -j
+  switches)
+
+- Fix for problems detecting openpty() with uClibc - many thanks to various
+  people for reporting and testing fixes, including (in random order) Cristian
+  Ionescu-Idbohrn, James Ewing, Steve Dover, Thomas Lundquist and Frederic
+  Lavernhe
+
+- Improved portability for IRIX, thanks to Paul Marinceu
+
+- AIX and HPUX portability fixes, thanks to Darren Tucker for patches
+
+- prngd should now work correctly, thanks to Darren Tucker for the patch
+
+- scp compilation on systems without strlcpy() is fixed, thanks to Peter
+  Jannesen and David Muse for reporting it (independently and simultaneously :)
+
+- Merged in new LibTomCrypt 0.92 and LibTomMath 0.28
+
+0.39 - Tue Dec 16 2003 15:19:19 +0800
+
+- Better checking of key lengths and parameters for DSS and RSA auth
+
+- Print fingerprint of keys used for pubkey auth
+
+- More consistent logging of usernames and IPs
+
+- Added option to disable password auth (or just for root) at runtime
+
+- Avoid including bignum functions which don't give much speed benefit but
+  take up binary size
+
+- Added a stripped down version of OpenSSH's scp binary
+
+- Added additional supporting functions for Irix, thanks to Paul Marinceu
+
+- Don't check for unused libraries in configure script
+
+- Removed trailing comma in algorithm lists (thanks to Mihnea Stoenescu)
+
+- Fixed up channel close handling, always send close packet in response
+  (also thanks to Mihnea Stoenescu)
+
+- Various makefile improvements for cross-compiling, thanks to Friedrich
+  Lobenstock and Mihnea Stoenescu
+
+- Use daemon() function if available (or our own copy) rather than separate
+  code (thanks to Fr�d�ric Lavernhe for the report and debugging, and Bernard
+  Blackham for his suggestion on what to look at)
+
+- Fixed up support for first_kex_packet_follows, required to talk to ssh.com
+  clients. Thanks to Marian Stagarescu for the bug report.
+
+- Avoid using MAXPATHLEN, pointer from Ian Morris
+
+- Improved input sanity checking
+
+0.38 - Sat Oct 11 2003 16:28:13 +0800
+
+- Default hostkey path changed to /etc/dropbear/dropbear_{rsa,dss}_host_key
+  rather than /etc/dropbear_{rsa,dss}_host_key
+
+- Added SMALL and MULTI text files which have info on compiling for multiple
+  binaries or small binaries
+
+- Allow for commandline definition of some options.h settings
+  (without warnings)
+
+- Be more careful handling EINTR
+
+- More fixes for channel closing
+
+- Added multi-binary support
+
+- Improved logging of IPs, now get logged in all cases
+
+- Don't chew cpu when waiting for version identification string, also
+  make sure that we kick off people if they don't auth within 5 minutes.
+
+- Various small fixes, warnings etc
+
+- Display MOTD if requested - suggested by
+  Trent Lloyd <lathiat at sixlabs.org> and
+  Zach White <zwhite at darkstar.frop.org>
+
+- sftp support works (relies on OpenSSH sftp binary or similar)
+
+- Added --disable-shadow option (requested by the floppyfw guys)
+
+0.37 - Wed Sept 24 2003 19:42:12 +0800
+
+- Various portability fixes, fixes for Solaris 9, Tru64 5.1, Mac OS X 10.2,
+  AIX, BSDs
+
+- Updated LibTomMath to 0.27 and LibTomCrypt to 0.90
+
+- Renamed util.{c,h} to dbutil.{c,h} to avoid conflicts with system util.h
+
+- Added some small changes so it'll work with AIX (plus Linux Affinity).
+  Thanks to Shig for them.
+
+- Improved the closing messages, so a clean exit is "Exited normally"
+
+- Added some more robust integer/size checking in buffer.c as a backstop for
+  integer overflows
+
+- X11 forwarding fixed for OSX, path for xauth changed to /usr/X11R6/bin/xauth
+
+- Channel code handles closing more nicely, doesn't sit waiting for an extra
+  keystroke on BSD/OSX platforms, and data is flushed fully before closing
+  child processes (thanks to 
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com> for
+  pointing that out).
+
+- Changed "DISABLE_TCPFWD" to "ENABLE_TCPFWD" (and for x11/auth) so
+  "disable DISABLE_TCPWD" isn't so confusing.
+
+- Fix authorized_keys handling (don't crash on too-long keys, and
+  use fgetc not getc to avoid strange macro-related issues), thanks to
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com> 
+  and Steve Rodgers <hwstar at cox.net> for reporting and testing.
+
+- Fixes to the README with regard to uClibc systems, thanks to 
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com>,
+  as well as general improvements to documentation (split README/INSTALL)
+
+- Fixed up some compilation problems with dropbearconvert/dropbearkey if
+  DSS or RSA were disabled, reported by Patrik Karlsson <patrik at cqure.net>
+
+- Fix double-free bug for hostkeys, reported by
+  Vincent Sanders <vince at kyllikki.org>
+
+- Fix up missing \ns from dropbearconvert help message,
+  thanks to Mordy Ovits <movits at bloomberg.com> for the patch
+
+0.36 - Tue August 19 2003 12:16:23 +0800
+
+- Fix uninitialised temporary variable in DSS signing code
+  (thanks to Matthew Franz <mdfranz at io.com> for reporting, and the authors
+  of Valgrind for making it easy to track down)
+- Fix remote version-string parsing error
+  (thanks to Bernard Blackham <bernard at blackham.com.au> for noticing)
+- Improved host-algorithm-matching algorithm in algo.c
+- Decreased MAX_STRING_LEN to a more realistic value
+- Fix incorrect version (0.34) in this CHANGES file for the previous release.
+
+0.35 - Sun August 17 2003 05:37:47 +0800
+
+- Fix for remotely exploitable format string buffer overflow.
+  (thanks to Joel Eriksson <je at bitnux.com>)
+
+0.34 - Fri August 15 2003 15:10:00 +0800
+
+- Made syslog optional, both at compile time and as a compile option
+  (suggested by Laurent Bercot <ska at skarnet.org>)
+- Fixup for bad base64 parsing in authorized_keys
+  (noticed by Davyd Madeley <davyd at zdlcomputing.com>)
+- Added initial tcp forwarding code, only -L (local) at this stage
+- Improved "make install" with DESTDIR and changing ownership seperately,
+  don't check for setpgrp on Linux for crosscompiling.
+  (from Erik Andersen <andersen at codepoet.org>)
+- More commenting, fix minor compile warnings, make return values more
+  consistent etc
+- Various signedness fixes
+- Can listen on multiple ports
+- added option to disable openpty with configure script,
+  (from K.-P. Kirchd�rfer <kapeka at epost.de>)
+- Various cleanups to bignum code
+  (thanks to Tom St Denis <tomstdenis at iahu.ca>)
+- Fix compile error when disabling RSA
+  (from Marc Kleine-Budde <kleine-budde at gmx.de>)
+- Other cleanups, splitting large functions for packet and kex handling etc
+
+0.33 - Sun June 22 2003 22:24:12 +0800
+
+- Fixed some invalid assertions in the channel code, fixing the server dying
+  when forwarding X11 connections.
+- Add dropbearconvert to convert to/from OpenSSH host keys and Dropbear keys
+- RSA keys now keep p and q parameters for compatibility -- old Dropbear keys
+  still work, but can't be converted to OpenSSH etc.
+- Debian packaging directory added, thanks to 
+  Grahame (grahame at angrygoats.net)
+- 'install' target added to the makefile
+- general tidying, improve consistency of functions etc
+- If RSA or DSS hostkeys don't exist, that algorithm won't be used.
+- Improved RSA and DSS key generation, more efficient and fixed some minor bugs
+  (thanks to Tom St Denis for the advice)
+- Merged new versions of LibTomCrypt (0.86) and LibTomMath (0.21)
+
+0.32 - Sat May 24 2003 12:44:11 +0800
+
+- Don't compile unused code from libtomcrypt (test vectors etc)
+- Updated to libtommath 0.17 and libtomcrypt 0.83. New libtommath results
+  in smaller binary size, due to not linking unrequired code
+- X11 forwarding added
+- Agent forwarding added (for OpenSSH.com ssh client/agent)
+- Fix incorrect buffer freeing when banners are used
+- Hostname resolution works
+- Various minor bugfixes/code size improvements etc
+
+0.31 - Fri May 9 2003 17:57:16 +0800
+
+- Improved syslog messages - IP logging etc
+- Strip control characters from log messages (specified username currently)
+- Login recording (utmp/wtmp) support, so last/w/who work - taken from OpenSSH
+- Shell is started as a proper login shell, so /etc/profile etc is sourced
+- Ptys work on Solaris (2.8 x86 tested) now
+- Fixed bug in specifying the rsa hostkey
+- Fixed bug in compression code, could trigger if compression resulted in
+  larger output than input (uncommon but possible).
+
+0.30 - Thu Apr 17 2003 18:46:15 +0800
+
+- SECURITY: buffer.c had bad checking for buffer increment length - fixed
+- channel code now closes properly on EOF - scp processes don't hang around
+- syslog support added - improved auth/login/failure messages
+- general code tidying, made return codes more consistent
+- Makefile fixed for dependencies and makes libtomcrypt as well
+- Implemented sending SSH_MSG_UNIMPLEMENTED :)
+
+0.29 - Wed Apr 9 2003
+
+- Fixed a stupid bug in 0.28 release, 'newstr = strdup(oldstr)',
+  not 'newstr=oldstr'
+
+0.28 - Sun Apr 6 2003
+
+- Initial public release
+
+Development was started in October 2002
--- a/Doxyfile	Thu Jan 11 04:28:09 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1155 +0,0 @@
-# Doxyfile 1.3.9.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = LibTomCrypt
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 1.16
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = doc/doxygen
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of source 
-# files, where putting all generated files in the same directory would otherwise 
-# cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# This tag can be used to specify the encoding used in the generated output. 
-# The encoding is not always determined by the language that is chosen, 
-# but also whether or not the output is meant for Windows or non-Windows users. 
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
-# forces the Windows encoding (this is the default for the Windows binary), 
-# whereas setting the tag to NO uses a Unix-style encoding (the default for 
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING   = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is used 
-# as the annotated text. Otherwise, the brief description is used as-is. If left 
-# blank, the following values are used ("$name" is automatically replaced with the 
-# name of the entity): "The $name class" "The $name widget" "The $name file" 
-# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
-# members of a class in the documentation of that class as if those members were 
-# ordinary class members. Constructors, destructors and assignment operators of 
-# the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = src
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = src/headers
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like the Qt-style comments (thus requiring an 
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = YES
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 4
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
-# only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
-# only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = YES
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = src
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
-# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS          = 
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
-# that are symbolic links (a Unix filesystem feature) are excluded from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories.
-
-EXCLUDE_PATTERNS       = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = YES
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = YES
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = doc/header.html
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = doc/footer.html
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 1
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = YES
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = YES
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = YES
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = src/headers
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse the 
-# parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
-# super classes. Setting the tag to NO turns the diagrams off. Note that this 
-# option is superseded by the HAVE_DOT option below. This is only a fallback. It is 
-# recommended to install and use dot, since it yields more powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = NO
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
-
-CALL_GRAPH             = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes that 
-# lay further from the root node will be omitted. Note that setting this option to 
-# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
-# note that a graph may be further truncated if the graph's image dimensions are 
-# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
-# If 0 is used for the depth value (the default), the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,79 @@
+Basic Dropbear build instructions:
+
+- Edit options.h to set which features you want.
+- Edit debug.h if you want any debug options (not usually required).
+
+(If using a non-tarball copy, "autoconf; autoheader")
+
+./configure      (optionally with --disable-zlib or --disable-syslog,
+                  or --help for other options)
+
+Now compile:
+
+make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
+
+And install (/usr/local/bin is usual default):
+
+make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
+
+(you can leave items out of the PROGRAMS list to avoid compiling them. If you
+recompile after changing the PROGRAMS list, you *MUST* "make clean" before
+recompiling - bad things will happen otherwise)
+
+See MULTI for instructions on making all-in-one binaries.
+
+If you want to compile statically, add "STATIC=1" to the make command-line.
+
+Binaries can be strippd with "make strip"
+
+============================================================================
+
+If you're compiling for a 386-class CPU, you will probably need to add
+CFLAGS=-DLTC_NO_BSWAP so that libtomcrypt doesn't use 486+ instructions.
+
+============================================================================
+
+Compiling with uClibc:
+
+Firstly, make sure you have at least uclibc 0.9.17, as getusershell() in prior
+versions is broken. Also note that you may get strange issues if your uClibc
+headers don't match the library you are running with, ie the headers might
+say that shadow password support exists, but the libraries don't have it.
+
+Compiling for uClibc should be the same as normal, just set CC to the magic
+uClibc toolchain compiler (ie export CC=i386-uclibc-gcc or whatever).
+You can use "make STATIC=1" to make statically linked binaries, and it is
+advisable to strip the binaries too. If you're looking to make a small binary,
+you should remove unneeded ciphers and MD5, by editing options.h
+
+It is possible to compile zlib in, by copying zlib.h and zconf.h into a
+subdirectory (ie zlibincludes), and 
+
+export CFLAGS="-Izlibincludes -I../zlibincludes"
+export LDFLAGS=/usr/lib/libz.a
+
+before ./configure and make.
+
+If you disable zlib, you must explicitly disable compression for the client -
+OpenSSH is possibly buggy in this regard, it seems you need to disable it
+globally in ~/.ssh/config, not just in the host entry in that file.
+
+You may want to manually disable lastlog recording when using uClibc, configure
+with --disable-lastlog.
+
+One common problem is pty allocation. There are a number of types of pty
+allocation which can be used -- if they work properly, the end result is the
+same for each type. Running configure should detect the best type to use
+automatically, however for some systems, this may be incorrect. Some
+things to note:
+
+    If your system expects /dev/pts to be mounted (this is a uClibc option),
+	make sure that it is.
+
+	Make sure that your libc headers match the library version you are using.
+
+	If openpty() is being used (HAVE_OPENPTY defined in config.h) and it fails,
+	you can try compiling with --disable-openpty. You will probably then need
+	to create all the /dev/pty?? and /dev/tty?? devices, which can be
+	problematic for devfs. In general, openpty() is the best way to allocate
+	PTYs, so it's best to try and get it working.
--- a/LICENSE	Thu Jan 11 04:28:09 2007 +0000
+++ b/LICENSE	Thu Jan 11 04:29:08 2007 +0000
@@ -1,5 +1,89 @@
-LibTomCrypt is public domain.  As should all quality software be.
-
-Tom St Denis
+Dropbear contains a number of components from different sources, hence there
+are a few licenses and authors involved. All licenses are fairly 
+non-restrictive.
 
 
+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-2006 Matt Johnston
+Portions copyright (c) 2004 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.
+
+=====
+
+LibTomCrypt and LibTomMath are written by Tom St Denis, and are Public Domain.
+
+=====
+
+sshpty.c is taken from OpenSSH 3.5p1, 
+  Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
+                     All rights reserved
+ "As far as I am concerned, the code I have written for this software
+  can be used freely for any purpose.  Any derived versions of this
+  software must be clearly marked as such, and if the derived work is
+  incompatible with the protocol description in the RFC file, it must be
+  called by a name other than "ssh" or "Secure Shell". "
+
+=====
+
+loginrec.c
+loginrec.h
+atomicio.h
+atomicio.c
+and strlcat() (included in util.c) are from OpenSSH 3.6.1p2, and are licensed
+under the 2 point BSD license.
+
+loginrec is written primarily by Andre Lucas, atomicio.c by Theo de Raadt.
+
+strlcat() is (c) Todd C. Miller
+
+=====
+
+Import code in keyimport.c is modified from PuTTY's import.c, licensed as
+follows:
+
+PuTTY is copyright 1997-2003 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, and CORE SDI S.A.
+
+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 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MULTI	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,26 @@
+Multi-binary compilation
+========================
+
+To compile for systems without much space (floppy distributions etc), you
+can create a single binary. This will save disk space by avoiding repeated
+code between the various parts.
+If you are familiar with "busybox", it's the same principle.
+
+To compile the multi-binary, first "make clean" (if you've compiled
+previously), then
+
+make PROGRAMS="programs you want here" MULTI=1
+
+To use the binary, symlink it from the desired executable:
+
+ln -s dropbearmulti dropbear
+ln -s dropbearmulti dbclient
+etc
+
+then execute as normal:
+
+./dropbear <options here>
+
+"make install" doesn't currently work for multi-binary configuration, though
+in most situations where it is being used, the target and build systems will
+differ.
--- a/Makefile.in	Thu Jan 11 04:28:09 2007 +0000
+++ b/Makefile.in	Thu Jan 11 04:29:08 2007 +0000
@@ -1,317 +1,211 @@
-# MAKEFILE for linux GCC
+# This Makefile is for Dropbear SSH Server and Client
+# @configure_input@
+
+# invocation:
+# make PROGRAMS="dropbear dbclient scp" MULTI=1 STATIC=1 SCPPROGRESS=1
 #
-# Tom St Denis
-# Modified by Clay Culver
+# to make a multiple-program statically linked binary "staticdropbearmulti".
+# This example will include dropbear, scp, dropbearkey, dropbearconvert, and
+# dbclient functionality, and includes the progress-bar functionality in scp.
+# Hopefully that seems intuitive.
+
+ifndef PROGRAMS
+	PROGRAMS=dropbear dbclient dropbearkey dropbearconvert
+endif
+
+LTC=libtomcrypt/libtomcrypt.a
+LTM=libtommath/libtommath.a
+
+COMMONOBJS=dbutil.o buffer.o \
+		dss.o bignum.o \
+		signkey.o rsa.o random.o \
+		queue.o \
+		atomicio.o compat.o  fake-rfc2553.o
+
+SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \
+		svr-authpasswd.o svr-authpubkey.o svr-session.o svr-service.o \
+		svr-chansession.o svr-runopts.o svr-agentfwd.o svr-main.o svr-x11fwd.o\
+		svr-tcpfwd.o svr-authpam.o
 
-# The version
-VERSION=1.16
+CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
+		cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
+		cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o
+
+CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
+			common-channel.o common-chansession.o termcodes.o loginrec.o \
+			tcp-accept.o listener.o process-packet.o \
+			common-runopts.o circbuffer.o
+
+KEYOBJS=dropbearkey.o gendss.o genrsa.o
+
+CONVERTOBJS=dropbearconvert.o keyimport.o
+
+SCPOBJS=scp.o progressmeter.o atomicio.o scpmisc.o
+
+HEADERS=options.h dbutil.h session.h packet.h algo.h ssh.h buffer.h kex.h \
+		dss.h bignum.h signkey.h rsa.h random.h service.h auth.h \
+		debug.h channel.h chansession.h config.h queue.h sshpty.h \
+		termcodes.h gendss.h genrsa.h runopts.h includes.h \
+		loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd.h compat.h \
+		listener.h fake-rfc2553.h
+
+dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) 
+dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
+dropbearkeyobjs=$(COMMONOBJS) $(KEYOBJS)
+dropbearconvertobjs=$(COMMONOBJS) $(CONVERTOBJS)
+scpobjs=$(SCPOBJS)
 
 VPATH=@srcdir@
 srcdir=@srcdir@
 
-# Compiler and Linker Names
-#CC=gcc
-#LD=ld
-
-# Archiver [makes .a files]
-#AR=ar
-#ARFLAGS=r
-
-# Compilation flags. Note the += does not write over the user's CFLAGS!
-# The rest of the flags come from the parent Dropbear makefile
-CFLAGS += -c -I$(srcdir)/src/headers/ -I$(srcdir)/../
+prefix=@prefix@
+exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
 
-# additional warnings (newer GCC 3.4 and higher)
-ifdef GCC_34
-CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
-		  -Wmissing-declarations -Wpointer-arith 
-endif
-
-ifndef IGNORE_SPEED
+CC=@CC@
+AR=@AR@
+RANLIB=@RANLIB@
+STRIP=@STRIP@
+INSTALL=@INSTALL@
+CPPFLAGS=@CPPFLAGS@
+CFLAGS=-I. -I$(srcdir) -I$(srcdir)/libtomcrypt/src/headers/ $(CPPFLAGS) @CFLAGS@
+LIBS=$(LTC) $(LTM) @LIBS@
+LDFLAGS=@LDFLAGS@
 
-# optimize for SPEED
-#CFLAGS += -O3 -funroll-loops
+EXEEXT=@EXEEXT@
 
-# add -fomit-frame-pointer.  hinders debugging!
-#CFLAGS += -fomit-frame-pointer
-
-# optimize for SIZE
-#CFLAGS += -Os -DLTC_SMALL_CODE
-
+# whether we're building client, server, or both for the common objects.
+# evilness so we detect 'dropbear' by itself as a word
+space:= $(empty) $(empty)
+ifneq (,$(strip $(foreach prog, $(PROGRAMS), $(findstring ZdropbearZ, Z$(prog)Z))))
+	CFLAGS+= -DDROPBEAR_SERVER
+endif
+ifneq (,$(strip $(foreach prog, $(PROGRAMS), $(findstring ZdbclientZ, Z$(prog)Z))))
+	CFLAGS+= -DDROPBEAR_CLIENT
 endif
 
-# older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros
-# define this to help
-#CFLAGS += -DLTC_NO_ROLC
-
-# compile for DEBUGING (required for ccmalloc checking!!!)
-#CFLAGS += -g3 -DLTC_NO_ASM
 
-#Output filenames for various targets.
-ifndef LIBNAME
-   LIBNAME=libtomcrypt.a
-endif
-ifndef LIBTEST
-   LIBTEST=libtomcrypt_prof.a
-endif
-LIBTEST_S=$(LIBTEST)
+# these are exported so that libtomcrypt's makefile will use them
+export CC
+export CFLAGS
+export RANLIB AR STRIP
 
-HASH=hashsum
-CRYPT=encrypt
-SMALL=small
-PROF=x86_prof
-TV=tv_gen
-MULTI=multi
-TIMING=timing
-TEST=test
-
-#LIBPATH-The directory for libtomcrypt to be installed to.
-#INCPATH-The directory to install the header files for libtomcrypt.
-#DATAPATH-The directory to install the pdf docs.
-ifndef DESTDIR
-   DESTDIR=
+ifeq ($(STATIC), 1)
+	LDFLAGS+=-static
 endif
 
-ifndef LIBPATH
-   LIBPATH=/usr/lib
-endif
-ifndef INCPATH
-   INCPATH=/usr/include
-endif
-ifndef DATAPATH
-   DATAPATH=/usr/share/doc/libtomcrypt/pdf
+ifeq ($(MULTI), 1)
+	TARGETS=dropbearmulti
+else
+	TARGETS=$(PROGRAMS)
 endif
 
-#Who do we install as?
-ifdef INSTALL_USER
-USER=$(INSTALL_USER)
-else
-USER=root
-endif
-
-ifdef INSTALL_GROUP
-GROUP=$(INSTALL_GROUP)
-else
-GROUP=wheel
+# for the scp progress meter. The -D doesn't affect anything else.
+ifeq ($(SCPPROGRESS), 1)
+	CFLAGS+=-DPROGRESS_METER
 endif
 
-#List of objects to compile.
-#START_INS
-OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \
-src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \
-src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \
-src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \
-src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \
-src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \
-src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \
-src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \
-src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \
-src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \
-src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \
-src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \
-src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \
-src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \
-src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \
-src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \
-src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \
-src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \
-src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o \
-src/hashes/sha1.o src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \
-src/hashes/whirl/whirl.o src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o \
-src/mac/f9/f9_memory.o src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o \
-src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \
-src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \
-src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
-src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
-src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
-src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
-src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
-src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \
-src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \
-src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \
-src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \
-src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \
-src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \
-src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \
-src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \
-src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \
-src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \
-src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_hash_oid.o \
-src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o src/misc/crypt/crypt_hash_descriptor.o \
-src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_ltc_mp_descriptor.o \
-src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \
-src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \
-src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \
-src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \
-src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \
-src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
-src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
-src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
-src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
-src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
-src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
-src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
-src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
-src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
-src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \
-src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
-src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
-src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
-src/modes/ofb/ofb_start.o 
+#%: $(HEADERS)
+#%: $(HEADERS) Makefile
+# TODO
+
+all: $(TARGETS)
+
+strip: $(TARGETS)
+	$(STRIP) $(addsuffix $(EXEEXT), $(TARGETS))
+
+install: $(addprefix inst_, $(TARGETS))
+
+installdropbearmulti: insdbmulti $(addprefix insmulti, $(PROGRAMS)) 
 
-HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
-src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
-src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \
-src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
-src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+insdbmulti: dropbearmulti
+	$(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 dropbearmulti$(EXEEXT) $(DESTDIR)$(bindir)
+	-chown root $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT)
+	-chgrp 0 $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT)
 
-#END_INS
+insmultidropbear: dropbearmulti
+	-rm -f $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
+	-ln -s $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(sbindir)/dropbear$(EXEEXT) 
+
+insmulti%: dropbearmulti
+	-rm -f $(DESTDIR)$(bindir)/$*$(EXEEXT) 
+	-ln -s $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(bindir)/$*$(EXEEXT) 
 
-TESTOBJECTS=demos/test.o
-HASHOBJECTS=demos/hashsum.o
-CRYPTOBJECTS=demos/encrypt.o
-SMALLOBJECTS=demos/small.o
-TVS=demos/tv_gen.o
-MULTIS=demos/multi.o
-TIMINGS=demos/timing.o
-TESTS=demos/test.o
-
-#Files left over from making the crypt.pdf.
-LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
-
-#Compressed filenames
-COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
-
-#The default rule for make builds the libtomcrypt library.
-default:library
+# dropbear should go in sbin, so it needs a seperate rule
+inst_dropbear: dropbear
+	$(INSTALL) -d -m 755 $(DESTDIR)$(sbindir)
+	$(INSTALL) -m 755 dropbear$(EXEEXT) $(DESTDIR)$(sbindir)
+	-chown root $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
+	-chgrp 0 $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
 
-#ciphers come in two flavours... enc+dec and enc 
-src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
-	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
+inst_%: $*
+	$(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 $*$(EXEEXT) $(DESTDIR)$(bindir)
+	-chown root $(DESTDIR)$(bindir)/$*$(EXEEXT)
+	-chgrp 0 $(DESTDIR)$(bindir)/$*$(EXEEXT)
 
-#These are the rules to make certain object files.
-src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
-src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
-src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
-src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
-src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
-
-#This rule makes the libtomcrypt library.
-library: $(LIBNAME)
-
-testprof/$(LIBTEST): 
-	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) 
-
-$(LIBNAME): $(OBJECTS)
-	$(AR) $(ARFLAGS) $@ $(OBJECTS) 
-	$(RANLIB) $@
 
-#This rule makes the hash program included with libtomcrypt
-hashsum: library $(HASHOBJECTS)
-	$(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN)
-
-#makes the crypt program
-crypt: library $(CRYPTOBJECTS)
-	$(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN)
+# for some reason the rule further down doesn't like $($@objs) as a prereq.
+dropbear: $(dropbearobjs)
+dbclient: $(dbclientobjs)
+dropbearkey: $(dropbearkeyobjs)
+dropbearconvert: $(dropbearconvertobjs)
 
-#makes the small program
-small: library $(SMALLOBJECTS)
-	$(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN)
-	
-tv_gen: library $(TVS)
-	$(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV)
-
-multi: library $(MULTIS)
-	$(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI)
+dropbear dbclient dropbearkey dropbearconvert: $(HEADERS)  $(LTC) $(LTM) \
+													Makefile
+	$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBS)
 
-timing: library testprof/$(LIBTEST) $(TIMINGS)
-	$(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING)
+# scp doesn't use the libs so is special.
+scp: $(SCPOBJS)  $(HEADERS) Makefile
+	$(CC) $(LDFLAGS) -o $@$(EXEEXT) $(SCPOBJS)
 
-test: library testprof/$(LIBTEST) $(TESTS)
-	$(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
 
-#This rule installs the library and the header files. This must be run
-#as root in order to have a high enough permission to write to the correct
-#directories and to set the owner and group to root.
-ifndef NODOCS
-install: library docs
-else
-install: library
-endif
-	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
-	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
-	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
-	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
-	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
-ifndef NODOCS
-	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
+# multi-binary compilation.
+MULTIOBJS=
+ifeq ($(MULTI),1)
+	MULTIOBJS=dbmulti.o $(sort $(foreach prog, $(PROGRAMS), $($(prog)objs)))
+	CFLAGS+=$(addprefix -DDBMULTI_, $(PROGRAMS)) -DDROPBEAR_MULTI
 endif
 
-install_test: testprof/$(LIBTEST)
-	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
-	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
-	install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH)
+dropbearmulti: multilink 
+
+multibinary: $(HEADERS) $(MULTIOBJS) $(LTC) $(LTM) Makefile
+	$(CC) $(LDFLAGS) -o dropbearmulti$(EXEEXT) $(MULTIOBJS) $(LIBS)
+
+multilink: multibinary $(addprefix link, $(PROGRAMS))
 
-profile:
-	CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
-	./timing
-	rm -f timing `find . -type f | grep [.][ao] | xargs`
-	CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
+link%:
+	-rm -f $*$(EXEEXT)
+	-ln -s dropbearmulti$(EXEEXT) $*$(EXEEXT)
 
+$(LTC): options.h
+	cd libtomcrypt && $(MAKE) clean && $(MAKE)
 
-#This rule cleans the source tree of all compiled code, not including the pdf
-#documentation.
-clean:
-	-rm -f $(OBJECTS)
-	-rm -f libtomcrypt.a
+$(LTM): options.h
+	cd libtommath && $(MAKE)
+
+.PHONY : clean sizes thisclean distclean tidy ltc-clean ltm-clean
 
-#build the doxy files (requires Doxygen, tetex and patience)
-doxy:
-	doxygen
-	cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
-	echo The huge doxygen PDF should be available as doc/refman.pdf
-	
-#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
-#from the clean command! This is because most people would like to keep the
-#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
-#delete it if we are rebuilding it.
-docs: crypt.tex
-	rm -f doc/crypt.pdf $(LEFTOVERS)
-	echo "hello" > crypt.ind
-	latex crypt > /dev/null
-	latex crypt > /dev/null
-	makeindex crypt.idx > /dev/null
-	perl fixupind.pl
-	latex crypt > /dev/null
-	dvipdf crypt
-	mv -ivf crypt.pdf doc/crypt.pdf
-	rm -f $(LEFTOVERS)
+ltc-clean:
+	cd libtomcrypt && $(MAKE) clean
+
+ltm-clean:
+	cd libtommath && $(MAKE) clean
+
+sizes: dropbear
+	objdump -t dropbear|grep ".text"|cut -d "." -f 2|sort -rn
+
+clean: ltc-clean ltm-clean thisclean
 
-docdvi: crypt.tex
-	echo hello > crypt.ind
-	latex crypt > /dev/null
-	latex crypt > /dev/null
-	makeindex crypt.idx
-	perl fixupind.pl
-	latex crypt > /dev/null
-	latex crypt > /dev/null
+thisclean:
+	-rm -f dropbear dbclient dropbearkey dropbearconvert scp scp-progress \
+			dropbearmulti *.o *.da *.bb *.bbg *.prof 
 
-#zipup the project (take that!)
-no_oops: clean
-	cd .. ; cvs commit 
-	echo Scanning for scratch/dirty files
-	find . -type f | grep -v CVS | xargs -n 1 bash mess.sh
+distclean: clean tidy
+	-rm -f config.h
+	-rm -f Makefile
 
-zipup: no_oops docs
-	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
-	cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; \
-	cd libtomcrypt-$(VERSION) ; rm -rf `find . -type d | grep CVS | xargs` ; cd .. ; \
-	tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION) ; \
-	zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \
-	gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \
-	mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION)
-
-
-# $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
-# $Revision: 1.145 $ 
-# $Date: 2006/12/02 19:23:21 $ 
+tidy:
+	-rm -f *~ *.gcov */*~
--- a/README	Thu Jan 11 04:28:09 2007 +0000
+++ b/README	Thu Jan 11 04:29:08 2007 +0000
@@ -1,3 +1,74 @@
-See doc/crypt.pdf
+This is Dropbear, a smallish SSH 2 server and client.
+
+INSTALL has compilation instructions.
+
+MULTI has instructions on making a multi-purpose binary (ie a single binary
+which performs multiple tasks, to save disk space)
+
+SMALL has some tips on creating small binaries.
+
+See TODO for a few of the things I know need looking at, and please contact
+me if you have any questions/bugs found/features/ideas/comments etc :)
+
+Matt Johnston
[email protected]
 
 
+In the absence of detailed documentation, some notes follow:
+============================================================================
+
+Server public key auth:
+
+You can use ~/.ssh/authorized_keys in the same way as with OpenSSH, just put
+the key entries in that file. They should be of the form:
+
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwVa6M6cGVmUcLl2cFzkxEoJd06Ub4bVDsYrWvXhvUV+ZAM9uGuewZBDoAqNKJxoIn0Hyd0Nk/yU99UVv6NWV/5YSHtnf35LKds56j7cuzoQpFIdjNwdxAN0PCET/MG8qyskG/2IE2DPNIaJ3Wy+Ws4IZEgdJgPlTYUBWWtCWOGc= someone@hostname
+
+You must make sure that ~/.ssh, and the key file, are only writable by the
+user. Beware of editors that split the key into multiple lines.
+
+NOTE: Dropbear ignores authorized_keys options such as those described in the
+OpenSSH sshd manpage, and will not allow a login for these keys. 
+
+============================================================================
+
+Client public key auth:
+
+Dropbear can do public key auth as a client, but you will have to convert
+OpenSSH style keys to Dropbear format, or use dropbearkey to create them.
+
+If you have an OpenSSH-style private key ~/.ssh/id_rsa, you need to do:
+
+dropbearconvert openssh dropbear ~/.ssh/id_rsa  ~/.ssh/id_rsa.db
+dbclient -i ~/.ssh/id_rsa.db <hostname>
+
+Currently encrypted keys aren't supported, neither is agent forwarding. At some
+stage both hopefully will be.
+
+============================================================================
+
+If you want to get the public-key portion of a Dropbear private key, look at
+dropbearkey's '-y' option.
+
+============================================================================
+
+To run the server, you need to generate server keys, this is one-off:
+./dropbearkey -t rsa -f dropbear_rsa_host_key
+./dropbearkey -t dss -f dropbear_dss_host_key
+
+or alternatively convert OpenSSH keys to Dropbear:
+./dropbearconvert openssh dropbear /etc/ssh/ssh_host_dsa_key dropbear_dss_host_key
+
+============================================================================
+
+If the server is run as non-root, you most likely won't be able to allocate a
+pty, and you cannot login as any user other than that running the daemon
+(obviously). Shadow passwords will also be unusable as non-root.
+
+============================================================================
+
+The Dropbear distribution includes a standalone version of OpenSSH's scp
+program. You can compile it with "make scp", you may want to change the path
+of the ssh binary, specified by _PATH_SSH_PROGRAM in options.h . By default
+the progress meter isn't compiled in to save space, you can enable it by 
+adding 'SCPPROGRESS=1' to the make commandline.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SMALL	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,53 @@
+Tips for a small system:
+
+If you only want server functionality (for example), compile with
+	make PROGRAMS=dropbear
+rather than just
+	make dropbear
+so that client functionality in shared portions of Dropbear won't be included.
+The same applies if you are compiling just a client.
+
+---
+
+The following are set in options.h:
+
+	- You can safely disable blowfish and twofish ciphers, and MD5 hmac, without
+	  affecting interoperability
+
+	- If you're compiling statically, you can turn off host lookups
+
+	- You can disable either password or public-key authentication, though note
+	  that the IETF draft states that pubkey authentication is required.
+
+	- Similarly with DSS and RSA, you can disable one of these if you know that
+	  all clients will be able to support a particular one. The IETF draft
+	  states that DSS is required, however you may prefer to use RSA. 
+	  DON'T disable either of these on systems where you aren't 100% sure about
+	  who will be connecting and what clients they will be using.
+
+	- Disabling the MOTD code and SFTP-SERVER may save a small amount of codesize
+
+	- You can disable x11, tcp and agent forwarding as desired. None of these are
+	  essential, although agent-forwarding is often useful even on firewall boxes.
+
+---
+
+If you are compiling statically, you may want to disable zlib, as it will use
+a few tens of kB of binary-size (./configure --disable-zlib).
+
+You can create a combined binary, see the file MULTI, which will put all
+the functions into one binary, avoiding repeated code.
+
+If you're compiling with gcc, you might want to look at gcc's options for
+stripping unused code. The relevant vars to set before configure are:
+
+LDFLAGS=-Wl,--gc-sections
+CFLAGS="-ffunction-sections -fdata-sections"
+
+You can also experiment with optimisation flags such as -Os, note that in some
+cases these flags actually seem to increase size, so experiment before
+deciding.
+
+Of course using small C libraries such as uClibc and dietlibc can also help.
+
+If you have any queries, mail me and I'll see if I can help.
--- a/TODO	Thu Jan 11 04:28:09 2007 +0000
+++ b/TODO	Thu Jan 11 04:29:08 2007 +0000
@@ -1,11 +1,27 @@
-stopped at ch12
--- needs examples for ecc/dsa!!! (and for asn.1)
+Current:
+
+Things which might need doing:
+
+- default private dbclient keys
+
+- Make options.h generated from configure perhaps?
+
+- handle /etc/environment in AIX
+
+- check that there aren't timing issues with valid/invalid user authentication
+  feedback.
 
-must have for v1.16
-- document PK build flags
-- document makefile flags [INSTALL_* for instance]
-- prepare manual for printing (both soft and hard cover)
+- Binding to different interfaces
+
+- CTR mode
+- SSH_MSG_IGNORE sending to improve CBC security
+- DH Group Exchange possibly, or just add group14 (whatever it's called today)
 
-Nice to have [in order of precedence]
-- add X9.63 IES
-- add CPP macros like OpenSSL has for ASN1 (e.g. encode/decode functions, etc) shameless ripoff :-)
+- fix scp.c for IRIX
+
+- Be able to use OpenSSH keys for the client? or at least have some form of 
+  encrypted keys.
+
+- Client agent forwarding
+
+- Handle restrictions in ~/.ssh/authorized_keys ?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agentfwd.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,43 @@
+/*
+ * 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. */
+#ifndef _AGENTFWD_H_
+#define _AGENTFWD_H_
+#ifndef DISABLE_AGENTFWD
+
+#include "includes.h"
+#include "chansession.h"
+#include "channel.h"
+
+int agentreq(struct ChanSess * chansess);
+void agentsetauth(struct ChanSess *chansess);
+void agentcleanup(struct ChanSess * chansess);
+void agentset(struct ChanSess *chansess);
+
+#ifdef __hpux
+#define seteuid(a)       setresuid(-1, (a), -1)
+#define setegid(a)       setresgid(-1, (a), -1)
+#endif
+
+#endif /* DROPBEAR_AGENTFWD */
+#endif /* _AGENTFWD_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/algo.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,74 @@
+/*
+ * 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. */
+
+#ifndef _ALGO_H_
+
+#define _ALGO_H_
+
+#include "includes.h"
+#include "buffer.h"
+
+struct Algo_Type {
+
+	unsigned char *name; /* identifying name */
+	char val; /* a value for this cipher, or -1 for invalid */
+	void *data; /* algorithm specific data */
+	unsigned usable : 1; /* whether we can use this algorithm */
+
+};
+
+typedef struct Algo_Type algo_type;
+
+/* lists mapping ssh types of algorithms to internal values */
+extern algo_type sshkex[];
+extern algo_type sshhostkey[];
+extern algo_type sshciphers[];
+extern algo_type sshhashes[];
+extern algo_type sshcompress[];
+
+extern const struct dropbear_cipher dropbear_nocipher;
+extern const struct dropbear_hash dropbear_nohash;
+
+struct dropbear_cipher {
+	const struct ltc_cipher_descriptor *cipherdesc;
+	unsigned long keysize;
+	unsigned char blocksize;
+};
+
+struct dropbear_hash {
+	const struct ltc_hash_descriptor *hashdesc;
+	unsigned long keysize;
+	unsigned char hashsize;
+};
+
+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 * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
+		int *goodguess);
+algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[],
+		int *goodguess);
+
+#endif /* _ALGO_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atomicio.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copied from OpenSSH 3.6.1p2.
+ * 
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* RCSID("OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp "); */
+
+#include "atomicio.h"
+
+/*
+ * ensure all of data on socket comes through. f==read || f==write
+ */
+ssize_t
+atomicio(f, fd, _s, n)
+	ssize_t (*f) ();
+	int fd;
+	void *_s;
+	size_t n;
+{
+	char *s = _s;
+	ssize_t res;
+	size_t pos = 0;
+
+	while (n > pos) {
+		res = (f) (fd, s + pos, n - pos);
+		switch (res) {
+		case -1:
+#ifdef EWOULDBLOCK
+			if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+			if (errno == EINTR || errno == EAGAIN)
+#endif
+				continue;
+		case 0:
+			return (res);
+		default:
+			pos += res;
+		}
+	}
+	return (pos);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atomicio.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,36 @@
+
+/*
+ * Copied from OpenSSH 3.6.1p2, required for loginrec.c
+ *
+ * $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $
+ *
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==write
+ */
+ssize_t	atomicio(ssize_t (*)(), int, void *, size_t);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/auth.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,111 @@
+/*
+ * 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. */
+
+#ifndef _AUTH_H_
+#define _AUTH_H_
+
+#include "includes.h"
+
+void svr_authinitialise();
+void cli_authinitialise();
+
+/* Server functions */
+void recv_msg_userauth_request();
+void send_msg_userauth_failure(int partial, int incrfail);
+void send_msg_userauth_success();
+void svr_auth_password();
+void svr_auth_pubkey();
+void svr_auth_pam();
+
+/* Client functions */
+void recv_msg_userauth_failure();
+void recv_msg_userauth_success();
+void recv_msg_userauth_specific_60();
+void recv_msg_userauth_pk_ok();
+void recv_msg_userauth_info_request();
+void cli_get_user();
+void cli_auth_getmethods();
+void cli_auth_try();
+void recv_msg_userauth_banner();
+void cli_pubkeyfail();
+void cli_auth_password();
+int cli_auth_pubkey();
+void cli_auth_interactive();
+char* getpass_or_cancel(char* prompt);
+
+
+#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */
+
+#define AUTH_TYPE_NONE      1
+#define AUTH_TYPE_PUBKEY    1 << 1
+#define AUTH_TYPE_PASSWORD  1 << 2
+#define AUTH_TYPE_INTERACT  1 << 3
+
+#define AUTH_METHOD_NONE "none"
+#define AUTH_METHOD_NONE_LEN 4
+#define AUTH_METHOD_PUBKEY "publickey"
+#define AUTH_METHOD_PUBKEY_LEN 9
+#define AUTH_METHOD_PASSWORD "password"
+#define AUTH_METHOD_PASSWORD_LEN 8
+#define AUTH_METHOD_INTERACT "keyboard-interactive"
+#define AUTH_METHOD_INTERACT_LEN 20
+
+
+
+/* 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 */
+	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. Applies for
+							  client and server (though has differing [obvious]
+							  meanings). */
+	unsigned perm_warn : 1; /* Server only, set if bad permissions on 
+							   ~/.ssh/authorized_keys have already been
+							   logged. */
+
+	/* These are only used for the server */
+	char *printableuser; /* stripped of control chars, used for logs etc */
+	struct passwd * pw;
+
+};
+
+struct SignKeyList;
+/* A singly linked list of signing keys */
+struct SignKeyList {
+
+	sign_key *key;
+	int type; /* The type of key */
+	struct SignKeyList *next;
+	/* filename? or the buffer? for encrypted keys, so we can later get
+	 * the private key portion */
+
+};
+
+#endif /* _AUTH_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bignum.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,75 @@
+/*
+ * 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. */
+
+/* Contains helper functions for mp_int handling */
+
+#include "includes.h"
+#include "dbutil.h"
+
+/* wrapper for mp_init, failing fatally on errors (memory allocation) */
+void m_mp_init(mp_int *mp) {
+
+	if (mp_init(mp) != MP_OKAY) {
+		dropbear_exit("mem alloc error");
+	}
+}
+
+/* simplified duplication of bn_mp_multi's mp_init_multi, but die fatally
+ * on error */
+void m_mp_init_multi(mp_int *mp, ...) 
+{
+    mp_int* cur_arg = mp;
+    va_list args;
+
+    va_start(args, mp);        /* init args to next argument from caller */
+    while (cur_arg != NULL) {
+        if (mp_init(cur_arg) != MP_OKAY) {
+			dropbear_exit("mem alloc error");
+        }
+        cur_arg = va_arg(args, mp_int*);
+    }
+    va_end(args);
+}
+
+void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
+
+	if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
+		dropbear_exit("mem alloc error");
+	}
+}
+
+/* hash the ssh representation of the mp_int mp */
+void sha1_process_mp(hash_state *hs, mp_int *mp) {
+
+	int i;
+	buffer * buf;
+
+	buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, 
+								plus header + some leeway*/
+	buf_putmpint(buf, mp);
+	i = buf->pos;
+	buf_setpos(buf, 0);
+	sha1_process(hs, buf_getptr(buf, i), i);
+	buf_free(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bignum.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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. */
+
+#ifndef _BIGNUM_H_
+#define _BIGNUM_H_
+
+#include "includes.h"
+
+void m_mp_init(mp_int *mp);
+void m_mp_init_multi(mp_int *mp, ...);
+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_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buffer.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,338 @@
+/*
+ * 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. */
+
+/* Buffer handling routines, designed to avoid overflows/using invalid data */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "buffer.h"
+
+/* Prevent integer overflows when incrementing buffer position/length.
+ * Calling functions should check arguments first, but this provides a
+ * backstop */
+#define BUF_MAX_INCR 1000000000
+#define BUF_MAX_SIZE 1000000000
+
+/* avoid excessively large numbers, > ~8192 bits */
+#define BUF_MAX_MPINT (8240 / 8)
+
+/* Create (malloc) a new buffer of size */
+buffer* buf_new(unsigned int size) {
+
+	buffer* buf;
+	
+	if (size > BUF_MAX_SIZE) {
+		dropbear_exit("buf->size too big");
+	}
+
+	buf = (buffer*)m_malloc(sizeof(buffer));
+
+	if (size > 0) {
+		buf->data = (unsigned char*)m_malloc(size);
+	} else {
+		buf->data = NULL;
+	}
+
+	buf->size = size;
+	buf->pos = 0;
+	buf->len = 0;
+
+	return buf;
+
+}
+
+/* free the buffer's data and the buffer itself */
+void buf_free(buffer* buf) {
+
+	m_free(buf->data)
+	m_free(buf);
+}
+
+/* overwrite the contents of the buffer to clear it */
+void buf_burn(buffer* buf) {
+	
+	m_burn(buf->data, buf->size);
+
+}
+
+/* resize a buffer, pos and len will be repositioned if required when
+ * downsizing */
+void buf_resize(buffer *buf, unsigned int newsize) {
+
+	if (newsize > BUF_MAX_SIZE) {
+		dropbear_exit("buf->size too big");
+	}
+
+	buf->data = m_realloc(buf->data, newsize);
+	buf->size = newsize;
+	buf->len = MIN(newsize, buf->len);
+	buf->pos = MIN(newsize, buf->pos);
+
+}
+
+/* Create a copy of buf, allocating required memory etc. */
+/* The new buffer is sized the same as the length of the source buffer. */
+buffer* buf_newcopy(buffer* buf) {
+	
+	buffer* ret;
+
+	ret = buf_new(buf->len);
+	ret->len = buf->len;
+	memcpy(ret->data, buf->data, buf->len);
+	return ret;
+}
+
+/* Set the length of the buffer */
+void buf_setlen(buffer* buf, unsigned int len) {
+	if (len > buf->size) {
+		dropbear_exit("bad buf_setlen");
+	}
+	buf->len = len;
+}
+
+/* Increment the length of the buffer */
+void buf_incrlen(buffer* buf, unsigned int incr) {
+	if (incr > BUF_MAX_INCR || buf->len + incr > buf->size) {
+		dropbear_exit("bad buf_incrlen");
+	}
+	buf->len += incr;
+}
+/* Set the position of the buffer */
+void buf_setpos(buffer* buf, unsigned int pos) {
+
+	if (pos > buf->len) {
+		dropbear_exit("bad buf_setpos");
+	}
+	buf->pos = pos;
+}
+
+/* increment the postion by incr, increasing the buffer length if required */
+void buf_incrwritepos(buffer* buf, unsigned int incr) {
+	if (incr > BUF_MAX_INCR || buf->pos + incr > buf->size) {
+		dropbear_exit("bad buf_incrwritepos");
+	}
+	buf->pos += incr;
+	if (buf->pos > buf->len) {
+		buf->len = buf->pos;
+	}
+}
+
+/* increment the position by incr, negative values are allowed, to
+ * decrement the pos*/
+void buf_incrpos(buffer* buf,  int incr) {
+	if (incr > BUF_MAX_INCR ||
+			(unsigned int)((int)buf->pos + incr) > buf->len 
+			|| ((int)buf->pos + incr) < 0) {
+		dropbear_exit("bad buf_incrpos");
+	}
+	buf->pos += incr;
+}
+
+/* Get a byte from the buffer and increment the pos */
+unsigned char buf_getbyte(buffer* buf) {
+
+	/* This check is really just ==, but the >= allows us to check for the
+	 * bad case of pos > len, which should _never_ happen. */
+	if (buf->pos >= buf->len) {
+		dropbear_exit("bad buf_getbyte");
+	}
+	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) {
+
+	if (buf->pos >= buf->len) {
+		buf_incrlen(buf, 1);
+	}
+	buf->data[buf->pos] = val;
+	buf->pos++;
+}
+
+/* returns an in-place pointer to the buffer, checking that
+ * the next len bytes from that position can be used */
+unsigned char* buf_getptr(buffer* buf, unsigned int len) {
+
+	if (buf->pos + len > buf->len) {
+		dropbear_exit("bad buf_getptr");
+	}
+	return &buf->data[buf->pos];
+}
+
+/* like buf_getptr, but checks against total size, not used length.
+ * This allows writing past the used length, but not past the size */
+unsigned char* buf_getwriteptr(buffer* buf, unsigned int len) {
+
+	if (buf->pos + len > buf->size) {
+		dropbear_exit("bad buf_getwriteptr");
+	}
+	return &buf->data[buf->pos];
+}
+
+/* Return a null-terminated string, it is malloced, so must be free()ed
+ * Note that the string isn't checked for null bytes, hence the retlen
+ * may be longer than what is returned by strlen */
+unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) {
+
+	unsigned int len;
+	unsigned char* ret;
+	len = buf_getint(buf);
+	if (len > MAX_STRING_LEN) {
+		dropbear_exit("string too long");
+	}
+
+	if (retlen != NULL) {
+		*retlen = len;
+	}
+	ret = m_malloc(len+1);
+	memcpy(ret, buf_getptr(buf, len), len);
+	buf_incrpos(buf, len);
+	ret[len] = '\0';
+
+	return ret;
+}
+
+/* Just increment the buffer position the same as if we'd used buf_getstring,
+ * but don't bother copying/malloc()ing for it */
+void buf_eatstring(buffer *buf) {
+
+	buf_incrpos( buf, buf_getint(buf) );
+}
+
+/* Get an uint32 from the buffer and increment the pos */
+unsigned int buf_getint(buffer* buf) {
+	unsigned int ret;
+
+	LOAD32H(ret, buf_getptr(buf, 4));
+	buf_incrpos(buf, 4);
+	return ret;
+}
+
+/* put a 32bit uint into the buffer, incr bufferlen & pos if required */
+void buf_putint(buffer* buf, int unsigned val) {
+
+	STORE32H(val, buf_getwriteptr(buf, 4));
+	buf_incrwritepos(buf, 4);
+
+}
+
+/* put a SSH style string into the buffer, increasing buffer len if required */
+void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len) {
+	
+	buf_putint(buf, len);
+	buf_putbytes(buf, str, len);
+
+}
+
+/* put the set of len bytes into the buffer, incrementing the pos, increasing
+ * len if required */
+void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len) {
+	memcpy(buf_getwriteptr(buf, len), bytes, len);
+	buf_incrwritepos(buf, len);
+}
+	
+
+/* for our purposes we only need positive (or 0) numbers, so will
+ * fail if we get negative numbers */
+void buf_putmpint(buffer* buf, mp_int * mp) {
+
+	unsigned int len, pad = 0;
+	TRACE(("enter buf_putmpint"))
+
+	dropbear_assert(mp != NULL);
+
+	if (SIGN(mp) == MP_NEG) {
+		dropbear_exit("negative bignum");
+	}
+
+	/* zero check */
+	if (USED(mp) == 1 && DIGIT(mp, 0) == 0) {
+		len = 0;
+	} else {
+		/* SSH spec requires padding for mpints with the MSB set, this code
+		 * implements it */
+		len = mp_count_bits(mp);
+		/* if the top bit of MSB is set, we need to pad */
+		pad = (len%8 == 0) ? 1 : 0;
+		len = len / 8 + 1; /* don't worry about rounding, we need it for
+							  padding anyway when len%8 == 0 */
+
+	}
+
+	/* store the length */
+	buf_putint(buf, len);
+	
+	/* store the actual value */
+	if (len > 0) {
+		if (pad) {
+			buf_putbyte(buf, 0x00);
+		}
+		if (mp_to_unsigned_bin(mp, buf_getwriteptr(buf, len-pad)) != MP_OKAY) {
+			dropbear_exit("mpint error");
+		}
+		buf_incrwritepos(buf, len-pad);
+	}
+
+	TRACE(("leave buf_putmpint"))
+}
+
+/* Retrieve an mp_int from the buffer.
+ * Will fail for -ve since they shouldn't be required here.
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+int buf_getmpint(buffer* buf, mp_int* mp) {
+
+	unsigned int len;
+	len = buf_getint(buf);
+	
+	if (len == 0) {
+		mp_zero(mp);
+		return DROPBEAR_SUCCESS;
+	}
+
+	if (len > BUF_MAX_MPINT) {
+		return DROPBEAR_FAILURE;
+	}
+
+	/* check for negative */
+	if (*buf_getptr(buf, 1) & (1 << (CHAR_BIT-1))) {
+		return DROPBEAR_FAILURE;
+	}
+
+	if (mp_read_unsigned_bin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
+		return DROPBEAR_FAILURE;
+	}
+
+	buf_incrpos(buf, len);
+	return DROPBEAR_SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buffer.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,66 @@
+/*
+ * 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. */
+
+#ifndef _BUFFER_H_
+
+#define _BUFFER_H_
+
+#include "includes.h"
+
+struct buf {
+
+	unsigned char * data;
+	unsigned int len; /* the used size */
+	unsigned int pos;
+	unsigned int size; /* the memory size */
+
+};
+
+typedef struct buf buffer;
+
+buffer * buf_new(unsigned int size);
+void buf_resize(buffer *buf, unsigned int newsize);
+void buf_free(buffer* buf);
+void buf_burn(buffer* buf);
+buffer* buf_newcopy(buffer* buf);
+void buf_setlen(buffer* buf, unsigned int len);
+void buf_incrlen(buffer* buf, unsigned int incr);
+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);
+unsigned char* buf_getstring(buffer* buf, unsigned int *retlen);
+void buf_eatstring(buffer *buf);
+void buf_putint(buffer* buf, unsigned int val);
+void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len);
+void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len);
+void buf_putmpint(buffer* buf, mp_int * mp);
+int buf_getmpint(buffer* buf, mp_int* mp);
+unsigned int buf_getint(buffer* buf);
+
+#endif /* _BUFFER_H_ */
--- a/build.sh	Thu Jan 11 04:28:09 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#!/bin/bash
-echo "$1 ($2, $3)..."
-make clean 1>/dev/null 2>/dev/null
-echo -n "building..."
-CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" make -j4 -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1)
-echo -n "testing..."
-if [ -a test ] && [ -f test ] && [ -x test ]; then
-   ((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1)
-   if find *_tv.txt -type f 1>/dev/null 2>/dev/null ; then
-      for f in *_tv.txt; do if (diff --ignore-case $f notes/$f) then true; else (echo "tv_gen $f failed" && rm -f testok.txt && exit 1); fi; done
-   fi
-fi
-if [ -a testok.txt ] && [ -f testok.txt ]; then
-   exit 0
-fi
-exit 1
-
-# $Source: /cvs/libtom/libtomcrypt/build.sh,v $   
-# $Revision: 1.9 $   
-# $Date: 2006/03/18 14:10:55 $ 
--- a/changes	Thu Jan 11 04:28:09 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1556 +0,0 @@
-December 16th, 2006
-v1.16 -- Brian Gladman pointed out that a recent change to GCM broke how the IV was handled.  Currently the code complies against his test vectors
-         so the code should be considered frozen now.
-      -- Trevor from Cryptography Research Inc. submitted patches to convert the ECC code to be generic allowing curve parameters to be submitted
-         at runtime.  
-      -- Fixed various doxygen comments
-      -- Added UTF8 support to the ASN1 code
-      -- Fixed STOREXXH macros for x86 platforms (Fix found at Elliptic Inc.)
-      -- Added makefile.unix which is BSD compatible, you have to manually tweak it since well I don't use it normally
-      -- removed a few lingering memcpy's
-      -- Fixed memory free errors in ecc_sign_hash() that can arise if the mp_init_multi() fails
-      -- Fixed incorrect return value in pkcs_1_pss_decode() which would correctly set res to 0 (indicating an incorrect signature) but 
-         would return CRYPT_OK to the caller
-      -- ltc_ecc_mulmod() could leak memory if mp_init(&mu) failed, fixed.  Would you believe that ltc_ecc_mulmod_timing() had the same
-         bug?  Also fixed.  :-)
-      -- Added Shamir's trick to the ECC side (defined as LTC_ECC_SHAMIR, enabled by default), gets ~1.34x to ~1.40x faster ECC verifications
-      -- Added Brian's vector #46 to the GCM code.  It catches the ctr counter error from v1.15.  Originally I was going to add all of his vectors,
-         but they're not as easy to parse and I got a lot of other things to do.  Regression!
-      -- Various other small fixes to the ECC code to clean up error handling (I think most of that was from the move in 1.06 to the plugins)
-         All of the errors were in cleaning up from heap failures.  So they were not likely to be triggered in normal usage
-         Made similar fixes to the RSA and DSA code (my bad)
-      -- Cryptography Research Inc. contributed a bunch of fixes to silence warnings (with MSVC) w.r.t. assigned data to unsigned char types.
-      -- Martin Marko suggested some fixes to make the RNG build with WinCE.
-      -- Updates to the manual for print (some fixes thanks to Martin Marko)
-      
-
-November 17th, 2006
-v1.15 -- Andreas Lange found that if sha256_init DID fail in fortuna it wouldn't clean up the state correctly.  Thanks.
-         Fortunately sha256_init cannot fail (as of v1.14) :-)
-      -- Andreas Lange contributed RMD-256 and RMD-320 code.
-      -- Removed mutex locks from fortuna_import as they create a deadlock and aren't required anyways [Avi Zelmanovich]
-      -- Added LTC_NO_PROTOTYPES to avoid prototyping functions like memset/memcpy.  Required for fans of GCC 3.3.x
-      -- David Eder caught a off by one overrun bug in pmac_done() which can be exploited if your output tag buffer is 
-         smaller than the block size of the cipher, e.g. if you have a 4-byte buffer and you tell pmac_done that you want
-         a 4-byte TAG it will store 4 bytes but return an outlen of 5.
-      -- Added signatures to the ECC and RSA benchmarks
-      -- Added LTC_PROFILE to run the PK tests only once in the timing demo (so you can capture events properly)
-      -- Andreas contributed PKCS #1 v1.5 code that merged cleanly with the existing PKCS code.  w00t.
-         (update: I had to fix it to include the digestInfo and what not.  Bad Andreas, bad! hehehe)
-      -- Fixed a signed variable error in gcm_process() (hard to trigger bug fortunately)
-      -- Removed all memcmp/memset/memcpy from the source (replaced with X macros)
-      -- Renamed macros HMAC/OMAC/PMAC to have a LTC_ prefix.  If you pass these on the command line please update your makefiles
-      -- Added XCBC-MAC support [RFC 3566]
-      -- fixed LOAD32H and LOAD64H to stop putting out that darn warning :-)
-      -- Added the Korean SEED block cipher [RFC 4269]
-      -- Added LTC_VALGRIND define which makes SOBER-128 and RC4 a pure PRNG (and not a stream cipher).  Useful if you use 
-         Valgrind to debug your code (reported by Andreas Lange)
-      -- Made SOBER-128 more portable by removing the ASCII key in the test function (my bad, sorry).
-      -- Martin Mocko pointed out that if you have no PRNGs defined the lib won't build.  Fixed, also fixed for if you have no
-         hashes defined.
-      -- Sped up F8 mode with LTC_FAST
-      -- Made CTR mode RFC 3686 compliant (increment counter first), to enable, OR the value LTC_CTR_RFC3686 to the "mode"
-         parameter you pass to ctr_start(), otherwise it will be LTC compliant (e.g. encrypt then increment)
-      -- Added ctr_test() to test CTR mode against RFC 3686
-      -- Added crypt_fsa() ... O_o
-      -- Fixed LTC_ECC_TIMING_RESISTANT so it once again builds properly (pt add/dbl are through the plugin now)
-      -- Added ANSI X9.63 (sec 4.3.6) import/export of public keys (cannot export to compressed formats but will import 
-         hybrid compressed)
-      -- Added SECP curves for 112, 128, and 160 bits (only the 'r1' curves)
-      -- Added 3GPP-F9 MAC (thanks to Greg Rose for the test vectors)
-      -- Added the KASUMI block cipher
-      -- Added F9/XCBC/OMAC callbacks to the cipher plugin
-      -- Added RSA PKCS #1 v1.5 signature/encrypt tests to rsa_test.c
-      -- Fix to yarrow_test() to not call yarrow_done() which is invalid in that context (thanks Valgrind)
-      -- Christophe Devine pointed out that Anubis would fail on various 64-bit UNIX boxes when "x>>24" was used as an index, we needed 
-         to mask it with 0xFF.  Thanks.  Fixed.
-
-August 0x1E, 0x07D6
-v1.14 -- Renamed the chaining mode macros from XXX to LTC_XXX_MODE.  Should help avoid polluting the macro name space.
-      -- clean up of SHA-256
-      -- Chris Colman pointed out that der_decode_sequence_* allows LTC_ASN1_SETOF to accept SEQUENCEs and vice versa.
-         Decoder [non-flexi decoder that is] is more strict now and requires a match.
-      -- Steffen Jaeckel pointed out a typo in the user manual (re: rsa_exptmod).  Fixed.  This disproves the notion that
-         nobody reads it.  :-)
-      -- Made GCM a bit more portable w.r.t. handling the CTR IV (e.g. & with 255)
-      -- Add LTC_VERBOSE if you really want to see what test is doing :-)
-      -- Added SSE2 support to GCM [use GCM_TABLES_SSE2 to enable], shaves 2 cycles per byte on Opteron processors
-         Shaved 4 cycles on a Prescott (Intel P4)
-         Requires you align your gcm_state on a 16 byte boundary, see gcm_memory() for more info
-      -- Added missing prototype for f8_test_mode()
-      -- two fixes to CCM for corner cases [L+noncelen > 15] and fixing the CTR pad to encrypt the CBC-MAC tag
-      -- Franz Glasner pointed out the ARGTYPE=4 is not actually valid.  Fixed.
-      -- Fixed bug in f8_start() if your key < saltkey unspecified behaviour occurs.  :-(
-      -- Documented F8 mode.  Yeah, because you read the manual.  
-      -- Minor updates to the technotes.
-
-
-June 17th, 2006
-v1.13 -- Fixed to fortuna_start() to clean up state if an error occurs.  Not really useful at this stage (sha256 can't fail) but useful
-         if I ever make fortuna pluggable
-      -- Mike Marin submitted a whole bunch of patches for fixing up the libs on traditional UNIX platforms.  Go AIX!  Thanks!
-      -- One of bugs found in the multi demo highlights that at least with gcc you need to pass integers with a UL prefix to ensure
-         they're unsigned long
-      -- Updated the FP ECC code to use affine points.  It's teh fast.
-      -- Made it so many functions which return CRYPT_BUFFER_OVERFLOW now also indicate the required buffer size, note that not all functions
-         do this (most do though).
-      -- Added F8 chaining mode.  It's super neato.
-
-May 29th, 2006
-v1.12 -- Fixed OID encoder/decoder/length to properly handle the first two parts of an OID, matches 2002 X.690 now.
-      -- [Wesley Shields] Allows both GMP/LTM and TFM to be defined now.  
-      -- [Wesley Shields] GMP pluggin is cleaner now and doesn't use deprecated symbols. Yipee
-      -- Added count_lsb_bits to get the number of leading LSB zero bits there are.
-      -- Fixed a bug in the INTEGER encoders for values of -(256**k)/2
-      -- Added BOOLEAN type to ASN.1 thingy-ma-do-hicky
-      -- Testprof doesn't strictly require GMP ... oops [Nils Durner]
-      -- Added LTC_CALL and LTC_EXPORT macros in tomcrypt_cfg.h to support various calling and linker conventions
-         (Thanks to John Kirk from Demonware)
-      -- In what has to be the best thing since sliced bread I bring you MECC_FP which is the fixed point
-         ECC point multiplier.  It's fast, it's sexy and what's more it's hella fast [did I mention it's fast?]
-         You can tune it somewhat with FP_LUT (default to 8) for look-up width.
-         Read section 8.2 of the manual for more info.
-         It is disabled by default, you'll have to build LTC with it defined to get it.  
-      -- Fixed bug in ecc_test.c (from testprof) to include the 521 [not 512] bit curve.  :-)
-
-April 4th, 2006
-v1.11 -- Removed printf's from lrw_test ... whoops
-      -- lrw_process now checks the return of the cipher ecb encrypt/decrypt calls
-      -- lrw_start was not using num_rounds ...
-      -- Adam Miller reported a bug in the flexi decoder with elements past the end of a sequence.  Fixed.
-      -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++.  (I applied this to LTM and TFM)
-      -- Optimized the ECC for TFM a bit by removing the useless "if" statements (most TFM functions don't return error codes)
-         Actually shaved a good chunk of time off and made the code smaller.  By default with TFM the stock LTC point add/dbl functions 
-         will be totally omitted (ECC-256 make key times on a Prescott for old vs. new are 11.03M vs. 9.59M cycles)
-      -- added missing CVS tags to ltc_ecc_mulmod.c
-      -- corrected typo in tomcrypt_cfg.h about what the file has been called 
-      -- corrected my address in the user manual.  A "bit" out of date.
-      -- added lrw_gen to tv_gen
-      -- added GMP plugin, only tested on a AMD64 and x86_32 Gentoo Linux box so be aware
-      -- made testme.sh runs diff case insensitivityly [whatever...] cuz GMP outputs lowercase satan text
-      -- added LDFLAGS to the makefile to allow cross porting linking options
-      -- added lrw_test() to the header file ... whoops
-      -- changed libtomcrypt.org to libtomcrypt.com .... mumble mumble
-      -- Updates to detect __STRICT_ANSI__ which is defined in --std=c99 modes (note -ansi is not supported as it lacks long long) so you can
-         build LTC out of the box with c99 (note: it'll be slower as there is no asm in this case)
-      -- Updated pelican.c and aes_tab.c to undef tables not-required.  The tables are static so both AES and Pelican MAC would have copies.  Save a few KB in the final binary.
-      -- Added LTC_NO_FAST to the makefile.icc to compensate for the fact ICC v9 can't handle it (Pelican MAC fails for instance)
-
-February 11th, 2006
-v1.10 -- Free ecb/cbc/ctr/lrw structures in timing code by calling the "done" function
-      -- fixed bug in lrw_process() which would always use the slow update ...
-      -- vastly sped up gcm_gf_mult() when LTC_FAST is defined.  This speeds up LRW and GCM state creation, useful for servers with GCM
-      -- Removed NLS since there are some attacks against it.  
-      -- fixed memory leak in rsa_import reported by John Kuhns
-      ++ re-released as the rsa fix was incorrect (bad John bad ... hehehe) and I missed some NULLs in the static descriptor entry for ciphers 
-
-January 26th, 2006
-v1.09 -- Added missing doxygen comments to some of the ASN.1 routines
-      -- Added "easy button" define LTC_EASY and LTC will build with a subset of all the algos.  Reduces build times for typical
-         configurations.  Tunable [see tomcrypt_custom.h]
-      -- Added some error detection to reg_algs() of the testprof.a library to detect when the PRNG is not setup correctly (took me 10 mins to figure out, PITA!)
-      -- Similar fixes to timing demo (MD5 not defined when EASY is defined)
-      -- Added the NLS enc+mac stream cipher from QUALCOMM, disabled for this release, waiting on test vectors
-      -- Finally added an auto-update script for the makefiles.  So when I add new files/dirs it can automatically fix up the makefiles [all four of them...]
-      -- Added LRW to the list of cipher modes supported
-      -- cleaned up ciphers definitions to remove cbc/cfb/ofb/ctr/etc from the namespace when not used.
-
-November 24th, 2005
-v1.08 -- Added SET and SET OF support to the ASN.1 side
-      -- Fixed up X macros, added QSORT to the mix [thanks SET/SETOF]
-      -- Added XMEMCMP to the list of X macros
-      -- In der_decode_sequence() the SHORT_INTEGER type was not being handled correctly [oddly enough it worked just enough to make RSA work ... go figure!]
-      -- Fixed bug in math descriptors where if you hadn't defined MECC (ECC support) you would get linker errors
-      -- Added RSA accelerators to the math descriptors to make it possible to not include the stock routines if you supply your own.
-      -- dsa_decrypt_key() was erroneously dependent on MECC not MDSA ... whoops
-      -- Moved DSA size limits to tomcrypt_pk.h so they're defined with LTC_NO_PK+MDSA
-      -- cleaned up tomcrypt_custom.h to make customizable PK easier (and also cleaned up the error traps so they're correctly reported)
-
-November 18th, 2005
-v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly.  That's because as of a few releases ago
-         I added support to set the mode of the counter at init time
-      -- Fixed some "testprof" make issues
-      -- Added RSA keygen to the math descriptors
-      -- Fixed install_test target ... oops
-      -- made the "ranlib" program renamable useful for cross-compiling
-      -- Made the cipher accelerators return error codes.  :-)
-      -- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets
-      -- Added "Katja" public key crypto.  It's based on the recent N = p^2q work by Katja.  I added OAEP padding
-         to it.  Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly
-         analyzed.   It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also
-         some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible.
-      -- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya  :-)
-      -- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER
-      -- Cleaned up the LIBTEST_S definitions in both GNU makefiles.  A few minor touchups as well.
-      -- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this.  
-      -- der_decode_choice() would fail to mark a NULL as "used" when decoding.  Fixed
-      -- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-)
-      -- Added mp_neg() to the math descriptors.
-      -- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent)
-      -- Made the math descriptors buildable when RSA has been undefined
-      -- ECC timing demo now capable of detecting which curves have been defined
-      -- Refactored the ECC code so it's easier to maintain.  (note: the form of this code hasn't really changed since I first added ECC ... :-/)
-      -- Updated the documentation w.r.t. ECC and the accelerators to keep it current
-      -- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error.
-      -- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes)
-      -- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters)
-      -- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead!
-      -- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used)
-      -- ECC code now ALWAYS uses the accelerator interface.  This allows people who use the accelerators to not have the stock
-         ECC point add/dbl/mul code linked in.  Yeah space savings! Rah Rah Rah.
-      -- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at
-         build time (e.g. LTC_PTHREAD == pthreads)
-      -- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock)
-      -- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-)
-      -- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that]
-      -- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD]
-      -- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing
-         their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask)
-
-August 1st, 2005
-v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson]
-      -- Added fourth ARGCHK type which outputs to stderr and continues.  Useful if you trap sigsegv.   [Valient Gough]
-      -- Removed the DH code from the tree
-      -- Made the ECC code fully public (you can access ecc_mulmod directly now) useful for debuging
-      -- Added ecc test to tv_gen
-      -- Added hmac callback to hash descriptors.
-      -- Fixed two doxy comment errors in the UTCTIME functions
-      -- rsa_import() can now read OpenSSL format DER public keys as well as the PKCS #1 RSAPublicKey format.
-         Note that rsa_export()  **ONLY** writes PKCS #1 formats
-      -- Changed MIN/MAX to only define if not already present.  -- Kirk J from Demonware ... 
-      -- Ported tv_gen to new framework (and yes, I made ecc vectors BEFORE changing the API and YES they match now :-))
-      -- ported testing scripts to support pluggable math.  yipee!
-      -- Wrote a TFM descriptor ... yipee
-      -- Cleaned up LTC_FAST in CBC mode a bit 
-      -- Merged in patches from Michael Brown for the sparc/sparc64 targets
-      -- Added find_hash_oid() to search for a hash by its OID
-      -- Cleaned up a few stray CLEAN_STACKs that should have been LTC_CLEAN_STACK
-      -- Added timing resistant ECC, enable by defining LTC_ECC_TIMING_RESISTANT then use ECC API as normal 
-      -- Updated the ECC documentation as it was a bit out of date
-
-June 27th, 2005
-v1.05
-      -- Added Technote #6 which covers the current PK compliance.  
-      -- Fixed buffer overflow in OAEP decoder
-      -- Added CHOICE to the list of ASN.1 types
-      -- Added UTCTIME to the list of ASN.1 types
-      -- Added MUTEX locks around descriptor table functions [but not on the functions that are dependent on them]
-         All functions call *_is_valid() before using a descriptor index which means the respective table must be unlocked before 
-         it can be accessed.  However, during the operation [e.g. CCM] if the descriptor has been altered the results will be 
-         undefined.  
-      -- Minor updates to the manual to reflect recent changes
-      -- Added a catch to for an error that should never come up in rsa_exptmod().  Just being thorough.
-
-June 15th, 2005
-v1.04
-      -- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent]
-      -- ECC-224 curve was wrong [it was an ok curve just not NIST, so no security flaw just interoperability].
-      -- Removed point compression since it slows down ECC ops to save a measly couple bytes.
-         This makes the ecc export format incompatible with 1.03 [it shouldn't change in the future]
-      -- Removed ECC-160 from timing and added the other curves
-
-June 9th, 2005
-v1.03
-      -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes.
-      --------------------------------------------------------------------------------------------------------------
-      -- Made it install the testing library in the icc/static makefiles
-      -- Found bug in ccm_memory.c which would fail to compile when LTC_CLEAN_STACK was enabled
-      -- Simon Johnson proposed I do a fully automated test suite.  Hence "testme.sh" was born
-      -- Added LTC_NO_TEST which forces test vectors off (regardless of what tomcrypt_custom.h has)
-      -- Added LTC_NO_TABLES which disables large tables (where possible, regardless of what tomcrypt_custom.h has)
-      -- New test script found a bug in twofish.c when TABLES was disabled.  Yeah testing!
-      -- Added a LTC_FAST specific test to the testing software.
-      -- Updated test driver to actually halt on errors and just print them out (useful for say... automated testing...)
-      -- Added bounds checking to Pelican MAC
-      -- Added BIT and OCTET STRING to the ASN.1 side of things.  
-      -- Pekka Riikonen pointed out that my ctr_start() function should accept the counter mode. 
-      -- Cleaned up warnings in testprof
-      -- Removed redundant mu and point mapping in ecc_verify_hash() so it should be a bit faster now
-      -- Pekka pointed out that the AES key structure was using 32 bytes more than it ought to.
-      -- Added quick defines to remove entire classes of algorithms.  This makes it easier if you want to build with just 
-         one algorithm (say AES or SHA-256).  Defines are LTC_NO_CIPHERS, LTC_NO_MODES, LTC_NO_HASHES, LTC_NO_MACS,
-         LTC_NO_PRNGS, LTC_NO_PK, LTC_NO_PKCS
-      -- As part of the move for ECC to X9.62 I've changed the signature algorithm to EC DSA.  No API changes.
-      -- Pekka helped me clean up the PKCS #1 v2.1 [OAEP/PSS] code
-      -- Wrote new DER SEQUENCE coder/decoder
-      -- RSA, DSA and ECDSA now use the DER SEQUENCE code (saves a lot of code!)
-      -- DSA output is now a DER SEQUENCE (so not compatible with previous releases).  
-      -- Added Technote #5 which shows how to build LTC on an AMD64 to have a variety of algorithms in only ~80KB of code.
-      -- Changed temp variable in LOAD/STORE macros to "ulong32" for 32-bit ops.  Makes it safer on Big endian platforms
-      -- Added INSTALL_GROUP and INSTALL_USER which you can specify on the build to override the default USER/GROUP the library 
-         is to be installed as
-      -- Removed "testprof" from the default build.  
-      -- Added IA5, NULL and Object Identifier to the list of ASN.1 DER supported types
-      -- The "no_oops" target (part of zipup) now scans for non-cvs files.  This helps prevent temp/scratch files from appearing in releases ;-)
-      -- Added DERs for missing hashes, but just the OID not the PKCS #1 v1.5 additions. 
-      -- Removed PKCS #1 v1.5 from the tree since it's taking up space and you ought to use v2.1 anyways
-      -- Kevin Kenny pointed out a few stray // comments
-      -- INTEGER code properly supports negatives and zero padding [Pekka!]
-      -- Sorted asn1/der/ directory ... less of a mess now ;-)
-      -- Added PRINTABLE STRING type
-      -- Removed ECC-160 as it wasn't a standard curve
-      -- Made ecc_shared_secret() ANSI X9.63 compliant
-      -- Changed "printf" to "fprintf(stderr, " in the testbench... ;-)
-      -- Optimized the GCM table creation.  On 1KB packets [with key switching] the new GCM is 12.7x faster than before.
-      -- Changed OID representation for hashes to be just a list of unsigned longs (so you can compare against them nicely after decoding a sequence)
-      -- ECC code now uses Montgomery reduction ... it's even faster [ECC-256 make key down from 37.4M to 4.6M cycles on an Athlon64]
-      -- Added SHORT_INTEGER so users can easily store DER encoded INTEGER types without using the bignum math library
-      -- Fixed OMAC code so that with LTC_FAST it doesn't require that LTC_FAST_TYPE divides 16 [it has to divide the block size instead]
-      -- ECC key export is now a simple [and documented] SEQUENCE, the "encrypt_key" also uses a new SEQUENCE format.
-      -- Thanks goes to the following testers
-            Michael Brown             - Solaris 10/uSPARCII
-            Richard Outerbridge       - MacOS
-            Martin Carpenter          - Solaris 8/uSPARCII [Thanks for cleaning up the scripts]
-            Greg Rose                 -  ... SunOS 5.8/SPARC [... what's with the SPARCS?]
-            Matt Johnston             - MacOS X  [Thanks for pointing out GCC 4 problems with -Os]
-
-April 19th, 2005
-v1.02
-      -- Added LTC_TEST support to gcm_test()
-      -- "pt/ct" can now be NULL in gcm_process() if you are processing zero bytes
-      -- Optimized GCM by removing the "double copy" handling of the plaintext/aad
-      -- Richard Outerbridge pointed out that x86_prof won't build on MACOS and that the manual 
-         erroneously refers to "mycrypt" all over the place.  Fixed.
-
-April 17th, 2005
-v1.01
-       ** Secure Science Corporation has supported this release cycle by sponsoring the development time taken.  Their 
-          continuing support of this project has helped me maintain a steady pace in order to keep LibTomCrypt up to date,
-          stable and more efficient.
-       -----------------------------------------------------------------------------------------------------
-       -- Updated base64_decode.c so if there are more than 3 '=' signs it would stop parsing
-       -- Merged in latest mpi that fixed a few bugs here and there
-       -- Updated OAEP encoder/decoder to catch when the hash output is too large
-          Cleaned up PSS code too
-       -- Andy Bontoft fixed a bug in my demos/tests/makefile.msvc ... seems "dsa_test.c" isn't an object
-          afterall.  Thanks.
-       -- Made invalid ECC key sizes (configuration) not hard fault the program (it returns an error code now)
-       -- SAFER has been re-enabled after I was pointed to http://www.ciphersbyritter.com/NEWS2/95032301.HTM
-          [Mark Kotiaho]
-       -- Added CCM mode to the encauth list (now has EAX, OCB and CCM, c'est un treo magnifique!)
-       -- Added missing ASN.1 header to the RSA keys ... oops... now the rsa_export/import are FULLY compatible
-          with other libs like OpenSSL (comment:  Test vectors would go a long way RSA...)
-       -- Manually merged in fix to the prime_random_ex() LTM function that ensures the 2nd MSB is set properly.  Now
-          When you say "I want a 1024/8 byte RSA key" the MSB bit of the modulus is set as expected.  Note I generally 
-          don't view this as a "huge issue" but it's just one less nit to worry about. [Bryan Klisch]
-       -- A new CVS has been setup on my Athlon64 box... if you want developer access send me an email (and at this point the email would have to be awesome).
-       -- Updated API for ECB and CBC shell code.  Now can process N whole blocks in one call (like $DEITY intended)
-       -- Introduced a new "hardware accel" framework that can be used to speed up cipher ECB, CBC and CTR mode
-          calls.  Later on dependent code (e.g. OMAC, CCM) will be re-written to use the generic cbc/ctr functions.  But now
-          if you [say] call ctr_encrypt() with a cipher descriptor that has hardware CTR it will automatically
-          be used (e.g. no code rewrites)
-       -- Now ships with 20% more love.
-       -- x86_prof now uses ECB shell code (hint: accelerators) and outputs cycles per BLOCK not byte.  This will make it a bit 
-          easier to compare hardware vs. software cipher implementations.  It also emits timings for CBC and CTR modes
-       -- [Peter LaDow] fixed a typo w.r.t. XREALLOC macro (spelling counts kids!)
-       -- Fixed bug with __x86_64__ where ROL64/ROR64 with LTC_NO_ROLC would be the 32-bit versions instead...
-       -- Shipping with preliminary GCM code (disabled).  It's buggy (stack overflow hidden somewhere).  If anyone can spot it let me know.
-       -- Added Pelican MAC [it's an AES based fast MAC] to the list of supported MACs
-       -- Added LTC_FAST [and you can disable by defining LTC_NO_FAST] so that CBC and CTR mode XOR whole words [e.g. 32 or 64 bits] at a time
-          instead of one byte.  On my AMD64 this reduced the overhead for AES-128-CBC from 4.56 cycles/byte to around 1 cycle/byte.  This requires
-          that you either allow unaligned read/writes [e.g. x86_32/x86_64] or align all your data.  It won't go out of it's way to ensure 
-          aligned access.  Only enabled for x86_* platforms by default since they allow unaligned read/writes.
-       -- Added LTC_FAST support to PMAC (drops the cycle/byte by about 9 cycles on my AMD64) [note: I later rewrote this prior to release]
-       -- Updated "profiled" target to work with the new directory layout
-       -- Added [demo only] optimized RC5-CTR code to x86_prof demo to show off how to make an accelerator
-          [This has been removed prior to release... It may re-appear later]
-       -- Added CCM acelerator callbacks to the list [now supports ECB, CTR, CBC and now CCM].
-       -- Added chapter to manual about accelerators (you know you want it)
-       -- Added "bswap" optimizations to x86 LOAD/STORE with big endian.  Can be disabled by defining LTC_NO_BSWAP
-       -- LTC_NO_ASM is now the official "disable all non-portable stuff" macro.  When defined it will make the code endian-neutral,
-          disable any form of ASM and disable LTC_FAST load/stores.  Essentially build the library with this defined if you're having
-          trouble building the library (old GCCs for instance dislike the ROLc macro)
-       -- Added tomcrypt_mac.h and moved MAC/encMAC functions from tomcrypt_hash.h into it
-       -- Added "done" function to ciphers and the five chaining modes [and things like omac/pmac/etc]
-       -- Changed install group to "wheel" from "root".
-       -- Replaced // comments with /**/ so it will build on older UNIX-like platforms
-       -- x86_prof builds and runs with IntelCC fine now 
-       -- Added "stest" build to intel CC to test static linked from within the dir (so you don't have to install to test)
-       -- Moved testing/benchmark into testprof directory and build it as part of the build.  Now you can link against libtomcrypt_prof.a to get 
-          testing info (hint: hardware developers ;-) )
-       -- Added CCM to tv_gen 
-       -- Added demos to MSVC makefile
-       -- Removed -funroll-all-loops from GCC makefile and replaced with -funroll-loops which is a bit more sane (P4 ain't got much cache for the IDATA)
-       -- Fixed GCM prior to release and re-enabled it.  It has not been optimized but it does conform when compiled with optimizations.
-       -- I've since optimized GCM and CCM.  They're close in speed but GCM is more flexible imho (though EAX is more flexible than both)
-       -- For kicks I optimized the ECC code to use projective points.  Gets between 3.21x (Prescott P4) to 4.53x (AMD64) times faster than before at 160-bit keys and the
-          speedup grows as the keysize grows.  Basically removing most practical reasons to "not use the ECC code".  Enjoy.
-       -- Added LTC_FAST support to OMAC/PMAC and doubled it's speed on my amd64 [faster on the P4 too I guess]
-       -- Added GCM to tv_gen
-       -- Removed "makefile.cygwin_dll" as it's not really used by anyone and not worth the effort (hell I hardly maintain the MSVC makefiles ...)
-       -- Updated a few files in the "misc" directory to have correct @file comments for doxygen
-       -- Removed "profile" target since it was slower anyways (go figure...)
-
-December 31st, 2004
-v1.00  
-       -- Added "r,s == 0" check to dsa_verify_hash()
-       -- Added "multi block" helpers for hash, hmac, pmac and omac routines so you can process multiple non-adjacent
-          blocks of data with one call (added demos/multi.c to make sure they work)
-          -- Note these are not documented but they do have doxygen comments inside them
-          -- Also I don't use them in other functions (like pkcs_5_2()) because I didn't have the time.  Job for the new LTC maintainer ;-)
-       -- Added tweaked Anubis test vectors and made it default (undefined ANUBIS_TWEAK to get original Anubis)
-       -- Merged in fix for mp_prime_random_ex() to deal with MSB and LSB "bugs"
-       -- Removed tim_exptmod() completely, updated several RSA functions (notably v15 and the decrypt/verify) so they 
-          don't require a prng now
-       -- This release brought to you by the fine tunes of Macy Gray.  We miss you.
-
-December 23rd, 2004
-v1.00rc1
-       -- Renamed "mycrypt_*" to "tomcrypt_*" to be more specific and professional
-          Now just include "tomcrypt.h" instead of "mycrypt.h" to get LTC ;-)
-       -- Cleaned up makefiles to ensure all headers are correctly installed
-       -- Added "rotate by constant" macros for portable, x86-32 and x86-64
-          You can disable this new code with LTC_NO_ROLC which is useful for older GCCs
-       -- Cleaned up detection of x86-64 so it works for ROL/ROR macros
-       -- Fixed rsa_import() so that it would detect multi-prime RSA keys and error appropriately
-       -- Sorted the source files by category and updated the makefiles appropriately
-       -- Added LTC_DER define so you can trim out DER code if not required
-       -- Fixed up RSA's decrypt functions changing "res" to "stat" to be more in sync
-          with the signature variables nomenclature. (no code change just renamed the arguments)
-       -- Removed all labels starting with __ and replaced with LBL_ to avoid namespace conflicts (Randy Howard)
-       -- Merged in LTM fix to mp_prime_random_ex() which zap'ed the most significant byte if the bit size
-          requested was a multiple of eight.
-       -- Made RSA_TIMING off by default as it's not terribly useful [and likely to be deprecated]
-       -- Renamed SMALL_CODE, CLEAN_STACK and NO_FILE to have a LTC_ prefix to avoid namespace collisions
-          with other programs.  e.g. SMALL_CODE => LTC_SMALL_CODE
-       -- Zed Shaw pointed out that on certain systems installing libs as "root" isn't possible as the super-user
-          is not root.  Now the makefiles allow this to be changed easily.
-       -- Renamed "struct _*_descriptor" to "struct ltc_*_descriptor" to avoid using a leading _
-          Also renamed _ARGCHK to LTC_ARGCHK
-       -- Zed Shaw pointed out that I still defined the prng structs in tomcrypt_prng.h even if they 
-          weren't defined.  This made undef'ing FORTUNA break the build.
-       -- Added LTC_NO_ASM to disable inline asm macros [ROL/ROR/etc]
-       -- Changed RSA decrypt functions to change the output length variable name from "keylen" to "outlen" to make 
-          it more consistent.
-       -- Added the 64-bit Khazad block cipher [NESSIE]
-       -- Added the 128-bit Anubis block cipher [with key support for 128...320 bit keys] [NESSIE]
-       -- Changes to several MAC functions to rename input arguments to more sensible names
-       -- Removed FAST_PK support from dh_sys.c
-       -- Declared deskey() from des.c as static instead of a global
-       -- Added pretty much all practical GCC warning tests to the GCC [related] makefiles.  These additional
-          warnings can easily be disabled for those with older copies of GCC [or even non GNU cc's]
-       -- Added doxygen @ tags to the code...  phew that was a hell of a lot of [repetitive] work
-       -- Also added pre-configured Doxygen script.
-       -- Cleaned up quite a few functions [ciphers, pk, etc] to make the parameters naming style consistent
-          E.g. ciphers keys are called "skey" consistently now.  The input to PK encryption is called "in", etc.
-          These changes require no code changes on the behalf of developers fortunately
-       -- Started a SAFER+ optimizer [does encrypt only] which shaves a good 30 or so cycles/byte on my AMD64
-          at an expense of huge code.  It's in notes/etc/saferp_optimizer.c
-       -- DSA sign/verify now uses DER encoded output/inputs and no LTC style headers.  
-       -- Matt Johnston found a missing semi-colon in mp_exptmod().  Fix has been merged in.  
-
-October 29th, 2004
-v0.99  -- Merged in the latest version of LTM which includes all of the recent bug fixes
-       -- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
-       -- Stefan Arentz pointed out that mp_s_rmap should be extern
-       -- Kristian Gj?steen pointed out that there are typos in the 
-          "test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
-       -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword 
-          so changed the PRNG api to use "pexport" and "pimport"
-       -- Updated "hashsum" demo so it builds ;-)
-       -- Added automatic support for x86-64 (will configure for 64-bit little endian automagically)
-       -- Zhi Chen pointed out a bug in rsa_exptmod which would leak memory on error. 
-       -- Made hash functions "init" return an int.  slight change to API ;-(
-       -- Added "CHC" mode which turns any cipher into a hash the other LTC functions can use
-       -- Added CHC mode stuff to demos such as tv_gen and hashsum
-       -- Added "makefile.shared" which builds and installs shared/static object copies
-          of the library.
-       -- Added DER for bignum support 
-       -- RSA is now fully joy.  rsa_export/rsa_import use PKCS #1 encodings and should be 
-          compatible with other crypto libs that use the format.
-       -- Added support for x86-64 for the ROL/ROR macros 
-       -- Changed the DLL and SO makefiles to optimize for speed, commented SMALL_CODE in
-          mycrypt_custom.h and added -DSMALL_CODE to the default makefile
-       -- Updated primality testing code so it does a minimum of 5 tests [of Miller-Rabin]
-          (AFAIK not a security fix, just warm fuzzies)
-       -- Minor updates to the OMAC code (additional __ARGCHK and removed printf from omac_test... oops!)
-       -- Update build and configuration info which was really really really out of date.  (Chapter 14)
-       ++ Minor update, switch RSA to use the PKCS style CRT
-
-August 6th, 2004
-v0.98  -- Update to hmac_init to free all allocated memory on error
-       -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow
-       -- Added test functions to PRNG api, RC4 now conforms ;-) [was a minor issue]
-       -- Added the SOBER-128 PRNG based off of code donated by Greg Rose.
-       -- Added Tech Note #4 [notes/tech0004.txt] 
-       -- Changed RC4 back [due to request].  It will now XOR the output so you can use it like 
-          a stream cipher easily.
-       -- Update Fortuna's export() to emit a hash of each pool.  This means that the accumulated 
-          entropy that was spread over all the pools isn't entirely lost when you export/import.
-       -- Zhi Chen suggested a comment for rsa_encrypt_key() to let users know [easily] that it was
-          PKCS #1 v2.0 padding.  (updated other rsa_* functions)
-       -- Cleaned up Noekeon to remove unrolling [wasn't required, was messy and actually slower with GCC/ICC]
-       -- Updated RC4 so that when you feed it >256 bytes of entropy it quietly ignores additional
-          bytes.  Also removed the % from the key setup to speed it up a bit.
-       -- Added cipher/hash/prng tests to x86_prof to help catch bugs while testing
-       -- Made the PRNG "done" return int, fixed sprng_done to not require prng* to be non-null
-       -- Spruced up mycrypt_custom.h to trap more errors and also help prevent LTMSSE from being defined
-          on non-i386 platforms by accident.
-       -- Added RSA/ECC/DH speed tests to x86_prof and cleaned it up to build with zero warnings
-       -- Changed Fortuna to count only entropy [not the 2 byte header] added to pool[0] into the 
-          reseed mechanism.  
-       -- Added "export_size" member to prng_descriptor tables so you can know in advance the size of 
-          the exported state for any given PRNG.  
-       -- Ported over patch on LTM 0.30 [not ready to release LTM 0.31] that fixes bug in mp_mul()/mp_div()
-          that used to result in negative zeroes when you multiplied zero by a negative integer.  
-          (patch due to "Wolfgang Ehrhardt" <[email protected]>)
-       -- Fixed rsa_*decrypt_key() and rsa_*verify_hash() to default to invalid "stat" or "res".  This way
-          if any of the higher level functions fail [before you get to the padding] the result will be in
-          a known state].  Applied to both v2 and v1.5 padding helpers.
-       -- Added MACs to x86_prof
-       -- Fixed up "warnings" in x86_prof and tv_gen
-       -- Added a "profiled" target back [for GCC 3.4 and ICC v8].  Doesn't seem to help but might be worth
-          tinkering with.
-       -- Beefed up load/store test in demos/test
-
-       ++ New note, in order to use the optimized LOAD/STORE macros your platform
-          must support unaligned 32/64 bit load/stores.  The x86s support this
-          but some [ARM for instance] do not.  If your platform cannot perform
-          unaligned operations you must use the endian neutral code which is safe for 
-          any sort of platform.
-
-July 23rd, 2004
-v0.97b -- Added PKCS #1 v1.5 RSA encrypt/sign helpers (like rsa_sign_hash, etc...)
-       -- Added missing prng check to rsa_decrypt_key() [not critical as I don't use 
-          descriptors directly in that function]
-       -- Merged in LTM-SSE, define LTMSSE before you build and you will get SSE2 optimized math ;-)
-          (roughly 3x faster on a P4 Northwood).  By default it will compile as ISO C portable
-          code (when LTMSSE is undefined).
-       -- Fixed bug in ltc_tommath.h where I had the kara/toom cutoffs not marked as ``extern''
-          Thanks to "Stefan Arentz" <stefan at organicnetwork.net>
-       -- Steven Dake <[email protected]> and Richard Amacker <[email protected]> submitted patches to 
-          fix pkcs_5_2().  It now matches the output of another crypto library.  Whoops... hehehe
-       -- Updated PRNG api.  Added Fortuna PRNG to the list of supported PRNGs
-       -- Fixed up the descriptor tables since globals are automatically zero'ed on startup.
-       -- Changed RC4 to store it's output.  If you want to encrypt with RC4
-          you'll have to do the XOR yourself.
-       -- Fixed buffer overflows/overruns in the HMAC code.  
-
-       ++ API change for the PRNGs there now is a done() function per PRNG.  You
-          should call it when you are done with a prng state.  So far it's
-          not absolutely required (won't cause problems) but is a good idea to
-          start.  
-
-
-June 23rd, 2004
-v0.97a ++ Fixed several potentially crippling bugs... [read on]
-       -- Fixed bug in OAEP decoder that would incorrectly report 
-          buffer overflows. [Zhi Chen]
-       -- Fixed headers which had various C++ missing [extern "C"]'s
-       -- Added "extern" to sha384_desc descriptor which I removed by mistake
-       -- Fixed bugs in ENDIAN_BIG macros using the wrong byte order [Matt Johnston]
-       -- Updated tiger.c and des.c to not shadow "round" which is intrinsic on
-          some C compilers.
-       -- Updated demos/test/rsa_test.c to test the RSA functionality better
-       ++ This update has been tested with GCC [v3.3.3], ICC [v8] and MSVC [v6+SP6] 
-          all on a x86 P4  [GCC/ICC tested in Gentoo Linux, MSVC in WinXP]
-       ++ Outcome: The bug Zhi Chen pointed out has been fixed.  So have the bugs
-          that Matt Johnston found.  
-
-June 19th, 2004
-v0.97  -- Removed spurious unused files [arrg!]
-       -- Patched buffer overflow in tim_exptmod()
-       -- Fixed buffer overrun bug in pkcs_1_v15_es_decode()
-       -- Reduced stack usage in PKCS #1 v2.0 padding functions (by several KBs)
-       -- Removed useless extern's that were an artifact from the project start... ;-)
-       -- Replaced memcpy/memset with XMEMCPY and XMEMSET for greater flexibility
-       -- fixed bugs in hmac_done()/hmac_init()/[various others()] where I didn't trap errors 
-       -- Reduced stack usage in OMAC/PMAC/HMAC/EAX/OCB/PKCS#5 by mallocing any significant sized
-          arrays (e.g. > 100 bytes or so).  Only in non-critical functions (e.g. eax_init())
-       -- "Zhi Chen" <[email protected]> pointed out that rsa_decrypt_key() requires
-          an incorrect output size (too large).  Fixed.
-       -- Added a "pretty" target to the GCC makefile.  Requires PERL.  It is NEAT!
-       -- Minor updates to ch1 of the manual.
-       -- Cleaned up the indentation and added comments to rsa_make_key(), rsa_exptmod() and 
-          rsa_verify_hash()
-       -- Updated makefile.icc so the "install" target would work ;-)
-       -- Removed demos/test.c [deprecated from demos/test/test.c]
-       -- Changed MAXBLOCKSIZE from 128 to 64 to reflect the true size...
-
-May 30th, 2004
-v0.96  -- Removed GF and Keyring code
-       -- Extended OAEP decoder to distinguish better [and use a more uniform API]
-       -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
-       -- rsa_exptmod() now pads with leading zeroes as per I2OSP.
-       -- added error checking to yarrow code
-       --  pointed out that tommath.h from this distro will overwrite tommath.h
-          from libtommath.  I changed this to ltc_tommath.h to avoid any such problems.
-       -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
-       -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
-       -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-)
-       -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used.
-       -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding
-       -- replaced old test harness with new over-engineer'ed one in /demos/test/
-       -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying.
-       -- Added PKCS #1 v1.5 RSA encryption and signature padding routines
-       -- Added DER OID's to most hash descriptors (as many as I could find) 
-       -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations 
-          added #define RSA_TIMING which can turn on/off this feature.
-       -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks
-       -- Small update to rand_prime()
-       -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined.  If you want speed though,
-          you're going to have to undefine SMALL_CODE ;-)
-       -- Worked over AES so that it's even smaller now [in both modes].
-       
-May 12th, 2004
-v0.95  -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact
-          the transforms are circulant.  AES dropped 5KB and WHIRLPOOL dropped 13KB
-          using the default build options on the x86.
-       -- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when
-          CLEAN_STACK has been defined.
-       -- added LTC_TEST support to rmd160
-       -- updates to mycrypt_pk.h
-       -- updated rand_prime() to faciliate making RSA composites 
-       -- DSA/RSA now makes composites of the exact size desired.
-       -- Refactored quite a bit of the code, fewer functions per C file
-       -- cleaned up the makefiles to organize the objects logically
-       -- added ICC makefile along with "profiled" targets for both GNU and ICC compilers
-       -- Marked functions for removal before v1.00 see PLAN for more information
-       -- GCC 3.4.0 tested and seems to work
-       -- Added PKCS #5 support
-       -- Fixed typo in comment header of .C files  ;-)
-       -- Added PKCS #1 OAEP and PSS support.  
-       
-Feb 20th, 2004
-v0.94  -- removed unused variables from ocb.c and fixed it to match known test vectors.
-       -- Added PMAC support, minor changes to OMAC/EAX code [I think....]
-       -- Teamed up with Brian Gladman.  His code verifies against my vectors and my code
-          verifies against his test vectors.  Hazaa for co-operation!
-       -- Various small changes (added missing ARGCHKs and cleaned up indentation)
-       -- Optimization to base64, removed unused variable "c"
-       -- Added base64 gen to demos/tv_gen.c
-       -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird...
-       -- Fixed up all of the PK code by adding missing error checking, removed "res" variables,
-          shrunk some stack variables, removed non-required stack variables and added proper
-          error conversion from MPI to LTC codes.  I also spotted a few "off by one" error
-          checking which could have been used to force the code to read past the end of
-          the buffer (in theory, haven't checked if it would work) by a few bytes.
-       -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I 
-          also modded it so it stores in the output provided to the function (that is not on
-          the local stack) which saves memory and time.
-       -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later)
-       -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my
-          Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte].  This code uses the 
-          teams new sbox design (not the original NESSIE one).
-      
-
-Jan 25th, 2004
-v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
-       -- Fix to RC2 to not deference pointer before ARGCHK
-       -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit
-       -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish
-       -- Fix to OMAC to test cipher block size first [prevents wasting any time]
-       -- Added more OMAC test vectors
-       -- Added EAX Encrypt+Authenticate support
-       -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin]
-       -- Added common headers to all C files
-       -- CTR mode supports big and little [default] endian counters now.  
-       -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table.
-       -- added find_hash_any() akin to find_cipher_any().
-       -- Added EAX code to demos/tv_gen.c  Hazaa! 
-       -- Removed SONY defines and files from codebase.
-       -- Added OCB support [patents be damned] and to demos/tv_gen.c
-       -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h
-       -- Made appropriate changes to the debug string in crypt.c
-
-Dec 24th, 2003
-v0.92  -- Updated the config.pl script so the options have more details.
-       -- Updated demos/tv_gen to include RIPEMD hashes
-       -- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table
-          is included [speedup: slight, about 4k cycles on my Athlon].
-       -- Re-wrote the twofish large key generation [the four 8x32 key dependent tables].  Now about twice as fast.
-          With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled
-          in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size.
-       -- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops]
-       -- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified
-          (e.g. not PK_PRIVATE or PK_PUBLIC)
-       -- Fixed up demos/x86_prof so it sorts the output now :-)  
-       -- The project is now powered by radioactive rubber pants.
-       -- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it 
-          will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do]
-       -- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?]
-       -- Massive updates to the prime generation code.  I use the LTM random prime functions [and provide a nice 
-          interface between the LTC PRNG's and the LTM generic prng prototype].  I also use a variable number of tests
-          depending on the input size.  This nicely speeds up most prime generation/testing within the library.
-       -- Added SHA-224 to the list of hashes.
-       -- Made HMAC test vectors constant and static [takes ROM space instead of RAM]
-       -- This release was brought to you by the letter P which stands for Patent Infringement.
-       -- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions
-          I also optimized the compression functions of all but MD2 to not perform input copies when avoidable.
-       -- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon]
-       -- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code.  
-       -- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and 
-          demos/x86_prof.c]
-       -- Added mechanical testing to cipher test vector routines.  Now it encrypts 1000 times, then decrypts and
-          compares.  Any fault (e.g. bug in code, compiler) in the routines is likely to show through.  Doesn't
-          stress test the key gen though...
-       -- Matt Johnson found a bug in the blowfish.c  apparently I was out of my mind and put twofish defines in there 
-          The code now builds with any config.  Thanks.
-       -- Added OMAC1 Message Authentication Code support to the library.
-       -- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit].  
-          Updated HMAC code to use them too.  Hazaa!
-       -- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash().
-       -- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin 
-          conversion [now returns CRYPT_MEM, will fix it up better later]
-       -- Added DSA to the list of supported PK algorithms.  
-       -- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent
-          problems on platforms where CHAR_BIT != 8 
-       -- Merged in LibTomMath v0.28
-       -- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable
-          /dev/random]. 
-       -- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/ 
-       -- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line)
-       -- Fixed bug in hmac_done().  Apparently FIPS-198 [HMAC] specifies that the output can be truncated.  My code
-          would not support that (does now just like the new OMAC code).
-       -- Removed "hashsize" from hmac_state as it wasn't being used.
-       -- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going).
-       -- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos].
-       -- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version.  Dropped +10 cycles/byte
-          on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz)
-       -- Added _ARGCHK() calls to is_prime() for the two input pointers.
-
-Sept 25th, 2003
-v0.91  -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash.
-       -- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines.
-       -- Added RIPEMD hashes to the hashsum demo.
-       -- Added hashsum demo to MSVC makefile.
-       -- Added RMD160 to the x86_prof demo [oops]
-       -- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28
-          Fixes another potential memory leak.
-
-Sept 7th, 2003
-v0.90  -- new ROL/ROR for x86 GCC
-       -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library
-          when not required.
-       == By default the KR code is not enabled [it's only a demo anyways!]
-       -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes]
-       -- hmac_done() now requires you pass it the size of the destination buffer to prevent
-          buffer overflows.  (API CHANGE)
-       -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined.
-       -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default
-          configuration of LibTomMath.  Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size,
-
-768-bit,     4 vs.  10
-1024-bit,    8 vs.  18
-1280-bit,   12 vs.  34
-1536-bit,   20 vs.  56
-1792-bit    28 vs.  88
-2048-bit,   40 vs. 124
-2560-bit,   71 vs. 234
-3072-bit,  113 vs. 386
-4096-bit,  283 vs. 916
-
-          Times are all in milliseconds for key generation.  New primes times on the left.  This makes the code binary
-          incompatible with previous releases.  However, this addition is long overdue as LibTomMath has supported DR
-          reductions for quite some time.
-       -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total].
-       -- The project has been released as public domain.  TDCAL no longer applies.
-
-July 15th, 2003
-v0.89  -- Fix a bug in bits.c which would prevent it from building with msvc
-       -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!]
-       -- Removed the LTC version of next_prime() and replaced it with a call to the
-          mp_prime_next_prime() from LibTomMath
-       -- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC
-          or cygwin.
-
-Jul 10th, 2003
-v0.88  -- Sped up CAST5 key schedule for MSVC
-       -- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in
-          ciphers like blowfish and AES to be 32-bits.  E.g. when unsigned long is 64-bits.
-       -- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!]
-       -- Optimized SHA-1 and SHA-256 quite a bit too.
-       -- Fixed up the makefile to use -fomit-frame-pointer more liberally
-       -- Added tv_gen program which makes test vectors for ciphers/hashes
-       -- Merged in LibTomMath v0.22
-       
-Jun 19th, 2003
-v0.87  -- Many MSVC optimizations to the code base
-       -- Improved the AES and Twofish key schedule [faster, more constant time]
-       -- Tons of optimizations here and there.  
-       
-Jun 15th, 2003
-v0.86  -- Fixed up AES to workaround MSVC optimizer bug
-       -- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC
-       -- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte.
-       -- Fixed up demos/encrypt to remove serpent_desc from the list
-       -- Re-enabled MSVC optimizations w00t w00t
-       -- Replaced "errno" with "err" in all functions that had it so it wouldn't clash
-          with the global "errno"
-       -- Removed a set of unused variables from certain functions
-       -- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C  :-)
-       
-Jun 11th, 2003
-v0.85  -- Swapped in a new AES routine
-       -- Removed Serpent
-       -- Added TDCAL policy document
-       
-Jun 1st, 2003
-v0.84  -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
-       -- Fixed another potential buffer problem.  Not an overflow but could cause the 
-          PK import routines to read past the end of the buffer.
-       -- Optimized the ECC mulmod more by removing a if condition that will always be false
-       -- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime
-          test from LibTomMath now
-       -- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h]
-       -- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now].
-        
-
-Mar 29th, 2003
-v0.83  -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space
-       -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL
-       -- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy
-          buffer overflow.
-       -- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return
-          errors now.
-       
-Mar 15th, 2003
-v0.82  -- Manual updated
-       -- Added MSVC makefile [back, actually its written from scratch to work with NMAKE]
-       -- Change to HMAC helper functions API to avoid buffer overflow [source changes]
-       -- the rsa_encrypt_key was supposed to reject key sizes out of bounds ... 
-          same fix to the rsa_sign_hash 
-       -- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid
-          structures when being called.  E.g. the indexes to the pad/ivs are not out of bounds
-       -- Cleaned up the DES code and simplified the core desfunc routine.
-       -- Simplified one of the boolean functions in MD4
-       
-Jan 16th, 2003
-v0.81  -- Merged in new makefile from Clay Culver and Mike Frysinger
-       -- Sped up the ECC mulmod() routine by making the word size adapt to the input.  Saves a whopping 9 point
-          operations on 521-bit keys now (translates to about 8ms on my Athlon XP).  I also now use barrett reduction
-          as much as possible.  This sped the routine up quite a bit.
-       -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
-       -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
-          (fix due to Mika Bostr?m)
-       -- Merged in LibTomMath for kicks
-       -- Changed the build process so that by default "mycrypt_custom.h" is included and provided
-          The makefile doesn't include any build options anymore
-       -- Removed the PS2 and VC makefiles.
-       
-Dec 16th, 2002
-v0.80  -- Found a change I made to the MPI that is questionable.  Not quite a bug but definately not desired.  Had todo
-          with the digit shifting.  In v0.79 I simply truncated without zeroing.  It didn't cause problems during my
-          testing but I fixed it up none the less.
-       -- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes.
-       -- Fixed in rsa_exptmod() where I was getting the size of the result.  Basically it accomplishes the same thing
-          but the fixed code is more readable.
-       -- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been.  I've
-          also made the #define FAST_PK speed up signatures as well.  Essentially FAST_PK tells the DH sub-system to 
-          limit any private exponent to 256-bits.   Note that when FAST_PK is defined does not make the library
-          binary or source incompatible with a copy of the library with it undefined.
-       -- Removed the DSA code.  If you want fast diffie-hellman just define FAST_PK :-)
-       -- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums.  Saves two bytes but is not binary
-          compatible with the previous release... sorry!  I've performed the same fix to the ecc code as well.
-       -- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now]
-       -- Fixed a bug in the DH code where it missed trapping a few errors if they occurred.
-       -- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function.  Essentially it was
-          testing to ensure that in the loop that searches for the next candidate that the step never grows beyond
-          65000.  Should have been testing for MP_DIGIT_MAX
-       -- Spruced up the config.pl script.  It now makes a header file "mycrypt_custom.h" which can be included *before*
-          you include mycrypt.h.  This allows you to add libtomcrypt to a project without completely changing your make
-          system around.  Note that you should use the makefile it writes to at least build the library initially.
-       -- Used splint to check alot of the code out.  Tons of minor fixes and explicit casts added.
-       -- Also made all the internal functions of MPI are now static to avoid poluting the namespace
-       -- **Notice**:  There are no planned future releases for at least a month from the this release date.
-       
-Dec 14th, 2002
-v0.79  -- Change to PK code [binary and source].  I made it so you have to pass the buffer size to the *_decrypt_key and
-          *_verify_hash functions.  This prevents malformed packets from performing buffer overflows.  I've also trimmed
-          the packet header size [by 4 bytes].
-       -- Made the test program halt on the first error it occurs.  Also made it trap more errors than before.
-       -- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website!
-       -- Included a perl script "config.pl" that will make "makefile.out" according to the users needs.  
-       -- Added shell script to look for latest release
-       -- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles
-       -- updated the makefile to use BSD friendly archiving invokations
-       -- Changed the DH and ECC code to use base64 static key settings [e.g. the primes].  Dropped the code size by 3KB
-          and is ever-so-slightly faster than before.
-       -- added "mp_shrink" function to shrink the size of bignums.  Specially useful for PK code :-)
-       -- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto
-          sized numbers].  Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of
-          heap todo the calculation.  Both are #define'able controlled
-       -- Added XREALLOC macro to provide realloc() functionality.
-       -- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's
-          not being used.
-       -- Fixed potential bug in the ECC code.  Only would occur on platforms where char is not eight bits [which isn't
-          often!]
-       -- Fixed up the ECC point multiplication, its about 15% faster now
-       -- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines
-          so they export as "unsigned" types saving 1 byte per bignum outputted.  Not a lot but heck why not.
-          
-Nov 28th, 2002
-v0.78  -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB.
-       -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly.
-       -- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition.
-       -- Made the KR code check if the other PK systems are included [provides error when building otherwise].
-       -- Made "aes" an alias for Rijndael via a pre-processor macro.  Now you can use "aes_ecb_encrypt", etc... :-)
-          Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion.
-       -- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt).  The *_sign_hash and *_encrypt_key functions
-          are all that is to remain.
-       -- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter.  This fixes a
-          bug where improperly made key packets could result in reading passed the end of the buffer.  This means
-          the code is no longer source compatible but still binary compatible.
-       -- Fixed a few other minor bugs in the PK import code while I was at it.
-       
-Nov 26th, 2002
-v0.77  -- Updated the XTEA code to use pre-computed keys.  With optimizations for speed it achieves 222Mbit/sec
-          compared to the 121Mbit/sec before.  It is 288 bytes bigger than before.
-       -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes)
-       -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys]
-       -- Removed most test cases from Blowfish, left three of them there.  Makes it smaller and faster to test.
-       -- Changed the primality routines around.  I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve
-          step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work.
-       -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity.  This means
-          that a invalid value could have caused segfaults, etc...
-       -- **NOTE** Changed the way the ECC/DH export/import functions work.  They are source but not binary compatible
-          with v0.76.  Essentially insteading of exporting the setting index like before I export the key size.  Now
-          if you ever re-configure which key settings are supported the lib will still be able to make use of your 
-          keys.
-       -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the 
-          rest.  It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before.  The new blowfish 
-          object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller.  So the code is both smaller and 
-          faster!
-       -- Optimized Twofish as well by inlining the round function.  Gets ~400Mbit/sec compared to 280Mbit/sec before
-          and the code is only 78 bytes larger than the previous copy.
-       -- Removed SMALL_PRIME_TAB build option.  I use the smaller table always.
-       -- Fixed some mistakes concerning prime generation in the manual.
-       -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz]
-
-Nov 25th, 2002
-v0.76  -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size.  Got the lib
-          downto 265KB using GCC 3.2 on my x86 box.
-       -- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design.
-       -- Updated all other test vector routines to return as soon as an error is found
-       -- fixed a bug in the test program where errors in the hash test routines would not be reported
-          correctly.  I found this by temporarily changing one of the bytes of the test vectors.  All the
-          hashes check out [the demos/test.c would still have reported an error, just the wrong one].
-          
-
-Nov 24th, 2002
-v0.75  -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL
-       -- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would 
-          not be closed.
-       -- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code
-          In the next release "-Wconversion" will be enabled which will deal with all implicit casts.
-
-Nov 22nd, 2002 [later in the day]
-v0.74  -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms
-       -- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions]
-       -- Wrote a small variant of Rijndael (trimmed 13KB)
-       -- Trimmed the TIGER/192 hash function a bit
-       -- Overall the entire lib compiled is 295KB [down from 400KB before]
-       -- Fixed a few minor oversights in the MSVC makefile
-
-Nov 22nd, 2002
-v0.73  -- Fixed bug in RC4 code where it could only use 255 byte keys.
-       -- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it...
-       -- Removed the ecc compress/expand points from the global scope.  Reduces namespace polution
-       -- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be
-          able todo since the SPRNG has no state...
-       -- Corrected some oversights in the manual and the examples...
-       -- By default the GF(2^W) math library is excluded from the build.  The source is maintained because I wrote it
-          and like it :-).  This way the built library is a tad smaller
-       -- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized.
-
-Nov 21th, 2002
-v0.72  -- Fixed bug in the prime testing.  In the Miller-Rabin test I was raising the base to "N-1" not "r".
-          The math still worked out fine because in effect it was performing a Fermat test.  Tested the new code and it 
-          works properly
-       -- Fixed some of the code where it was still using the old error syntax
-       -- Sped up the RSA decrypt/sign routines
-       -- Optimized the ecc_shared_secret routine to not use so much stack
-       -- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip
-          to
-
-Nov 19th, 2002
-v0.71  -- HELP TOM.  I need tuition for the January semester.  Now I don't want to force donations [nor will I ever]
-          but I really need the help!  See my website http://tom.iahu.ca/help_tom.html for more details.  Please help
-          if you can! 
-       --------------------------------------------------------------------------------------------------------------
-       -- Officially the library is no longer supported in GCC 3.2 in windows [cygwin].
-          In windows you can either use GCC 2.95.3 or try your luck with 3.2  It seems that
-          "-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???]
-          If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2"
-       -- Started new error handling API.  Similar to the previous except there are more error codes than just
-          CRYPT_ERROR
-       -- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!]
-       -- Merged in more changes from Sky Schulz.  I have to make mention here that he has been a tremendous help in 
-          getting me motivated to make some much needed updates to the library!
-       -- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards
-       -- Fixed a bug in the RC4 code [wasn't setting up the key correctly]
-       -- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...)
-       -- Fixed numerous bugs in the PK code.  Essentially I was "freeing" keys when the import failed.  This is neither
-          required nor a good a idea [double free].  
-       -- Tom needs a job.
-       -- Fixed up the test harness as requested by Sky Schulz.  Also modifed the timing routines to run for X seconds
-          and count # of ops performed.  This is more suitable than say encrypting 10 million blocks on a slow processor
-          where it could take minutes!
-       -- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax
-       -- Removed the PKCS code since it was incomplete.  In the future I plan on writing a "add-on" library that
-          provides PKCS support... 
-       -- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h  
-       -- Willing to work on an hourly basis for 15$ CDN per hour.
-       -- updated the test program to not test ciphers not included
-       -- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...]
-       -- fixed numerous failures to detect buffer overflows [minor] in the PK code.
-       -- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup
-          function
-       -- check out my CV at http://tom.iahu.ca/cv.html
-       -- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...]
-       -- merged in rudimentary [for testing] PS2 RNG from Sky Schulz
-       -- merged in PS2 timer code [only shell included due to NDA reasons...]
-       -- updated HMAC code to return errors where possible
-       -- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt]
-
-Nov 12th, 2002
-v0.70  -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz)
-       -- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h
-       -- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?]
-       -- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz....
-       -- Added support for substituting out the clock() function (Sky Schulz)
-       -- Fixed up makefile to include new headers in the HEADERS variable
-       -- Removed "coin.c" as its not really useful anyways
-       -- Removed many "debug" printfs that would show up on failures.  Basically I wanted to ensure the only output
-          would be from the developer themselves.
-       -- Added "rc4.c" a RC4 implementation with a PRNG interface.  Since RC4 isn't a block cipher it wouldn't work
-          too well as a block cipher.
-       -- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code
-       -- updated makefile to make subdirectory properly (Sku Schulz)
-       -- Started towards new API setup.  Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK"
-          In future releases functions will return things other than CRYPT_ERROR on error to give more useful
-          thread safe error reporting.  The manual will be updated to reflect this.  For this release all
-          errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change.         
-       -- Removed the zlib branch since its not really required anyways.  Makes the package smaller
-
-Nov 11th, 2002
-v0.69  -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers
-       -- Note I forgot to change the CRYPT version tag in v0.68... fixed now.
-
-Nov 8th, 2002
-v0.68  -- Fixed flaw in kr_import/kr_export that wasted 4 bytes.  Source but not binary compatible with v0.67
-       -- Fixed bug in kr_find_name that used memcmp to match strings.  Uses strncmp now.
-       -- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing]
-       -- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt.
-       -- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the
-          respective ciphers can use.  
-       -- Fixed a bug in hashsum demo that would report the hash for files that don't exist!
-
-Oct 16th, 2002
-v0.67  -- Moved the function prototypes into files mycrypt_*.h.  To "install" the lib just copy all the 
-          header files "*.h" from the base of this project into your global include path.
-       -- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int"
-       -- Added keyring support for the PK functions
-       -- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key.  Basically
-          move the first argument to the next to last.
-       -- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group
-       -- replaced the primes in the DH code with new ones that are larger than the size they are 
-          associated with.  That is a 1024-bit DH key will have a 1025-bit prime as the modulus
-       -- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66]
-       -- major editing of the manual, started Docer program
-       -- added 160 and 224 bit key settings for ECC.  This makes the DH and ECC binary wise incompatible with v0.66
-       -- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit
-       -- Removed ID_TAG from all files [meh, not a big fan...]
-       -- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo
-       -- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start()
-       -- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls
-          Returns int now instead of void.
-
-Sept 24th, 2002
-v0.66  -- Updated the /demos/test.c program to time the hashes correctly.  Also it uses the yarrow PRNG for all of the 
-          tests meaning its possible to run on RNG less platforms 
-       -- Updated the /demos/hashsum.c program to hash from the standard input
-       -- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same
-          time.
-       -- Dan Kaminsky suggested some cleanups for the code and the MPI config
-          Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want
-          to read the stuff you'll have to convert it 
-       -- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed
-
-Sept 20th, 2002
-v0.65  -- Wayne Scott ([email protected]) made a few of suggestions to improve the library.  Most 
-          importantly he pointed out the math lib is not really required.  He's also tested the lib on 18 
-          different platforms.  According to him with only a few troubles [lack of /dev/random, etc] the 
-          library worked as it was supposed to.  You can find the list at 
-          http://www.bitkeeper.com/Products.BitKeeper.Platforms.html
-       -- Updated the hash_file and hash_memory functions to keep track of the size of the output
-       -- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more
-       -- Modified the mycrypt_cfg.h to autodetect x86-32 machines
-
-Sept 19th, 2002
-v0.64  -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally]
-       -- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages
-       -- fixed more typos in the manual
-       -- removed all unused variables from the core library (ignore the ID_TAG stuff)
-       -- added "const char *crypt_build_settings" string which is a build time constant that gives a listing
-          of all the build time options.  Useful for debugging since you can send that to me and I will know what 
-          exactly you had set for the mycrypt_cfg.h file.
-       -- Added control over endianess.  Out of the box it defaults to endianess neutral but you can trivially 
-          configure the library for your platform.  Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my 
-          Athlon box.  See "mycrypt_cfg.h" for more information.
-
-Sept 11th, 2002
-v0.63  -- Made hashsum demo output like the original md5sum program 
-       -- Made additions to the examples in the manual (fixed them up a bunch)
-       -- Merged in the base64 code from Wayne Scott ([email protected])
-
-Aug 29th, 2002
-v0.62  -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update.
-
-Aug 9th, 2002
-v0.61  -- Fixed a bug in the DES code [oops I read something wrong].
-
-Aug 8th, 2002
-v0.60  -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V.
-
-Aug 7th, 2002
-v0.59  -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC.
-       -- Cleaned up a little in the makefile
-       -- added code that times the hash functions too in the test program
-
-Aug 3rd, 2002
-v0.58  -- Added more stack cleaning conditionals throughout the code.  
-       -- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK
-       -- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message
-          now they only make one call to ctr_encrypt()/ctr_decrypt().
-
-Aug 2nd, 2002
-v0.57  -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name.
-       -- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a
-          key size.  By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that 
-          down if required.
-       -- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus).
-       -- The padding method for RSA is more clearly documented.  Namely if you want to encrypt/sign something of length
-          N then your modulus must be of length 1+3N.  So to sign a message with say SHA-384 [48 bytes] you need a 
-          145 byte (1160 bits) modulus.  This is all in the manual now.
-       -- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every
-          cipher/hash call
-       -- Sped up the hash "process()" functions by not copying one byte at a time.
-       ++ (added just after I uploaded...)
-          MD4 process() now handles input buffers > 64 bytes
-
-Aug 1st, 2002
-v0.56  -- Cleaned up the comments in the Blowfish code.
-       -- Oh yeah, in v0.55 I made all of the descriptor elements constant.  I just forgot to mention it.
-       -- fixed a couple of places where descriptor indexes were tested wrong.  Not a huge bug but now its harder
-          to mess up.
-       -- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library.
-       -- Added the RC2 block cipher to the library.
-       -- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers
-          can use them with less confusion.
-
-July 29th, 2002
-v0.55  -- My god stupid Blowfish has yet again been fixed.  I swear I hate that cipher.  Next bug in it and boom its out of the
-          library.  Use AES or something else cuz I really hate Blowfish at this stage....
-       -- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!]
-
-July 19th, 2002
-v0.54  -- Blowfish now conforms to known test vectors.  Silly bad coding tom!
-       -- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before]
-
-July 18th, 2002
-v0.53  -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)]
-       -- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code
-          with an invalid index ever now.
-       -- Simplified the Yarrow code once again :-)
-
-July 12th, 2002
-v0.52  -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512.  Now MD4 will work with
-          all the routines...
-       -- Fixed the comments in SHA-512 to be a bit more meaningful
-       -- In md4 I made the PADDING array const [again to store it in ROM]
-       -- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer
-       -- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1
-       -- Fixed a logical error in the CTR code which would make it skip the first IV value.  This means
-          the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more
-          sense this way.
-       -- Added {} braces for as many if/for/blocks of code I could find.  My rule is that every for/if/while/do block
-          must have {} braces around it.
-       -- made the rounds table in saferp_setup const [again for the ROM think about the ROM!]
-       -- fixed RC5 since it no longer requires rc5 to be registered in the lib.  It used to since the descriptors used to 
-          be part of the table...
-       -- the packet.c code now makes crypt_error literal string errors when an error occurs
-       -- cleaned up the SAFER+ key schedule to be a bit easier to read.
-       -- fixed a huge bug in Twofish with the TWOFISH_SMALL define.  Because I clean the stack now I had
-          changed the "g_func()" to be called indirectly.  I forgot to actually return the return of the Twofish
-          g_func() function which caused it not to work... [does now :-)]
-
-July 11th, 2002
-v0.51  -- Fixed a bug in SHA512/384 code for multi-block messages.
-       -- Added more test vectors to the SHA384/512 and TIGER hash functions
-       -- cleaned up the hash done routines to make more sense
- 
-July 10th, 2002
-v0.50  -- Fixed yarrow.c so that the cipher/hash used would be registered.  Also fixed
-          a bug where the SAFER+ name was "safer" but should have been "safer+".
-       -- Added an element to the hash descriptors that gives the size of a block [sent into the compressor]
-       -- Cleaned up the support for HMAC's
-       -- Cleaned up the test vector routines to make the test vector data const.  This means on some platforms it will be
-          placed in ROM not RAM now.
-       -- Added MD4 code submited by Dobes Vandermeer ([email protected])
-       -- Added "burn_stack" function [idea taken from another source of crypto code].  The idea is if a function has
-          alot of variables it will clean up better.  Functions like the ecb serpent and twofish code will now have their
-          stacks cleaned and the rest of the code is getting much more straightforward.
-       -- Added a hashing demo by Daniel Richards ([email protected])
-       -- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style.
-          For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec.
-       -- Fixed the register/unregister functions to properly report errors in crypt_error
-       -- Correctly updated yarrow code to remove a few unused variables.
-       -- Updated manual to fix a few erroneous examples.
-       -- Added section on Hash based Message Authentication Codes (HMAC) to the manual
-
-June 19th, 2002
-v0.46  -- Added in HMAC code from Dobes Vandermeer ([email protected])
-
-June 8th, 2002
-v0.45  -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause
-          undefined behaviour.
-       -- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key.
-       -- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h
-
-Apr 4th, 2002
-v0.44  -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it.
-
-Mar 22nd, 2002
-v0.43  -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug.  
-       -- Updated the GCC makefile not to use -O3 or -funroll-loops
-       -- Version tag in mycrypt.h has been updated :-)
-
-Mar 10th, 2002
-v0.42  -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste)
-
-Mar 3rd, 2002
-v0.41  -- Added support to link and use ciphers at compile time.  This can greatly reduce the code size!
-       -- Added a demo to show off how small an application can get... 46kb!
-       -- Disastry pointed out that Blowfish is supposed to be high endian.
-       -- Made registry code for the PRNGs as well [now the smallest useable link is 43kb]
-
-Feb 11th, 2002
-v0.40  -- RSA signatures use [and check for] fixed padding scheme.
-       -- I'm developing in Linux now :-)
-       -- No more warnings from GCC 2.96
-
-Feb 5th, 2002
-v0.39  -- Updated the XTEA code to work in accordance with the XTEA design
-
-January 24th, 2002
-v0.38  -- CFB and OFB modes can now handle blocks of variable size like the CTR code
-       -- Wrote a wrapper around the memory compress functions in Zlib that act like the functions
-          in the rest of my crypto lib
-
-January 23rd, 2002
-v0.37  -- Added support code so that if a hash size and key size for a cipher don't match up they will
-          use the next lower key supported.  (mainly for the PK code).  So you can now use SHA-1 with
-          Twofish, etc...
-       -- Added more options for Twofish.  You can now tell it to use precomputed sboxes and MDS multiplications
-          This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes.
-       -- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB
-       -- Fixed all of the PK packet code to use the same header format [see packet.c].  This makes the PK code
-          binary wise incompatible with previous releases while the API has not changed at all.
-
-January 22nd, 2002
-v0.36  -- Corrections to the manual
-       -- Made a modification to Twofish which lets you build a "small ram" variant.  It requires
-          about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal 
-          variant requires.
-       -- Reduced the stack space used in all of the PK routines.
-
-January 19th, 2002
-v0.35  -- If you removed the first hash or cipher from the library it wouldn't return an error if 
-          you used an ID=0 [i.e blowfish or sha256] in any routine.  Now it checks for that and will
-          return an error like it should
-       -- Merged in new routines from Clay Culver.  These routines are for the PK code so you can easily 
-          encode a symmetric key for multiple recipients.
-       -- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed.
-          Originally I wanted to ensure that the keys were smaller than the order of the field used
-          However, the bias is so insignifcant using full sizes.  For example, with a ECC-192 key the order
-          is about 2^191.99, so instead I rounded down and used a 184-bit secret key.  Now I simply use a full 192-bit
-          key the code will work just the same except that some 192-bit keys will be duplicates which is not a big
-          deal since 1/2^192 is a very small bias!
-       -- Made the configuration a bit simpler and more exacting.  You can for example now select which DH or ECC
-          key settings you wish to support without including the data for all other key settings.  I put the #defines
-          in a new file called "mycrypt_cfg.h"
-       -- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used
-       -- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues.  The yarrow code will now
-          use what ever remaining hash/cipher combo is left [after you #undef them] at build time.   He also suggested
-          a fix to remove unused structures from the symmetric_key and hash_state unions.
-       -- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can
-          encrypt messages any size block at a time.
-       -- Simplified the yarrow code to take advantage of the new CTR code.
-       -- Added a 4096-bit DH key setting.  That took me about 36 hours to find!
-       -- Changed the base64 routines to use a real base64 encoding scheme.
-       -- Added in DH and ECC "encrypt_key()" functions.  They are still rather "beta"ish.
-       -- Added **Twofish** to the list of ciphers!
-
-January 18th, 2002
-v0.34  -- Added "sha512" to the list of hashes.  Produces a 512-bit message digest.  Note that with the current
-          padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures.
-       -- Cleaned up the other hash functions to use the LOAD and STORE macros...
-
-January 17th, 2002
-v0.33  -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't
-          work with the padding scheme and large symmetric keys.
-       -- Added information concerning the Zlib license to the manual
-       -- Added a 3072-bit key setting for the DH code.
-       -- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion.
-       -- Fixed an embarassing typo in the manual concerning the hashes.  Thank's Clay for finding it!
-       -- Fixed rand_prime() so that it makes primes bigger than the setting you give.  For example,
-          if you want a 1024-bit prime it would make a 1023-bit one.  Now it ensures that the prime
-          it makes is always greater than 2^(8n) (n == bytes in prime).  This doesn't have a huge
-          impact on security but I corrected it just the same.
-       -- Fixed the CTR routine to work on platforms where char != 8-bits 
-       -- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries
-          I "AND" with 0xFFFFFFFF.  That forces only the lower 32-bits to have information in it.  On x86 platforms
-          most compilers optimize out the AND operation since its a nop.
-
-January 16th, 2002
-v0.32  -- Made Rijndael's setup function fully static so it is thread safe
-       -- Svante Seleborg suggested a cosmetic style fixup for aes.c, 
-          basically to remove some of the #defines to clean it up
-       -- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes
-          the PK message formats *incompatible* with previous releases.
-       -- Merge in Zlib :-)
- 
-  
-January 15th, 2002
-v0.31  -- The RSA routines can now use CRT to speed up decryption/signatures.  The routines are backwards 
-          compatible with previous releases.
-       -- Fixed another bug that Svante Seleborg found.  Basically you could buffer-overrun the 
-          rsa_exptmod() function itself if you're not careful.  That's fixed now.  Fixed another bug in
-          rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used 
-          memory.       
-       -- improved the readability of the PK import/export functions
-       -- Added a fix to RSA.C by Clay Culver
-       -- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64".
-
-January 14th, 2002
-v0.30  -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found.
-          Basically if you added entropy to the pool in small increments it could in fact
-          cancel out.  Now I hash the pool with the new data which is way smarter.
-
-January 12th, 2002
-v0.29  -- Added MPI code written by Svante Seleborg to the library.  This will make the PK code much
-          easier to follow and debug.  Actually I've already fixed a memory leak in dh_shared_secret().
-       -- Memory leaks found and correct in all three PK routines.  The leaks would occur when a bignum
-          operation fails so it wouldn't normally turn up in the course of a program
-       -- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es
-
-January 11th, 2002
-v0.28  -- Cleaned up some code so that it doesn't assume "char == 8bits".  Mainly SAFER+ has been 
-          changed.
-       -- ***HUGE*** changes in the PK code.  I check all return values in the bignum code so if there
-          are errors [insufficient memory, etc..] it will be reported.  This makes the code fairly more
-          robust and likely to catch any errors.
-       -- Updated the is_prime() function to use a new prototype [it can return errors now] and it also
-          does trial divisions against more primes before the Rabin Miller steps
-       -- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations.
-       -- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation.
-          I should note that there is not alot of concrete information about the cipher.  "Ansi C" versions
-          I found did not address endianess and were not even portable!.  This code is portable and to the
-          best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper.
-       -- Reformated the manual to include the **FULL** source code optimized to be pritable.
-
-January 9th, 2002
-v0.27  -- Changed the char constants to numerical values.  It is backwards compatible and should work on
-          platforms where 'd' != 100 [for example].
-       -- Made a change to rand_prime() which takes the input length as a signed type so you can pass
-          a negative len to get a "3 mod 4" style prime... oops
-       -- changed the MSVC makefile to build with a warning level of three, no warnings!
-
-January 8th, 2002
-v0.26  -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt
-          the output
-       -- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions.
-       -- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int()
-          I added a work around that catches the error and continues normally.
-
-January 8th, 2002
-v0.25  -- Added a stupid define so MSVC 6.00 can build the library.
-       -- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC
-
-January 7th, 2002
-v0.24  -- Sped up Blowfish by unrolling and removing the swaps.
-       -- Made the code comply with more traditional ANSI C standards
-          Should compile with MSVC with less errors
-       -- moved the demos and documentation into their own directories
-          so you can easily build the library with other tool chains
-          by compiling the files in the root
-       -- converted functions with length of outputs to use 
-          "unsigned long" so 16-bit platforms will like this library more.
-
-January 5th, 2002
-v0.23  -- Fixed a small error in the MPI config it should build fine anywhere.
-
-January 4th, 2002
-v0.22  -- faster gf_mul() code
-       -- gf_shl() and gf_shr() are safe on 64-bit platforms now
-       -- Fixed an error in the hashes that Brian Gladman found.  
-          Basically if the message has exactly 56 bytes left to be 
-          compressed I handled them incorrectly.
-
-January 4th, 2002
-v0.21  -- sped up the ECC code by removing redundant divisions in the 
-          point add and double routines.  I also extract the bits more
-          efficiently in "ecc_mulmod()" now.
-       -- sped up [and documented] the rand_prime() function.  Now it just
-          makes a random integer and increments by two until a prime is found
-          This is faster since it doesn't require alot of calls to the PRNG and
-          it doesn't require loading huge integers over and over.  rand_prime()
-          can also make primes congruent to 3 mod 4 [i.e for a blum integer]
-       -- added a gf_sqrt() function that finds square roots in a GF(2^w) field
-       -- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator
-          divisor than the dividend.
-
-January 4th, 2002
-v0.20  -- Added the fixed MPI back in so RSA and DH are much faster again
-
-v0.19  -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code.
-       -- DH, ECC and RSA signature/decryption functions check if the key is private
-       -- new DH signature/verification code works just like the RSA/ECC versions
-
-January 3rd, 2002
-v0.18  -- Added way more comments to each .C file 
-       -- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer]
-       -- fixed RC5 so it reads the default rounds out of the cipher_descriptor table
-       -- cleaned up ecc_export()
-       -- Cleaned up dh_import() and ecc_import() which also perform more 
-          error checking now
-       -- Fixed a serious flaw in rsa_import() with private keys.
-
-January 2nd, 2002
-v0.17  -- Fixed a bug in the random prime generator that fixes the wrong bits to one
-       -- ECC and DH code verify that the moduli and orders are in fact prime.  That 
-          slows down the test routines alot but what are you gonna do? 
-       -- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some
-          values of p.  I replaced it with a slow function.  Once the author of MPI fixes his faster routine
-          I will switch back.
-  
-January 1st, 2002 [whoa new year!]
-v0.16  -- Improved GF division code that is faster.
-       -- documented the GF code
-
-December 31st, 2001
-v0.15  -- A 1792-bit and 2048-bit DH setting was added.  Took me all night to 
-          find a 1792 and 2048-bit strong prime but what the heck
-       -- Library now has polynomial-basis GF(2^w) routines I wrote myself.  Can be used to perform
-          ECC over GF(2^w) later on....
-       -- Fixed a bug with the defines that allows it to build in windows
-       
-December 30th, 2001
-v0.14  -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size 
-          for the cipher used.  It was defaulting to making a 256-bit IV...
-       -- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed...
-       -- spell checked the manual again... :-)
-
-December 30th, 2001
-v0.13  -- Switching back to older copy of MPI since it works! arrg..
-       -- Added sign/verify functions for ECC
-       -- all signature verification routines default to invalid signatures.
-       -- Changed all calls to memset to zeromem.  Fixed up some buffer problems 
-          in other routines.  All calls to zeromem let the compiler determine the size
-          of the data to wipe.
-
-December 29th, 2001
-v0.12  -- Imported a new version of MPI [the bignum library] that should
-          be a bit more stable [if you want to write your own bignum
-          routines with the library that is...]
-       -- Manual has way more info
-       -- hash_file() clears stack now [like it should]
-       -- The artificial cap on the hash input size of 2^32 bits has been
-          removed.  Basically I was too lazy todo 64-bit math before
-          [don't ask why... I can't remember].  Anyways the hashes
-          support the size of 2^64 bits [if you ever use that many bits in a message
-          that's just wierd...]
-       -- The hashes now wipe the "hash_state" after the digest is computed.  This helps
-          prevent the internal state of the hash being leaked accidently [i.e stack problems]
-
-December 29th, 2001
-v0.11  -- Made #define's so you can trim the library down by removing
-          ciphers, hashs, modes of operation, prngs, and even PK algorithms
-          For example, the library with rijndael+ctr+sha1+ECC is 91KB compared
-          to the 246kb the full library takes.
-       -- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to
-          the RSA packet routines.
-       -- ECC now compresses the public key, a ECC-192 public key takes 33 bytes 
-          for example....
-
-December 28th, 2001
-v0.10  -- going to restart the manual from scratch to make it more 
-          clear and professional
-       -- Added ECC over Z/pZ.  Basically provides as much as DH
-          except its faster since the numbers are smaller.  For example,
-          A comparable 256-bit ECC key provides as much security as expected
-          from a DH key over 1024-bits.
-       -- Cleaned up the DH code to not export the symbol "sets[]"
-       -- Fixed a bug in the DH code that would not make the correct size 
-          random string if you made the key short.  For instance if you wanted 
-          a 512-bit DH key it would make a 768-bit one but only make up 512-bits 
-          for the exponent... now it makes the full 768 bits [or whatever the case 
-          is]
-       -- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit
-          keys by mistake.
-
-December 25th, 2001
-v0.09  -- Includes a demo program called file_crypt which shows off
-          how to use the library to make a command line tool which
-          allows the user to encode/decode a file with any
-          hash (on the passphrase) and cipher in CTR mode.
-       -- Switched everything to use typedef's now to clear up the code.
-       -- Added AES (128/192 and 256 bit key modes)
-
-December 24th, 2001
-v0.08  -- fixed a typo in the manual. MPI stores its bignums in
-          BIG endian not little.
-       -- Started adding a RNG to the library.  Right now it tries
-          to open /dev/random and if that fails it uses either the 
-          MS CSP or the clock drift RNG.  It also allows callbacks 
-          since the drift RNG is slow (about 3.5 bytes/sec)
-       -- the RNG can also automatically setup a PRNG as well now
-
-v0.07  -- Added basic DH routines sufficient to 
-          negotiate shared secrets 
-          [see the manual for a complete example!]
-       -- Fixed rsa_import to detect when the input
-          could be corrupt.  
-       -- added more to the manual.
-
-December 22nd, 2001
-v0.06  -- Fixed some formatting errors in 
-          the hash functions [just source code cleaning]
-       -- Fixed a typo in the error message for sha256 :-)
-       -- Fixed an error in base64_encode() that 
-          would fail to catch all buffer overruns
-       -- Test program times the RSA and symmetric cipher 
-          routines for kicks...
-       -- Added the "const" modifier to alot of routines to 
-          clear up the purpose of each function.
-       -- Changed the name of the library to "TomCrypt" 
-          following a suggestion from a sci.crypt reader....
-
-v0.05  -- Fixed the ROL/ROR macro to be safe on platforms 
-          where unsigned long is not 32-bits
-       -- I have added a bit more to the documentation 
-          manual "crypt.pdf" provided.
-       -- I have added a makefile for LCC-Win32.  It should be 
-          easy to port to other LCC platforms by changing a few lines.
-       -- Ran a spell checker over the manual.
-       -- Changed the header and library from "crypt" to "mycrypt" to not
-          clash with the *nix package "crypt".
-
-v0.04  -- Fixed a bug in the RC5,RC6,Blowfish key schedules
-          where if the key was not a multiple of 4 bytes it would
-          not get loaded correctly.
-
-December 21st, 2001
-
-v0.03  -- Added Serpent to the list of ciphers.
-
-v0.02  -- Changed RC5 to only allow 12 to 24 rounds
-       -- Added more to the manual.
-
-v0.01  -- We will call this the first version.
-
-/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
-/* $Revision: 1.274 $ */
-/* $Date: 2006/12/16 19:08:17 $ */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/channel.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,135 @@
+/*
+ * 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. */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "includes.h"
+#include "buffer.h"
+#include "circbuffer.h"
+
+/* channel->type values */
+#define CHANNEL_ID_NONE 0
+#define CHANNEL_ID_SESSION 1
+#define CHANNEL_ID_X11 2
+#define CHANNEL_ID_AGENT 3
+#define CHANNEL_ID_TCPDIRECT 4
+#define CHANNEL_ID_TCPFORWARDED 5
+
+#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED    1
+#define SSH_OPEN_CONNECT_FAILED                 2
+#define SSH_OPEN_UNKNOWN_CHANNEL_TYPE           3
+#define SSH_OPEN_RESOURCE_SHORTAGE              4
+
+/* Not a real type */
+#define SSH_OPEN_IN_PROGRESS					99
+
+#define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11
+							connection, so can't be _too_ small */
+
+#define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */
+
+#define RECV_MAXWINDOW 8000 /* tweak */
+#define RECV_WINDOWEXTEND 1000 /* We send a "window extend" every
+								RECV_WINDOWEXTEND bytes */
+#define RECV_MAXPACKET RECV_MAXWINDOW /* tweak */
+
+struct ChanType;
+
+struct Channel {
+
+	unsigned int index; /* the local channel index */
+	unsigned int remotechan;
+	unsigned int recvwindow, transwindow;
+	unsigned int recvdonelen;
+	unsigned int recvmaxpacket, transmaxpacket;
+	void* typedata; /* a pointer to type specific data */
+	int writefd; /* read from wire, written to insecure side */
+	int readfd; /* read from insecure size, written to wire */
+	int errfd; /* used like writefd or readfd, depending if it's client or server.
+				  Doesn't exactly belong here, but is cleaner here */
+	circbuffer *writebuf; /* data from the wire, for local consumption */
+	circbuffer *extrabuf; /* extended-data for the program - used like writebuf
+					     but for stderr */
+
+	int sentclosed, recvclosed;
+
+	/* this is set when we receive/send a channel eof packet */
+	int recveof, senteof;
+
+	int initconn; /* used for TCP forwarding, whether the channel has been
+					 fully initialised */
+
+	int await_open; /* flag indicating whether we've sent an open request
+					   for this channel (and are awaiting a confirmation
+					   or failure). */
+
+	const struct ChanType* type;
+
+};
+
+struct ChanType {
+
+	int sepfds; /* Whether this channel has seperate pipes for in/out or not */
+	char *name;
+	int (*inithandler)(struct Channel*);
+	int (*checkclose)(struct Channel*);
+	void (*reqhandler)(struct Channel*);
+	void (*closehandler)(struct Channel*);
+
+};
+
+void chaninitialise(const struct ChanType *chantypes[]);
+void chancleanup();
+void setchannelfds(fd_set *readfd, fd_set *writefd);
+void channelio(fd_set *readfd, fd_set *writefd);
+struct Channel* getchannel();
+struct Channel* newchannel(unsigned int remotechan, 
+		const struct ChanType *type, 
+		unsigned int transwindow, unsigned int transmaxpacket);
+
+void recv_msg_channel_open();
+void recv_msg_channel_request();
+void send_msg_channel_failure(struct Channel *channel);
+void send_msg_channel_success(struct Channel *channel);
+void recv_msg_channel_data();
+void recv_msg_channel_extended_data();
+void recv_msg_channel_window_adjust();
+void recv_msg_channel_close();
+void recv_msg_channel_eof();
+
+void common_recv_msg_channel_data(struct Channel *channel, int fd, 
+		circbuffer * buf);
+
+#ifdef DROPBEAR_CLIENT
+extern const struct ChanType clichansess;
+#endif
+
+#if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
+int send_msg_channel_open_init(int fd, const struct ChanType *type);
+void recv_msg_channel_open_confirmation();
+void recv_msg_channel_open_failure();
+#endif
+
+#endif /* _CHANNEL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chansession.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,92 @@
+/*
+ * 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. */
+
+#ifndef _CHANSESSION_H_
+#define _CHANSESSION_H_
+
+#include "loginrec.h"
+#include "channel.h"
+#include "listener.h"
+
+struct exitinfo {
+
+	int exitpid; /* -1 if not exited */
+	int exitstatus;
+	int exitsignal;
+	int exitcore;
+};
+
+struct ChanSess {
+
+	unsigned char * cmd; /* command to exec */
+	pid_t pid; /* child process pid */
+
+	/* pty details */
+	int master; /* the master terminal fd*/
+	int slave;
+	unsigned char * tty;
+	unsigned char * term;
+
+	/* exit details */
+	struct exitinfo exit;
+	
+#ifndef DISABLE_X11FWD
+	struct Listener * x11listener;
+	int x11port;
+	char * x11authprot;
+	char * x11authcookie;
+	unsigned int x11screennum;
+	unsigned char x11singleconn;
+#endif
+
+#ifndef DISABLE_AGENTFWD
+	struct Listener * agentlistener;
+	char * agentfile;
+	char * agentdir;
+#endif
+};
+
+struct ChildPid {
+	pid_t pid;
+	struct ChanSess * chansess;
+};
+
+
+void addnewvar(const char* param, const char* var);
+
+void cli_send_chansess_request();
+void cli_tty_cleanup();
+void cli_chansess_winchange();
+
+void svr_chansessinitialise();
+extern const struct ChanType svrchansess;
+
+struct SigMap {
+	int signal;
+	char* name;
+};
+
+extern const struct SigMap signames[];
+
+#endif /* _CHANSESSION_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/circbuffer.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,138 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002-2004 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 "dbutil.h"
+#include "circbuffer.h"
+
+#define MAX_CBUF_SIZE 100000000
+
+circbuffer * cbuf_new(unsigned int size) {
+
+	circbuffer *cbuf = NULL;
+
+	if (size > MAX_CBUF_SIZE) {
+		dropbear_exit("bad cbuf size");
+	}
+
+	cbuf = (circbuffer*)m_malloc(sizeof(circbuffer));
+	cbuf->data = (unsigned char*)m_malloc(size);
+	cbuf->used = 0;
+	cbuf->readpos = 0;
+	cbuf->writepos = 0;
+	cbuf->size = size;
+
+	return cbuf;
+}
+
+void cbuf_free(circbuffer * cbuf) {
+
+	m_free(cbuf->data);
+	m_free(cbuf);
+}
+
+unsigned int cbuf_getused(circbuffer * cbuf) {
+
+	return cbuf->used;
+
+}
+
+unsigned int cbuf_getavail(circbuffer * cbuf) {
+
+	return cbuf->size - cbuf->used;
+
+}
+
+unsigned int cbuf_readlen(circbuffer *cbuf) {
+
+	dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
+	dropbear_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"))
+		return 0;
+	}
+
+	if (cbuf->readpos < cbuf->writepos) {
+		return cbuf->writepos - cbuf->readpos;
+	}
+
+	return cbuf->size - cbuf->readpos;
+}
+
+unsigned int cbuf_writelen(circbuffer *cbuf) {
+
+	dropbear_assert(cbuf->used <= cbuf->size);
+	dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
+	dropbear_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"))
+		return 0; /* full */
+	}
+	
+	if (cbuf->writepos < cbuf->readpos) {
+		return cbuf->readpos - cbuf->writepos;
+	}
+
+	return cbuf->size - cbuf->writepos;
+}
+
+unsigned char* cbuf_readptr(circbuffer *cbuf, unsigned int len) {
+	if (len > cbuf_readlen(cbuf)) {
+		dropbear_exit("bad cbuf read");
+	}
+
+	return &cbuf->data[cbuf->readpos];
+}
+
+unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len) {
+
+	if (len > cbuf_writelen(cbuf)) {
+		dropbear_exit("bad cbuf write");
+	}
+
+	return &cbuf->data[cbuf->writepos];
+}
+
+void cbuf_incrwrite(circbuffer *cbuf, unsigned int len) {
+	if (len > cbuf_writelen(cbuf)) {
+		dropbear_exit("bad cbuf write");
+	}
+
+	cbuf->used += len;
+	dropbear_assert(cbuf->used <= cbuf->size);
+	cbuf->writepos = (cbuf->writepos + len) % cbuf->size;
+}
+
+
+void cbuf_incrread(circbuffer *cbuf, unsigned int len) {
+	if (len > cbuf_readlen(cbuf)) {
+		dropbear_exit("bad cbuf read");
+	}
+
+	dropbear_assert(cbuf->used >= len);
+	cbuf->used -= len;
+	cbuf->readpos = (cbuf->readpos + len) % cbuf->size;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/circbuffer.h	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,50 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002-2004 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 _CIRCBUFFER_H_
+#define _CIRCBUFFER_H_
+struct circbuf {
+
+	unsigned int size;
+	unsigned int readpos;
+	unsigned int writepos;
+	unsigned int used;
+	unsigned char* data;
+};
+
+typedef struct circbuf circbuffer;
+
+circbuffer * cbuf_new(unsigned int size);
+void cbuf_free(circbuffer * cbuf);
+
+unsigned int cbuf_getused(circbuffer * cbuf); /* how much data stored */
+unsigned int cbuf_getavail(circbuffer * cbuf); /* how much we can write */
+unsigned int cbuf_readlen(circbuffer *cbuf); /* max linear read len */
+unsigned int cbuf_writelen(circbuffer *cbuf); /* max linear write len */
+
+unsigned char* cbuf_readptr(circbuffer *cbuf, unsigned int len);
+unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len);
+void cbuf_incrwrite(circbuffer *cbuf, unsigned int len);
+void cbuf_incrread(circbuffer *cbuf, unsigned int len);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-algo.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,99 @@
+/*
+ * 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"
+
+
+/*
+ * The chosen [encryption | MAC | compression] algorithm to each 
+ * 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[],
+		int *goodguess) {
+
+	unsigned char * algolist = NULL;
+	unsigned char * remotealgos[MAX_PROPOSED_ALGO];
+	unsigned int len;
+	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))
+	if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
+		goto out; /* just a sanity check, no other use */
+	}
+
+	/* remotealgos will contain a list of the strings parsed out */
+	/* We will have at least one string (even if it's just "") */
+	remotealgos[0] = algolist;
+	count = 1;
+	/* Iterate through, replacing ','s with NULs, to split it into
+	 * words. */
+	for (i = 0; i < len; i++) {
+		if (algolist[i] == '\0') {
+			/* someone is trying something strange */
+			goto out;
+		}
+		if (algolist[i] == ',') {
+			algolist[i] = '\0';
+			remotealgos[count] = &algolist[i+1];
+			count++;
+		}
+		if (count == MAX_PROPOSED_ALGO) {
+			break;
+		}
+	}
+
+	/* iterate and find the first match */
+
+	for (j = 0; localalgos[j].name != NULL; j++) {
+		if (localalgos[j].usable) {
+		len = strlen(localalgos[j].name);
+			for (i = 0; i < count; i++) {
+				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;
+				}
+			}
+		}
+	}
+
+out:
+	m_free(algolist);
+	return ret;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-auth.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,295 @@
+/*
+ * 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"
+#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));
+}
+
+
+/* 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, 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 */
+
+	encrypt_packet();
+	TRACE(("leave cli_auth_getmethods"))
+
+}
+
+void recv_msg_userauth_banner() {
+
+	unsigned char* banner = NULL;
+	unsigned int bannerlen;
+	unsigned int i, linecount;
+
+	TRACE(("enter recv_msg_userauth_banner"))
+	if (ses.authstate.authdone) {
+		TRACE(("leave recv_msg_userauth_banner: banner after auth done"))
+		return;
+	}
+
+	banner = buf_getstring(ses.payload, &bannerlen);
+	buf_eatstring(ses.payload); /* The language string */
+
+	if (bannerlen > MAX_BANNER_SIZE) {
+		TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen))
+		goto out;
+	}
+
+	cleantext(banner);
+
+	/* Limit to 25 lines */
+	linecount = 1;
+	for (i = 0; i < bannerlen; i++) {
+		if (banner[i] == '\n') {
+			if (linecount >= MAX_BANNER_LINES) {
+				banner[i] = '\0';
+				break;
+			}
+			linecount++;
+		}
+	}
+
+	printf("%s\n", banner);
+
+out:
+	m_free(banner);
+	TRACE(("leave recv_msg_userauth_banner"))
+}
+
+/* This handles the message-specific types which
+ * all have a value of 60. These are
+ * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ,
+ * SSH_MSG_USERAUTH_PK_OK, &
+ * SSH_MSG_USERAUTH_INFO_REQUEST. */
+void recv_msg_userauth_specific_60() {
+
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) {
+		recv_msg_userauth_pk_ok();
+		return;
+	}
+#endif
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) {
+		recv_msg_userauth_info_request();
+		return;
+	}
+#endif
+
+#ifdef ENABLE_CLI_PASSWORD_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) {
+		/* Eventually there could be proper password-changing
+		 * support. However currently few servers seem to
+		 * implement it, and password auth is last-resort
+		 * regardless - keyboard-interactive is more likely
+		 * to be used anyway. */
+		dropbear_close("Your password has expired.");
+	}
+#endif
+
+	dropbear_exit("Unexpected userauth packet");
+}
+
+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"))
+
+	if (cli_ses.state != USERAUTH_REQ_SENT) {
+		/* Perhaps we should be more fatal? */
+		dropbear_exit("Unexpected userauth failure");
+	}
+
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	/* If it was a pubkey auth request, we should cross that key 
+	 * off the list. */
+	if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) {
+		cli_pubkeyfail();
+	}
+#endif
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	/* If we get a failure message for keyboard interactive without
+	 * receiving any request info packet, then we don't bother trying
+	 * keyboard interactive again */
+	if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT
+			&& !cli_ses.interact_request_received) {
+		TRACE(("setting auth_interact_failed = 1"))
+		cli_ses.auth_interact_failed = 1;
+	}
+#endif
+
+	cli_ses.lastauthtype = AUTH_TYPE_NONE;
+
+	methods = buf_getstring(ses.payload, &methlen);
+
+	partial = buf_getbool(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'", tok))
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+			if (strncmp(AUTH_METHOD_PUBKEY, tok,
+				AUTH_METHOD_PUBKEY_LEN) == 0) {
+				ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
+			}
+#endif
+#ifdef ENABLE_CLI_INTERACT_AUTH
+			if (strncmp(AUTH_METHOD_INTERACT, tok,
+				AUTH_METHOD_INTERACT_LEN) == 0) {
+				ses.authstate.authtypes |= AUTH_TYPE_INTERACT;
+			}
+#endif
+#ifdef ENABLE_CLI_PASSWORD_AUTH
+			if (strncmp(AUTH_METHOD_PASSWORD, tok,
+				AUTH_METHOD_PASSWORD_LEN) == 0) {
+				ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
+			}
+#endif
+			tok = &methods[i+1]; /* Must make sure we don't use it after the
+									last loop, since it'll point to something
+									undefined */
+		}
+	}
+
+	m_free(methods);
+
+	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;
+	cli_ses.state = USERAUTH_SUCCESS_RCVD;
+	cli_ses.lastauthtype = AUTH_TYPE_NONE;
+}
+
+void cli_auth_try() {
+
+	int finished = 0;
+	TRACE(("enter cli_auth_try"))
+
+	CHECKCLEARTOWRITE();
+	
+	/* Order to try is pubkey, interactive, password.
+	 * As soon as "finished" is set for one, we don't do any more. */
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) {
+		finished = cli_auth_pubkey();
+		cli_ses.lastauthtype = AUTH_TYPE_PUBKEY;
+	}
+#endif
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) {
+		if (cli_ses.auth_interact_failed) {
+			finished = 0;
+		} else {
+			cli_auth_interactive();
+			cli_ses.lastauthtype = AUTH_TYPE_INTERACT;
+			finished = 1;
+		}
+	}
+#endif
+
+#ifdef ENABLE_CLI_PASSWORD_AUTH
+	if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) {
+		cli_auth_password();
+		finished = 1;
+		cli_ses.lastauthtype = AUTH_TYPE_PASSWORD;
+	}
+#endif
+
+	TRACE(("cli_auth_try lastauthtype %d", cli_ses.lastauthtype))
+
+	if (!finished) {
+		dropbear_exit("No auth methods could be used.");
+	}
+
+	TRACE(("leave cli_auth_try"))
+}
+
+/* A helper for getpass() that exits if the user cancels. The returned
+ * password is statically allocated by getpass() */
+char* getpass_or_cancel(char* prompt)
+{
+	char* password = NULL;
+
+	password = getpass(prompt);
+
+	/* 0x03 is a ctrl-c character in the buffer. */
+	if (password == NULL || strchr(password, '\3') != NULL) {
+		dropbear_close("Interrupted.");
+	}
+	return password;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-authinteract.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,169 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2005 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"
+#include "session.h"
+#include "ssh.h"
+#include "runopts.h"
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+
+static unsigned char* get_response(unsigned char* prompt)
+{
+	FILE* tty = NULL;
+	unsigned char* response = NULL;
+	/* not a password, but a reasonable limit */
+	char buf[DROPBEAR_MAX_CLI_PASS];
+	char* ret = NULL;
+
+	fprintf(stderr, "%s", prompt);
+
+	tty = fopen(_PATH_TTY, "r");
+	if (tty) {
+		ret = fgets(buf, sizeof(buf), tty);
+		fclose(tty);
+	} else {
+		ret = fgets(buf, sizeof(buf), stdin);
+	}
+
+	if (ret == NULL) {
+		response = (unsigned char*)m_strdup("");
+	} else {
+		unsigned int buflen = strlen(buf);
+		/* fgets includes newlines */
+		if (buflen > 0 && buf[buflen-1] == '\n')
+			buf[buflen-1] = '\0';
+		response = (unsigned char*)m_strdup(buf);
+	}
+
+	m_burn(buf, sizeof(buf));
+
+	return response;
+}
+
+void recv_msg_userauth_info_request() {
+
+	unsigned char *name = NULL;
+	unsigned char *instruction = NULL;
+	unsigned int num_prompts = 0;
+	unsigned int i;
+
+	unsigned char *prompt = NULL;
+	unsigned int echo = 0;
+	unsigned char *response = NULL;
+
+	TRACE(("enter recv_msg_recv_userauth_info_request"))
+
+	cli_ses.interact_request_received = 1;
+
+	name = buf_getstring(ses.payload, NULL);
+	instruction = buf_getstring(ses.payload, NULL);
+
+	/* language tag */
+	buf_eatstring(ses.payload);
+
+	num_prompts = buf_getint(ses.payload);
+	
+	if (num_prompts >= DROPBEAR_MAX_CLI_INTERACT_PROMPTS) {
+		dropbear_exit("Too many prompts received for keyboard-interactive");
+	}
+
+	/* we'll build the response as we go */
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_INFO_RESPONSE);
+	buf_putint(ses.writepayload, num_prompts);
+
+	if (strlen(name) > 0) {
+		cleantext(name);
+		fprintf(stderr, "%s", name);
+	}
+	m_free(name);
+
+	if (strlen(instruction) > 0) {
+		cleantext(instruction);
+		fprintf(stderr, "%s", instruction);
+	}
+	m_free(instruction);
+
+	for (i = 0; i < num_prompts; i++) {
+		unsigned int response_len = 0;
+		prompt = buf_getstring(ses.payload, NULL);
+		cleantext(prompt);
+
+		echo = buf_getbool(ses.payload);
+
+		if (!echo) {
+			unsigned char* p = getpass_or_cancel(prompt);
+			response = m_strdup(p);
+			m_burn(p, strlen(p));
+		} else {
+			response = get_response(prompt);
+		}
+
+		response_len = strlen(response);
+		buf_putstring(ses.writepayload, response, response_len);
+		m_burn(response, response_len);
+		m_free(response);
+	}
+
+	encrypt_packet();
+
+
+	TRACE(("leave recv_msg_recv_userauth_info_request"))
+}
+
+void cli_auth_interactive() {
+
+	TRACE(("enter cli_auth_interactive"))
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+	/* username */
+	buf_putstring(ses.writepayload, cli_opts.username,
+			strlen(cli_opts.username));
+
+	/* service name */
+	buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, 
+			SSH_SERVICE_CONNECTION_LEN);
+
+	/* method */
+	buf_putstring(ses.writepayload, AUTH_METHOD_INTERACT,
+			AUTH_METHOD_INTERACT_LEN);
+
+	/* empty language tag */
+	buf_putstring(ses.writepayload, "", 0);
+
+	/* empty submethods */
+	buf_putstring(ses.writepayload, "", 0);
+
+	encrypt_packet();
+	cli_ses.interact_request_received = 0;
+
+	TRACE(("leave cli_auth_interactive"))
+
+}
+#endif	/* ENABLE_CLI_INTERACT_AUTH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-authpasswd.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,153 @@
+/*
+ * 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"
+#include "session.h"
+#include "ssh.h"
+#include "runopts.h"
+
+#ifdef ENABLE_CLI_PASSWORD_AUTH
+
+#ifdef ENABLE_CLI_ASKPASS_HELPER
+/* Returns 1 if we want to use the askpass program, 0 otherwise */
+static int want_askpass()
+{
+	char* askpass_prog = NULL;
+
+	askpass_prog = getenv("SSH_ASKPASS");
+	return askpass_prog && !isatty(STDIN_FILENO) && getenv("DISPLAY");
+}
+
+/* returns a statically allocated password from a helper app, or NULL
+ * on failure */
+static char *gui_getpass(const char *prompt) {
+
+	pid_t pid;
+	int p[2], maxlen, len, status;
+	static char buf[DROPBEAR_MAX_CLI_PASS + 1];
+	char* helper = NULL;
+
+	TRACE(("enter gui_getpass"))
+
+	helper = getenv("SSH_ASKPASS");
+	if (!helper)
+	{
+		TRACE(("leave gui_getpass: no askpass program"))
+		return NULL;
+	}
+
+	if (pipe(p) < 0) {
+		TRACE(("error creating child pipe"))
+		return NULL;
+	}
+
+	pid = fork();
+
+	if (pid < 0) {
+		TRACE(("fork error"))
+		return NULL;
+	}
+
+	if (!pid) {
+		/* child */
+		close(p[0]);
+		if (dup2(p[1], STDOUT_FILENO) < 0) {
+			TRACE(("error redirecting stdout"))
+			exit(1);
+		}
+		close(p[1]);
+		execlp(helper, helper, prompt, (char *)0);
+		TRACE(("execlp error"))
+		exit(1);
+	}
+
+	close(p[1]);
+	maxlen = sizeof(buf);
+	while (maxlen > 0) {
+		len = read(p[0], buf + sizeof(buf) - maxlen, maxlen);
+		if (len > 0) {
+			maxlen -= len;
+		} else {
+			if (errno != EINTR)
+				break;
+		}
+	}
+
+	close(p[0]);
+
+	while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
+		;
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		return(NULL);
+
+	len = sizeof(buf) - maxlen;
+	buf[len] = '\0';
+	if (len > 0 && buf[len - 1] == '\n')
+		buf[len - 1] = '\0';
+
+	TRACE(("leave gui_getpass"))
+	return(buf);
+}
+#endif /* ENABLE_CLI_ASKPASS_HELPER */
+
+void cli_auth_password() {
+
+	char* password = NULL;
+	char prompt[80];
+
+	TRACE(("enter cli_auth_password"))
+	CHECKCLEARTOWRITE();
+
+	snprintf(prompt, sizeof(prompt), "%s@%s's password: ", 
+				cli_opts.username, cli_opts.remotehost);
+#ifdef ENABLE_CLI_ASKPASS_HELPER
+	if (want_askpass())
+		password = gui_getpass(prompt);
+	else
+#endif
+		password = getpass_or_cancel(prompt);
+
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+	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, 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"))
+}
+#endif	/* ENABLE_CLI_PASSWORD_AUTH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-authpubkey.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,188 @@
+/*
+ * 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"
+#include "session.h"
+#include "ssh.h"
+#include "runopts.h"
+#include "auth.h"
+
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign);
+
+/* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
+ * We use it to remove the key we tried from the list */
+void cli_pubkeyfail() {
+
+	struct SignKeyList *keyitem;
+	struct SignKeyList **previtem;
+
+	TRACE(("enter cli_pubkeyfail"))
+	previtem = &cli_opts.privkeys;
+
+	/* Find the key we failed with, and remove it */
+	for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
+		if (keyitem == cli_ses.lastprivkey) {
+			*previtem = keyitem->next;
+		}
+		previtem = &keyitem;
+	}
+
+	sign_key_free(cli_ses.lastprivkey->key); /* It won't be used again */
+	m_free(cli_ses.lastprivkey);
+
+	TRACE(("leave cli_pubkeyfail"))
+}
+
+void recv_msg_userauth_pk_ok() {
+
+	struct SignKeyList *keyitem;
+	buffer* keybuf;
+	char* algotype = NULL;
+	unsigned int algolen;
+	int keytype;
+	unsigned int remotelen;
+
+	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))
+	m_free(algotype);
+
+	keybuf = buf_new(MAX_PUBKEY_SIZE);
+
+	remotelen = buf_getint(ses.payload);
+
+	/* Iterate through our keys, find which one it was that matched, and
+	 * send a real request with that key */
+	for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
+
+		if (keyitem->type != keytype) {
+			/* Types differed */
+			TRACE(("types differed"))
+			continue;
+		}
+
+		/* Now we compare the contents of the key */
+		keybuf->pos = keybuf->len = 0;
+		buf_put_pub_key(keybuf, keyitem->key, keytype);
+		buf_setpos(keybuf, 0);
+		buf_incrpos(keybuf, 4); /* first int is the length of the remainder (ie
+								   remotelen) which has already been taken from
+								   the remote buffer */
+
+
+		if (keybuf->len-4 != 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"))
+			continue;
+		}
+
+		/* Success */
+		break;
+	}
+	buf_free(keybuf);
+
+	if (keyitem != NULL) {
+		TRACE(("matching key"))
+		/* XXX TODO: if it's an encrypted key, here we ask for their
+		 * password */
+		send_msg_userauth_pubkey(keyitem->key, keytype, 1);
+	} 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(("leave recv_msg_userauth_pk_ok"))
+}
+
+/* TODO: make it take an agent reference to use as well */
+static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
+
+	const char *algoname = NULL;
+	int algolen;
+	buffer* sigbuf = NULL;
+
+	TRACE(("enter send_msg_userauth_pubkey"))
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+	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, AUTH_METHOD_PUBKEY, 
+			AUTH_METHOD_PUBKEY_LEN);
+
+	buf_putbyte(ses.writepayload, realsign);
+
+	algoname = signkey_name_from_type(type, &algolen);
+
+	buf_putstring(ses.writepayload, algoname, algolen);
+	buf_put_pub_key(ses.writepayload, key, type);
+
+	if (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);
+		buf_putstring(sigbuf, ses.session_id, SHA1_HASH_SIZE);
+		buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
+		buf_put_sign(ses.writepayload, key, type, sigbuf->data, sigbuf->len);
+		buf_free(sigbuf); /* Nothing confidential in the buffer */
+	}
+
+	encrypt_packet();
+	TRACE(("leave send_msg_userauth_pubkey"))
+}
+
+int cli_auth_pubkey() {
+
+	TRACE(("enter cli_auth_pubkey"))
+
+	if (cli_opts.privkeys != NULL) {
+		/* Send a trial request */
+		send_msg_userauth_pubkey(cli_opts.privkeys->key,
+				cli_opts.privkeys->type, 0);
+		cli_ses.lastprivkey = cli_opts.privkeys;
+		TRACE(("leave cli_auth_pubkey-success"))
+		return 1;
+	} else {
+		TRACE(("leave cli_auth_pubkey-failure"))
+		return 0;
+	}
+}
+#endif /* Pubkey auth */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-channel.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,62 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002-2004 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 "channel.h"
+#include "buffer.h"
+#include "circbuffer.h"
+#include "dbutil.h"
+#include "session.h"
+#include "ssh.h"
+
+/* We receive channel data - only used by the client chansession code*/
+void recv_msg_channel_extended_data() {
+
+	struct Channel *channel;
+	unsigned int datatype;
+
+	TRACE(("enter recv_msg_channel_extended_data"))
+
+	channel = getchannel();
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+
+	if (channel->type != &clichansess) {
+		TRACE(("leave recv_msg_channel_extended_data: chantype is wrong"))
+		return; /* we just ignore it */
+	}
+
+	datatype = buf_getint(ses.payload);
+	
+	if (datatype != SSH_EXTENDED_DATA_STDERR) {
+		TRACE(("leave recv_msg_channel_extended_data: wrong datatype: %d",
+					datatype))
+		return;	
+	}
+
+	common_recv_msg_channel_data(channel, channel->errfd, channel->extrabuf);
+
+	TRACE(("leave recv_msg_channel_extended_data"))
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-chansession.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,380 @@
+/*
+ * 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"
+#include "session.h"
+#include "dbutil.h"
+#include "channel.h"
+#include "ssh.h"
+#include "runopts.h"
+#include "termcodes.h"
+#include "chansession.h"
+
+static void cli_closechansess(struct Channel *channel);
+static int cli_initchansess(struct Channel *channel);
+static void cli_chansessreq(struct Channel *channel);
+
+static void start_channel_request(struct Channel *channel, unsigned char *type);
+
+static void send_chansess_pty_req(struct Channel *channel);
+static void send_chansess_shell_req(struct Channel *channel);
+
+static void cli_tty_setup();
+
+const struct ChanType clichansess = {
+	0, /* sepfds */
+	"session", /* name */
+	cli_initchansess, /* inithandler */
+	NULL, /* checkclosehandler */
+	cli_chansessreq, /* reqhandler */
+	cli_closechansess, /* closehandler */
+};
+
+static void cli_chansessreq(struct Channel *channel) {
+
+	unsigned char* type = NULL;
+	int wantreply;
+
+	TRACE(("enter cli_chansessreq"))
+
+	type = buf_getstring(ses.payload, NULL);
+	wantreply = buf_getbool(ses.payload);
+
+	if (strcmp(type, "exit-status") != 0) {
+		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))
+
+out:
+	m_free(type);
+}
+	
+
+/* If the main session goes, we close it up */
+static void cli_closechansess(struct Channel *UNUSED(channel)) {
+
+	/* This channel hasn't gone yet, so we have > 1 */
+	if (ses.chancount > 1) {
+		dropbear_log(LOG_INFO, "Waiting for other channels to close...");
+	}
+
+	cli_tty_cleanup(); /* Restore tty modes etc */
+
+}
+
+static void start_channel_request(struct Channel *channel, 
+		unsigned char *type) {
+
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	buf_putstring(ses.writepayload, type, strlen(type));
+
+}
+
+/* Taken from OpenSSH's sshtty.c:
+ * RCSID("OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp "); */
+static void cli_tty_setup() {
+
+	struct termios tio;
+
+	TRACE(("enter cli_pty_setup"))
+
+	if (cli_ses.tty_raw_mode == 1) {
+		TRACE(("leave cli_tty_setup: already in raw mode!"))
+		return;
+	}
+
+	if (tcgetattr(STDIN_FILENO, &tio) == -1) {
+		dropbear_exit("Failed to set raw TTY mode");
+	}
+
+	/* make a copy */
+	cli_ses.saved_tio = tio;
+
+	tio.c_iflag |= IGNPAR;
+	tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
+#ifdef IUCLC
+	tio.c_iflag &= ~IUCLC;
+#endif
+	tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
+#ifdef IEXTEN
+	tio.c_lflag &= ~IEXTEN;
+#endif
+	tio.c_oflag &= ~OPOST;
+	tio.c_cc[VMIN] = 1;
+	tio.c_cc[VTIME] = 0;
+	if (tcsetattr(STDIN_FILENO, TCSADRAIN, &tio) == -1) {
+		dropbear_exit("Failed to set raw TTY mode");
+	}
+
+	cli_ses.tty_raw_mode = 1;
+	TRACE(("leave cli_tty_setup"))
+}
+
+void cli_tty_cleanup() {
+
+	TRACE(("enter cli_tty_cleanup"))
+
+	if (cli_ses.tty_raw_mode == 0) {
+		TRACE(("leave cli_tty_cleanup: not in raw mode"))
+		return;
+	}
+
+	if (tcsetattr(STDIN_FILENO, TCSADRAIN, &cli_ses.saved_tio) == -1) {
+		dropbear_log(LOG_WARNING, "Failed restoring TTY");
+	} else {
+		cli_ses.tty_raw_mode = 0; 
+	}
+
+	TRACE(("leave cli_tty_cleanup"))
+}
+
+static void put_termcodes() {
+
+	struct termios tio;
+	unsigned int sshcode;
+	const struct TermCode *termcode;
+	unsigned int value;
+	unsigned int mapcode;
+
+	unsigned int bufpos1, bufpos2;
+
+	TRACE(("enter put_termcodes"))
+
+	if (tcgetattr(STDIN_FILENO, &tio) == -1) {
+		dropbear_log(LOG_WARNING, "Failed reading termmodes");
+		buf_putint(ses.writepayload, 1); /* Just the terminator */
+		buf_putbyte(ses.writepayload, 0); /* TTY_OP_END */
+		return;
+	}
+
+	bufpos1 = ses.writepayload->pos;
+	buf_putint(ses.writepayload, 0); /* A placeholder for the final length */
+
+	/* As with Dropbear server, we ignore baud rates for now */
+	for (sshcode = 1; sshcode < MAX_TERMCODE; sshcode++) {
+
+		termcode = &termcodes[sshcode];
+		mapcode = termcode->mapcode;
+
+		switch (termcode->type) {
+
+			case TERMCODE_NONE:
+				continue;
+
+			case TERMCODE_CONTROLCHAR:
+				value = tio.c_cc[mapcode];
+				break;
+
+			case TERMCODE_INPUT:
+				value = tio.c_iflag & mapcode;
+				break;
+
+			case TERMCODE_OUTPUT:
+				value = tio.c_oflag & mapcode;
+				break;
+
+			case TERMCODE_LOCAL:
+				value = tio.c_lflag & mapcode;
+				break;
+
+			case TERMCODE_CONTROL:
+				value = tio.c_cflag & mapcode;
+				break;
+
+			default:
+				continue;
+
+		}
+
+		/* If we reach here, we have something to say */
+		buf_putbyte(ses.writepayload, sshcode);
+		buf_putint(ses.writepayload, value);
+	}
+
+	buf_putbyte(ses.writepayload, 0); /* THE END, aka TTY_OP_END */
+
+	/* Put the string length at the start of the buffer */
+	bufpos2 = ses.writepayload->pos;
+
+	buf_setpos(ses.writepayload, bufpos1); /* Jump back */
+	buf_putint(ses.writepayload, bufpos2 - bufpos1 - 4); /* len(termcodes) */
+	buf_setpos(ses.writepayload, bufpos2); /* Back where we were */
+
+	TRACE(("leave put_termcodes"))
+}
+
+static void put_winsize() {
+
+	struct winsize ws;
+
+	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) {
+		/* Some sane defaults */
+		ws.ws_row = 25;
+		ws.ws_col = 80;
+		ws.ws_xpixel = 0;
+		ws.ws_ypixel = 0;
+	}
+
+	buf_putint(ses.writepayload, ws.ws_col); /* Cols */
+	buf_putint(ses.writepayload, ws.ws_row); /* Rows */
+	buf_putint(ses.writepayload, ws.ws_xpixel); /* Width */
+	buf_putint(ses.writepayload, ws.ws_ypixel); /* Height */
+
+}
+
+static void sigwinch_handler(int UNUSED(unused)) {
+
+	cli_ses.winchange = 1;
+
+}
+
+void cli_chansess_winchange() {
+
+	unsigned int i;
+	struct Channel *channel = NULL;
+
+	for (i = 0; i < ses.chansize; i++) {
+		channel = ses.channels[i];
+		if (channel != NULL && channel->type == &clichansess) {
+			CHECKCLEARTOWRITE();
+			buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
+			buf_putint(ses.writepayload, channel->remotechan);
+			buf_putstring(ses.writepayload, "window-change", 13);
+			buf_putbyte(ses.writepayload, 0); /* FALSE says the spec */
+			put_winsize();
+			encrypt_packet();
+		}
+	}
+	cli_ses.winchange = 0;
+}
+
+static void send_chansess_pty_req(struct Channel *channel) {
+
+	unsigned char* term = NULL;
+
+	TRACE(("enter send_chansess_pty_req"))
+
+	start_channel_request(channel, "pty-req");
+
+	/* Don't want replies */
+	buf_putbyte(ses.writepayload, 0);
+
+	/* Get the terminal */
+	term = getenv("TERM");
+	if (term == NULL) {
+		term = "vt100"; /* Seems a safe default */
+	}
+	buf_putstring(ses.writepayload, term, strlen(term));
+
+	/* Window size */
+	put_winsize();
+
+	/* Terminal mode encoding */
+	put_termcodes();
+
+	encrypt_packet();
+
+	/* Set up a window-change handler */
+	if (signal(SIGWINCH, sigwinch_handler) == SIG_ERR) {
+		dropbear_exit("signal error");
+	}
+	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"))
+
+	if (cli_opts.cmd) {
+		reqtype = "exec";
+	} else {
+		reqtype = "shell";
+	}
+
+	start_channel_request(channel, reqtype);
+
+	/* XXX TODO */
+	buf_putbyte(ses.writepayload, 0); /* Don't want replies */
+	if (cli_opts.cmd) {
+		buf_putstring(ses.writepayload, cli_opts.cmd, strlen(cli_opts.cmd));
+	}
+
+	encrypt_packet();
+	TRACE(("leave send_chansess_shell_req"))
+}
+
+static int cli_initchansess(struct Channel *channel) {
+
+
+	channel->writefd = STDOUT_FILENO;
+	setnonblocking(STDOUT_FILENO);
+
+	channel->readfd = STDIN_FILENO;
+	setnonblocking(STDIN_FILENO);
+
+	channel->errfd = STDERR_FILENO;
+	setnonblocking(STDERR_FILENO);
+
+	channel->extrabuf = cbuf_new(RECV_MAXWINDOW);
+
+	if (cli_opts.wantpty) {
+		send_chansess_pty_req(channel);
+	}
+
+	send_chansess_shell_req(channel);
+
+	if (cli_opts.wantpty) {
+		cli_tty_setup();
+	}
+
+	return 0; /* Success */
+
+}
+
+void 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");
+	}
+
+	/* No special channel request data */
+	encrypt_packet();
+	TRACE(("leave cli_send_chansess_request"))
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-kex.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,298 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * 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
+ * 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"
+#include "signkey.h"
+
+
+static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen);
+#define MAX_KNOWNHOSTS_LINE 4500
+
+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();
+	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() {
+
+	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))
+
+	hostkey = new_sign_key();
+	keybloblen = buf_getint(ses.payload);
+
+	keyblob = buf_getptr(ses.payload, keybloblen);
+	if (!ses.kexstate.donefirstkex) {
+		/* Only makes sense the first time */
+		checkhostkey(keyblob, keybloblen);
+	}
+
+	if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
+		TRACE(("failed getting pubkey"))
+		dropbear_exit("Bad KEX packet");
+	}
+
+	if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
+		TRACE(("failed getting mpint"))
+		dropbear_exit("Bad KEX packet");
+	}
+
+	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) {
+		dropbear_exit("Bad hostkey signature");
+	}
+
+	sign_key_free(hostkey);
+	hostkey = NULL;
+
+	send_msg_newkeys();
+	ses.requirenext = SSH_MSG_NEWKEYS;
+	TRACE(("leave recv_msg_kexdh_init"))
+}
+
+static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
+
+	char* fp = NULL;
+	FILE *tty = NULL;
+	char response = 'z';
+
+	fp = sign_key_fingerprint(keyblob, keybloblen);
+	fprintf(stderr, "\nHost '%s' is not in the trusted hosts file.\n(fingerprint %s)\nDo you want to continue connecting? (y/n)\n", 
+			cli_opts.remotehost, 
+			fp);
+	m_free(fp);
+
+	tty = fopen(_PATH_TTY, "r");
+	if (tty) {
+		response = getc(tty);
+		fclose(tty);
+	} else {
+		response = getc(stdin);
+	}
+
+	if (response == 'y') {
+		return;
+	}
+
+	dropbear_exit("Didn't validate host key");
+}
+
+static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
+
+	char * filename = NULL;
+	FILE *hostsfile = NULL;
+	int readonly = 0;
+	struct passwd *pw = NULL;
+	char * homedir = NULL;
+	unsigned int hostlen, algolen;
+	unsigned long len;
+	const char *algoname = NULL;
+	buffer * line = NULL;
+	int ret;
+	
+	homedir = getenv("HOME");
+
+	if (!homedir) {
+		pw = getpwuid(getuid());
+		if (pw) {
+			homedir = pw->pw_dir;
+		}
+		pw = NULL;
+	}
+
+	if (homedir) {
+
+		len = strlen(homedir);
+		filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/
+
+		snprintf(filename, len+18, "%s/.ssh", homedir);
+		/* Check that ~/.ssh exists - easiest way is just to mkdir */
+		if (mkdir(filename, S_IRWXU) != 0) {
+			if (errno != EEXIST) {
+				dropbear_log(LOG_INFO, "Warning: failed creating %s/.ssh: %s",
+						homedir, strerror(errno));
+				TRACE(("mkdir didn't work: %s", strerror(errno)))
+				ask_to_confirm(keyblob, keybloblen);
+				goto out; /* only get here on success */
+			}
+		}
+
+		snprintf(filename, len+18, "%s/.ssh/known_hosts", homedir);
+		hostsfile = fopen(filename, "a+");
+		
+		if (hostsfile != NULL) {
+			fseek(hostsfile, 0, SEEK_SET);
+		} 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)))
+					readonly = 1;
+					hostsfile = fopen(filename, "r");
+			}
+		}
+	}
+
+	if (hostsfile == NULL) {
+		TRACE(("hostsfile didn't open: %s", strerror(errno)))
+		dropbear_log(LOG_WARNING, "Failed to open %s/.ssh/known_hosts",
+				homedir);
+		ask_to_confirm(keyblob, keybloblen);
+		goto out; /* We only get here on success */
+	}
+
+	line = buf_new(MAX_KNOWNHOSTS_LINE);
+	hostlen = strlen(cli_opts.remotehost);
+	algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &algolen);
+
+	do {
+		if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) {
+			TRACE(("failed reading line: prob EOF"))
+			break;
+		}
+
+		/* The line is too short to be sensible */
+		/* "30" is 'enough to hold ssh-dss plus the spaces, ie so we don't
+		 * 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"))
+			continue;
+		}
+
+		/* Compare hostnames */
+		if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen),
+					hostlen) != 0) {
+			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"))
+			continue;
+		}
+
+		if ( strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) {
+			TRACE(("algo doesn't match"))
+			continue;
+		}
+
+		buf_incrpos(line, algolen);
+		if (buf_getbyte(line) != ' ') {
+			TRACE(("missing space after algo"))
+			continue;
+		}
+
+		/* Now we're at the interesting hostkey */
+		ret = cmp_base64_key(keyblob, keybloblen, algoname, algolen, line);
+
+		if (ret == DROPBEAR_SUCCESS) {
+			/* Good matching key */
+			TRACE(("good matching key"))
+			goto out;
+		}
+
+		/* The keys didn't match. eep. */
+	} while (1); /* keep going 'til something happens */
+
+	/* Key doesn't exist yet */
+	ask_to_confirm(keyblob, keybloblen);
+
+	/* If we get here, they said yes */
+
+	if (readonly) {
+		TRACE(("readonly"))
+		goto out;
+	}
+
+	/* put the new entry in the file */
+	fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */
+	buf_setpos(line, 0);
+	buf_setlen(line, 0);
+	buf_putbytes(line, ses.remotehost, hostlen);
+	buf_putbyte(line, ' ');
+	buf_putbytes(line, algoname, algolen);
+	buf_putbyte(line, ' ');
+	len = line->size - line->pos;
+	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);
+	buf_incrwritepos(line, len);
+	buf_putbyte(line, '\n');
+	buf_setpos(line, 0);
+	fwrite(buf_getptr(line, line->len), line->len, 1, hostsfile);
+	/* We ignore errors, since there's not much we can do about them */
+
+out:
+	if (hostsfile != NULL) {
+		fclose(hostsfile);
+	}
+	m_free(filename);
+	if (line != NULL) {
+		buf_free(line);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-main.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,112 @@
+/*
+ * 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"
+#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;
+	char* hostandport;
+	int len;
+
+	_dropbear_exit = cli_dropbear_exit;
+	_dropbear_log = cli_dropbear_log;
+
+	cli_getopts(argc, argv);
+
+	TRACE(("user='%s' host='%s' port='%s'", cli_opts.username,
+				cli_opts.remotehost, cli_opts.remoteport))
+
+	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+		dropbear_exit("signal() error");
+	}
+
+	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:%s", 
+			cli_opts.remotehost, cli_opts.remoteport);
+
+	cli_session(sock, hostandport);
+
+	/* 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);
+	}
+
+	/* Do the cleanup first, since then the terminal will be reset */
+	cli_session_cleanup();
+	common_session_cleanup();
+
+	_dropbear_log(LOG_INFO, fmtbuf, param);
+
+	exit(exitcode);
+}
+
+static void cli_dropbear_log(int UNUSED(priority), 
+		const char* format, va_list param) {
+
+	char printbuf[1024];
+
+	vsnprintf(printbuf, sizeof(printbuf), format, param);
+
+	fprintf(stderr, "%s: %s\n", cli_opts.progname, printbuf);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-runopts.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,429 @@
+/*
+ * 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"
+#include "signkey.h"
+#include "buffer.h"
+#include "dbutil.h"
+#include "algo.h"
+#include "tcpfwd.h"
+
+cli_runopts cli_opts; /* GLOBAL */
+
+static void printhelp();
+static void parsehostname(char* userhostarg);
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+static void loadidentityfile(const char* filename);
+#endif
+#ifdef ENABLE_CLI_ANYTCPFWD
+static void addforward(char* str, struct TCPFwdList** fwdlist);
+#endif
+
+static void printhelp() {
+
+	fprintf(stderr, "Dropbear client v%s\n"
+					"Usage: %s [options] [user@]host [command]\n"
+					"Options are:\n"
+					"-p <remoteport>\n"
+					"-l <username>\n"
+					"-t    Allocate a pty\n"
+					"-T    Don't allocate a pty\n"
+					"-N    Don't run a remote command\n"
+					"-f    Run in background after auth\n"
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+					"-i <identityfile>   (multiple allowed)\n"
+#endif
+#ifdef ENABLE_CLI_LOCALTCPFWD
+					"-L <listenport:remotehost:remoteport> Local port forwarding\n"
+					"-g    Allow remote hosts to connect to forwarded ports\n"
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+					"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
+#endif
+#ifdef DEBUG_TRACE
+					"-v    verbose\n"
+#endif
+					,DROPBEAR_VERSION, cli_opts.progname);
+}
+
+void cli_getopts(int argc, char ** argv) {
+
+	unsigned int i, j;
+	char ** next = 0;
+	unsigned int cmdlen;
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	int nextiskey = 0; /* A flag if the next argument is a keyfile */
+#endif
+#ifdef ENABLE_CLI_LOCALTCPFWD
+	int nextislocal = 0;
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+	int nextisremote = 0;
+#endif
+	char* dummy = NULL; /* Not used for anything real */
+
+	/* see printhelp() for options */
+	cli_opts.progname = argv[0];
+	cli_opts.remotehost = NULL;
+	cli_opts.remoteport = NULL;
+	cli_opts.username = NULL;
+	cli_opts.cmd = NULL;
+	cli_opts.no_cmd = 0;
+	cli_opts.backgrounded = 0;
+	cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	cli_opts.privkeys = NULL;
+#endif
+#ifdef ENABLE_CLI_LOCALTCPFWD
+	cli_opts.localfwds = NULL;
+	opts.listen_fwd_all = 0;
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+	cli_opts.remotefwds = NULL;
+#endif
+	/* not yet
+	opts.ipv4 = 1;
+	opts.ipv6 = 1;
+	*/
+
+	/* Iterate all the arguments */
+	for (i = 1; i < (unsigned int)argc; i++) {
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+		if (nextiskey) {
+			/* Load a hostkey since the previous argument was "-i" */
+			loadidentityfile(argv[i]);
+			nextiskey = 0;
+			continue;
+		}
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+		if (nextisremote) {
+			TRACE(("nextisremote true"))
+			addforward(argv[i], &cli_opts.remotefwds);
+			nextisremote = 0;
+			continue;
+		}
+#endif
+#ifdef ENABLE_CLI_LOCALTCPFWD
+		if (nextislocal) {
+			TRACE(("nextislocal true"))
+			addforward(argv[i], &cli_opts.localfwds);
+			nextislocal = 0;
+			continue;
+		}
+#endif
+		if (next) {
+			/* The previous flag set a value to assign */
+			*next = argv[i];
+			if (*next == NULL) {
+				dropbear_exit("Invalid null argument");
+			}
+			next = NULL;
+			continue;
+		}
+
+		if (argv[i][0] == '-') {
+			/* A flag *waves* */
+
+			switch (argv[i][1]) {
+				case 'p': /* remoteport */
+					next = &cli_opts.remoteport;
+					break;
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+				case 'i': /* an identityfile */
+					/* Keep scp happy when it changes "-i file" to "-ifile" */
+					if (strlen(argv[i]) > 2) {
+						loadidentityfile(&argv[i][2]);
+					} else  {
+						nextiskey = 1;
+					}
+					break;
+#endif
+				case 't': /* we want a pty */
+					cli_opts.wantpty = 1;
+					break;
+				case 'T': /* don't want a pty */
+					cli_opts.wantpty = 0;
+					break;
+				case 'N':
+					cli_opts.no_cmd = 1;
+					break;
+				case 'f':
+					cli_opts.backgrounded = 1;
+					break;
+#ifdef ENABLE_CLI_LOCALTCPFWD
+				case 'L':
+					nextislocal = 1;
+					break;
+				case 'g':
+					opts.listen_fwd_all = 1;
+					break;
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+				case 'R':
+					nextisremote = 1;
+					break;
+#endif
+				case 'l':
+					next = &cli_opts.username;
+					break;
+				case 'h':
+					printhelp();
+					exit(EXIT_SUCCESS);
+					break;
+#ifdef DEBUG_TRACE
+				case 'v':
+					debug_trace = 1;
+					break;
+#endif
+				case 'F':
+				case 'e':
+				case 'c':
+				case 'm':
+				case 'D':
+#ifndef ENABLE_CLI_REMOTETCPFWD
+				case 'R':
+#endif
+#ifndef ENABLE_CLI_LOCALTCPFWD
+				case 'L':
+#endif
+				case 'o':
+				case 'b':
+					next = &dummy;
+				default:
+					fprintf(stderr, 
+						"WARNING: Ignoring unknown argument '%s'\n", argv[i]);
+					break;
+			} /* Switch */
+			
+			/* Now we handle args where they might be "-luser" (no spaces)*/
+			if (next && strlen(argv[i]) > 2) {
+				*next = &argv[i][2];
+				next = NULL;
+			}
+
+			continue; /* next argument */
+
+		} else {
+			TRACE(("non-flag arg: '%s'", argv[i]))
+
+			/* Either the hostname or commands */
+
+			if (cli_opts.remotehost == NULL) {
+
+				parsehostname(argv[i]);
+
+			} else {
+
+				/* this is part of the commands to send - after this we
+				 * don't parse any more options, and flags are sent as the
+				 * command */
+				cmdlen = 0;
+				for (j = i; j < (unsigned int)argc; j++) {
+					cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
+				}
+				/* Allocate the space */
+				cli_opts.cmd = (char*)m_malloc(cmdlen);
+				cli_opts.cmd[0] = '\0';
+
+				/* Append all the bits */
+				for (j = i; j < (unsigned int)argc; j++) {
+					strlcat(cli_opts.cmd, argv[j], cmdlen);
+					strlcat(cli_opts.cmd, " ", cmdlen);
+				}
+				/* It'll be null-terminated here */
+
+				/* We've eaten all the options and flags */
+				break;
+			}
+		}
+	}
+
+	if (cli_opts.remotehost == NULL) {
+		printhelp();
+		exit(EXIT_FAILURE);
+	}
+
+	if (cli_opts.remoteport == NULL) {
+		cli_opts.remoteport = "22";
+	}
+
+	/* If not explicitly specified with -t or -T, we don't want a pty if
+	 * there's a command, but we do otherwise */
+	if (cli_opts.wantpty == 9) {
+		if (cli_opts.cmd == NULL) {
+			cli_opts.wantpty = 1;
+		} else {
+			cli_opts.wantpty = 0;
+		}
+	}
+
+	if (cli_opts.backgrounded && cli_opts.cmd == NULL
+			&& cli_opts.no_cmd == 0) {
+		dropbear_exit("command required for -f");
+	}
+}
+
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+static void loadidentityfile(const char* filename) {
+
+	struct SignKeyList * nextkey;
+	sign_key *key;
+	int keytype;
+
+	key = new_sign_key();
+	keytype = DROPBEAR_SIGNKEY_ANY;
+	if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) {
+
+		fprintf(stderr, "Failed loading keyfile '%s'\n", filename);
+		sign_key_free(key);
+
+	} else {
+
+		nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
+		nextkey->key = key;
+		nextkey->next = cli_opts.privkeys;
+		nextkey->type = keytype;
+		cli_opts.privkeys = nextkey;
+	}
+}
+#endif
+
+
+/* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding
+ * - note that it will be modified */
+static void parsehostname(char* orighostarg) {
+
+	uid_t uid;
+	struct passwd *pw = NULL; 
+	char *userhostarg = NULL;
+
+	/* We probably don't want to be editing argvs */
+	userhostarg = m_strdup(orighostarg);
+
+	cli_opts.remotehost = strchr(userhostarg, '@');
+	if (cli_opts.remotehost == NULL) {
+		/* no username portion, the cli-auth.c code can figure the
+		 * local user's name */
+		cli_opts.remotehost = userhostarg;
+	} else {
+		cli_opts.remotehost[0] = '\0'; /* Split the user/host */
+		cli_opts.remotehost++;
+		cli_opts.username = userhostarg;
+	}
+
+	if (cli_opts.username == NULL) {
+		uid = getuid();
+		
+		pw = getpwuid(uid);
+		if (pw == NULL || pw->pw_name == NULL) {
+			dropbear_exit("Unknown own user");
+		}
+
+		cli_opts.username = m_strdup(pw->pw_name);
+	}
+
+	if (cli_opts.remotehost[0] == '\0') {
+		dropbear_exit("Bad hostname");
+	}
+}
+
+#ifdef ENABLE_CLI_ANYTCPFWD
+/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
+ * set, and add it to the forwarding list */
+static void addforward(char* origstr, struct TCPFwdList** fwdlist) {
+
+	char * listenport = NULL;
+	char * connectport = NULL;
+	char * connectaddr = NULL;
+	struct TCPFwdList* newfwd = NULL;
+	char * str = NULL;
+
+	TRACE(("enter addforward"))
+
+	/* We probably don't want to be editing argvs */
+	str = m_strdup(origstr);
+
+	listenport = str;
+
+	connectaddr = strchr(str, ':');
+	if (connectaddr == NULL) {
+		TRACE(("connectaddr == NULL"))
+		goto fail;
+	}
+
+	connectaddr[0] = '\0';
+	connectaddr++;
+
+	connectport = strchr(connectaddr, ':');
+	if (connectport == NULL) {
+		TRACE(("connectport == NULL"))
+		goto fail;
+	}
+
+	connectport[0] = '\0';
+	connectport++;
+
+	newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList));
+
+	/* Now we check the ports - note that the port ints are unsigned,
+	 * the check later only checks for >= MAX_PORT */
+	newfwd->listenport = strtol(listenport, NULL, 10);
+	if (errno != 0) {
+		TRACE(("bad listenport strtol"))
+		goto fail;
+	}
+
+	newfwd->connectport = strtol(connectport, NULL, 10);
+	if (errno != 0) {
+		TRACE(("bad connectport strtol"))
+		goto fail;
+	}
+
+	newfwd->connectaddr = connectaddr;
+
+	if (newfwd->listenport > 65535) {
+		TRACE(("listenport > 65535"))
+		goto badport;
+	}
+		
+	if (newfwd->connectport > 65535) {
+		TRACE(("connectport > 65535"))
+		goto badport;
+	}
+
+	newfwd->next = *fwdlist;
+	*fwdlist = newfwd;
+
+	TRACE(("leave addforward: done"))
+	return;
+
+fail:
+	dropbear_exit("Bad TCP forward '%s'", origstr);
+
+badport:
+	dropbear_exit("Bad TCP port in '%s'", origstr);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-service.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,85 @@
+/*
+ * 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"
+#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.writepayload, SSH_MSG_SERVICE_REQUEST);
+	buf_putstring(ses.writepayload, 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");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-session.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,322 @@
+/*
+ * 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"
+#include "kex.h"
+#include "ssh.h"
+#include "packet.h"
+#include "tcpfwd.h"
+#include "channel.h"
+#include "random.h"
+#include "service.h"
+#include "runopts.h"
+#include "chansession.h"
+
+static void cli_remoteclosed();
+static void cli_sessionloop();
+static void cli_session_init();
+static void cli_finished();
+
+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, FUNCTION */
+	{SSH_MSG_CHANNEL_DATA, recv_msg_channel_data},
+	{SSH_MSG_CHANNEL_EXTENDED_DATA, recv_msg_channel_extended_data},
+	{SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust},
+	{SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, /* client */
+	{SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, /* client */
+	{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_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},
+	{SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, /* client */
+	{SSH_MSG_USERAUTH_SPECIFIC_60, recv_msg_userauth_specific_60}, /* client */
+	{0, 0} /* End */
+};
+
+static const struct ChanType *cli_chantypes[] = {
+#ifdef ENABLE_CLI_REMOTETCPFWD
+	&cli_chan_tcpremote,
+#endif
+	NULL /* Null termination */
+};
+
+void cli_session(int sock, char* remotehost) {
+
+	seedrandom();
+
+	crypto_init();
+
+	common_session_init(sock, remotehost);
+
+	chaninitialise(cli_chantypes);
+
+	/* Set up cli_ses vars */
+	cli_session_init();
+
+	/* Ready to go */
+	sessinitdone = 1;
+
+	/* Exchange identification */
+	session_identification();
+
+	send_msg_kexinit();
+
+	session_loop(cli_sessionloop);
+
+	/* Not reached */
+
+}
+
+static void cli_session_init() {
+
+	cli_ses.state = STATE_NOTHING;
+	cli_ses.kex_state = KEX_NOTHING;
+
+	cli_ses.tty_raw_mode = 0;
+	cli_ses.winchange = 0;
+
+	/* We store std{in,out,err}'s flags, so we can set them back on exit
+	 * (otherwise busybox's ash isn't happy */
+	cli_ses.stdincopy = dup(STDIN_FILENO);
+	cli_ses.stdinflags = fcntl(STDIN_FILENO, F_GETFL, 0);
+	cli_ses.stdoutcopy = dup(STDOUT_FILENO);
+	cli_ses.stdoutflags = fcntl(STDOUT_FILENO, F_GETFL, 0);
+	cli_ses.stderrcopy = dup(STDERR_FILENO);
+	cli_ses.stderrflags = fcntl(STDERR_FILENO, F_GETFL, 0);
+
+	cli_ses.retval = EXIT_SUCCESS; /* Assume it's clean if we don't get a
+									  specific exit status */
+
+	/* Auth */
+	cli_ses.lastprivkey = NULL;
+	cli_ses.lastauthtype = 0;
+
+	/* 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;
+
+	ses.isserver = 0;
+}
+
+/* This function drives the progress of the session - it initiates KEX,
+ * service, userauth and channel requests */
+static void cli_sessionloop() {
+
+	TRACE(("enter cli_sessionloop"))
+
+	if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) {
+		cli_ses.kex_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. */
+		send_msg_kexdh_init();
+		cli_ses.kex_state = KEXDH_INIT_SENT;
+		TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD"))
+		return;
+	}
+
+	/* 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"))
+		return;
+	}
+
+	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;
+			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"))
+			return;
+			
+		case USERAUTH_FAIL_RCVD:
+			cli_auth_try();
+			cli_ses.state = USERAUTH_REQ_SENT;
+			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"))
+			return;
+
+		case SERVICE_CONN_ACCEPT_RCVD:
+			cli_send_chansess_request();
+			TRACE(("leave cli_sessionloop: cli_send_chansess_request"))
+			cli_ses.state = SESSION_RUNNING;
+			return;
+			*/
+
+		case USERAUTH_SUCCESS_RCVD:
+
+			if (cli_opts.backgrounded) {
+				int devnull;
+				// keeping stdin open steals input from the terminal and
+				// is confusing, though stdout/stderr could be useful.
+				devnull = open(_PATH_DEVNULL, O_RDONLY);
+				if (devnull < 0) {
+					dropbear_exit("opening /dev/null: %d %s",
+							errno, strerror(errno));
+				}
+				dup2(devnull, STDIN_FILENO);
+				if (daemon(0, 1) < 0) {
+					dropbear_exit("Backgrounding failed: %d %s", 
+							errno, strerror(errno));
+				}
+			}
+			
+#ifdef ENABLE_CLI_LOCALTCPFWD
+			setup_localtcp();
+#endif
+#ifdef ENABLE_CLI_REMOTETCPFWD
+			setup_remotetcp();
+#endif
+			if (!cli_opts.no_cmd) {
+				cli_send_chansess_request();
+			}
+			TRACE(("leave cli_sessionloop: running"))
+			cli_ses.state = SESSION_RUNNING;
+			return;
+
+		case SESSION_RUNNING:
+			if (ses.chancount < 1 && !cli_opts.no_cmd) {
+				cli_finished();
+			}
+
+			if (cli_ses.winchange) {
+				cli_chansess_winchange();
+			}
+			return;
+
+		/* XXX more here needed */
+
+
+	default:
+		break;
+	}
+
+	TRACE(("leave cli_sessionloop: fell out"))
+
+}
+
+void cli_session_cleanup() {
+
+	if (!sessinitdone) {
+		return;
+	}
+
+	/* Set std{in,out,err} back to non-blocking - busybox ash dies nastily if
+	 * we don't revert the flags */
+	fcntl(cli_ses.stdincopy, F_SETFL, cli_ses.stdinflags);
+	fcntl(cli_ses.stdoutcopy, F_SETFL, cli_ses.stdoutflags);
+	fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags);
+
+	cli_tty_cleanup();
+
+}
+
+static void cli_finished() {
+
+	cli_session_cleanup();
+	common_session_cleanup();
+	fprintf(stderr, "Connection to %s@%s:%s closed.\n", cli_opts.username,
+			cli_opts.remotehost, cli_opts.remoteport);
+	exit(cli_ses.retval);
+}
+
+
+/* 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("remote closed the connection");
+}
+
+/* Operates in-place turning dirty (untrusted potentially containing control
+ * characters) text into clean text. 
+ * Note: this is safe only with ascii - other charsets could have problems. */
+void cleantext(unsigned char* dirtytext) {
+
+	unsigned int i, j;
+	unsigned char c;
+
+	j = 0;
+	for (i = 0; dirtytext[i] != '\0'; i++) {
+
+		c = dirtytext[i];
+		/* We can ignore '\r's */
+		if ( (c >= ' ' && c <= '~') || c == '\n' || c == '\t') {
+			dirtytext[j] = c;
+			j++;
+		}
+	}
+	/* Null terminate */
+	dirtytext[j] = '\0';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-tcpfwd.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,216 @@
+/*
+ * 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"
+#include "tcpfwd.h"
+#include "channel.h"
+#include "runopts.h"
+#include "session.h"
+#include "ssh.h"
+
+#ifdef ENABLE_CLI_REMOTETCPFWD
+static int newtcpforwarded(struct Channel * channel);
+
+const struct ChanType cli_chan_tcpremote = {
+	1, /* sepfds */
+	"forwarded-tcpip",
+	newtcpforwarded,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+#ifdef ENABLE_CLI_LOCALTCPFWD
+static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
+		unsigned int remoteport);
+static const struct ChanType cli_chan_tcplocal = {
+	1, /* sepfds */
+	"direct-tcpip",
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+#ifdef ENABLE_CLI_LOCALTCPFWD
+void setup_localtcp() {
+
+	int ret;
+
+	TRACE(("enter setup_localtcp"))
+
+	if (cli_opts.localfwds == NULL) {
+		TRACE(("cli_opts.localfwds == NULL"))
+	}
+
+	while (cli_opts.localfwds != NULL) {
+		ret = cli_localtcp(cli_opts.localfwds->listenport,
+				cli_opts.localfwds->connectaddr,
+				cli_opts.localfwds->connectport);
+		if (ret == DROPBEAR_FAILURE) {
+			dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
+					cli_opts.localfwds->listenport,
+					cli_opts.localfwds->connectaddr,
+					cli_opts.localfwds->connectport);
+		}
+
+		cli_opts.localfwds = cli_opts.localfwds->next;
+	}
+	TRACE(("leave setup_localtcp"))
+
+}
+
+static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
+		unsigned int remoteport) {
+
+	struct TCPListener* tcpinfo = NULL;
+	int ret;
+
+	TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr,
+				remoteport));
+
+	tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
+
+	tcpinfo->sendaddr = m_strdup(remoteaddr);
+	tcpinfo->sendport = remoteport;
+
+	if (opts.listen_fwd_all) {
+		tcpinfo->listenaddr = m_strdup("");
+	} else {
+		tcpinfo->listenaddr = m_strdup("localhost");
+	}
+	tcpinfo->listenport = listenport;
+
+	tcpinfo->chantype = &cli_chan_tcplocal;
+	tcpinfo->tcp_type = direct;
+
+	ret = listen_tcpfwd(tcpinfo);
+
+	if (ret == DROPBEAR_FAILURE) {
+		m_free(tcpinfo);
+	}
+	TRACE(("leave cli_localtcp: %d", ret))
+	return ret;
+}
+#endif /* ENABLE_CLI_LOCALTCPFWD */
+
+#ifdef  ENABLE_CLI_REMOTETCPFWD
+static void send_msg_global_request_remotetcp(int port) {
+
+	char* listenspec = NULL;
+	TRACE(("enter send_msg_global_request_remotetcp"))
+
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
+	buf_putstring(ses.writepayload, "tcpip-forward", 13);
+	buf_putbyte(ses.writepayload, 0);
+	if (opts.listen_fwd_all) {
+		listenspec = "";
+	} else {
+		listenspec = "localhost";
+	}
+	/* TODO: IPv6? */;
+	buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
+	buf_putint(ses.writepayload, port);
+
+	encrypt_packet();
+
+	TRACE(("leave send_msg_global_request_remotetcp"))
+}
+
+void setup_remotetcp() {
+
+	struct TCPFwdList * iter = NULL;
+
+	TRACE(("enter setup_remotetcp"))
+
+	if (cli_opts.remotefwds == NULL) {
+		TRACE(("cli_opts.remotefwds == NULL"))
+	}
+
+	iter = cli_opts.remotefwds;
+
+	while (iter != NULL) {
+		send_msg_global_request_remotetcp(iter->listenport);
+		iter = iter->next;
+	}
+	TRACE(("leave setup_remotetcp"))
+}
+
+static int newtcpforwarded(struct Channel * channel) {
+
+	unsigned int origport;
+	struct TCPFwdList * iter = NULL;
+	char portstring[NI_MAXSERV];
+	int sock;
+	int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
+
+	/* We don't care what address they connected to */
+	buf_eatstring(ses.payload);
+
+	origport = buf_getint(ses.payload);
+
+	/* Find which port corresponds */
+	iter = cli_opts.remotefwds;
+
+	while (iter != NULL) {
+		if (origport == iter->listenport) {
+			break;
+		}
+		iter = iter->next;
+	}
+
+	if (iter == NULL) {
+		/* We didn't request forwarding on that port */
+		dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", 
+										origport);
+		goto out;
+	}
+	
+	snprintf(portstring, sizeof(portstring), "%d", iter->connectport);
+	sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
+	if (sock < 0) {
+		TRACE(("leave newtcpdirect: sock failed"))
+		err = SSH_OPEN_CONNECT_FAILED;
+		goto out;
+	}
+
+	ses.maxfd = MAX(ses.maxfd, sock);
+
+	/* We don't set readfd, that will get set after the connection's
+	 * progress succeeds */
+	channel->writefd = sock;
+	channel->initconn = 1;
+	
+	err = SSH_OPEN_IN_PROGRESS;
+
+out:
+	TRACE(("leave newtcpdirect: err %d", err))
+	return err;
+}
+#endif /* ENABLE_CLI_REMOTETCPFWD */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-algo.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,228 @@
+/*
+ * 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 "algo.h"
+#include "dbutil.h"
+
+/* This file (algo.c) organises the ciphers which can be used, and is used to
+ * decide which ciphers/hashes/compression/signing to use during key exchange*/
+
+/* 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};
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+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};
+#endif
+#ifdef DROPBEAR_3DES_CBC
+static const struct dropbear_cipher dropbear_3des = 
+	{&des3_desc, 24, 8};
+#endif
+
+/* used to indicate no encryption, as defined in rfc2410 */
+const struct dropbear_cipher dropbear_nocipher =
+	{NULL, 16, 8}; 
+
+/* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
+   {&hash_desc, keysize, hashsize} */
+
+#ifdef DROPBEAR_SHA1_HMAC
+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};
+#endif
+
+const struct dropbear_hash dropbear_nohash =
+	{NULL, 16, 0}; /* used initially */
+	
+
+/* The following map ssh names to internal values */
+
+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_TWOFISH256_CBC
+	{"twofish256-cbc", 0, (void*)&dropbear_twofish256, 1},
+	{"twofish-cbc", 0, (void*)&dropbear_twofish256, 1},
+#endif
+#ifdef DROPBEAR_TWOFISH128_CBC
+	{"twofish128-cbc", 0, (void*)&dropbear_twofish128, 1},
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+	{"blowfish-cbc", 0, (void*)&dropbear_blowfish, 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
+#ifdef DROPBEAR_MD5_HMAC
+	{"hmac-md5", 0, (void*)&dropbear_md5, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshcompress[] = {
+#ifndef DISABLE_ZLIB
+	{"zlib", DROPBEAR_COMP_ZLIB, NULL, 1},
+#endif
+	{"none", DROPBEAR_COMP_NONE, NULL, 1},
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshhostkey[] = {
+#ifdef DROPBEAR_RSA
+	{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1},
+#endif
+#ifdef DROPBEAR_DSS
+	{"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshkex[] = {
+	{"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1},
+	{NULL, 0, NULL, 0}
+};
+
+
+/* Register the compiled in ciphers.
+ * This should be run before using any of the ciphers/hashes */
+void crypto_init() {
+
+	const struct ltc_cipher_descriptor *regciphers[] = {
+#ifdef DROPBEAR_AES_CBC
+		&aes_desc,
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+		&blowfish_desc,
+#endif
+#ifdef DROPBEAR_TWOFISH_CBC
+		&twofish_desc,
+#endif
+#ifdef DROPBEAR_3DES_CBC
+		&des3_desc,
+#endif
+		NULL
+	};
+
+	const struct ltc_hash_descriptor *reghashes[] = {
+		/* we need sha1 for hostkey stuff regardless */
+		&sha1_desc,
+#ifdef DROPBEAR_MD5_HMAC
+		&md5_desc,
+#endif
+		NULL
+	};	
+	int i;
+	
+	for (i = 0; regciphers[i] != NULL; i++) {
+		if (register_cipher(regciphers[i]) == -1) {
+			dropbear_exit("error registering crypto");
+		}
+	}
+
+	for (i = 0; reghashes[i] != NULL; i++) {
+		if (register_hash(reghashes[i]) == -1) {
+			dropbear_exit("error registering crypto");
+		}
+	}
+}
+
+/* algolen specifies the length of algo, algos is our local list to match
+ * against.
+ * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
+ * otherwise */
+int have_algo(char* algo, size_t algolen, algo_type algos[]) {
+
+	int i;
+
+	for (i = 0; algos[i].name != NULL; i++) {
+		if (strlen(algos[i].name) == algolen
+				&& (strncmp(algos[i].name, algo, algolen) == 0)) {
+			return DROPBEAR_SUCCESS;
+		}
+	}
+
+	return DROPBEAR_FAILURE;
+}
+
+
+
+/* Output a comma separated list of algorithms to a buffer */
+void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
+
+	unsigned int i, len;
+	unsigned int donefirst = 0;
+	buffer *algolist = NULL;
+
+	algolist = buf_new(100);
+	for (i = 0; localalgos[i].name != NULL; i++) {
+		if (localalgos[i].usable) {
+			if (donefirst)
+				buf_putbyte(algolist, ',');
+			donefirst = 1;
+			len = strlen(localalgos[i].name);
+			buf_putbytes(algolist, localalgos[i].name, len);
+		}
+	}
+	buf_putstring(buf, algolist->data, algolist->len);
+	buf_free(algolist);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-channel.c	Thu Jan 11 04:29:08 2007 +0000
@@ -0,0 +1,1070 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002-2004 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. */
+
+/* Handle the multiplexed channels, such as sessions, x11, agent connections */
+
+#include "includes.h"
+#include "session.h"
+#include "packet.h"
+#include "ssh.h"
+#include "buffer.h"
+#include "circbuffer.h"
+#include "dbutil.h"
+#include "channel.h"
+#include "ssh.h"
+#include "listener.h"
+
+static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
+		const unsigned char *text, const unsigned char *lang);
+static void send_msg_channel_open_confirmation(struct Channel* channel,
+		unsigned int recvwindow, 
+		unsigned int recvmaxpacket);
+static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf);
+static void send_msg_channel_window_adjust(struct Channel *channel, 
+		unsigned int incr);
+static void send_msg_channel_data(struct Channel *channel, int isextended,
+		unsigned int exttype);
+static void send_msg_channel_eof(struct Channel *channel);
+static void send_msg_channel_close(struct Channel *channel);
+static void removechannel(struct Channel *channel);
+static void deletechannel(struct Channel *channel);
+static void checkinitdone(struct Channel *channel);
+static void checkclose(struct Channel *channel);
+
+static void closewritefd(struct Channel * channel);
+static void closereadfd(struct Channel * channel, int fd);
+static void closechanfd(struct Channel *channel, int fd, int how);
+
+#define FD_UNINIT (-2)
+#define FD_CLOSED (-1)
+
+/* Initialise all the channels */
+void chaninitialise(const struct ChanType *chantypes[]) {
+
+	/* may as well create space for a single channel */
+	ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*));
+	ses.chansize = 1;
+	ses.channels[0] = NULL;
+	ses.chancount = 0;
+
+	ses.chantypes = chantypes;
+
+#ifdef USING_LISTENERS
+	listeners_initialise();
+#endif
+
+}
+
+/* Clean up channels, freeing allocated memory */
+void chancleanup() {
+
+	unsigned int i;
+
+	TRACE(("enter chancleanup"))
+	for (i = 0; i < ses.chansize; i++) {
+		if (ses.channels[i] != NULL) {
+			TRACE(("channel %d closing", i))
+			removechannel(ses.channels[i]);
+		}
+	}
+	m_free(ses.channels);
+	TRACE(("leave chancleanup"))
+}
+
+/* Create a new channel entry, send a reply confirm or failure */
+/* If remotechan, transwindow and transmaxpacket are not know (for a new
+ * outgoing connection, with them to be filled on confirmation), they should
+ * all be set to 0 */
+struct Channel* newchannel(unsigned int remotechan, 
+		const struct ChanType *type, 
+		unsigned int transwindow, unsigned int transmaxpacket) {
+
+	struct Channel * newchan;
+	unsigned int i, j;
+
+	TRACE(("enter newchannel"))
+	
+	/* first see if we can use existing channels */
+	for (i = 0; i < ses.chansize; i++) {
+		if (ses.channels[i] == NULL) {
+			break;
+		}
+	}
+
+	/* otherwise extend the list */
+	if (i == ses.chansize) {
+		if (ses.chansize >= MAX_CHANNELS) {
+			TRACE(("leave newchannel: max chans reached"))
+			return NULL;
+		}
+
+		/* extend the channels */
+		ses.channels = (struct Channel**)m_realloc(ses.channels,
+				(ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
+
+		ses.chansize += CHAN_EXTEND_SIZE;
+
+		/* set the new channels to null */
+		for (j = i; j < ses.chansize; j++) {
+			ses.channels[j] = NULL;
+		}
+
+	}
+	
+	newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
+	newchan->type = type;
+	newchan->index = i;
+	newchan->sentclosed = newchan->recvclosed = 0;
+	newchan->senteof = newchan->recveof = 0;
+
+	newchan->remotechan = remotechan;
+	newchan->transwindow = transwindow;
+	newchan->transmaxpacket = transmaxpacket;
+	
+	newchan->typedata = NULL;
+	newchan->writefd = FD_UNINIT;
+	newchan->readfd = FD_UNINIT;
+	newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
+	newchan->initconn = 0;
+	newchan->await_open = 0;
+
+	newchan->writebuf = cbuf_new(RECV_MAXWINDOW);
+	newchan->extrabuf = NULL; /* The user code can set it up */
+	newchan->recvwindow = RECV_MAXWINDOW;
+	newchan->recvdonelen = 0;
+	newchan->recvmaxpacket = RECV_MAXPACKET;
+
+	ses.channels[i] = newchan;
+	ses.chancount++;
+
+	TRACE(("leave newchannel"))
+
+	return newchan;
+}
+
+/* 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;
+	}
+	return ses.channels[chan];
+}
+
+/* Iterate through the channels, performing IO if available */
+void channelio(fd_set *readfds, fd_set *writefds) {
+
+	struct Channel *channel;
+	unsigned int i;
+	int ret;
+
+	/* iterate through all the possible channels */
+	for (i = 0; i < ses.chansize; i++) {
+
+		channel = ses.channels[i];
+		if (channel == NULL) {
+			/* only process in-use channels */
+			continue;
+		}
+
+		/* read data and send it over the wire */
+		if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
+			send_msg_channel_data(channel, 0, 0);
+		}
+
+		/* read stderr data and send it over the wire */
+		if (channel->extrabuf == NULL &&
+				channel->errfd >= 0 && FD_ISSET(channel->errfd, readfds)) {
+				send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
+		}
+
+		/* if we can read from the writefd, it might be closed, so we try to
+		 * see if it has errors */
+		if (IS_DROPBEAR_SERVER && channel->writefd >= 0 
+				&& channel->writefd != channel->readfd
+				&& FD_ISSET(channel->writefd, readfds)) {
+			if (channel->initconn) {
+				/* Handling for "in progress" connection - this is needed
+				 * to avoid spinning 100% CPU when we connect to a server
+				 * which doesn't send anything (tcpfwding) */
+				checkinitdone(channel);
+				continue; /* Important not to use the channel after 
+							 checkinitdone(), as it may be NULL */
+			}
+			ret = write(channel->writefd, NULL, 0); /* Fake write */
+			if (ret < 0 && errno != EINTR && errno != EAGAIN) {
+				closewritefd(channel);
+			}
+		}
+
+		/* write to program/pipe stdin */
+		if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
+			if (channel->initconn) {
+				checkinitdone(channel);
+				continue; /* Important not to use the channel after
+							 checkinitdone(), as it may be NULL */
+			}
+			writechannel(channel, channel->writefd, channel->writebuf);
+		}
+		
+		/* stderr for client mode */
+		if (channel->extrabuf != NULL 
+				&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
+			writechannel(channel, channel->errfd, channel->extrabuf);
+		}
+	
+		/* now handle any of the channel-closing type stuff */
+		checkclose(channel);
+
+	} /* foreach channel */
+
+	/* Listeners such as TCP, X11, agent-auth */
+#ifdef USING_LISTENERS
+	handle_listeners(readfds);
+#endif
+}
+
+
+/* do all the EOF/close type stuff checking for a channel */
+static void checkclose(struct Channel *channel) {
+
+	TRACE(("checkclose: writefd %d, readfd %d, errfd %d, sentclosed %d, recvclosed %d",
+				channel->writefd, channel->readfd,
+				channel->errfd, channel->sentclosed, channel->recvclosed))
+	TRACE(("writebuf size %d extrabuf ptr 0x%x extrabuf size %d",
+				cbuf_getused(channel->writebuf),
+				channel->writebuf,
+				channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
+
+	/* server chansession channels are special, since readfd mightn't
+	 * close in the case of "sleep 4 & echo blah" until the sleep is up */
+	if (channel->type->checkclose) {
+		if (channel->type->checkclose(channel)) {
+			closewritefd(channel);
+			closereadfd(channel, channel->readfd);
+			closereadfd(channel, channel->errfd);
+		}
+	}
+
+	if (!channel->senteof
+		&& channel->readfd == FD_CLOSED 
+		&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
+		send_msg_channel_eof(channel);
+	}
+
+	if (!channel->sentclosed
+		&& channel->writefd == FD_CLOSED
+		&& channel->readfd == FD_CLOSED
+		&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
+		send_msg_channel_close(channel);
+	}
+
+	/* When either party wishes to terminate the channel, it sends
+	 * SSH_MSG_CHANNEL_CLOSE.  Upon receiving this message, a party MUST
+	 * send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
+	 * message for the channel.  The channel is considered closed for a
+	 * party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
+	 * the party may then reuse the channel number.  A party MAY send
+	 * SSH_MSG_CHANNEL_CLOSE without having sent or received
+	 * SSH_MSG_CHANNEL_EOF. 
+	 * (from draft-ietf-secsh-connect)
+	 */
+	if (channel->recvclosed) {
+		if (! channel->sentclosed) {
+			TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
+			send_msg_channel_close(channel);
+		}
+		removechannel(channel);
+	}
+}
+
+
+/* Check whether a deferred (EINPROGRESS) connect() was successful, and
+ * if so, set up the channel properly. Otherwise, the channel is cleaned up, so
+ * it is important that the channel reference isn't used after a call to this
+ * function */
+static void checkinitdone(struct Channel *channel) {
+
+	int val;
+	socklen_t vallen = sizeof(val);
+
+	TRACE(("enter checkinitdone"))
+
+	if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen)
+			|| val != 0) {
+		send_msg_channel_open_failure(channel->remotechan,
+				SSH_OPEN_CONNECT_FAILED, "", "");
+		close(channel->writefd);
+		deletechannel(channel);
+		TRACE(("leave checkinitdone: fail"))
+	} else {
+		send_msg_channel_open_confirmation(channel, channel->recvwindow,
+				channel->recvmaxpacket);
+		channel->readfd = channel->writefd;
+		channel->initconn = 0;
+		TRACE(("leave checkinitdone: success"))
+	}
+}
+
+
+
+/* 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"))
+	/* XXX server */
+	if (channel->type->closehandler) {
+		channel->type->closehandler(channel);
+	}
+	
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+
+	channel->senteof = 1;
+	channel->sentclosed = 1;
+	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"))
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+
+	channel->senteof = 1;
+
+	TRACE(("leave send_msg_channel_eof"))
+}
+
+/* Called to write data out to the local side of the channel. 
+ * Only called when we know we can write to a channel, writes as much as
+ * possible */
+static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
+
+	int len, maxlen;
+
+	TRACE(("enter writechannel"))
+
+	maxlen = cbuf_readlen(cbuf);
+
+	/* Write the data out */
+	len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen);
+	if (len <= 0) {
+		if (len < 0 && errno != EINTR) {
+			/* no more to write - we close it even if the fd was stderr, since
+			 * that's a nasty failure too */
+			closewritefd(channel);
+		}
+		TRACE(("leave writechannel: len <= 0"))
+		return;
+	}
+
+	cbuf_incrread(cbuf, len);
+	channel->recvdonelen += len;
+
+	if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recveof) { 
+		/* Check if we're closing up */
+		closewritefd(channel);
+		TRACE(("leave writechannel: recveof set"))
+		return;
+	}
+
+	/* Window adjust handling */
+	if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
+		/* Set it back to max window */
+		send_msg_channel_window_adjust(channel, channel->recvdonelen);
+		channel->recvwindow += channel->recvdonelen;
+		channel->recvdonelen = 0;
+	}
+
+	dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
+	dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
+	dropbear_assert(channel->extrabuf == NULL ||
+			channel->recvwindow <= cbuf_getavail(channel->extrabuf));
+	
+	
+	TRACE(("leave writechannel"))
+}
+
+/* Set the file descriptors for the main select in session.c
+ * This avoid channels which don't have any window available, are closed, etc*/
+void setchannelfds(fd_set *readfds, fd_set *writefds) {
+	
+	unsigned int i;
+	struct Channel * channel;
+	
+	for (i = 0; i < ses.chansize; i++) {
+
+		channel = ses.channels[i];
+		if (channel == NULL) {
+			continue;
+		}
+
+		/* Stuff to put over the wire */
+		if (channel->transwindow > 0) {
+
+			if (channel->readfd >= 0) {
+				FD_SET(channel->readfd, readfds);
+			}
+			
+			if (channel->extrabuf == NULL && channel->errfd >= 0) {
+					FD_SET(channel->errfd, readfds);
+			}
+		}
+
+		TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d", 
+					channel->writefd, channel->readfd,
+					channel->errfd,
+					cbuf_getused(channel->writebuf) ))
+
+		/* For checking FD status (ie closure etc) - we don't actually
+		 * read data from writefd. We don't want to do this for the client,
+		 * since redirection to /dev/null will make it spin in the select */
+		if (IS_DROPBEAR_SERVER && channel->writefd >= 0 
+				&& channel->writefd != channel->readfd) {
+			FD_SET(channel->writefd, readfds);
+		}
+
+		/* Stuff from the wire */
+		if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
+				|| channel->initconn) {
+				FD_SET(channel->writefd, writefds);
+		}
+
+		if (channel->extrabuf != NULL && channel->errfd >= 0 
+				&& cbuf_getused(channel->extrabuf) > 0 ) {
+				FD_SET(channel->errfd, writefds);
+		}
+
+	} /* foreach channel */
+
+#ifdef USING_LISTENERS
+	set_listener_fds(readfds);
+#endif
+
+}
+
+/* handle the channel EOF event, by closing the channel filedescriptor. The
+ * channel isn't closed yet, it is left until the incoming (from the program
+ * etc) FD is also EOF */
+void recv_msg_channel_eof() {
+
+	struct Channel * channel;
+
+	TRACE(("enter recv_msg_channel_eof"))
+
+	channel = getchannel();
+	if (channel == NULL) {
+		dropbear_exit("EOF for unknown channel");
+	}
+
+	channel->recveof = 1;
+	if (cbuf_getused(channel->writebuf) == 0
+			&& (channel->extrabuf == NULL 
+					|| cbuf_getused(channel->extrabuf) == 0)) {
+		closewritefd(channel);
+	}
+
+	TRACE(("leave recv_msg_channel_eof"))
+}
+
+
+/* Handle channel closure(), respond in kind and close the channels */
+void recv_msg_channel_close() {
+
+	struct Channel * channel;
+
+	TRACE(("enter recv_msg_channel_close"))
+
+	channel = getchannel();
+	if (channel == NULL) {
+		/* disconnect ? */
+		dropbear_exit("Close for unknown channel");
+	}
+
+	channel->recveof = 1;
+	channel->recvclosed = 1;
+
+	if (channel->sentclosed) {
+		removechannel(channel);
+	}
+
+	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))
+
+	cbuf_free(channel->writebuf);
+	channel->writebuf = NULL;
+
+	if (channel->extrabuf) {
+		cbuf_free(channel->extrabuf);
+		channel->extrabuf = NULL;
+	}
+
+
+	/* close the FDs in case they haven't been done
+	 * yet (ie they were shutdown etc */
+	close(channel->writefd);
+	close(channel->readfd);
+	close(channel->errfd);
+
+	channel->typedata = NULL;
+
+	deletechannel(channel);
+
+	TRACE(("leave removechannel"))
+}
+
+/* Remove a channel entry */
+static void deletechannel(struct Channel *channel) {
+
+	ses.channels[channel->index] = NULL;
+	m_free(channel);
+	ses.chancount--;
+	
+}
+
+
+/* Handle channel specific requests, passing off to corresponding handlers
+ * such as chansession or x11fwd */
+void recv_msg_channel_request() {
+
+	struct Channel *channel;
+
+	TRACE(("enter recv_msg_channel_request"))
+	
+	channel = getchannel();
+	if (channel == NULL) {
+		/* disconnect ? */
+		dropbear_exit("Unknown channel");
+	}
+
+	if (channel->type->reqhandler) {
+		channel->type->reqhandler(channel);
+	} else {
+		send_msg_channel_failure(channel);
+	}
+
+	TRACE(("leave recv_msg_channel_request"))
+
+}
+
+/* Reads data from the server's program/shell/etc, and puts it in a
+ * channel_data packet to send.
+ * chan is the remote channel, isextended is 0 if it is normal data, 1
+ * if it is extended data. if it is extended, then the type is in
+ * exttype */
+static void send_msg_channel_data(struct Channel *channel, int isextended,
+		unsigned int exttype) {
+
+	buffer *buf;
+	int len;
+	unsigned int maxlen;
+	int fd;
+
+/*	TRACE(("enter send_msg_channel_data"))
+	TRACE(("extended = %d type = %d", isextended, exttype))*/
+
+	CHECKCLEARTOWRITE();
+
+	dropbear_assert(!channel->sentclosed);
+
+	if (isextended) {
+		fd = channel->errfd;
+	} else {
+		fd = channel->readfd;
+	}
+	dropbear_assert(fd >= 0);
+
+	maxlen = MIN(channel->transwindow, channel->transmaxpacket);
+	/* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
+	 * exttype if is extended */
+	maxlen = MIN(maxlen, 
+			ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
+	if (maxlen == 0) {
+		TRACE(("leave send_msg_channel_data: no window"))
+		return; /* the data will get written later */
+	}
+
+	/* read the data */
+	TRACE(("maxlen %d", maxlen))
+	buf = buf_new(maxlen);
+	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 */
+		if (len == 0 || errno != EINTR) {
+			closereadfd(channel, fd);
+		}
+		buf_free(buf);
+		buf = NULL;
+		TRACE(("leave send_msg_channel_data: read err or EOF for fd %d", 
+					channel->index));
+		return;
+	}
+	buf_incrlen(buf, len);
+
+	buf_putbyte(ses.writepayload, 
+			isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	if (isextended) {
+		buf_putint(ses.writepayload, exttype);
+	}
+
+	buf_putstring(ses.writepayload, buf_getptr(buf, len), len);
+	buf_free(buf);
+	buf = NULL;
+
+	channel->transwindow -= len;
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_data"))
+}
+
+/* We receive channel data */
+void recv_msg_channel_data() {
+
+	struct Channel *channel;
+
+	channel = getchannel();
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+
+	common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
+}
+
+/* Shared for data and stderr data - when we receive data, put it in a buffer
+ * for writing to the local file descriptor */
+void common_recv_msg_channel_data(struct Channel *channel, int fd, 
+		circbuffer * cbuf) {
+
+	unsigned int datalen;
+	unsigned int maxdata;
+	unsigned int buflen;
+	unsigned int len;
+
+	TRACE(("enter recv_msg_channel_data"))
+
+	if (channel->recveof) {
+		dropbear_exit("received data after eof");
+	}
+
+ 	if (fd < 0) {
+		dropbear_exit("received data with bad writefd");
+	}
+
+	datalen = buf_getint(ses.payload);
+
+
+	maxdata = cbuf_getavail(cbuf);
+
+	/* Whilst the spec says we "MAY ignore data past the end" this could
+	 * lead to corrupted file transfers etc (chunks missed etc). It's better to
+	 * just die horribly */
+	if (datalen > maxdata) {
+		dropbear_exit("Oversized packet");
+	}
+
+	/* We may have to run throught twice, if the buffer wraps around. Can't
+	 * just "leave it for next time" like with writechannel, since this
+	 * is payload data */
+	len = datalen;
+	while (len > 0) {
+		buflen = cbuf_writelen(cbuf);
+		buflen = MIN(buflen, len);
+
+		memcpy(cbuf_writeptr(cbuf, buflen), 
+				buf_getptr(ses.payload, buflen), buflen);
+		cbuf_incrwrite(cbuf, buflen);
+		buf_incrpos(ses.payload, buflen);
+		len -= buflen;
+	}
+
+	dropbear_assert(channel->recvwindow >= datalen);
+	channel->recvwindow -= datalen;
+	dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
+
+	TRACE(("leave recv_msg_channel_data"))
+}
+
+/* Increment the outgoing data window for a channel - the remote end limits
+ * the amount of data which may be transmitted, this window is decremented
+ * as data is sent, and incremented upon receiving window-adjust messages */
+void recv_msg_channel_window_adjust() {
+
+	struct Channel * channel;
+	unsigned int incr;
+	
+	channel = getchannel();
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+	
+	incr = buf_getint(ses.payload);
+	TRACE(("received window increment %d", incr))
+	incr = MIN(incr, MAX_TRANS_WIN_INCR);
+	
+	channel->transwindow += incr;
+	channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW);
+
+}
+
+/* Increment the incoming data window for a channel, and let the remote
+ * end know */
+static void send_msg_channel_window_adjust(struct Channel* channel, 
+		unsigned int incr) {
+
+	TRACE(("sending window adjust %d", incr))
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
+	buf_putint(ses.writepayload, channel->remotechan);
+	buf_putint(ses.writepayload, incr);
+
+	encrypt_packet();
+}
+	
+/* Handle a new channel request, performing any channel-type-specific setup */
+/* XXX server */
+void recv_msg_channel_open() {
+
+	unsigned char *type;
+	unsigned int typelen;
+	unsigned int remotechan, transwindow, transmaxpacket;
+	struct Channel *channel;