]> andersk Git - gssapi-openssh.git/blobdiff - setup/setup-openssh.pl
The man2html from jbasney on pkilab2 works whereas the standard one doesn't.
[gssapi-openssh.git] / setup / setup-openssh.pl
index 27707a5fa720a5ee87761f6abe49ba8da21f9fa5..6a4cdd50db13f254b0dafc77ecf29ea87432baac 100644 (file)
@@ -24,7 +24,7 @@ $gptpath = $ENV{GPT_LOCATION};
 $gpath = $ENV{GLOBUS_LOCATION};
 if (!defined($gpath))
 {
-    die "GLOBUS_LOCATION needs to be set before running this script"
+    exitDie("ERROR: GLOBUS_LOCATION needs to be set before running this script!\n");
 }
 
 #
@@ -35,18 +35,6 @@ use Getopt::Long;
 use Cwd;
 use Cwd 'abs_path';
 
-#
-# 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
@@ -76,7 +64,7 @@ my $myname = "setup-openssh.pl";
 
 $prefix = ${globusdir};
 $exec_prefix = "${prefix}";
-$bindir = "${exec_prefix}/bin";
+$bindir = "${exec_prefix}/bin/ssh.d";
 $sbindir = "${exec_prefix}/sbin";
 $sysconfdir = "$prefix/etc/ssh";
 $localsshdir = "/etc/ssh";
@@ -97,115 +85,58 @@ my $keyfiles = {
 # to verify correct args by using anon subs in various places.
 #
 
-my($interactive, $force, $verbose);
+my($prompt, $force, $verbose);
+
+$prompt = 1;
+$verbose = 0;
 
 GetOptions(
-            'interactive!' => \$interactive,
+            'prompt!' => \$prompt,
             'force' => \$force,
             'verbose' => \$verbose,
           ) or pod2usage(2);
 
 #
-# main execution.  This should find its way into a subroutine at some future
-# point.
+# miscellaneous initialization functions
 #
 
-print "$myname: Configuring package 'gsi_openssh'...\n";
-print "---------------------------------------------------------------------\n";
-print "Hi, I'm the setup script for the gsi_openssh package!  I will create\n";
-print "a number of configuration files based on your local system setup.  I\n";
-print "will also attempt to copy or create a number of SSH key pairs for\n";
-print "this machine.  (Loosely, if I find a pair of host keys in /etc/ssh,\n";
-print "I will copy them into \$GLOBUS_LOCATION/etc/ssh.  Otherwise, I will\n";
-print "generate them for you.)\n";
-print "\n";
-print "    Jacobim Mugatu says,\n";
-print "    \t\"Utopian Prime Minister Bad!  GSI-OpenSSH Good!\"\n";
-print "\n";
-
-if ( isForced() )
-{
-    print "WARNING:\n";
-    print "\n";
-    print "    Using the '-force' flag will cause all gsi_openssh_setup files to\n";
-    print "    be removed and replaced by new versions!  Backup any critical\n";
-    print "    SSH configuration files before you choose to continue!\n";
-    print "\n";
-}
-
-$response = query_boolean("Do you wish to continue with the setup package?","y");
-if ($response eq "n")
-{
-    print "\n";
-    print "Exiting gsi_openssh setup.\n";
+setPrivilegeSeparation(0);
 
-    exit 0;
-}
+#
+# main execution.  This should find its way into a subroutine at some future
+# point.
+#
 
-print "\n";
+debug0("Configuring gsi_openssh\n");
+debug0("------------------------------------------------------------\n");
+debug0("Executing...\n");
 
 makeConfDir();
 copyPRNGFile();
 $keyhash = determineKeys();
 runKeyGen($keyhash->{gen});
-copyKeyFiles($keyhash->{copy});
+linkKeyFiles($keyhash->{link});
 copyConfigFiles();
 
 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 "    After that you may execute, for example:\n";
-print "\n";
-print "    \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
-print "\n";
-print "    to prepare your environment for running the gsi_openssh\n";
-print "    executables.\n";
-
-if ( !getPrivilegeSeparation() )
+debug0("\n");
+debug0("Notes:\n\n");
+
+if ( getPrivilegeSeparation() )
 {
-    print "\n";
-    print "  o For System Administrators:\n";
-    print "\n";
-    print "    If you are going to run the GSI-OpenSSH server, we recommend\n";
-    print "    enabling privilege separation.  Although this package supports\n";
-    print "    this feature, your system appears to require some additional\n";
-    print "    configuration.\n";
-    print "\n";
-    print "    To enable privilege separation:\n";
-    print "\n";
-    print "    \tIf the system user 'sshd' does not already exist,\n";
-    print "    \tadd a user with that username.\n";
-    print "\n";
-    print "    \tVerify that /var/empty exists, is owned by root,\n";
-    print "    \tand has a mode of 0700.\n";
-    print "\n";
-    print "    \tEnable the feature UsePrivilegeSeparation in\n";
-    print "    \t\$GLOBUS_LOCATION/etc/ssh/sshd_config.\n";
+    debug0("  o Privilege separation is on.\n");
+}
+elsif ( !getPrivilegeSeparation() )
+{
+    debug0("  o Privilege separation is off.\n");
 }
 
-#
-# give the user a chance to read all of this output
-#
-
-print "\n";
-print "Press <return> to continue... ";
-$trash = <STDIN>;
-
-print "\n";
-print "---------------------------------------------------------------------\n";
-print "$myname: Finished configuring package 'gsi_openssh'.\n";
+debug0("  o GSI-OpenSSH website is <http://grid.ncsa.uiuc.edu/ssh/>.\n");
+debug0("------------------------------------------------------------\n");
+debug0("Finished configuring gsi_openssh.\n");
 
 exit;
 
@@ -241,7 +172,7 @@ sub initPRNGHash( )
     addPRNGCommand("\@PROG_IPCS\@", "ipcs");
     addPRNGCommand("\@PROG_TAIL\@", "tail");
 
-    print "Determining paths for PRNG commands...\n";
+    debug1("Determining paths for PRNG commands...\n");
 
     $paths = determinePRNGPaths();
 
@@ -304,15 +235,15 @@ sub copyPRNGFile
     my($mode, $uid, $gid);
     my($data);
 
-    if ( isPresent("/dev/random") && !isForced() )
+    if ( isPresent("$sysconfdir/ssh_prng_cmds") && !isForced() )
     {
-        printf("/dev/random found and not forced.  Not installing ssh_prng_cmds...\n");
+        debug1("ssh_prng_cmds found and not forced.  Not installing ssh_prng_cmds...\n");
         return;
     }
 
     initPRNGHash();
 
-    print "Fixing paths in ssh_prng_cmds...\n";
+    debug1("Fixing paths in ssh_prng_cmds...\n");
 
     $fileInput = "$setupdir/ssh_prng_cmds.in";
     $fileOutput = "$sysconfdir/ssh_prng_cmds";
@@ -323,7 +254,7 @@ sub copyPRNGFile
 
     if ( !isReadable($fileInput) )
     {
-        printf("Cannot read $fileInput... skipping.\n");
+        debug1("Cannot read $fileInput... skipping.\n");
         return;
     }
 
@@ -483,22 +414,22 @@ sub findExecutable
     return "undef";
 }
 
