- Created contrib/ subdirectory. Included helpers from Phil Hands'

Debian package, README file and chroot patch from Ricardo Cerqueira
   <rmcc@clix.pt>
 - Moved gnome-ssh-askpass.c to contrib directory and reomved config
   option.
 - Slight cleanup to doc files
This commit is contained in:
Damien Miller 2000-03-15 12:13:01 +11:00
parent f09b07a971
commit 8b1c22b775
11 changed files with 1479 additions and 42 deletions

View File

@ -3,6 +3,12 @@
problems with gcc/Solaris.
- Don't free argument to putenv() after use (in setenv() replacement).
Report from Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp>
- Created contrib/ subdirectory. Included helpers from Phil Hands'
Debian package, README file and chroot patch from Ricardo Cerqueira
<rmcc@clix.pt>
- Moved gnome-ssh-askpass.c to contrib directory and reomved config
option.
- Slight cleanup to doc files
20000314
- Include macro for IN6_IS_ADDR_V4MAPPED. Report from

10
INSTALL
View File

@ -15,12 +15,6 @@ supports it. PAM is standard on Redhat and Debian Linux and on Solaris.
PAM:
http://www.kernel.org/pub/linux/libs/pam/
Dante:
http://www.inet.no/dante
OpenSSH can also use the Dante SOCKS libraries, version 1.1.1pre1 or higher,
if you have them installed on your system.
If you wish to build the GNOME passphrase requester, you will need the GNOME
libraries and headers.
@ -145,10 +139,6 @@ created.
--with-xauth=PATH specifies the location of the xauth binary
--with-dante[=DIR] will enable Dante SOCKS library support. If the Dante
libsocks library isn't installed in a library searched by the compiler,
add the directory name as the option.
--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

View File

