X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/7d8818908887bbdabb02eed03f88e683263db6d3..6193a4afe7d80d39e45e8516cddfd2cae73b2151:/setup/setup-openssh.pl diff --git a/setup/setup-openssh.pl b/setup/setup-openssh.pl index ac96b14..8331aa8 100644 --- a/setup/setup-openssh.pl +++ b/setup/setup-openssh.pl @@ -1,15 +1,28 @@ +#!/usr/bin/perl # -# setup-openssh.pl: -# Adapts the installed gsi-ssh environment to the current machine, -# performing actions that originally occurred during the package's -# 'make install' phase. +# setup-openssh.pl # -# Large parts adapted from 'fixpath', a tool found in openssh-3.0.2p1. +# Adapts the installed gsi-openssh environment to the current machine, +# performing actions that originally occurred during the package's +# 'make install' phase. # # Send comments/fixes/suggestions to: # Chase Phillips # +printf("setup-openssh.pl: Configuring gsi-openssh package\n"); + +# +# Get user's GPT_LOCATION since we may be installing this using a new(er) +# version of GPT. +# + +$gptpath = $ENV{GPT_LOCATION}; + +# +# And the old standby.. +# + $gpath = $ENV{GLOBUS_LOCATION}; if (!defined($gpath)) { @@ -21,17 +34,20 @@ if (!defined($gpath)) # do so # -@INC = (@INC, "$gpath/lib/perl"); +if (defined($gptpath)) +{ + @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl"); +} +else +{ + @INC = (@INC, "$gpath/lib/perl"); +} require Grid::GPT::Setup; my $globusdir = $gpath; -my $setupdir = "$globusdir/setup/globus"; my $myname = "setup-openssh.pl"; -print "$myname: Configuring package 'gsi_openssh'...\n"; -print "Run this as root for the intended effect...\n"; - # # Set up path prefixes for use in the path translations # @@ -39,118 +55,123 @@ print "Run this as root for the intended effect...\n"; $prefix = ${globusdir}; $exec_prefix = "${prefix}"; $bindir = "${exec_prefix}/bin"; -$sbindir = "${exec_prefix}/sbin"; -$mandir = "${prefix}/man"; -$mansubdir = "man"; -$libexecdir = "${exec_prefix}/libexec"; -$sysconfdir = "/etc/ssh"; -$piddir = "/var/run"; -$xauth_path = "/usr/bin/X11/xauth"; +$sysconfdir = "$prefix/etc/ssh"; +$localsshdir = "/etc/ssh"; + +my $keyfiles = { + "dsa" => "ssh_host_dsa_key", + "rsa" => "ssh_host_rsa_key", + "rsa1" => "ssh_host_key", + }; # -# We need to make sure it's okay to copy our setup files (if some files are already -# present). If we do copy any files, we backup the old files so the user can (possibly) -# reverse any damage. +# Check that we are running as root # -sub copy_setup_files +$uid = $>; + +if ($uid != 0) { - my $response, $curr_time; + print "--> NOTE: You must be root to run this script! <--\n"; + exit 0; +} - $curr_time = time(); +sub copyKeyFiles +{ + my($copylist) = @_; + my($regex, $basename); - $response = "y"; - if ( -e "${sysconfdir}/ssh_config" ) + print "Copying ssh host keys...\n"; + + for my $f (@$copylist) { - $response = query_boolean("${sysconfdir}/ssh_config already exists. Overwrite? ", "n"); - if ($response eq "y") + $f =~ s:/+:/:g; + + if (length($f) > 0) { - action("cp ${sysconfdir}/ssh_config ${sysconfdir}/ssh_config.bak_${curr_time}"); + $keyfile = "$f"; + $pubkeyfile = "$f.pub"; + + action("cp $localsshdir/$keyfile $sysconfdir/$keyfile"); + action("cp $localsshdir/$pubkeyfile $sysconfdir/$pubkeyfile"); } } +} - if ($response eq "y") +sub isReadable +{ + my($file) = @_; + + if ( ( -e $file ) && ( -r $file ) ) + { + return 1; + } + else { - action("cp ${globusdir}/setup/globus/ssh_config ${sysconfdir}/ssh_config"); + return 0; } +} - # - # Reset response for our new query - # +sub determineKeys +{ + my($keyhash, $keylist); + my($count); + + $count = 0; - $response = "y"; - if ( -e "${sysconfdir}/sshd_config" ) + $keyhash = {}; + $keyhash->{gen} = []; # a list of keytypes to generate + $keyhash->{copy} = []; # a list of files to copy from the + $genlist = $keyhash->{gen}; + $copylist = $keyhash->{copy}; + + for my $keytype (keys %$keyfiles) { - $response = query_boolean("${sysconfdir}/sshd_config already exists. Overwrite? ", "n"); - if ($response eq "y") + $basekeyfile = $keyfiles->{$keytype}; + $keyfile = "$localsshdir/$basekeyfile"; + $pubkeyfile = "$keyfile.pub"; + + if ( !isReadable($keyfile) || !isReadable($pubkeyfile) ) { - action("cp ${sysconfdir}/sshd_config ${sysconfdir}/sshd_config.bak_${curr_time}"); + push(@$genlist, $keytype); + $count++; } } - if ($response eq "y") + for my $keytype (keys %$keyfiles) { - action("cp ${globusdir}/setup/globus/sshd_config ${sysconfdir}/sshd_config"); + if ( !grep(/^$keytype$/, @$genlist) ) + { + $keyfile = $keyfiles->{$keytype}; + push(@$copylist, $keyfile); + $count++; + } } - # - # Reset response for our new query - # - - $response = "y"; - if ( -e "${sysconfdir}/moduli" ) + if ($count > 0) { - $response = query_boolean("${sysconfdir}/moduli already exists. Overwrite? ", "n"); - if ($response eq "y") + if ( ! -d $sysconfdir ) { - action("cp ${sysconfdir}/moduli ${sysconfdir}/moduli.bak_${curr_time}"); + print "Could not find ${sysconfdir} directory... creating\n"; + action("mkdir -p $sysconfdir"); } } - if ($response eq "y") - { - action("cp ${globusdir}/setup/globus/moduli ${sysconfdir}/moduli"); - } + return $keyhash; } -sub runkeygen +sub runKeyGen { - if ( ! -d "${sysconfdir}" ) - { - print "Could not find ${sysconfdir} directory... creating\n"; - mkdir($sysconfdir, 16877); - # 16877 should be 755, or drwxr-xr-x - } + my($gen_keys) = @_; - print "Generating ssh keys (if necessary)...\n"; - if ( -e "${sysconfdir}/ssh_host_key" ) - { - print "${sysconfdir}/ssh_host_key already exists, skipping.\n"; - } - else - { - # if $sysconfdir/ssh_host_key doesn't exist.. - action("$bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N \"\""); - } + print "Generating ssh host keys...\n"; - if ( -e "${sysconfdir}/ssh_host_dsa_key" ) - { - print "${sysconfdir}/ssh_host_dsa_key already exists, skipping.\n"; - } - else + for my $k (@$gen_keys) { - # if $sysconfdir/ssh_host_dsa_key doesn't exist.. - action("$bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N \"\""); - } + $keyfile = $keyfiles->{$k}; - if ( -e "${sysconfdir}/ssh_host_rsa_key" ) - { - print "${sysconfdir}/ssh_host_rsa_key already exists, skipping.\n"; - } - else - { - # if $sysconfdir/ssh_host_rsa_key doesn't exist.. - action("$bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N \"\""); + # if $sysconfdir/$keyfile doesn't exist.. + action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\""); } return 0; @@ -158,121 +179,198 @@ sub runkeygen sub fixpaths { + my $g, $h; + + print "Fixing sftp-server path in sshd_config...\n"; + + $f = "$gpath/etc/ssh/sshd_config"; + $g = "$f.tmp"; + + if ( ! -f "$f" ) + { + die("Cannot find $f!"); + } + # - # Set up path translations for the installation files + # Grab the current mode/uid/gid for use later # - %def = ( - "/etc/ssh_config" => "${sysconfdir}/ssh_config", - "/etc/ssh_known_hosts" => "${sysconfdir}/ssh_known_hosts", - "/etc/sshd_config" => "${sysconfdir}/sshd_config", - "/usr/libexec" => "${libexecdir}", - "/etc/shosts.equiv" => "${sysconfdir}/shosts.equiv", - "/etc/ssh_host_key" => "${sysconfdir}/ssh_host_key", - "/etc/ssh_host_dsa_key" => "${sysconfdir}/ssh_host_dsa_key", - "/etc/ssh_host_rsa_key" => "${sysconfdir}/ssh_host_rsa_key", - "/var/run/sshd.pid" => "${piddir}/sshd.pid", - "/etc/moduli" => "${sysconfdir}/moduli", - "/etc/sshrc" => "${sysconfdir}/sshrc", - "/usr/X11R6/bin/xauth" => "${xauth_path}", - "/usr/bin:/bin:/usr/sbin:/sbin" => "/usr/bin:/bin:/usr/sbin:/sbin:${bindir}", - "(/path/to/scp.real)" => "${bindir}/scp.real", - "(/path/to/ssh)" => "${bindir}/ssh", - "(/path/to/sftp.real)" => "${bindir}/sftp.real", - "(/path/to/sshd.real)" => "${sbindir}/sshd.real", - "(/path/to/ssh_config)" => "${sysconfdir}/ssh_config", - "(/path/to/sshd_config)" => "${sysconfdir}/sshd_config", - ); + $mode = (stat($f))[2]; + $uid = (stat($f))[4]; + $gid = (stat($f))[5]; # - # Files on which to perform path translations + # Move $f into a .tmp file for the translation step # - %files = ( - "${bindir}/scp" => 0, - "${bindir}/sftp" => 0, - "${sbindir}/sshd" => 0, - "${sysconfdir}/ssh_config" => 1, - "${sysconfdir}/sshd_config" => 1, - "${sysconfdir}/moduli" => 1, - "${mandir}/${mansubdir}1/scp.1" => 0, - "${mandir}/${mansubdir}1/ssh-add.1" => 0, - "${mandir}/${mansubdir}1/ssh-agent.1" => 0, - "${mandir}/${mansubdir}1/ssh-keygen.1" => 0, - "${mandir}/${mansubdir}1/ssh-keyscan.1" => 0, - "${mandir}/${mansubdir}1/ssh.1" => 0, - "${mandir}/${mansubdir}8/sshd.8" => 0, - "${mandir}/${mansubdir}8/sftp-server.8" => 0, - "${mandir}/${mansubdir}1/sftp.1" => 0, - ); - - print "Translating strings in config/man files...\n"; - for my $f (keys %files) + $result = system("mv $f $g 2>&1"); + if ($result or $?) { - $f =~ /(.*\/)*(.*)$/; + die "ERROR: Unable to execute command: $!\n"; + } + + open(IN, "<$g") || die ("$0: input file $g missing!\n"); + open(OUT, ">$f") || die ("$0: unable to open output file $f!\n"); + while () + { # - # we really should create a random filename and make sure that it - # doesn't already exist (based off current time_t or something) + # sorry for the whacky regex, but i need to verify a whole line # - $g = "$f.tmp"; + if ( /^\s*Subsystem\s+sftp\s+\S+\s*$/ ) + { + $_ = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n"; + $_ =~ s:/+:/:g; + } + print OUT "$_"; + } # while + + close(OUT); + close(IN); - # - # Grab the current mode/uid/gid for use later - # + # + # Remove the old .tmp file + # - $mode = (stat($f))[2]; - $uid = (stat($f))[4]; - $gid = (stat($f))[5]; + $result = system("rm $g 2>&1"); - action("mv $f $g"); + if ($result or $?) + { + die "ERROR: Unable to execute command: $!\n"; + } - open(IN, "<$g") || die ("$0: input file $g missing!\n"); - open(OUT, ">$f") || die ("$0: unable to open output file $f!\n"); + # + # An attempt to revert the new file back to the original file's + # mode/uid/gid + # - while () - { - for $s (keys(%def)) - { - s#$s#$def{$s}#; - } # for $s - print OUT "$_"; - } # while + chmod($mode, $f); + chown($uid, $gid, $f); - close(OUT); - close(IN); + return 0; +} - if ($file{$f} eq 0) - { - action("rm $g"); - } - else - { - print "Left backup config file '$g'\n"; - } +sub alterFileGlobusLocation +{ + my ($file) = @_; - # - # An attempt to revert the new file back to the original file's - # mode/uid/gid - # + $data = readFile($file); + $data =~ s|\@GSI_OPENSSH_GLOBUS_LOCATION\@|$gpath|g; + writeFile($file, $data); +} - chmod($mode, $f); - chown($uid, $gid, $f); - } # for $f +sub alterFiles +{ + my (@files); - return 0; + @files = ( + "$gosharedir/contrib/caldera/sshd.init", + ); +} + +### readFile( $filename ) +# +# reads and returns $filename's contents +# + +sub readFile +{ + my ($filename) = @_; + my $data; + + open (IN, "$filename") || die "Can't open '$filename': $!"; + $/ = undef; + $data = ; + $/ = "\n"; + close(IN); + + return $data; +} + +### writeFile( $filename, $fileinput ) +# +# create the inputs to the ssl program at $filename, appending the common name to the +# stream in the process +# + +sub writeFile +{ + my ($filename, $fileinput) = @_; + + # + # test for a valid $filename + # + + if ( !defined($filename) || (length($filename) lt 1) ) + { + die "Filename is undefined"; + } + + if ( ( -e "$filename" ) && ( ! -w "$filename" ) ) + { + die "Cannot write to filename '$filename'"; + } + + # + # write the output to $filename + # + + open(OUT, ">$filename"); + print OUT "$fileinput"; + close(OUT); +} + +print "---------------------------------------------------------------------\n"; +print "Hi, I'm the setup script for the gsi_openssh package! There\n"; +print "are some last minute details that I've got to set straight\n"; +print "in the sshd config file, along with generating the ssh keys\n"; +print "for this machine (if it doesn't already have them).\n"; +print "\n"; +print "If I find a pair of host keys in /etc/ssh, I will copy them into\n"; +print "\$GLOBUS_LOCATION/etc/ssh. If they aren't present, I will generate\n"; +print "them for you.\n"; +print "\n"; + +$response = query_boolean("Do you wish to continue with the setup package?","y"); + +if ($response eq "n") +{ + print "\n"; + print "Okay.. exiting gsi_openssh setup.\n"; + + exit 0; } -copy_setup_files(); -runkeygen(); +$keyhash = determineKeys(); +runKeyGen($keyhash->{gen}); +copyKeyFiles($keyhash->{copy}); fixpaths(); my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup"); $metadata->finish(); +print "---------------------------------------------------------------------\n"; print "$myname: Finished configuring package 'gsi_openssh'.\n"; +print "\n"; +print "Additional Notes:\n"; +print "\n"; +print " o I see that you have your GLOBUS_LOCATION environmental variable\n"; +print " set to:\n"; +print "\n"; +print " \t\"$gpath\"\n"; +print "\n"; +print " Remember to keep this variable set (correctly) when you want to\n"; +print " use the executables that came with this package.\n"; +print "\n"; +print " o You may need to set LD_LIBRARY_PATH to point to the location in\n"; +print " which your globus libraries reside. For example:\n"; +print "\n"; +print " \t\$ LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; \\\n"; +print " \t export LD_LIBRARY_PATH\n"; +print "\n"; +print "---------------------------------------------------------------------\n"; # # Just need a minimal action() subroutine for now.. @@ -313,14 +411,27 @@ sub query_boolean print "${query_text} "; print "[$default] "; - $foo = getc(STDIN); - $bar = ; + $foo = ; + ($bar) = split //, $foo; + + if ( grep(/\s/, $bar) ) + { + # this is debatable. all whitespace means 'default' + + $bar = $default; + } + elsif ($bar ne $default) + { + # everything else means 'nondefault'. - if ($foo ne $nondefault) + $bar = $nondefault; + } + else { - $foo = $default; + # extraneous step. to get here, $bar should be eq to $default anyway. + + $bar = $default; } - return $foo; + return $bar; } -