From 356a0b004aad93ec570b134664522a3a925ba556 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 8 Nov 1999 15:30:59 +1100 Subject: Lots of changes: - 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: - [sshd.c] don't send fail-msg but disconnect if too many authentication failures - [sshd.c] replace assert() with error, fatal or packet_disconnect - [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 - Fixed coredump after merge of OpenBSD rsa.c patch --- ChangeLog | 30 +++++++++++++ Makefile.in | 12 +++-- README | 9 +++- TODO | 7 +++ config.h.in | 142 ----------------------------------------------------------- configure.in | 17 ++----- includes.h | 4 -- openssh.spec | 23 ++++++---- pty.c | 7 ++- rsa.c | 34 ++++++++------ ssh-add.c | 76 ++++++++++++++++++++++++++++++-- ssh-agent.1 | 8 ++++ ssh-askpass | 38 ++++++++++++++++ ssh-keygen.c | 4 +- ssh.h | 8 +++- sshd.c | 85 ++++++++++++++++++++++++++--------- 16 files changed, 291 insertions(+), 213 deletions(-) create mode 100644 TODO delete mode 100644 config.h.in create mode 100755 ssh-askpass diff --git a/ChangeLog b/ChangeLog index 86b891be1..0248198a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +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: + - [sshd.c] don't send fail-msg but disconnect if too many authentication + failures + - [sshd.c] replace assert() with error, fatal or packet_disconnect + - [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 + - Fixed coredump after merge of OpenBSD rsa.c patch + 19991102 - Merged change from OpenBSD CVS - One-line cleanup in sshd.c diff --git a/Makefile.in b/Makefile.in index 6217c5848..151131c6d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ mandir=@mandir@ CC=@CC@ OPT_FLAGS=-g -CFLAGS=$(OPT_FLAGS) -Wall -DETCDIR=\"@sysconfdir@\" @DEFS@ +CFLAGS=$(OPT_FLAGS) -Wall -DETCDIR=\"@sysconfdir@\" -DSSH_PROGRAM=\"@bindir@/ssh\" @DEFS@ TARGETS=libssh.a ssh sshd ssh-add ssh-keygen ssh-agent scp LFLAGS=-L. LIBS=-lssh @LIBS@ @@ -48,7 +48,7 @@ ssh-keygen: ssh-keygen.o log-client.o clean: rm -f *.o core $(TARGETS) config.status config.cache config.log - + install: install -d $(bindir) install -d $(sbindir) @@ -56,12 +56,15 @@ install: install -d $(mandir)/man1 install -d $(mandir)/man8 install -s -c ssh $(bindir)/ssh + ln -s ssh $(bindir)/slogin install -s -c scp $(bindir)/scp install -s -c ssh-add $(bindir)/ssh-add + install -m755 -c ssh-askpass $(libdir)/ssh/ssh-askpass install -s -c ssh-agent $(bindir)/ssh-agent install -s -c ssh-keygen $(bindir)/ssh-keygen install -s -c sshd $(sbindir)/sshd install -m644 -c ssh.1 $(mandir)/man1/ssh.1 + ln -s ssh.1 $(mandir)/man1/slogin.1 install -m644 -c scp.1 $(mandir)/man1/scp.1 install -m644 -c ssh-add.1 $(mandir)/man1/ssh-add.1 install -m644 -c ssh-agent.1 $(mandir)/man1/ssh-agent.1 @@ -69,6 +72,9 @@ install: install -m644 -c sshd.8 $(mandir)/man8/sshd.8 distclean: clean - rm -f Makefile config.h core configure *~ + rm -f Makefile config.h core *~ mrproper: distclean + +veryclean: distclean + rm -f configure diff --git a/README b/README index 7c351d13a..b5734eae1 100644 --- a/README +++ b/README @@ -23,8 +23,8 @@ or abuse of this software. The code in strlcpy.c and mktemp.c is from the OpenBSD project and has its own license (see source file for details). -OpenSSH depends on Zlib, OpenSSL and PAM and optionally libpwdb. It now -uses autoconf to build thanks to Dan Brosemer +OpenSSH depends on Zlib[1], OpenSSL[2] and optionally PAM[3]. +It now uses autoconf to build thanks to Dan Brosemer Damien Miller Internet Business Solutions @@ -51,3 +51,8 @@ is released under a X11-style license (see source file for details). (A)RC4 code in rc4.[ch] is Copyright 1999 Damien Miller. It too is under a X11-style license (see source file for details). +References - + +[1] http://www.cdrom.com/pub/infozip/zlib/ +[2] http://www.openssl.org/ +[3] http://www.kernel.org/pub/linux/libs/pam/ diff --git a/TODO b/TODO new file mode 100644 index 000000000..128f6df14 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +-- Replacement for setproctitle() + +-- Improve PAM support (a pam_lastlog module will cause sshd to exit) + +-- Better documentation + +-- Port to other platforms diff --git a/config.h.in b/config.h.in deleted file mode 100644 index f106c04d6..000000000 --- a/config.h.in +++ /dev/null @@ -1,142 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define to `int' if doesn't define. */ -#undef gid_t - -/* Define if you don't have vprintf but do have _doprnt. */ -#undef HAVE_DOPRNT - -/* Define if your struct stat has st_blksize. */ -#undef HAVE_ST_BLKSIZE - -/* Define if you have that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* Define if utime(file, NULL) sets file's timestamp to the present. */ -#undef HAVE_UTIME_NULL - -/* Define if you have the vprintf function. */ -#undef HAVE_VPRINTF - -/* Define as __inline if that's what the C compiler calls it. */ -#undef inline - -/* Define to `int' if doesn't define. */ -#undef mode_t - -/* Define to `long' if doesn't define. */ -#undef off_t - -/* Define as the return type of signal handlers (int or void). */ -#undef RETSIGTYPE - -/* Define to `unsigned' if doesn't define. */ -#undef size_t - -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to `int' if doesn't define. */ -#undef uid_t - -/* Define if your ssl headers are included with #include */ -#undef HAVE_SSL - -/* Define if your ssl headers are included with #include */ -#undef HAVE_OPENSSL - -/* Define if you have the arc4random function. */ -#undef HAVE_ARC4RANDOM - -/* Define if you have the gethostname function. */ -#undef HAVE_GETHOSTNAME - -/* Define if you have the gettimeofday function. */ -#undef HAVE_GETTIMEOFDAY - -/* Define if you have the mkdir function. */ -#undef HAVE_MKDIR - -/* Define if you have the mkdtemp function. */ -#undef HAVE_MKDTEMP - -/* Define if you have the rmdir function. */ -#undef HAVE_RMDIR - -/* Define if you have the select function. */ -#undef HAVE_SELECT - -/* Define if you have the setproctitle function. */ -#undef HAVE_SETPROCTITLE - -/* Define if you have the socket function. */ -#undef HAVE_SOCKET - -/* Define if you have the strerror function. */ -#undef HAVE_STRERROR - -/* Define if you have the strlcpy function. */ -#undef HAVE_STRLCPY - -/* Define if you have the strspn function. */ -#undef HAVE_STRSPN - -/* Define if you have the strtol function. */ -#undef HAVE_STRTOL - -/* Define if you have the header file. */ -#undef HAVE_DIRENT_H - -/* Define if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define if you have the header file. */ -#undef HAVE_NDIR_H - -/* Define if you have the header file. */ -#undef HAVE_PATHS_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_DIR_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_IOCTL_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_NDIR_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define if you have the header file. */ -#undef HAVE_SYSLOG_H - -/* Define if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the crypto library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define if you have the dl library (-ldl). */ -#undef HAVE_LIBDL - -/* 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 pwdb library (-lpwdb). */ -#undef HAVE_LIBPWDB - -/* Define if you have the util library (-lutil). */ -#undef HAVE_LIBUTIL - -/* Define if you have the z library (-lz). */ -#undef HAVE_LIBZ diff --git a/configure.in b/configure.in index b6038523b..8df3ffc76 100644 --- a/configure.in +++ b/configure.in @@ -16,12 +16,10 @@ dnl Replace `main' with a function in -lz: AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first ***])) dnl check for nsl AC_CHECK_LIB(nsl, yp_match, , ) -dnl check for pwdb -AC_CHECK_LIB(pwdb, pwdb_new, , ) dnl check for dl -AC_CHECK_LIB(dl, dlopen, ,AC_MSG_ERROR([*** libdl missing - please install first ***])) +AC_CHECK_LIB(dl, dlopen, , ) dnl check for pam -AC_CHECK_LIB(pam, pam_authenticate, ,AC_MSG_ERROR([*** PAM missing - please install first ***])) +AC_CHECK_LIB(pam, pam_authenticate, , ) dnl Check for stuff in path. AC_CHECK_PROG(AR, ar, ar) @@ -31,10 +29,7 @@ dnl Check for ssl headers AC_CHECK_HEADER(openssl/bn.h, [AC_DEFINE(HAVE_OPENSSL)], [AC_CHECK_HEADER(ssl/bn.h, [AC_DEFINE(HAVE_SSL)], [AC_MSG_ERROR([*** ssl library missing - please install first ***])])]) dnl Checks for header files. -AC_HEADER_DIRENT -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(fcntl.h paths.h sys/ioctl.h sys/time.h syslog.h unistd.h) +AC_CHECK_HEADERS(pty.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -48,10 +43,6 @@ AC_HEADER_TIME dnl Checks for library functions. AC_PROG_GCC_TRADITIONAL -AC_FUNC_MEMCMP -AC_TYPE_SIGNAL -AC_FUNC_UTIME_NULL -AC_FUNC_VPRINTF -AC_CHECK_FUNCS(gethostname gettimeofday mkdir rmdir select socket strerror strspn strtol strlcpy mkdtemp arc4random setproctitle) +AC_CHECK_FUNCS(openpty strlcpy mkdtemp arc4random setproctitle) AC_OUTPUT(Makefile) diff --git a/includes.h b/includes.h index 609dd49b8..a1a6da6bd 100644 --- a/includes.h +++ b/includes.h @@ -67,10 +67,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include #endif /* HAVE_PAM */ -#ifdef HAVE_LIBPWDB -#include -#endif /* HAVE_PWDB */ - /* Define this to be the path of the xauth program. */ #ifndef XAUTH_PATH #define XAUTH_PATH "/usr/X11R6/bin/xauth" diff --git a/openssh.spec b/openssh.spec index 4f50420ce..25b50491b 100644 --- a/openssh.spec +++ b/openssh.spec @@ -1,6 +1,6 @@ Summary: OpenSSH free Secure Shell (SSH) implementation Name: openssh -Version: 1.2pre7 +Version: 1.2pre8 Release: 1 Packager: Damien Miller Source0: openssh-%{version}-linux.tar.gz @@ -20,6 +20,9 @@ up to date in terms of security and features, as well as removing all patented algorithms to seperate libraries (OpenSSL). %changelog +* 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 @@ -60,6 +63,7 @@ install -s -m755 scp $RPM_BUILD_ROOT/usr/bin install -s -m755 ssh-agent $RPM_BUILD_ROOT/usr/bin install -s -m755 ssh-add $RPM_BUILD_ROOT/usr/bin install -s -m755 ssh-keygen $RPM_BUILD_ROOT/usr/bin +ln -s ssh $RPM_BUILD_ROOT/usr/bin/slogin install -m644 sshd.8 $RPM_BUILD_ROOT/usr/man/man8 install -m644 ssh.1 $RPM_BUILD_ROOT/usr/man/man1 @@ -67,6 +71,7 @@ install -m644 scp.1 $RPM_BUILD_ROOT/usr/man/man1 install -m644 ssh-agent.1 $RPM_BUILD_ROOT/usr/man/man1 install -m644 ssh-add.1 $RPM_BUILD_ROOT/usr/man/man1 install -m644 ssh-keygen.1 $RPM_BUILD_ROOT/usr/man/man1 +ln -s ssh.1 $RPM_BUILD_ROOT/usr/bin/slogin.1 %clean rm -rf $RPM_BUILD_ROOT @@ -98,13 +103,15 @@ fi %attr(0755,root,root) /usr/bin/ssh-keygen %attr(0755,root,root) /usr/bin/ssh-add %attr(0755,root,root) /usr/bin/scp - -%attr(0755,root,root) /usr/man/man8/sshd.8 -%attr(0755,root,root) /usr/man/man1/ssh.1 -%attr(0755,root,root) /usr/man/man1/ssh-agent.1 -%attr(0755,root,root) /usr/man/man1/ssh-keygen.1 -%attr(0755,root,root) /usr/man/man1/ssh-add.1 -%attr(0755,root,root) /usr/man/man1/scp.1 +%attr(0755,root,root) /usr/bin/slogin + +%attr(0644,root,root) /usr/man/man8/sshd.8 +%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-keygen.1 +%attr(0644,root,root) /usr/man/man1/ssh-add.1 +%attr(0644,root,root) /usr/man/man1/scp.1 +%attr(0644,root,root) /usr/man/man1/slogin.1 %attr(0600,root,root) %config /etc/ssh/sshd_config %attr(0600,root,root) %config /etc/pam.d/sshd diff --git a/pty.c b/pty.c index 440994b51..141ef7d35 100644 --- a/pty.c +++ b/pty.c @@ -14,7 +14,12 @@ Allocating a pseudo-terminal, and making it the controlling tty. */ #include "includes.h" -RCSID("$Id: pty.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: pty.c,v 1.2 1999/11/08 04:30:59 damien Exp $"); + +#ifdef HAVE_PTY_H +/* Unfortunate namespace collision */ +#include +#endif /* HAVE_PTY_H */ #include "pty.h" #include "ssh.h" diff --git a/rsa.c b/rsa.c index 6d4b70442..6845fab9d 100644 --- a/rsa.c +++ b/rsa.c @@ -35,7 +35,7 @@ Description of the RSA algorithm can be found e.g. from the following sources: */ #include "includes.h" -RCSID("$Id: rsa.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); +RCSID("$Id: rsa.c,v 1.2 1999/11/08 04:30:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -70,8 +70,8 @@ rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits) } key = RSA_generate_key(bits, 35, NULL, NULL); - - assert(key != NULL); + if (key == NULL) + fatal("rsa_generate_key: key generation failed."); /* Copy public key parameters */ pub->n = BN_new(); @@ -110,24 +110,28 @@ void rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA* key) { char *inbuf, *outbuf; + int in_len; + int out_len; int len; if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) fatal("rsa_public_encrypt() exponent too small or not odd"); - len = BN_num_bytes(key->n); - outbuf = xmalloc(len); + out_len = BN_num_bytes(key->n); + outbuf = xmalloc(out_len); - len = BN_num_bytes(in); - inbuf = xmalloc(len); + in_len = BN_num_bytes(in); + inbuf = xmalloc(in_len); BN_bn2bin(in, inbuf); - if ((len = RSA_public_encrypt(len, inbuf, outbuf, key, + if ((len = RSA_public_encrypt(in_len, inbuf, outbuf, key, RSA_PKCS1_PADDING)) <= 0) fatal("rsa_public_encrypt() failed"); BN_bin2bn(outbuf, len, out); + memset(outbuf, 0, out_len); + memset(inbuf, 0, in_len); xfree(outbuf); xfree(inbuf); } @@ -136,21 +140,25 @@ void rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) { char *inbuf, *outbuf; + int in_len; + int out_len; int len; - len = BN_num_bytes(key->n); - outbuf = xmalloc(len); + out_len = BN_num_bytes(key->n); + outbuf = xmalloc(out_len); - len = BN_num_bytes(in); - inbuf = xmalloc(len); + in_len = BN_num_bytes(in); + inbuf = xmalloc(in_len); BN_bn2bin(in, inbuf); - if ((len = RSA_private_decrypt(len, inbuf, outbuf, key, + if ((len = RSA_private_decrypt(in_len, inbuf, outbuf, key, RSA_SSLV23_PADDING)) <= 0) fatal("rsa_private_decrypt() failed"); BN_bin2bn(outbuf, len, out); + memset(outbuf, 0, out_len); + memset(inbuf, 0, in_len); xfree(outbuf); xfree(inbuf); } diff --git a/ssh-add.c b/ssh-add.c index 2b4966d73..8effcdb07 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -14,7 +14,7 @@ Adds an identity to the authentication server, or removes an identity. */ #include "includes.h" -RCSID("$Id: ssh-add.c,v 1.2 1999/10/28 05:23:30 damien Exp $"); +RCSID("$Id: ssh-add.c,v 1.3 1999/11/08 04:30:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -52,6 +52,7 @@ delete_all(AuthenticationConnection *ac) fprintf(stderr, "Failed to remove all identitities.\n"); } +#define BUFSIZE 1024 void add_file(AuthenticationConnection *ac, const char *filename) { @@ -59,6 +60,11 @@ add_file(AuthenticationConnection *ac, const char *filename) RSA *public_key; char *saved_comment, *comment, *pass; int first; + int pipes[2]; + char buf[BUFSIZE]; + int tmp; + pid_t child; + FILE *pipef; key = RSA_new(); public_key = RSA_new(); @@ -80,8 +86,72 @@ add_file(AuthenticationConnection *ac, const char *filename) /* Ask for a passphrase. */ if (getenv("DISPLAY") && !isatty(fileno(stdin))) { - xfree(saved_comment); - return; + if (pipe(pipes) ==-1) + { + fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno)); + exit(1); + } + if (fflush(NULL)==EOF) + { + fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno)); + exit(1); + } + switch (child=fork()) + { + case -1: + fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); + exit(1); + case 0: + close(pipes[0]); + if (dup2(pipes[1], 1) ==-1) + { + fprintf(stderr, "dup2 failed: %s\n", strerror(errno)); + exit(1); + } + tmp=snprintf(buf, BUFSIZE, "Need passphrase for %s (%s)", + filename, saved_comment); + /* skip the prompt if it won't fit */ + if (tmp < 0 || tmp >= BUFSIZE) + tmp=execlp("/usr/lib/ssh/ssh-askpass", "ssh-askpass", 0); + else + tmp=execlp("/usr/lib/ssh/ssh-askpass", "ssh-askpass", buf, 0); + if (tmp==-1) + { + fprintf(stderr, "Executing ssh-askpass failed: %s\n", + strerror(errno)); + exit(1); + } + break; + default: + close(pipes[1]); + if ( (pipef=fdopen(pipes[0], "r")) ==NULL) + { + fprintf(stderr, "fdopen failed: %s\n", strerror(errno)); + exit(1); + } + if(fgets(buf, sizeof(buf), pipef)==NULL) + { + xfree(saved_comment); + return; + } + fclose(pipef); + if (strchr(buf, '\n')) + *strchr(buf, '\n') = 0; + pass = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + if (waitpid(child, NULL, 0) ==-1) + { + fprintf(stderr, "Waiting for child failed: %s\n", + strerror(errno)); + exit(1); + } + if (strcmp(pass, "") == 0) + { + xfree(saved_comment); + xfree(pass); + return; + } + } } else { diff --git a/ssh-agent.1 b/ssh-agent.1 index 8b9504fa5..3fef3a479 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -109,6 +109,14 @@ environment variable holds the agent's PID. .Pp The agent exits automatically when the command given on the command line terminates. +.Pp +Here's a trick that will allow you to start this up from your .bash_profile (just put it in as the first thing that happens): +.Sp +.Vb 1 + +\& [ ! "$SSH_AGENT_PID" ] && exec ssh-agent -- bash --login +\& ssh-add +.Ve .Sh FILES .Bl -tag -width Ds .It Pa $HOME/.ssh/identity diff --git a/ssh-askpass b/ssh-askpass new file mode 100755 index 000000000..b1e23c514 --- /dev/null +++ b/ssh-askpass @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +# Written by Tommi Virtanen . Consider it public domain. + +use strict; +use Tk; + +sub do_it($$;) { + my ($passphrase, $main) = @_; + print $passphrase->get(), "\n"; + $main->destroy(); +} + +sub ask($;) { + my ($prompt)=@_; + my $main=MainWindow->new; + $main->Label(-text=>$prompt)->pack(-fill=>'x'); + my $passphrase=$main->Entry(-show=>'*')->pack(-fill=>'x'); + $passphrase->focus(); + my $buttons=$main->Frame; + $buttons->pack(-side=>'right'); + my $ok=$buttons->Button(-text=>'Ok', + -command=>sub {do_it $passphrase, $main} + )->pack(-side=>'left'); + my $cancel=$buttons->Button(-text=>'Cancel', -command=>[$main=>'destroy']) + ->pack(-side=>'right'); + $main->bind('Tk::Button', '' => 'invoke'); + $main->bind('', [$ok => 'invoke']); + $main->bind('', [$cancel => 'invoke']); + $main->bind('' => [$main => 'grabGlobal']); + + MainLoop; +} + +ask ($#ARGV==0 + ? $ARGV[0] + : 'Please enter your authentication passphrase:'); + diff --git a/ssh-keygen.c b/ssh-keygen.c index 2ba64e756..e2cb48fd9 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -14,7 +14,7 @@ Identity and host key generation and maintenance. */ #include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.1 1999/10/27 03:42:45 damien Exp $"); +RCSID("$Id: ssh-keygen.c,v 1.2 1999/11/08 04:30:59 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -117,7 +117,7 @@ do_change_passphrase(struct passwd *pw) xfree(old_passphrase); } printf("Key has comment '%s'\n", comment); - + /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { diff --git a/ssh.h b/ssh.h index aaf74d875..841633c76 100644 --- a/ssh.h +++ b/ssh.h @@ -13,7 +13,7 @@ Generic header file for ssh. */ -/* RCSID("$Id: ssh.h,v 1.5 1999/10/29 00:21:15 damien Exp $"); */ +/* RCSID("$Id: ssh.h,v 1.6 1999/11/08 04:30:59 damien Exp $"); */ #ifndef SSH_H #define SSH_H @@ -85,7 +85,13 @@ only by root, whereas ssh_config should be world-readable. */ #define SERVER_CONFIG_FILE ETCDIR "/sshd_config" #define HOST_CONFIG_FILE ETCDIR "/ssh_config" +#ifndef SSH_PROGRAM #define SSH_PROGRAM "/usr/bin/ssh" +#endif /* SSH_PROGRAM */ + +#ifndef LOGIN_PROGRAM +#define LOGIN_PROGRAM "/usr/bin/login" +#endif /* LOGIN_PROGRAM */ /* The process id of the daemon listening for connections is saved here to make it easier to kill the correct daemon when necessary. */ diff --git a/sshd.c b/sshd.c index 49456cdb5..6cdcf75ed 100644 --- a/sshd.c +++ b/sshd.c @@ -18,7 +18,7 @@ agent connections. */ #include "includes.h" -RCSID("$Id: sshd.c,v 1.10 1999/11/02 08:05:02 damien Exp $"); +RCSID("$Id: sshd.c,v 1.11 1999/11/08 04:30:59 damien Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -142,6 +142,7 @@ static struct pam_conv conv = { }; struct pam_handle_t *pamh = NULL; const char *pampasswd = NULL; +char *pamconv_msg = NULL; static int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) @@ -171,6 +172,26 @@ static int pamconv(int num_msg, const struct pam_message **msg, case PAM_TEXT_INFO: reply[count].resp_retcode = PAM_SUCCESS; reply[count].resp = xstrdup(""); + + if (msg[count]->msg == NULL) break; + debug("Adding PAM message: %s", msg[count]->msg); + if (pamconv_msg == NULL) + { + pamconv_msg = malloc(strlen(msg[count]->msg) + 2); + + if (pamconv_msg == NULL) + return PAM_CONV_ERR; + + strncpy(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg)); + pamconv_msg[strlen(msg[count]->msg)] = '\n'; + pamconv_msg[strlen(msg[count]->msg) + 1] = '\0'; + } else + { + pamconv_msg = realloc(pamconv_msg, strlen(pamconv_msg) + strlen(msg[count]->msg) + 2); + strncat(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg)); + pamconv_msg[strlen(pamconv_msg)] = '\n'; + pamconv_msg[strlen(pamconv_msg) + 1] = '\0'; + } break; case PAM_PROMPT_ECHO_ON: @@ -964,8 +985,14 @@ void do_connection(int privileged_port) if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { /* Private key has bigger modulus. */ - assert(BN_num_bits(sensitive_data.private_key->n) >= - BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED); + if (BN_num_bits(sensitive_data.private_key->n) < + BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", + 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, @@ -974,9 +1001,13 @@ void do_connection(int privileged_port) else { /* Host key has bigger modulus (or they are equal). */ - assert(BN_num_bits(sensitive_data.host_key->n) >= - BN_num_bits(sensitive_data.private_key->n) + - SSH_KEY_BITS_RESERVED); + if (BN_num_bits(sensitive_data.host_key->n) < + BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { + fatal("do_connection: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", + 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, @@ -994,7 +1025,10 @@ void do_connection(int privileged_port) 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); - assert(BN_num_bytes(session_key_int) == sizeof(session_key)); + if (BN_num_bytes(session_key_int) != sizeof(session_key)){ + fatal("do_connection: session_key_int %d != sizeof(session_key) %d", + BN_num_bytes(session_key_int), sizeof(session_key)); + } BN_bn2bin(session_key_int, session_key); /* Xor the first 16 bytes of the session key with the session id. */ @@ -1243,7 +1277,7 @@ do_authentication(char *user, int privileged_port) int dlen; char *token_string = packet_get_string(&dlen); packet_integrity_check(plen, 4 + dlen, type); - if (!auth_afs_token(user, pw->pw_uid, token_string)) + if (!auth_afs_token(pw, token_string)) debug("AFS token REFUSED for %s", user); xfree(token_string); continue; @@ -1478,15 +1512,15 @@ do_authentication(char *user, int privileged_port) if (authenticated) break; - /* Send a message indicating that the authentication attempt failed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - if (++authentication_failures >= MAX_AUTH_FAILURES) { packet_disconnect("Too many authentication failures for %.100s from %.200s", pw->pw_name, get_canonical_hostname()); } + + /* Send a message indicating that the authentication attempt failed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); } /* Check if the user is logging in as root and root logins are disallowed. */ @@ -1556,16 +1590,16 @@ void eat_packets_and_disconnect(const char *user) packet_send_debug(skeyinfo); } #endif /* SKEY */ - /* Send failure. This should be indistinguishable from a failed - authentication. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); if (++authentication_failures >= MAX_AUTH_FAILURES) { packet_disconnect("Too many authentication failures for %.100s from %.200s", user, get_canonical_hostname()); } + /* Send failure. This should be indistinguishable from a failed + authentication. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); } /*NOTREACHED*/ abort(); @@ -2049,7 +2083,13 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd, /* Check if .hushlogin exists. */ snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); quiet_login = stat(line, &st) >= 0; - + +#ifdef HAVE_LIBPAM + /* output the results of the pamconv() */ + if (!quiet_login && pamconv_msg != NULL) + fprintf(stderr, pamconv_msg); +#endif + /* 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 @@ -2238,6 +2278,7 @@ void do_child(const char *command, struct passwd *pw, const char *term, struct stat st; char *argv[10]; +#ifndef HAVE_LIBPAM /* pam_nologin handles this */ /* Check /etc/nologin. */ f = fopen("/etc/nologin", "r"); if (f) @@ -2248,6 +2289,7 @@ void do_child(const char *command, struct passwd *pw, const char *term, if (pw->pw_uid != 0) exit(254); } +#endif /* Set uid, gid, and groups. */ /* Login(1) does this as well, and it needs uid 0 for the "-h" switch, @@ -2387,7 +2429,7 @@ void do_child(const char *command, struct passwd *pw, const char *term, 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); @@ -2525,6 +2567,7 @@ void do_child(const char *command, struct passwd *pw, const char *term, } } } + /* Start the shell. Set initial character to '-'. */ buf[0] = '-'; strncpy(buf + 1, cp, sizeof(buf) - 1); @@ -2540,7 +2583,7 @@ void do_child(const char *command, struct passwd *pw, const char *term, } else { /* Launch login(1). */ - execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL); + execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL); /* Login couldn't be executed, die. */ -- cgit v1.2.3