]> andersk Git - gssapi-openssh.git/blobdiff - setup/setup-openssh.pl
o Update version number of the package to 1.1.
[gssapi-openssh.git] / setup / setup-openssh.pl
index 4732285fafc5164df95194861b030745a41fbe5c..8ffc2d05d89e96557af052f7f957ebe40f066d6e 100644 (file)
@@ -105,6 +105,12 @@ GetOptions(
             'verbose' => \$verbose,
           ) or pod2usage(2);
 
+#
+# miscellaneous initialization functions
+#
+
+setPrivilegeSeparation(0);
+
 #
 # main execution.  This should find its way into a subroutine at some future
 # point.
@@ -115,11 +121,12 @@ 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.\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 "(Loosely, if I find a pair of host keys in /etc/ssh, I will copy them\n";
-print "into \$GLOBUS_LOCATION/etc/ssh.  Otherwise, I will generate them for\n";
-print "you.)\n";
+print "    Jacobim Mugatu says,\n";
+print "        \"Utopian Prime Minister Bad!  GSI-OpenSSH Good!\"\n";
 print "\n";
 
 if ( isForced() )
@@ -160,20 +167,63 @@ 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 "        \"$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 run, e.g.:\n";
+print "    After that you may execute, for example:\n";
 print "\n";
-print "    \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
+print "        \$ . \$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() )
+{
+    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 "    From the file README.privsep, included as a part of the OpenSSH\n";
+    print "    distribution:\n";
+    print "\n";
+    print "        When privsep is enabled, during the pre-authentication\n";
+    print "        phase sshd will chroot(2) to \"/var/empty\" and change its\n";
+    print "        privileges to the \"sshd\" user and its primary group.  sshd\n";
+    print "        is a pseudo-account that should not be used by other\n";
+    print "        daemons, and must be locked and should contain a \"nologin\"\n";
+    print "        or invalid shell.\n";
+    print "\n";
+    print "        You should do something like the following to prepare the\n";
+    print "        privsep preauth environment:\n";
+    print "\n";
+    print "            \# mkdir /var/empty\n";
+    print "            \# chown root:sys /var/empty\n";
+    print "            \# chmod 755 /var/empty\n";
+    print "            \# groupadd sshd\n";
+    print "            \# useradd -g sshd -c 'sshd privsep' -d /var/empty \\\n";
+    print "            -s /bin/false sshd\n";
+    print "\n";
+    print "        /var/empty should not contain any files.\n";
+}
+
+print "\n";
+print "  o For more information about GSI-Enabled OpenSSH, visit:\n";
+print "    <http://www.ncsa.uiuc.edu/Divisions/ACES/GSI/openssh/>\n";
+
+#
+# give the user a chance to read all of this output
+#
+
 print "\n";
-print "    \"Utopian Prime Minister bad!  GSI-OpenSSH *good*!\"\n";
-print "    \t--( Jacobim Mugatu )--\n";
+print "Press <return> to continue... ";
+$trash = <STDIN>;
+
 print "---------------------------------------------------------------------\n";
 print "$myname: Finished configuring package 'gsi_openssh'.\n";
 
@@ -274,9 +324,9 @@ 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");
+        printf("ssh_prng_cmds found and not forced.  Not installing ssh_prng_cmds...\n");
         return;
     }
 
@@ -724,6 +774,7 @@ sub copySSHDConfigFile
     my($fileInput, $fileOutput);
     my($mode, $uid, $gid);
     my($line, $newline);
+    my($privsep_enabled);
 
     print "Fixing paths in sshd_config...\n";
 
@@ -749,6 +800,28 @@ sub copySSHDConfigFile
         return;
     }
 
+    #
+    # check to see whether we should enable privilege separation
+    #
+
+    if ( userExists("sshd") && ( -d "/var/empty" ) && ( getOwnerID("/var/empty") eq 0 ) )
+    {
+        setPrivilegeSeparation(1);
+    }
+    else
+    {
+        setPrivilegeSeparation(0);
+    }
+
+    if ( getPrivilegeSeparation() )
+    {
+        $privsep_enabled = "yes";
+    }
+    else
+    {
+        $privsep_enabled = "no";
+    }
+
     #
     # Grab the current mode/uid/gid for use later
     #