-### copyKeyFiles( $copylist )
+### linkKeyFiles( $linklist )
 #
-# given an array of keys to copy, copy both the key and its public variant into
+# given an array of keys to link, link both the key and its public variant into
 # the gsi-openssh configuration directory.
 #
 
-sub copyKeyFiles
+sub linkKeyFiles
 {
-    my($copylist) = @_;
+    my($linklist) = @_;
     my($regex, $basename);
 
-    if (@$copylist)
+    if (@$linklist)
     {
-        print "Copying ssh host keys...\n";
+        debug1("Linking ssh host keys...\n");
 
-        for my $f (@$copylist)
+        for my $f (@$linklist)
         {
             $f =~ s:/+:/:g;
 
@@ -507,8 +438,8 @@ sub copyKeyFiles
                 $keyfile = "$f";
                 $pubkeyfile = "$f.pub";
 
-                copyFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
-                copyFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
+                linkFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
+                linkFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
             }
         }
     }
@@ -623,10 +554,11 @@ sub makeConfDir
             return;
         }
 
-        die("${sysconfdir} already exists and is not a directory!\n");
+        debug1("${sysconfdir} already exists and is not a directory!\n");
+        exit;
     }
 
-    print "Could not find ${sysconfdir} directory... creating.\n";
+    debug1("Could not find ${sysconfdir} directory... creating.\n");
     action("mkdir -p $sysconfdir");
 
     return;
@@ -652,10 +584,10 @@ sub determineKeys
 
     $keyhash = {};
     $keyhash->{gen} = [];   # a list of keytypes to generate
-    $keyhash->{copy} = [];  # a list of files to copy from the 
+    $keyhash->{link} = [];  # a list of files to link
 
     $genlist = $keyhash->{gen};
