Mercurial > dropbear
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;