@@ -761,36 +834,34 @@ sub copySSHDConfigFile
     # Open the files for reading and writing, and loop over the input's contents
     #
 
-    open(IN, "<$fileInput") || die ("$0: input file $fileInput missing!\n");
-    open(OUT, ">$fileOutput") || die ("$0: unable to open output file $fileOutput!\n");
+    $data = readFile($fileInput);
 
-    while (<IN>)
-    {
-        #
-        # sorry for the whacky regex, but i need to verify a whole line
-        #
+    #
+    # alter the PidFile config
+    #
 
-        $line = $_;
-        if ( $line =~ /^\s*Subsystem\s+sftp\s+\S+\s*$/ )
-        {
-            $line = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n";
-            $line =~ s:/+:/:g;
-        }
-        elsif ( $line =~ /^\s*PidFile.*$/ )
-        {
-            $line = "PidFile\t$gpath/var/sshd.pid\n";
-            $line =~ s:/+:/:g;
-        }
-        else
-        {
-            # do nothing
-        }
+    $text = "PidFile\t$gpath/var/sshd.pid";
+    $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
 
-        print OUT "$line";
-    } # while <IN>
+    #
+    # set the sftp directive
+    #
 
-    close(OUT);
-    close(IN);
+    $text = "Subsystem\tsftp\t$gpath/libexec/sftp-server";
+    $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
+
+    #
+    # set the privilege separation directive
+    #
+
+    $text = "UsePrivilegeSeparation\t${privsep_enabled}";
+    $data =~ s:^[\s|#]*UsePrivilegeSeparation.*$:$text:gm;
+
+    #
+    # dump the modified output to the config file
+    #
+
+    writeFile($fileOutput, $data);
 
     #
     # An attempt to revert the new file back to the original file's
@@ -803,6 +874,28 @@ sub copySSHDConfigFile
     return 0;
 }
 
+### setPrivilegeSeparation( $value )
+#
+# set the privilege separation variable to $value
+#
+
+sub setPrivilegeSeparation
+{
+    my($value) = @_;
+
+    $privsep = $value;
+}
+
+### getPrivilegeSeparation( )
+#
+# return the value of the privilege separation variable
+#
+
+sub getPrivilegeSeparation
+{
+    return $privsep;
+}
+
 ### prepareFileWrite( $file )
 #
 # test $file to prepare for writing to it.
@@ -904,6 +997,7 @@ sub copyFile
 sub copySXXScript
 {
     my($in, $out) = @_;
+    my($tmpgpath);
 
     if ( !isReadable($in) )
     {
@@ -916,8 +1010,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");
 }
@@ -1065,3 +1171,82 @@ sub absolutePath
     $file = abs_path($file);
     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.
+#
+
+sub getMode
+{
+    my($file) = @_;
+    my($tempmode, $mode);
+
+    #
+    # call stat() to get the mode of the file
+    #
+
+    $tempmode = (stat($file))[2];
+    if (length($tempmode) < 1)
+    {
+        return "";
+    }
+
+    #
+    # call sprintf to format the mode into a UNIX-like string
+    #
+
+    $mode = sprintf("%04o", $tempmode & 07777);
+
+    return $mode;
+}
+
+### userExists( $username )
+#
+# given a username, return true if the user exists on the system.  return false
+# otherwise.
+#
+
+sub userExists
+{
+    my($username) = @_;
+    my($uid);
+
+    #
+    # retrieve the userid of the user with the given username
+    #
+
+    $uid = getpwnam($username);
+
+    #
+    # return true if $uid is defined and has a length greater than 0
+    #
+
+    if ( defined($uid) and (length($uid) > 0) )
+    {
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
This page took 0.414899 seconds and 4 git commands to generate.