]> andersk Git - gssapi-openssh.git/blob - setup/setup-openssh.pl
o Rearrange output of message re: privsep to user.
[gssapi-openssh.git] / setup / setup-openssh.pl
1 #!/usr/bin/perl
2 #
3 # setup-openssh.pl
4 #
5 # Adapts the installed gsi-openssh environment to the current machine,
6 # performing actions that originally occurred during the package's
7 # 'make install' phase.
8 #
9 # Send comments/fixes/suggestions to:
10 # Chase Phillips <cphillip@ncsa.uiuc.edu>
11 #
12
13 #
14 # Get user's GPT_LOCATION since we may be installing this using a new(er)
15 # version of GPT.
16 #
17
18 $gptpath = $ENV{GPT_LOCATION};
19
20 #
21 # And the old standby..
22 #
23
24 $gpath = $ENV{GLOBUS_LOCATION};
25 if (!defined($gpath))
26 {
27     die "GLOBUS_LOCATION needs to be set before running this script"
28 }
29
30 #
31 # Include standard modules
32 #
33
34 use Getopt::Long;
35 use Cwd;
36 use Cwd 'abs_path';
37
38 #
39 # modify the ld library path for when we call ssh executables
40 #
41
42 $oldldpath = $ENV{LD_LIBRARY_PATH};
43 $newldpath = "$gpath/lib";
44 if (length($oldldpath) > 0)
45 {
46     $newldpath .= ":$oldldpath";
47 }
48 $ENV{LD_LIBRARY_PATH} = "$newldpath";
49
50 #
51 # i'm including this because other perl scripts in the gpt setup directories
52 # do so
53 #
54
55 if (defined($gptpath))
56 {
57     @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl");
58 }
59 else
60 {
61     @INC = (@INC, "$gpath/lib/perl");
62 }
63
64 require Grid::GPT::Setup;
65
66 #
67 # script-centred variable initialization
68 #
69
70 my $globusdir = $gpath;
71 my $myname = "setup-openssh.pl";
72
73 #
74 # Set up path prefixes for use in the path translations
75 #
76
77 $prefix = ${globusdir};
78 $exec_prefix = "${prefix}";
79 $bindir = "${exec_prefix}/bin";
80 $sbindir = "${exec_prefix}/sbin";
81 $sysconfdir = "$prefix/etc/ssh";
82 $localsshdir = "/etc/ssh";
83 $setupdir = "$prefix/setup/gsi_openssh_setup";
84
85 #
86 # standard key types and their root file name mappings
87 #
88
89 my $keyfiles = {
90                  "dsa" => "ssh_host_dsa_key",
91                  "rsa" => "ssh_host_rsa_key",
92                  "rsa1" => "ssh_host_key",
93                };
94
95 #
96 # argument specification.  we offload some processing work from later functions
97 # to verify correct args by using anon subs in various places.
98 #
99
100 my($interactive, $force, $verbose);
101
102 GetOptions(
103             'interactive!' => \$interactive,
104             'force' => \$force,
105             'verbose' => \$verbose,
106           ) or pod2usage(2);
107
108 #
109 # main execution.  This should find its way into a subroutine at some future
110 # point.
111 #
112
113 print "$myname: Configuring package 'gsi_openssh'...\n";
114 print "---------------------------------------------------------------------\n";
115 print "Hi, I'm the setup script for the gsi_openssh package!  I will create\n";
116 print "a number of configuration files based on your local system setup.  I\n";
117 print "will also attempt to copy or create a number of SSH key pairs for\n";
118 print "this machine.  (Loosely, if I find a pair of host keys in /etc/ssh,\n";
119 print "I will copy them into \$GLOBUS_LOCATION/etc/ssh.  Otherwise, I will\n";
120 print "generate them for you.)\n";
121 print "\n";
122 print "    Jacobim Mugatu says,\n";
123 print "        \"Utopian Prime Minister Bad!  GSI-OpenSSH Good!\"\n";
124 print "\n";
125
126 if ( isForced() )
127 {
128     print "WARNING:\n";
129     print "\n";
130     print "    Using the '-force' flag will cause all gsi_openssh_setup files to\n";
131     print "    be removed and replaced by new versions!  Backup any critical\n";
132     print "    SSH configuration files before you choose to continue!\n";
133     print "\n";
134 }
135
136 $response = query_boolean("Do you wish to continue with the setup package?","y");
137 if ($response eq "n")
138 {
139     print "\n";
140     print "Exiting gsi_openssh setup.\n";
141
142     exit 0;
143 }
144
145 print "\n";
146
147 makeConfDir();
148 copyPRNGFile();
149 $keyhash = determineKeys();
150 runKeyGen($keyhash->{gen});
151 copyKeyFiles($keyhash->{copy});
152 copyConfigFiles();
153
154 my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup");
155
156 $metadata->finish();
157
158 print "\n";
159 print "Additional Notes:\n";
160 print "\n";
161 print "  o I see that you have your GLOBUS_LOCATION environmental variable\n";
162 print "    set to:\n";
163 print "\n";
164 print "        \"$gpath\"\n";
165 print "\n";
166 print "    Remember to keep this variable set (correctly) when you want to\n";
167 print "    use the executables that came with this package.\n";
168 print "\n";
169 print "    After that you may execute, for example:\n";
170 print "\n";
171 print "        \$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
172 print "\n";
173 print "    to prepare your environment for running the gsi_openssh\n";
174 print "    executables.\n";
175
176 if ( !getPrivilegeSeparation() )
177 {
178     print "\n";
179     print "  o For System Administrators:\n";
180     print "\n";
181     print "    If you are going to run the GSI-OpenSSH server, we recommend\n";
182     print "    enabling privilege separation.  Although this package supports\n";
183     print "    this feature, your system appears to require some additional\n";
184     print "    configuration.\n";
185     print "\n";
186     print "    From the file README.privsep, included as a part of the OpenSSH\n";
187     print "    distribution:\n";
188     print "\n";
189     print "        When privsep is enabled, during the pre-authentication\n";
190     print "        phase sshd will chroot(2) to \"/var/empty\" and change its\n";
191     print "        privileges to the \"sshd\" user and its primary group.  sshd\n";
192     print "        is a pseudo-account that should not be used by other\n";
193     print "        daemons, and must be locked and should contain a \"nologin\"\n";
194     print "        or invalid shell.\n";
195     print "\n";
196     print "        You should do something like the following to prepare the\n";
197     print "        privsep preauth environment:\n";
198     print "\n";
199     print "            \# mkdir /var/empty\n";
200     print "            \# chown root:sys /var/empty\n";
201     print "            \# chmod 755 /var/empty\n";
202     print "            \# groupadd sshd\n";
203     print "            \# useradd -g sshd -c 'sshd privsep' -d /var/empty \\\n";
204     print "            -s /bin/false sshd\n";
205     print "\n";
206     print "        /var/empty should not contain any files.\n";
207 }
208
209 print "\n";
210 print "  o For more information about GSI-Enabled OpenSSH, visit:\n";
211 print "    <http://www.ncsa.uiuc.edu/Divisions/ACES/GSI/openssh/>\n";
212
213 #
214 # give the user a chance to read all of this output
215 #
216
217 print "\n";
218 print "Press <return> to continue... ";
219 $trash = <STDIN>;
220
221 print "---------------------------------------------------------------------\n";
222 print "$myname: Finished configuring package 'gsi_openssh'.\n";
223
224 exit;
225
226 #
227 # subroutines
228 #
229
230 ### initPRNGHash( )
231 #
232 # initialize the PRNG pathname hash
233 #
234
235 sub initPRNGHash( )
236 {
237     #
238     # standard prng to executable conversion names
239     #
240
241     addPRNGCommand("\@PROG_LS\@", "ls");
242     addPRNGCommand("\@PROG_NETSTAT\@", "netstat");
243     addPRNGCommand("\@PROG_ARP\@", "arp");
244     addPRNGCommand("\@PROG_IFCONFIG\@", "ifconfig");
245     addPRNGCommand("\@PROG_PS\@", "ps");
246     addPRNGCommand("\@PROG_JSTAT\@", "jstat");
247     addPRNGCommand("\@PROG_W\@", "w");
248     addPRNGCommand("\@PROG_WHO\@", "who");
249     addPRNGCommand("\@PROG_LAST\@", "last");
250     addPRNGCommand("\@PROG_LASTLOG\@", "lastlog");
251     addPRNGCommand("\@PROG_DF\@", "df");
252     addPRNGCommand("\@PROG_SAR\@", "sar");
253     addPRNGCommand("\@PROG_VMSTAT\@", "vmstat");
254     addPRNGCommand("\@PROG_UPTIME\@", "uptime");
255     addPRNGCommand("\@PROG_IPCS\@", "ipcs");
256     addPRNGCommand("\@PROG_TAIL\@", "tail");
257
258     print "Determining paths for PRNG commands...\n";
259
260     $paths = determinePRNGPaths();
261
262     return;
263 }
264
265 ### getDirectoryPaths( )
266 #
267 # return an array ref containing all of the directories in which we should search
268 # for our listing of executable names.
269 #
270
271 sub getDirectoryPaths( )
272 {
273     #
274     # read in the PATH environmental variable and prepend a set of 'safe'
275     # directories from which to test PRNG commands.
276     #
277
278     $path = $ENV{PATH};
279     $path = "/bin:/usr/bin:/sbin:/usr/sbin:/etc:" . $path;
280     @dirs = split(/:/, $path);
281
282     #
283     # sanitize each directory listed in the array.
284     #
285
286     @dirs = map {
287                   $tmp = $_;
288                   $tmp =~ s:/+:/:g;
289                   $tmp =~ s:^\s+|\s+$::g;
290                   $tmp;
291                 } @dirs;
292
293     return \@dirs;
294 }
295
296 ### addPRNGCommand( $prng_name, $exec_name )
297 #
298 # given a PRNG name and a corresponding executable name, add it to our list of
299 # PRNG commands for which to find on the system.
300 #
301
302 sub addPRNGCommand
303 {
304     my($prng_name, $exec_name) = @_;
305
306     prngAddNode($prng_name, $exec_name);
307 }
308
309 ### copyPRNGFile( )
310 #
311 # read in ssh_prng_cmds.in, translate the program listings to the paths we have
312 # found on the local system, and then write the output to ssh_prng_cmds.
313 #
314
315 sub copyPRNGFile
316 {
317     my($fileInput, $fileOutput);
318     my($mode, $uid, $gid);
319     my($data);
320
321     if ( isPresent("/dev/random") && !isForced() )
322     {
323         printf("/dev/random found and not forced.  Not installing ssh_prng_cmds...\n");
324         return;
325     }
326
327     initPRNGHash();
328
329     print "Fixing paths in ssh_prng_cmds...\n";
330
331     $fileInput = "$setupdir/ssh_prng_cmds.in";
332     $fileOutput = "$sysconfdir/ssh_prng_cmds";
333
334     #
335     # verify that we are prepared to work with $fileInput
336     #
337
338     if ( !isReadable($fileInput) )
339     {
340         printf("Cannot read $fileInput... skipping.\n");
341         return;
342     }
343
344     #
345     # verify that we are prepared to work with $fileOuput
346     #
347
348     if ( !prepareFileWrite($fileOutput) )
349     {
350         return;
351     }
352
353     #
354     # Grab the current mode/uid/gid for use later
355     #
356
357     $mode = (stat($fileInput))[2];
358     $uid = (stat($fileInput))[4];
359     $gid = (stat($fileInput))[5];
360
361     #
362     # Open the files for reading and writing, and loop over the input's contents
363     #
364
365     $data = readFile($fileInput);
366     for my $k (keys %$prngcmds)
367     {
368         $sub = prngGetExecPath($k);
369         $data =~ s:$k:$sub:g;
370     }
371     writeFile($fileOutput, $data);
372
373     #
374     # An attempt to revert the new file back to the original file's
375     # mode/uid/gid
376     #
377
378     chmod($mode, $fileOutput);
379     chown($uid, $gid, $fileOutput);
380
381     return 0;
382 }
383
384 ### determinePRNGPaths( )
385 #
386 # for every entry in the PRNG hash, seek out and find the path for the
387 # corresponding executable name.
388 #
389
390 sub determinePRNGPaths
391 {
392     my(@paths, @dirs);
393     my($exec_name, $exec_path);
394
395     $dirs = getDirectoryPaths();
396
397     for my $k (keys %$prngcmds)
398     {
399         $exec_name = prngGetExecName($k);
400         $exec_path = findExecutable($exec_name, $dirs);
401         prngSetExecPath($k, $exec_path);
402     }
403
404     return;
405 }
406
407 ### prngAddNode( $prng_name, $exec_name )
408 #
409 # add a new node to the PRNG hash
410 #
411
412 sub prngAddNode
413 {
414     my($prng_name, $exec_name) = @_;
415     my($node);
416
417     if (!defined($prngcmds))
418     {
419         $prngcmds = {};
420     }
421
422     $node = {};
423     $node->{prng} = $prng_name;
424     $node->{exec} = $exec_name;
425
426     $prngcmds->{$prng_name} = $node;
427 }
428
429 ### prngGetExecName( $key )
430 #
431 # get the executable name from the prng commands hash named by $key
432 #
433
434 sub prngGetExecName
435 {
436     my($key) = @_;
437
438     return $prngcmds->{$key}->{exec};
439 }
440
441 ### prngGetExecPath( $key )
442 #
443 # get the executable path from the prng commands hash named by $key
444 #
445
446 sub prngGetExecPath
447 {
448     my($key) = @_;
449
450     return $prngcmds->{$key}->{exec_path};
451 }
452
453 ### prngGetNode( $key )
454 #
455 # return a reference to the node named by $key
456 #
457
458 sub prngGetNode
459 {
460     my($key) = @_;
461
462     return ${$prngcmds}{$key};
463 }
464
465 ### prngSetExecPath( $key, $path )
466 #
467 # given a key, set the executable path in that node to $path
468 #
469
470 sub prngSetExecPath
471 {
472     my($key, $path) = @_;
473
474     $prngcmds->{$key}->{exec_path} = $path;
475 }
476
477 ### findExecutable( $exec_name, $dirs )
478 #
479 # given an executable name, test each possible path in $dirs to see if such
480 # an executable exists.
481 #
482
483 sub findExecutable
484 {
485     my($exec_name, $dirs) = @_;
486
487     for my $d (@$dirs)
488     {
489         $test = "$d/$exec_name";
490
491         if ( isExecutable($test) )
492         {
493             return $test;
494         }
495     }
496
497     return "undef";
498 }
499
500 ### copyKeyFiles( $copylist )
501 #
502 # given an array of keys to copy, copy both the key and its public variant into
503 # the gsi-openssh configuration directory.
504 #
505
506 sub copyKeyFiles
507 {
508     my($copylist) = @_;
509     my($regex, $basename);
510
511     if (@$copylist)
512     {
513         print "Copying ssh host keys...\n";
514
515         for my $f (@$copylist)
516         {
517             $f =~ s:/+:/:g;
518
519             if (length($f) > 0)
520             {
521                 $keyfile = "$f";
522                 $pubkeyfile = "$f.pub";
523
524                 copyFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
525                 copyFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
526             }
527         }
528     }
529 }
530
531 ### isForced( )
532 #
533 # return true if the user passed in the force flag.  return false otherwise.
534 #
535
536 sub isForced
537 {
538     if ( defined($force) && $force )
539     {
540         return 1;
541     }
542     else
543     {
544         return 0;
545     }
546 }
547
548 ### isReadable( $file )
549 #
550 # given a file, return true if that file both exists and is readable by the
551 # effective user id.  return false otherwise.
552 #
553
554 sub isReadable
555 {
556     my($file) = @_;
557
558     if ( ( -e $file ) && ( -r $file ) )
559     {
560         return 1;
561     }
562     else
563     {
564         return 0;
565     }
566 }
567
568 ### isExecutable( $file )
569 #
570 # return true if $file is executable.  return false otherwise.
571 #
572
573 sub isExecutable
574 {
575     my($file) = @_;
576
577     if ( -x $file )
578     {
579         return 1;
580     }
581     else
582     {
583         return 0;
584     }
585 }
586
587 ### isWritable( $file )
588 #
589 # given a file, return true if that file does not exist or is writable by the
590 # effective user id.  return false otherwise.
591 #
592
593 sub isWritable
594 {
595     my($file) = @_;
596
597     if ( ( ! -e $file ) || ( -w $file ) )
598     {
599         return 1;
600     }
601     else
602     {
603         return 0;
604     }
605 }
606
607 ### isPresent( $file )
608 #
609 # given a file, return true if that file exists.  return false otherwise.
610 #
611
612 sub isPresent
613 {
614     my($file) = @_;
615
616     if ( -e $file )
617     {
618         return 1;
619     }
620     else
621     {
622         return 0;
623     }
624 }
625
626 ### makeConfDir( )
627 #
628 # make the gsi-openssh configuration directory if it doesn't already exist.
629 #
630
631 sub makeConfDir
632 {
633     if ( isPresent($sysconfdir) )
634     {
635         if ( -d $sysconfdir )
636         {
637             return;
638         }
639
640         die("${sysconfdir} already exists and is not a directory!\n");
641     }
642
643     print "Could not find ${sysconfdir} directory... creating.\n";
644     action("mkdir -p $sysconfdir");
645
646     return;
647 }
648
649 ### determineKeys( )
650 #
651 # based on a set of key types, triage them to determine if for each key type, that
652 # key type should be copied from the main ssh configuration directory, or if it
653 # should be generated using ssh-keygen.
654 #
655
656 sub determineKeys
657 {
658     my($keyhash, $keylist);
659     my($count);
660
661     #
662     # initialize our variables
663     #
664
665     $count = 0;
666
667     $keyhash = {};
668     $keyhash->{gen} = [];   # a list of keytypes to generate
669     $keyhash->{copy} = [];  # a list of files to copy from the 
670
671     $genlist = $keyhash->{gen};
672     $copylist = $keyhash->{copy};
673
674     #
675     # loop over our keytypes and determine what we need to do for each of them
676     #
677
678     for my $keytype (keys %$keyfiles)
679     {
680         $basekeyfile = $keyfiles->{$keytype};
681
682         #
683         # if the key's are already present, we don't need to bother with this rigamarole
684         #
685
686         $gkeyfile = "$sysconfdir/$basekeyfile";
687         $gpubkeyfile = "$sysconfdir/$basekeyfile.pub";
688
689         if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) )
690         {
691             if ( isForced() )
692             {
693                 if ( isWritable("$sysconfdir/$basekeyfile") && isWritable("$sysconfdir/$basekeyfile.pub") )
694                 {
695                      action("rm $sysconfdir/$basekeyfile");
696                      action("rm $sysconfdir/$basekeyfile.pub");
697                 }
698                 else
699                 {
700                      next;
701                 }
702             }
703         }
704
705         #
706         # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's
707         # globus location
708         #
709
710         $mainkeyfile = "$localsshdir/$basekeyfile";
711         $mainpubkeyfile = "$localsshdir/$basekeyfile.pub";
712
713         if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) )
714         {
715             push(@$copylist, $basekeyfile);
716             $count++;
717             next;
718         }
719
720         #
721         # otherwise, we need to generate the key
722         #
723
724         push(@$genlist, $keytype);
725         $count++;
726     }
727
728     return $keyhash;
729 }
730
731 ### runKeyGen( $gen_keys )
732 #
733 # given a set of key types, generate private and public keys for that key type and
734 # place them in the gsi-openssh configuration directory.
735 #
736
737 sub runKeyGen
738 {
739     my($gen_keys) = @_;
740     my $keygen = "$bindir/ssh-keygen";
741
742     if (@$gen_keys && -x $keygen)
743     {
744         print "Generating ssh host keys...\n";
745
746         for my $k (@$gen_keys)
747         {
748             $keyfile = $keyfiles->{$k};
749
750             if ( !isPresent("$sysconfdir/$keyfile") )
751             {
752                 action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
753             }
754         }
755     }
756
757     return 0;
758 }
759
760 ### copySSHDConfigFile( )
761 #
762 # this subroutine 'edits' the paths in sshd_config to suit them to the current environment
763 # in which the setup script is being run.
764 #
765
766 sub copySSHDConfigFile
767 {
768     my($fileInput, $fileOutput);
769     my($mode, $uid, $gid);
770     my($line, $newline);
771     my($privsep_enabled);
772
773     print "Fixing paths in sshd_config...\n";
774
775     $fileInput = "$setupdir/sshd_config.in";
776     $fileOutput = "$sysconfdir/sshd_config";
777
778     #
779     # verify that we are prepared to work with $fileInput
780     #
781
782     if ( !isReadable($fileInput) )
783     {
784         printf("Cannot read $fileInput... skipping.\n");
785         return;
786     }
787
788     #
789     # verify that we are prepared to work with $fileOuput
790     #
791
792     if ( !prepareFileWrite($fileOutput) )
793     {
794         return;
795     }
796
797     #
798     # check to see whether we should enable privilege separation
799     #
800
801     if ( userExists("sshd") && ( -d "/var/empty" ) && ( getOwnerID("/var/empty") eq 0 ) )
802     {
803         setPrivilegeSeparation(1);
804     }
805     else
806     {
807         setPrivilegeSeparation(0);
808     }
809
810     if ( getPrivilegeSeparation() )
811     {
812         $privsep_enabled = "yes";
813     }
814     else
815     {
816         $privsep_enabled = "no";
817     }
818
819     #
820     # Grab the current mode/uid/gid for use later
821     #
822
823     $mode = (stat($fileInput))[2];
824     $uid = (stat($fileInput))[4];
825     $gid = (stat($fileInput))[5];
826
827     #
828     # Open the files for reading and writing, and loop over the input's contents
829     #
830
831     $data = readFile($fileInput);
832
833     #
834     # alter the PidFile config
835     #
836
837     $text = "PidFile\t$gpath/var/sshd.pid";
838     $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
839
840     #
841     # set the sftp directive
842     #
843
844     $text = "Subsystem\tsftp\t$gpath/libxec/sftp-server";
845     $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
846
847     #
848     # set the privilege separation directive
849     #
850
851     $text = "UsePrivilegeSeparation\t${privsep_enabled}";
852     $data =~ s:^[\s|#]*UsePrivilegeSeparation.*$:$text:gm;
853
854     #
855     # dump the modified output to the config file
856     #
857
858     writeFile($fileOutput, $data);
859
860     #
861     # An attempt to revert the new file back to the original file's
862     # mode/uid/gid
863     #
864
865     chmod($mode, $fileOutput);
866     chown($uid, $gid, $fileOutput);
867
868     return 0;
869 }
870
871 ### setPrivilegeSeparation( $value )
872 #
873 # set the privilege separation variable to $value
874 #
875
876 sub setPrivilegeSeparation
877 {
878     my($value) = @_;
879
880     $privsep = $value;
881 }
882
883 ### getPrivilegeSeparation( )
884 #
885 # return the value of the privilege separation variable
886 #
887
888 sub getPrivilegeSeparation
889 {
890     return $privsep;
891 }
892
893 ### prepareFileWrite( $file )
894 #
895 # test $file to prepare for writing to it.
896 #
897
898 sub prepareFileWrite
899 {
900     my($file) = @_;
901
902     if ( isPresent($file) )
903     {
904         printf("$file already exists... ");
905
906         if ( isForced() )
907         {
908             if ( isWritable($file) )
909             {
910                 printf("removing.\n");
911                 action("rm $file");
912                 return 1;
913             }
914             else
915             {
916                 printf("not writable -- skipping.\n");
917                 return 0;
918             }
919         }
920         else
921         {
922             printf("skipping.\n");
923             return 0;
924         }
925     }
926
927     return 1;
928 }
929
930 ### copyConfigFiles( )
931 #
932 # subroutine that copies some extra config files to their proper location in
933 # $GLOBUS_LOCATION/etc/ssh.
934 #
935
936 sub copyConfigFiles
937 {
938     #
939     # copy the sshd_config file into the ssh configuration directory and alter
940     # the paths in the file.
941     #
942
943     copySSHDConfigFile();
944
945     #
946     # do straight copies of the ssh_config and moduli files.
947     #
948
949     printf("Copying ssh_config and moduli to their proper location...\n");
950
951     copyFile("$setupdir/ssh_config", "$sysconfdir/ssh_config");
952     copyFile("$setupdir/moduli", "$sysconfdir/moduli");
953
954     #
955     # copy and alter the SXXsshd script.
956     #
957
958     copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
959 }
960
961 ### copyFile( $src, $dest )
962 #
963 # copy the file pointed to by $src to the location specified by $dest.  in the
964 # process observe the rules regarding when the '-force' flag was passed to us.
965 #
966
967 sub copyFile
968 {
969     my($src, $dest) = @_;
970
971     if ( !isReadable($src) )
972     {
973         printf("$src is not readable... not creating $dest.\n");
974         return;
975     }
976
977     if ( !prepareFileWrite($dest) )
978     {
979         return;
980     }
981
982     action("cp $src $dest");
983 }
984
985 ### copySXXScript( $in, $out )
986 #
987 # parse the input file, substituting in place the value of GLOBUS_LOCATION, and
988 # write the result to the output file.
989 #
990
991 sub copySXXScript
992 {
993     my($in, $out) = @_;
994
995     if ( !isReadable($in) )
996     {
997         printf("$in is not readable... not creating $out.\n");
998         return;
999     }
1000
1001     if ( !prepareFileWrite($out) )
1002     {
1003         return;
1004     }
1005
1006     $data = readFile($in);
1007     $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g;
1008     writeFile($out, $data);
1009     action("chmod 755 $out");
1010 }
1011
1012 ### readFile( $filename )
1013 #
1014 # reads and returns $filename's contents
1015 #
1016
1017 sub readFile
1018 {
1019     my($filename) = @_;
1020     my($data);
1021
1022     open(IN, "$filename") || die "Can't open '$filename': $!";
1023     $/ = undef;
1024     $data = <IN>;
1025     $/ = "\n";
1026     close(IN);
1027
1028     return $data;
1029 }
1030
1031 ### writeFile( $filename, $fileinput )
1032 #
1033 # create the inputs to the ssl program at $filename, appending the common name to the
1034 # stream in the process
1035 #
1036
1037 sub writeFile
1038 {
1039     my($filename, $fileinput) = @_;
1040
1041     #
1042     # test for a valid $filename
1043     #
1044
1045     if ( !defined($filename) || (length($filename) lt 1) )
1046     {
1047         die "Filename is undefined";
1048     }
1049
1050     #
1051     # verify that we are prepared to work with $filename
1052     #
1053
1054     if ( !prepareFileWrite($filename) )
1055     {
1056         return;
1057     }
1058
1059     #
1060     # write the output to $filename
1061     #
1062
1063     open(OUT, ">$filename");
1064     print OUT "$fileinput";
1065     close(OUT);
1066 }
1067
1068 ### action( $command )
1069 #
1070 # run $command within a proper system() command.
1071 #
1072
1073 sub action
1074 {
1075     my($command) = @_;
1076
1077     printf "$command\n";
1078
1079     my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
1080
1081     if (($result or $?) and $command !~ m!patch!)
1082     {
1083         die "ERROR: Unable to execute command: $!\n";
1084     }
1085 }
1086
1087 ### query_boolean( $query_text, $default )
1088 #
1089 # query the user with a string, and expect a response.  If the user hits
1090 # 'enter' instead of entering an input, then accept the default response.
1091 #
1092
1093 sub query_boolean
1094 {
1095     my($query_text, $default) = @_;
1096     my($nondefault, $foo, $bar);
1097
1098     #
1099     # Set $nondefault to the boolean opposite of $default.
1100     #
1101
1102     if ($default eq "n")
1103     {
1104         $nondefault = "y";
1105     }
1106     else
1107     {
1108         $nondefault = "n";
1109     }
1110
1111     print "${query_text} ";
1112     print "[$default] ";
1113
1114     $foo = <STDIN>;
1115     ($bar) = split //, $foo;
1116
1117     if ( grep(/\s/, $bar) )
1118     {
1119         # this is debatable.  all whitespace means 'default'
1120
1121         $bar = $default;
1122     }
1123     elsif ($bar ne $default)
1124     {
1125         # everything else means 'nondefault'.
1126
1127         $bar = $nondefault;
1128     }
1129     else
1130     {
1131         # extraneous step.  to get here, $bar should be eq to $default anyway.
1132
1133         $bar = $default;
1134     }
1135
1136     return $bar;
1137 }
1138
1139 ### absolutePath( $file )
1140 #
1141 # converts a given pathname into a canonical path using the abs_path function.
1142 #
1143
1144 sub absolutePath
1145 {
1146     my($file) = @_;
1147     my $home = $ENV{'HOME'};
1148     $file =~ s!~!$home!;
1149     my $startd = cwd();
1150     $file =~ s!^\./!$startd/!;
1151     $file = "$startd/$file" if $file !~ m!^\s*/!;
1152     $file = abs_path($file);
1153     return $file;
1154 }
1155
1156 ### getOwnerID( $file )
1157 #
1158 # return the uid containing the owner ID of the given file.
1159 #
1160
1161 sub getOwnerID
1162 {
1163     my($file) = @_;
1164     my($uid);
1165
1166     #
1167     # call stat() to get the mode of the file
1168     #
1169
1170     $uid = (stat($file))[4];
1171
1172     return $uid;
1173 }
1174
1175 ### getMode( $file )
1176 #
1177 # return a string containing the mode of the given file.
1178 #
1179
1180 sub getMode
1181 {
1182     my($file) = @_;
1183     my($tempmode, $mode);
1184
1185     #
1186     # call stat() to get the mode of the file
1187     #
1188
1189     $tempmode = (stat($file))[2];
1190     if (length($tempmode) < 1)
1191     {
1192         return "";
1193     }
1194
1195     #
1196     # call sprintf to format the mode into a UNIX-like string
1197     #
1198
1199     $mode = sprintf("%04o", $tempmode & 07777);
1200
1201     return $mode;
1202 }
1203
1204 ### userExists( $username )
1205 #
1206 # given a username, return true if the user exists on the system.  return false
1207 # otherwise.
1208 #
1209
1210 sub userExists
1211 {
1212     my($username) = @_;
1213     my($uid);
1214
1215     #
1216     # retrieve the userid of the user with the given username
1217     #
1218
1219     $uid = getpwnam($username);
1220
1221     #
1222     # return true if $uid is defined and has a length greater than 0
1223     #
1224
1225     if ( defined($uid) and (length($uid) > 0) )
1226     {
1227         return 1;
1228     }
1229     else
1230     {
1231         return 0;
1232     }
1233 }
This page took 0.131374 seconds and 5 git commands to generate.