@ -21,7 +21,6 @@ ASKPASS_PROGRAM=$(ASKPASS_LOCATION)/ssh-askpass
CC=@CC@
PATHS=-DETCDIR=\"$(sysconfdir)\" -DSSH_PROGRAM=\"$(SSH_PROGRAM)\" -DSSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\"
CFLAGS=@CFLAGS@ $(PATHS) @DEFS@
EXTRA_TARGETS=@GNOME_ASKPASS@
LIBS=@LIBS@
AR=@AR@
RANLIB=@RANLIB@
@ -29,9 +28,6 @@ INSTALL=@INSTALL@
PERL=@PERL@
LDFLAGS=-L. @LDFLAGS@
GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui`
GNOME_LIBS=`gnome-config --libs gnome gnomeui`
TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o random.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o
@ -76,9 +72,6 @@ ssh-agent: libssh.a ssh-agent.o log-client.o
ssh-keygen: libssh.a ssh-keygen.o log-client.o
$(CC) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh $(LIBS)
gnome-ssh-askpass: gnome-ssh-askpass.c
$(CC) $(CFLAGS) $(GNOME_CFLAGS) -o $@ gnome-ssh-askpass.c $(GNOME_LIBS)
$(MANPAGES) $(CONFIGFILES)::
$(FIXPATHSCMD) $(srcdir)/$@
@ -124,12 +117,6 @@ install: $(TARGETS)
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
if [ ! -z "@GNOME_ASKPASS@" ] ; then \
$(INSTALL) -d $(DESTDIR)$(libexecdir) ; \
$(INSTALL) -d $(DESTDIR)$(libexecdir)/ssh ; \
$(INSTALL) -s @GNOME_ASKPASS@ $(DESTDIR)${ASKPASS_LOCATION} ; \
fi
if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \
$(INSTALL) -d $(DESTDIR)$(sysconfdir); \
$(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \

View File

@ -577,25 +577,6 @@ AC_CHECK_FILE("/dev/ptc",
# Options from here on. Some of these are preset by platform above
# Check whether user wants GNOME ssh-askpass
AC_MSG_CHECKING([whether to build GNOME ssh-askpass])
AC_ARG_WITH(gnome-askpass,
[ --with-gnome-askpass Build the GNOME passphrase requester (default=no)],
[
if test "x$withval" = "xno" ; then
GNOME_ASKPASS="";
else
GNOME_ASKPASS="gnome-ssh-askpass";
fi
])
AC_SUBST(GNOME_ASKPASS)
if test -z "$GNOME_ASKPASS" ; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(yes)
fi
# Check for user-specified random device, otherwise check /dev/urandom
AC_ARG_WITH(random,
[ --with-random=FILE read randomness from FILE (default=/dev/urandom)],

49
contrib/README Normal file
View File

@ -0,0 +1,49 @@
Other patches and addons for OpenSSH. Please send submissions to
djm@ibs.com.au
In this directory
-----------------
chroot.diff:
Ricardo Cerqueira's <rmcc@clix.pt> 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 <Tero.Kivinen@hut.fi> PERL script to generate
ssh_known_hosts files by trawling tjhrough the DNS. More details in the
manpage.
ssh-copy-id:
Phil Hands' <phil@hands.com> 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.
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 <jmknoble@pobox.com> has written an excellent X11
passphrase requester. This is highly recommended:
http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html

134
contrib/chroot.diff Normal file
View File

@ -0,0 +1,134 @@
From: Ricardo Cerqueira <rmcc@clix.pt>
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.
diff -ruN openssh-1.2.3pre2-orig/acconfig.h openssh-1.2.3pre2/acconfig.h
--- openssh-1.2.3pre2-orig/acconfig.h Sat Mar 11 20:45:40 2000
+++ openssh-1.2.3pre2/acconfig.h Wed Mar 15 11:44:33 2000
@@ -159,6 +159,9 @@
/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
#undef IPV4_IN_IPV6
+/* Define if you want to enable chrooted users */
+#undef CHROOT
+
@BOTTOM@
/* ******************* Shouldn't need to edit below this line ************** */
diff -ruN openssh-1.2.3pre2-orig/config.h.in openssh-1.2.3pre2/config.h.in
--- openssh-1.2.3pre2-orig/config.h.in Wed Mar 15 11:51:02 2000
+++ openssh-1.2.3pre2/config.h.in Wed Mar 15 11:46:33 2000
@@ -140,6 +140,9 @@
/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
#undef IPV4_IN_IPV6
+/* Define if you want to enable chrooted users */
+#undef CHROOT
+
/* The number of bytes in a char. */
#undef SIZEOF_CHAR
diff -ruN openssh-1.2.3pre2-orig/configure openssh-1.2.3pre2/configure
--- openssh-1.2.3pre2-orig/configure Wed Mar 15 11:51:03 2000
+++ openssh-1.2.3pre2/configure Wed Mar 15 11:46:34 2000
@@ -52,6 +52,8 @@
ac_help="$ac_help
--with-4in6 Check for and convert IPv4 in IPv6 mapped addresses"
ac_help="$ac_help
+ --with-chroot Enable chroot using /./ directory token"
+ac_help="$ac_help
--with-pid-dir=PATH Specify location of ssh.pid file"
# Initialize some variables set by options.
@@ -3605,6 +3607,22 @@
else
echo "$ac_t""no (default)" 1>&6
+ fi
+
+
+fi
+
+
+# Whether to enable the magic chroot token
+# Check whether --with-chroot or --without-chroot was given.
+if test "${with_chroot+set}" = set; then
+ withval="$with_chroot"
+
+ if test "x$withval" != "xno" ; then
+ cat >> confdefs.h <<\EOF
+#define CHROOT 1
+EOF
+
fi
diff -ruN openssh-1.2.3pre2-orig/configure.in openssh-1.2.3pre2/configure.in
--- openssh-1.2.3pre2-orig/configure.in Sat Mar 11 20:45:41 2000
+++ openssh-1.2.3pre2/configure.in Wed Mar 15 11:46:04 2000
@@ -810,6 +810,16 @@
]
)
+# Whether to enable the magic chroot token
+AC_ARG_WITH(chroot,
+ [ --with-chroot Enable chroot using /./ directory token],
+ [
+ if test "x$withval" != "xno" ; then
+ AC_DEFINE(CHROOT)
+ fi
+ ]
+)
+
# Where to place sshd.pid
piddir=/var/run
AC_ARG_WITH(pid-dir,
diff -ruN openssh-1.2.3pre2-orig/sshd.c openssh-1.2.3pre2/sshd.c
--- openssh-1.2.3pre2-orig/sshd.c Sat Mar 11 11:58:29 2000
+++ openssh-1.2.3pre2/sshd.c Wed Mar 15 11:43:38 2000
@@ -2365,6 +2365,10 @@
extern char **environ;
struct stat st;
char *argv[10];
+#ifdef CHROOT /* patch by rmcc */
+ char *user_dir;
+ char *new_root;
+#endif /* CHROOT */
#ifndef USE_PAM /* pam_nologin handles this */
/* Check /etc/nologin. */
@@ -2422,6 +2426,29 @@
krb_afslog(0, 0);
}
#endif /* AFS */
+
+#ifdef CHROOT /* patch by rmcc */
+
+ user_dir = xstrdup(pw->pw_dir);
+ new_root = user_dir;
+
+ 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){
+ printf("Couldn't chroot!\n");
+ exit(1);
+ }
+ pw->pw_dir = new_root;
+ break;
+ }
+ new_root +=2;
+ }
+
+
+#endif /* CHROOT */
/* Initialize the environment. */
envsize = 100;

View File

@ -1,3 +1,12 @@
/*
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

View File

@ -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/Attic/make-ssh-known-hosts.1,v $
.\" Author : $Author: damien $
.\"
.\" (C) Tero Kivinen 1995 <Tero.Kivinen@hut.fi>
.\"
.\" 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
.\" <rmcc@clix.pt>
.\" - 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 <kivinen@hut.fi>
.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.

View File

@ -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/Attic/make-ssh-known-hosts.pl,v $
# Author : $Author: damien $
#
# (C) Tero Kivinen 1995 <Tero.Kivinen@hut.fi>
#
# 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
# <rmcc@clix.pt>
# - 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(<DNS>) {
$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(<KNOWNHOSTS>) {
@_ = 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 (<DNS>) {
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;

45
contrib/ssh-copy-id Normal file
View File

@ -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 <<EOF
Now try logging into the machine, with "ssh '$1'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
EOF

67
contrib/ssh-copy-id.1 Normal file
View File

@ -0,0 +1,67 @@
.ig \" -*- nroff -*-
Copyright (c) 1999 Philip Hands Computing <http://www.hands.com/>
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)