-    $copylist = $keyhash->{copy};
+    $linklist = $keyhash->{link};
 
     #
     # loop over our keytypes and determine what we need to do for each of them
@@ -689,16 +621,16 @@ sub determineKeys
         }
 
         #
-        # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's
+        # if we can find a copy of the keys in /etc/ssh, we'll link them to the user's
         # globus location
         #
 
         $mainkeyfile = "$localsshdir/$basekeyfile";
         $mainpubkeyfile = "$localsshdir/$basekeyfile.pub";
 
-        if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) )
+        if ( isPresent($mainkeyfile) && isPresent($mainpubkeyfile) )
         {
-            push(@$copylist, $basekeyfile);
+            push(@$linklist, $basekeyfile);
             $count++;
             next;
         }
@@ -727,7 +659,7 @@ sub runKeyGen
 
     if (@$gen_keys && -x $keygen)
     {
-        print "Generating ssh host keys...\n";
+        debug1("Generating ssh host keys...\n");
 
         for my $k (@$gen_keys)
         {
@@ -756,7 +688,7 @@ sub copySSHDConfigFile
     my($line, $newline);
     my($privsep_enabled);
 
-    print "Fixing paths in sshd_config...\n";
+    debug1("Fixing paths in sshd_config...\n");
 
     $fileInput = "$setupdir/sshd_config.in";
     $fileOutput = "$sysconfdir/sshd_config";
@@ -767,7 +699,7 @@ sub copySSHDConfigFile
 
     if ( !isReadable($fileInput) )
     {
-        printf("Cannot read $fileInput... skipping.\n");
+        debug1("Cannot read $fileInput... skipping.\n");
         return;
     }
 
@@ -784,7 +716,7 @@ sub copySSHDConfigFile
     # check to see whether we should enable privilege separation
     #
 
-    if ( userExists("sshd") && ( -d "/var/empty" ) && ( getMode("/var/empty") eq "0700" ) )
+    if ( userExists("sshd") && ( -d "/var/empty" ) && ( getOwnerID("/var/empty") eq 0 ) )
     {
         setPrivilegeSeparation(1);
     }
@@ -816,18 +748,18 @@ sub copySSHDConfigFile
 
     $data = readFile($fileInput);
 
-    #
-    # alter the PidFile config
-    #
-
-    $text = "PidFile\t$gpath/var/sshd.pid";
-    $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
+    # #
+    # alter the PidFile config
+    # #
+    # 
+    $text = "PidFile\t$gpath/var/sshd.pid";
+    $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
 
     #
     # set the sftp directive
     #
 
-    $text = "Subsystem\tsftp\t$gpath/libxec/sftp-server";
+    $text = "Subsystem\tsftp\t$gpath/libexec/sftp-server";
     $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
 
     #
@@ -887,25 +819,25 @@ sub prepareFileWrite
 
     if ( isPresent($file) )
     {
-        printf("$file already exists... ");
+        debug1("$file already exists... ");
 
         if ( isForced() )
         {
             if ( isWritable($file) )
             {
-                printf("removing.\n");
+                debug1("removing.\n");
                 action("rm $file");
                 return 1;
             }
             else
             {
-                printf("not writable -- skipping.\n");
+                debug1("not writable -- skipping.\n");
                 return 0;
             }
         }
         else
         {
-            printf("skipping.\n");
+            debug1("skipping.\n");
             return 0;
         }
     }
@@ -932,7 +864,7 @@ sub copyConfigFiles
     # do straight copies of the ssh_config and moduli files.
     #
 
-    printf("Copying ssh_config and moduli to their proper location...\n");
+    debug1("Copying ssh_config and moduli to their proper location...\n");
 
     copyFile("$setupdir/ssh_config", "$sysconfdir/ssh_config");
     copyFile("$setupdir/moduli", "$sysconfdir/moduli");
@@ -944,6 +876,29 @@ sub copyConfigFiles
     copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
 }
 
+### linkFile( $src, $dest )
+#
+# create a symbolic link from $src to $dest.
+#
+
+sub linkFile
+{
+    my($src, $dest) = @_;
+
+    if ( !isPresent($src) )
+    {
+        debug1("$src is not readable... not creating $dest.\n");
+        return;
+    }
+
+    if ( !prepareFileWrite($dest) )
+    {
+        return;
+    }
+
+    action("ln -s $src $dest");
+}
+
 ### copyFile( $src, $dest )
 #
 # copy the file pointed to by $src to the location specified by $dest.  in the
@@ -956,7 +911,7 @@ sub copyFile
 
     if ( !isReadable($src) )
     {
-        printf("$src is not readable... not creating $dest.\n");
+        debug1("$src is not readable... not creating $dest.\n");
         return;
     }
 
@@ -977,10 +932,11 @@ sub copyFile
 sub copySXXScript
 {
     my($in, $out) = @_;
+    my($tmpgpath);
 
     if ( !isReadable($in) )
     {
-        printf("$in is not readable... not creating $out.\n");
+        debug1("$in is not readable... not creating $out.\n");
         return;
     }
 
@@ -989,8 +945,20 @@ sub copySXXScript
         return;
     }
 
+    #
+    # clean up any junk in the globus path variable
+    #
+
+    $tmpgpath = $gpath;
+    $tmpgpath =~ s:/+:/:g;
+    $tmpgpath =~ s:([^/]+)/$:\1:g;
+
+    #
+    # read in the script, substitute globus location, then write it back out
+    #
+
     $data = readFile($in);
-    $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g;
+    $data =~ s|\@GLOBUS_LOCATION\@|$tmpgpath|g;
     writeFile($out, $data);
     action("chmod 755 $out");
 }
