X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/e9ec54550995bd474e16070d66b263d4d47673f1..e3118504578e45e19efe81514d732dff14983f67:/setup/setup-openssh.pl diff --git a/setup/setup-openssh.pl b/setup/setup-openssh.pl index 75c73ea..42446a0 100644 --- a/setup/setup-openssh.pl +++ b/setup/setup-openssh.pl @@ -1,32 +1,63 @@ +#!/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)) { die "GLOBUS_LOCATION needs to be set before running this script" } +# +# modify the ld library path for when we call ssh executables +# + +$oldldpath = $ENV{LD_LIBRARY_PATH}; +$newldpath = "$gpath/lib"; +if (length($oldldpath) > 0) +{ + $newldpath .= ":$oldldpath"; +} +$ENV{LD_LIBRARY_PATH} = "$newldpath"; + # # i'm including this because other perl scripts in the gpt setup directories # 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"; # @@ -36,187 +67,156 @@ my $myname = "setup-openssh.pl"; $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"; -# -# Backup-related variables -# +my $keyfiles = { + "dsa" => "ssh_host_dsa_key", + "rsa" => "ssh_host_rsa_key", + "rsa1" => "ssh_host_key", + }; -$curr_time = time(); -$backupdir = "globus_backup_${curr_time}"; -$confbackupdir = "$backupdir/s1_conf"; -$transbackupdir = "$backupdir/s2_trans"; +sub copyKeyFiles +{ + my($copylist) = @_; + my($regex, $basename); -# -# 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. -# + if (@$copylist) + { + print "Copying ssh host keys...\n"; -sub test_dirs -{ - my $composite; + for my $f (@$copylist) + { + $f =~ s:/+:/:g; - print "\nPreparatory: checking for existence of critical directories\n"; + if (length($f) > 0) + { + $keyfile = "$f"; + $pubkeyfile = "$f.pub"; - # - # Remember to put in check for /etc - # + action("cp $localsshdir/$keyfile $sysconfdir/$keyfile"); + action("cp $localsshdir/$pubkeyfile $sysconfdir/$pubkeyfile"); + } + } + } +} - # - # Test for /etc/ssh - # +sub isReadable +{ + my($file) = @_; - $composite = $sysconfdir; - if ( ! -d "$composite" ) + if ( ( -e $file ) && ( -r $file ) ) + { + return 1; + } + else { - print "Could not find directory: '${composite}'.. creating.\n"; - mkdir($composite, 16877); - # 16877 should be 755, or drwxr-xr-x + return 0; } +} - # - # Test for /etc/ssh/globus_backup_ - # +sub isPresent +{ + my($file) = @_; - $composite = "$sysconfdir/$backupdir"; - if ( ! -d "${composite}" ) + if ( -e $file ) { - print "Could not find directory: '${composite}'.. creating.\n"; - mkdir($composite, 16877); + return 1; } + else + { + return 0; + } +} + +sub determineKeys +{ + my($keyhash, $keylist); + my($count); # - # Test for /etc/ssh/globus_backup_/s1_conf + # initialize our variables # - $composite = "$sysconfdir/$confbackupdir"; - if ( ! -d "${composite}" ) - { - print "Could not find directory: '${composite}'.. creating.\n"; - mkdir($composite, 16877); - } + $count = 0; + + $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}; # - # Test for /etc/ssh/globus_backup_/s2_trans + # loop over our keytypes and determine what we need to do for each of them # - $composite = "$sysconfdir/$transbackupdir"; - if ( ! -d "${composite}" ) + for my $keytype (keys %$keyfiles) { - print "Could not find directory: '${composite}'.. creating.\n"; - mkdir($composite, 16877); - } + $basekeyfile = $keyfiles->{$keytype}; - return 0; -} - -sub copy_setup_files -{ - my $response; + # + # if the key's are already present, we don't need to bother with this rigamarole + # - print "\nStage 1: Copying configuration files into '${sysconfdir}'.\n"; + $gkeyfile = "$sysconfdir/$basekeyfile"; + $gpubkeyfile = "$sysconfdir/$basekeyfile.pub"; - $response = "y"; - if ( -e "${sysconfdir}/ssh_config" ) - { - $response = query_boolean("${sysconfdir}/ssh_config already exists. Overwrite? ", "n"); - if ($response eq "y") + if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) ) { - action("cp ${sysconfdir}/ssh_config ${sysconfdir}/${confbackupdir}/ssh_config"); + next; } - } - if ($response eq "y") - { - action("cp ${globusdir}/setup/globus/ssh_config ${sysconfdir}/ssh_config"); - } + # + # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's + # globus location + # - # - # Reset response for our new query - # + $mainkeyfile = "$localsshdir/$basekeyfile"; + $mainpubkeyfile = "$localsshdir/$basekeyfile.pub"; - $response = "y"; - if ( -e "${sysconfdir}/sshd_config" ) - { - $response = query_boolean("${sysconfdir}/sshd_config already exists. Overwrite? ", "n"); - if ($response eq "y") + if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) ) { - action("cp ${sysconfdir}/sshd_config ${sysconfdir}/${confbackupdir}/sshd_config"); + push(@$copylist, $basekeyfile); + $count++; + next; } - } - if ($response eq "y") - { - action("cp ${globusdir}/setup/globus/sshd_config ${sysconfdir}/sshd_config"); - } + # + # otherwise, we need to generate the key + # - # - # Reset response for our new query - # + push(@$genlist, $keytype); + $count++; + } - $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}/${confbackupdir}/moduli"); + 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 { - print "\nStage 2: Generating host keys.\n"; - - 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 (@$gen_keys) { - # 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 - { - # if $sysconfdir/ssh_host_dsa_key doesn't exist.. - action("$bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N \"\""); - } + for my $k (@$gen_keys) + { + $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; @@ -226,130 +226,195 @@ 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 "\nStage 3: Translating strings in config and 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 - # - # get the filename for $f and place it in $h. - # + close(OUT); + close(IN); - $h = $f; - $h =~ s#^.*/##; + # + # Remove the old .tmp file + # - # - # Grab the current mode/uid/gid for use later - # + $result = system("rm $g 2>&1"); - $mode = (stat($f))[2]; - $uid = (stat($f))[4]; - $gid = (stat($f))[5]; + if ($result or $?) + { + die "ERROR: Unable to execute command: $!\n"; + } - action("mv $f $g"); + # + # An attempt to revert the new file back to the original file's + # mode/uid/gid + # - if ($file{$f} == 1) - { - action("cp $f ${sysconfdir}/${transbackupdir}/$h"); - } + chmod($mode, $f); + chown($uid, $gid, $f); + + return 0; +} - open(IN, "<$g") || die ("$0: input file $g missing!\n"); - open(OUT, ">$f") || die ("$0: unable to open output file $f!\n"); +sub alterFileGlobusLocation +{ + my ($file) = @_; - while () - { - for $s (keys(%def)) - { - s#$s#$def{$s}#; - } # for $s - print OUT "$_"; - } # while + $data = readFile($file); + $data =~ s|\@GSI_OPENSSH_GLOBUS_LOCATION\@|$gpath|g; + writeFile($file, $data); +} - close(OUT); - close(IN); +sub alterFiles +{ + my (@files); - action("rm $g"); + @files = ( + "$gosharedir/contrib/caldera/sshd.init", + ); +} - # - # An attempt to revert the new file back to the original file's - # mode/uid/gid - # +### readFile( $filename ) +# +# reads and returns $filename's contents +# - chmod($mode, $f); - chown($uid, $gid, $f); - } # for $f +sub readFile +{ + my ($filename) = @_; + my $data; - return 0; + 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 "$myname: Configuring package 'gsi_openssh'..\n"; -print "NOTE: Run this as root for the intended effect.\n"; +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; +} -test_dirs(); -copy_setup_files(); -runkeygen(); +print "\n"; + +$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 "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"; print "$myname: Finished configuring package 'gsi_openssh'.\n"; # @@ -362,7 +427,7 @@ sub action printf "$command\n"; - my $result = system("$command 2>&1"); + my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1"); if (($result or $?) and $command !~ m!patch!) { @@ -394,13 +459,24 @@ sub query_boolean $foo = ; ($bar) = split //, $foo; - printf "bar = '$bar'\n"; + if ( grep(/\s/, $bar) ) + { + # this is debatable. all whitespace means 'default' + + $bar = $default; + } + elsif ($bar ne $default) + { + # everything else means 'nondefault'. - if ($bar ne $nondefault) + $bar = $nondefault; + } + else { + # extraneous step. to get here, $bar should be eq to $default anyway. + $bar = $default; } return $bar; } -