@@ -1005,7 +973,7 @@ sub readFile
     my($filename) = @_;
     my($data);
 
-    open(IN, "$filename") || die "Can't open '$filename': $!";
+    open(IN, "$filename") || exitDie("ERROR: Can't open '$filename': $!\n");
     $/ = undef;
     $data = <IN>;
     $/ = "\n";
@@ -1030,7 +998,7 @@ sub writeFile
 
     if ( !defined($filename) || (length($filename) lt 1) )
     {
-        die "Filename is undefined";
+        exitDie("ERROR: Filename is undefined!\n");
     }
 
     #
@@ -1051,6 +1019,47 @@ sub writeFile
     close(OUT);
 }
 
+### debug1( $arg1, $arg2 )
+#
+# Print out a debugging message at level 1.
+#
+
+sub debug1
+{
+    debug(string => \@_, level => 1);
+}
+
+### debug0( $arg1, $arg2 )
+#
+# Print out a debugging message at level 0.
+#
+
+sub debug0
+{
+    debug(string => \@_, level => 0);
+}
+
+### debug( string => $string, level => $level )
+#
+# Print out debugging messages at various levels.  Feel free to use debugN() directly
+# which in turn calls this subroutine.
+#
+
+sub debug
+{
+    my %args = @_;
+
+    if (!defined($args{'level'}))
+    {
+        $args{'level'} = 0;
+    }
+
+    if ($verbose >= $args{'level'})
+    {
+        printf(@{$args{'string'}});
+    }
+}
+
 ### action( $command )
 #
 # run $command within a proper system() command.
@@ -1060,16 +1069,30 @@ sub action
 {
     my($command) = @_;
 
-    printf "$command\n";
+    debug1("$command\n");
 
-    my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
+    my $result = system("$command >/dev/null 2>&1");
 
     if (($result or $?) and $command !~ m!patch!)
     {
-        die "ERROR: Unable to execute command: $!\n";
+        exitDie("ERROR: Unable to execute $command: $!\n");
     }
 }
 
+### exitDie( $error )
+#
+# a horribly named method meant to look like die but only exit, thereby not causing
+# gpt-postinstall to croak.
+#
+
+sub exitDie
+{
+    my($error) = @_;
+
+    print $error;
+    exit;
+}
+
 ### query_boolean( $query_text, $default )
 #
 # query the user with a string, and expect a response.  If the user hits
@@ -1081,6 +1104,12 @@ sub query_boolean
     my($query_text, $default) = @_;
     my($nondefault, $foo, $bar);
 
+    if ( !$prompt )
+    {
+        print "Prompt suppressed.  Continuing...\n";
+        return "y";
+    }
+
     #
     # Set $nondefault to the boolean opposite of $default.
     #
@@ -1106,6 +1135,10 @@ sub query_boolean
 
         $bar = $default;
     }
+    elsif ($bar eq '')
+    {
+        $bar = $default;
+    }
     elsif ($bar ne $default)
     {
         # everything else means 'nondefault'.
@@ -1139,6 +1172,25 @@ sub absolutePath
     return $file;
 }
 
+### getOwnerID( $file )
+#
+# return the uid containing the owner ID of the given file.
+#
+
+sub getOwnerID
+{
+    my($file) = @_;
+    my($uid);
+
+    #
+    # call stat() to get the mode of the file
+    #
+
+    $uid = (stat($file))[4];
+
+    return $uid;
+}
+
 ### getMode( $file )
 #
 # return a string containing the mode of the given file.
This page took 0.061212 seconds and 4 git commands to generate.