]>
Commit | Line | Data |
---|---|---|
5002372c | 1 | #!/usr/bin/perl |
20d3226a | 2 | # |
5002372c | 3 | # setup-openssh.pl |
4 | # | |
95f536ac | 5 | # Adapts the installed gsi-openssh environment to the current machine, |
5002372c | 6 | # performing actions that originally occurred during the package's |
7 | # 'make install' phase. | |
701aa556 | 8 | # |
1eab725d | 9 | # Send comments/fixes/suggestions to: |
10 | # Chase Phillips <cphillip@ncsa.uiuc.edu> | |
701aa556 | 11 | # |
20d3226a | 12 | |
1b936a7a | 13 | printf("setup-openssh.pl: Configuring gsi-openssh package\n"); |
14 | ||
7e12c9a7 | 15 | # |
16 | # Get user's GPT_LOCATION since we may be installing this using a new(er) | |
17 | # version of GPT. | |
18 | # | |
19 | ||
20 | $gptpath = $ENV{GPT_LOCATION}; | |
21 | ||
22 | # | |
23 | # And the old standby.. | |
24 | # | |
25 | ||
4f276ad7 | 26 | $gpath = $ENV{GLOBUS_LOCATION}; |
ad71c979 | 27 | if (!defined($gpath)) |
28 | { | |
53a54c67 | 29 | die "GLOBUS_LOCATION needs to be set before running this script" |
ad71c979 | 30 | } |
31 | ||
8b73e3d0 | 32 | # |
33 | # modify the ld library path for when we call ssh executables | |
34 | # | |
35 | ||
36 | $oldldpath = $ENV{LD_LIBRARY_PATH}; | |
37 | $newldpath = "$gpath/lib"; | |
38 | if (length($oldldpath) > 0) | |
39 | { | |
40 | $newldpath .= ":$oldldpath"; | |
41 | } | |
42 | $ENV{LD_LIBRARY_PATH} = "$newldpath"; | |
43 | ||
ad71c979 | 44 | # |
45 | # i'm including this because other perl scripts in the gpt setup directories | |
46 | # do so | |
47 | # | |
48 | ||
7e12c9a7 | 49 | if (defined($gptpath)) |
50 | { | |
51 | @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl"); | |
52 | } | |
53 | else | |
54 | { | |
55 | @INC = (@INC, "$gpath/lib/perl"); | |
56 | } | |
ad71c979 | 57 | |
4f276ad7 | 58 | require Grid::GPT::Setup; |
59 | ||
ad71c979 | 60 | my $globusdir = $gpath; |
ad71c979 | 61 | my $myname = "setup-openssh.pl"; |
62 | ||
20d3226a | 63 | # |
64 | # Set up path prefixes for use in the path translations | |
65 | # | |
66 | ||
d0a1bda7 | 67 | $prefix = ${globusdir}; |
68 | $exec_prefix = "${prefix}"; | |
69 | $bindir = "${exec_prefix}/bin"; | |
9cc10d0e | 70 | $sbindir = "${exec_prefix}/sbin"; |
95f536ac | 71 | $sysconfdir = "$prefix/etc/ssh"; |
72 | $localsshdir = "/etc/ssh"; | |
20bb6dc8 | 73 | $setupdir = "$prefix/setup/gsi_openssh_setup"; |
e9ec5455 | 74 | |
95f536ac | 75 | my $keyfiles = { |
76 | "dsa" => "ssh_host_dsa_key", | |
77 | "rsa" => "ssh_host_rsa_key", | |
78 | "rsa1" => "ssh_host_key", | |
79 | }; | |
823981ba | 80 | |
95f536ac | 81 | sub copyKeyFiles |
e9ec5455 | 82 | { |
95f536ac | 83 | my($copylist) = @_; |
84 | my($regex, $basename); | |
e9ec5455 | 85 | |
712b003f | 86 | if (@$copylist) |
e9ec5455 | 87 | { |
712b003f | 88 | print "Copying ssh host keys...\n"; |
e9ec5455 | 89 | |
712b003f | 90 | for my $f (@$copylist) |
95f536ac | 91 | { |
712b003f | 92 | $f =~ s:/+:/:g; |
93 | ||
94 | if (length($f) > 0) | |
95 | { | |
96 | $keyfile = "$f"; | |
97 | $pubkeyfile = "$f.pub"; | |
95f536ac | 98 | |
712b003f | 99 | action("cp $localsshdir/$keyfile $sysconfdir/$keyfile"); |
100 | action("cp $localsshdir/$pubkeyfile $sysconfdir/$pubkeyfile"); | |
101 | } | |
95f536ac | 102 | } |
e9ec5455 | 103 | } |
e9ec5455 | 104 | } |
105 | ||
95f536ac | 106 | sub isReadable |
1a1f62a4 | 107 | { |
95f536ac | 108 | my($file) = @_; |
1a1f62a4 | 109 | |
95f536ac | 110 | if ( ( -e $file ) && ( -r $file ) ) |
1a1f62a4 | 111 | { |
95f536ac | 112 | return 1; |
1a1f62a4 | 113 | } |
823981ba | 114 | else |
1a1f62a4 | 115 | { |
95f536ac | 116 | return 0; |
ac083f7a | 117 | } |
1a1f62a4 | 118 | } |
119 | ||
712b003f | 120 | sub isPresent |
121 | { | |
122 | my($file) = @_; | |
123 | ||
124 | if ( -e $file ) | |
125 | { | |
126 | return 1; | |
127 | } | |
128 | else | |
129 | { | |
130 | return 0; | |
131 | } | |
132 | } | |
133 | ||
c096bf39 | 134 | ### makeConfDir( ) |
135 | # | |
136 | # make the gsi-openssh configuration directory if it doesn't already exist. | |
137 | # | |
138 | ||
139 | sub makeConfDir | |
140 | { | |
141 | if ( isPresent($sysconfdir) ) | |
142 | { | |
143 | if ( -d $sysconfdir ) | |
144 | { | |
145 | return; | |
146 | } | |
147 | ||
148 | die("${sysconfdir} already exists and is not a directory!\n"); | |
149 | } | |
150 | ||
151 | print "Could not find ${sysconfdir} directory... creating.\n"; | |
152 | action("mkdir -p $sysconfdir"); | |
153 | ||
154 | return; | |
155 | } | |
156 | ||
95f536ac | 157 | sub determineKeys |
823981ba | 158 | { |
95f536ac | 159 | my($keyhash, $keylist); |
160 | my($count); | |
823981ba | 161 | |
712b003f | 162 | # |
163 | # initialize our variables | |
164 | # | |
165 | ||
95f536ac | 166 | $count = 0; |
823981ba | 167 | |
95f536ac | 168 | $keyhash = {}; |
169 | $keyhash->{gen} = []; # a list of keytypes to generate | |
170 | $keyhash->{copy} = []; # a list of files to copy from the | |
712b003f | 171 | |
95f536ac | 172 | $genlist = $keyhash->{gen}; |
173 | $copylist = $keyhash->{copy}; | |
e9ec5455 | 174 | |
712b003f | 175 | # |
176 | # loop over our keytypes and determine what we need to do for each of them | |
177 | # | |
178 | ||
95f536ac | 179 | for my $keytype (keys %$keyfiles) |
1a1f62a4 | 180 | { |
95f536ac | 181 | $basekeyfile = $keyfiles->{$keytype}; |
1a1f62a4 | 182 | |
712b003f | 183 | # |
184 | # if the key's are already present, we don't need to bother with this rigamarole | |
185 | # | |
186 | ||
187 | $gkeyfile = "$sysconfdir/$basekeyfile"; | |
188 | $gpubkeyfile = "$sysconfdir/$basekeyfile.pub"; | |
189 | ||
190 | if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) ) | |
95f536ac | 191 | { |
712b003f | 192 | next; |
95f536ac | 193 | } |
1a1f62a4 | 194 | |
712b003f | 195 | # |
196 | # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's | |
197 | # globus location | |
198 | # | |
199 | ||
200 | $mainkeyfile = "$localsshdir/$basekeyfile"; | |
201 | $mainpubkeyfile = "$localsshdir/$basekeyfile.pub"; | |
202 | ||
203 | if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) ) | |
95f536ac | 204 | { |
712b003f | 205 | push(@$copylist, $basekeyfile); |
95f536ac | 206 | $count++; |
712b003f | 207 | next; |
95f536ac | 208 | } |
712b003f | 209 | |
210 | # | |
211 | # otherwise, we need to generate the key | |
212 | # | |
213 | ||
214 | push(@$genlist, $keytype); | |
215 | $count++; | |
1a1f62a4 | 216 | } |
217 | ||
95f536ac | 218 | if ($count > 0) |
1a1f62a4 | 219 | { |
95f536ac | 220 | if ( ! -d $sysconfdir ) |
221 | { | |
222 | print "Could not find ${sysconfdir} directory... creating\n"; | |
223 | action("mkdir -p $sysconfdir"); | |
224 | } | |
1a1f62a4 | 225 | } |
95f536ac | 226 | |
227 | return $keyhash; | |
228 | } | |
229 | ||
230 | sub runKeyGen | |
231 | { | |
232 | my($gen_keys) = @_; | |
ce935927 | 233 | my $keygen = "$bindir/ssh-keygen"; |
95f536ac | 234 | |
ce935927 | 235 | if (@$gen_keys && -x $keygen) |
1a1f62a4 | 236 | { |
712b003f | 237 | print "Generating ssh host keys...\n"; |
238 | ||
239 | for my $k (@$gen_keys) | |
240 | { | |
241 | $keyfile = $keyfiles->{$k}; | |
95f536ac | 242 | |
712b003f | 243 | # if $sysconfdir/$keyfile doesn't exist.. |
244 | action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\""); | |
245 | } | |
1a1f62a4 | 246 | } |
247 | ||
248 | return 0; | |
249 | } | |
250 | ||
5b105785 | 251 | ### fixpaths( ) |
252 | # | |
253 | # this subroutine 'edits' the paths in sshd_config to suit them to the current environment | |
254 | # in which the setup script is being run. | |
255 | # | |
256 | ||
20d3226a | 257 | sub fixpaths |
258 | { | |
5b105785 | 259 | my($fileInput, $fileOutput); |
260 | my($mode, $uid, $gid); | |
261 | my($line, $newline); | |
823981ba | 262 | |
5b105785 | 263 | print "Fixing paths in sshd_config...\n"; |
95f536ac | 264 | |
5b105785 | 265 | $fileInput = "$setupdir/sshd_config.in"; |
266 | $fileOutput = "$sysconfdir/sshd_config"; | |
95f536ac | 267 | |
5b105785 | 268 | if ( ! -f "$fileInput" ) |
95f536ac | 269 | { |
5b105785 | 270 | printf("Cannot find $fileInput!\n"); |
271 | die(); | |
272 | } | |
273 | ||
274 | if ( -e "$fileOutput" ) | |
275 | { | |
276 | printf("$fileOutput already exists!\n"); | |
277 | die(); | |
95f536ac | 278 | } |
e9ec5455 | 279 | |
20d3226a | 280 | # |
95f536ac | 281 | # Grab the current mode/uid/gid for use later |
20d3226a | 282 | # |
283 | ||
5b105785 | 284 | $mode = (stat($fileInput))[2]; |
285 | $uid = (stat($fileInput))[4]; | |
286 | $gid = (stat($fileInput))[5]; | |
20d3226a | 287 | |
20d3226a | 288 | # |
5b105785 | 289 | # Open the files for reading and writing, and loop over the input's contents |
20d3226a | 290 | # |
291 | ||
5b105785 | 292 | open(IN, "<$fileInput") || die ("$0: input file $fileInput missing!\n"); |
293 | open(OUT, ">$fileOutput") || die ("$0: unable to open output file $fileOutput!\n"); | |
20d3226a | 294 | |
95f536ac | 295 | while (<IN>) |
296 | { | |
6193a4af | 297 | # |
298 | # sorry for the whacky regex, but i need to verify a whole line | |
299 | # | |
300 | ||
eb4172f6 | 301 | $line = $_; |
302 | if ( $line =~ /^\s*Subsystem\s+sftp\s+\S+\s*$/ ) | |
e9ec5455 | 303 | { |
eb4172f6 | 304 | $newline = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n"; |
305 | $newline =~ s:/+:/:g; | |
7c96a399 | 306 | } |
eb4172f6 | 307 | elsif ( $line =~ /^\s*PidFile.*$/ ) |
308 | { | |
309 | $newline = "PidFile\t$gpath/var/sshd.pid\n"; | |
310 | $newline =~ s:/+:/:g; | |
311 | } | |
312 | else | |
313 | { | |
314 | $newline = $line; | |
315 | } | |
316 | ||
317 | print OUT "$newline"; | |
95f536ac | 318 | } # while <IN> |
7c96a399 | 319 | |
95f536ac | 320 | close(OUT); |
321 | close(IN); | |
7c96a399 | 322 | |
95f536ac | 323 | # |
324 | # An attempt to revert the new file back to the original file's | |
325 | # mode/uid/gid | |
326 | # | |
7e12c9a7 | 327 | |
5b105785 | 328 | chmod($mode, $fileOutput); |
329 | chown($uid, $gid, $fileOutput); | |
20d3226a | 330 | |
331 | return 0; | |
332 | } | |
333 | ||
5b105785 | 334 | ### copyConfigFiles( ) |
335 | # | |
336 | # subroutine that copies some extra config files to their proper location in | |
337 | # $GLOBUS_LOCATION/etc/ssh. | |
338 | # | |
339 | ||
340 | sub copyConfigFiles | |
341 | { | |
342 | print "Copying ssh_config and moduli to their proper location...\n"; | |
343 | ||
344 | action("cp $setupdir/ssh_config $sysconfdir/ssh_config"); | |
345 | action("cp $setupdir/moduli $sysconfdir/moduli"); | |
346 | } | |
347 | ||
d58b3a33 | 348 | sub alterFileGlobusLocation |
a26c150d | 349 | { |
20bb6dc8 | 350 | my ($in, $out) = @_; |
d58b3a33 | 351 | |
4e865698 | 352 | if ( -r $in ) |
20bb6dc8 | 353 | { |
4e865698 | 354 | if ( ( -w $out ) || ( ! -e $out ) ) |
355 | { | |
356 | $data = readFile($in); | |
357 | $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g; | |
358 | writeFile($out, $data); | |
359 | action("chmod 755 $out"); | |
360 | } | |
20bb6dc8 | 361 | } |
d58b3a33 | 362 | } |
363 | ||
364 | sub alterFiles | |
365 | { | |
9cc10d0e | 366 | alterFileGlobusLocation("$setupdir/SXXsshd.in", "$sbindir/SXXsshd"); |
a26c150d | 367 | } |
368 | ||
369 | ### readFile( $filename ) | |
370 | # | |
371 | # reads and returns $filename's contents | |
372 | # | |
373 | ||
374 | sub readFile | |
375 | { | |
376 | my ($filename) = @_; | |
377 | my $data; | |
378 | ||
379 | open (IN, "$filename") || die "Can't open '$filename': $!"; | |
380 | $/ = undef; | |
381 | $data = <IN>; | |
382 | $/ = "\n"; | |
383 | close(IN); | |
384 | ||
385 | return $data; | |
386 | } | |
387 | ||
388 | ### writeFile( $filename, $fileinput ) | |
389 | # | |
390 | # create the inputs to the ssl program at $filename, appending the common name to the | |
391 | # stream in the process | |
392 | # | |
393 | ||
394 | sub writeFile | |
395 | { | |
396 | my ($filename, $fileinput) = @_; | |
397 | ||
398 | # | |
399 | # test for a valid $filename | |
400 | # | |
401 | ||
402 | if ( !defined($filename) || (length($filename) lt 1) ) | |
403 | { | |
404 | die "Filename is undefined"; | |
405 | } | |
406 | ||
407 | if ( ( -e "$filename" ) && ( ! -w "$filename" ) ) | |
408 | { | |
409 | die "Cannot write to filename '$filename'"; | |
410 | } | |
411 | ||
412 | # | |
413 | # write the output to $filename | |
414 | # | |
415 | ||
416 | open(OUT, ">$filename"); | |
417 | print OUT "$fileinput"; | |
418 | close(OUT); | |
419 | } | |
420 | ||
6e9c7232 | 421 | print "---------------------------------------------------------------------\n"; |
823981ba | 422 | print "Hi, I'm the setup script for the gsi_openssh package! There\n"; |
423 | print "are some last minute details that I've got to set straight\n"; | |
95f536ac | 424 | print "in the sshd config file, along with generating the ssh keys\n"; |
823981ba | 425 | print "for this machine (if it doesn't already have them).\n"; |
426 | print "\n"; | |
95f536ac | 427 | print "If I find a pair of host keys in /etc/ssh, I will copy them into\n"; |
6e9c7232 | 428 | print "\$GLOBUS_LOCATION/etc/ssh. If they aren't present, I will generate\n"; |
429 | print "them for you.\n"; | |
823981ba | 430 | print "\n"; |
431 | ||
432 | $response = query_boolean("Do you wish to continue with the setup package?","y"); | |
e9d69a89 | 433 | if ($response eq "n") |
823981ba | 434 | { |
435 | print "\n"; | |
c096bf39 | 436 | print "Exiting gsi_openssh setup.\n"; |
823981ba | 437 | |
438 | exit 0; | |
439 | } | |
e9ec5455 | 440 | |
9e979a2a | 441 | print "\n"; |
442 | ||
c096bf39 | 443 | makeConfDir(); |
95f536ac | 444 | $keyhash = determineKeys(); |
445 | runKeyGen($keyhash->{gen}); | |
446 | copyKeyFiles($keyhash->{copy}); | |
11b9a41c | 447 | fixpaths(); |
5b105785 | 448 | copyConfigFiles(); |
20bb6dc8 | 449 | alterFiles(); |
ad71c979 | 450 | |
472ec086 | 451 | my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup"); |
4f276ad7 | 452 | |
53a54c67 | 453 | $metadata->finish(); |
9ef2f439 | 454 | |
b0441584 | 455 | print "\n"; |
6e9c7232 | 456 | print "Additional Notes:\n"; |
457 | print "\n"; | |
458 | print " o I see that you have your GLOBUS_LOCATION environmental variable\n"; | |
459 | print " set to:\n"; | |
460 | print "\n"; | |
461 | print " \t\"$gpath\"\n"; | |
b0441584 | 462 | print "\n"; |
6e9c7232 | 463 | print " Remember to keep this variable set (correctly) when you want to\n"; |
464 | print " use the executables that came with this package.\n"; | |
5002372c | 465 | print "\n"; |
5b105785 | 466 | print " After that you may run, e.g.:\n"; |
753002f8 | 467 | print "\n"; |
468 | print " \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n"; | |
469 | print "\n"; | |
470 | print " to prepare your environment for running the gsi_openssh\n"; | |
471 | print " executables.\n"; | |
472 | print "\n"; | |
6e9c7232 | 473 | print "---------------------------------------------------------------------\n"; |
9e979a2a | 474 | print "$myname: Finished configuring package 'gsi_openssh'.\n"; |
ac083f7a | 475 | |
476 | # | |
477 | # Just need a minimal action() subroutine for now.. | |
478 | # | |
479 | ||
480 | sub action | |
481 | { | |
482 | my ($command) = @_; | |
483 | ||
484 | printf "$command\n"; | |
485 | ||
8b73e3d0 | 486 | my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1"); |
ac083f7a | 487 | |
488 | if (($result or $?) and $command !~ m!patch!) | |
489 | { | |
490 | die "ERROR: Unable to execute command: $!\n"; | |
491 | } | |
492 | } | |
493 | ||
494 | sub query_boolean | |
495 | { | |
496 | my ($query_text, $default) = @_; | |
497 | my $nondefault, $foo, $bar; | |
498 | ||
499 | # | |
500 | # Set $nondefault to the boolean opposite of $default. | |
501 | # | |
502 | ||
503 | if ($default eq "n") | |
504 | { | |
505 | $nondefault = "y"; | |
506 | } | |
507 | else | |
508 | { | |
509 | $nondefault = "n"; | |
510 | } | |
511 | ||
512 | print "${query_text} "; | |
513 | print "[$default] "; | |
514 | ||
e9ec5455 | 515 | $foo = <STDIN>; |
516 | ($bar) = split //, $foo; | |
517 | ||
e9d69a89 | 518 | if ( grep(/\s/, $bar) ) |
ac083f7a | 519 | { |
e9d69a89 | 520 | # this is debatable. all whitespace means 'default' |
521 | ||
522 | $bar = $default; | |
523 | } | |
524 | elsif ($bar ne $default) | |
525 | { | |
526 | # everything else means 'nondefault'. | |
527 | ||
528 | $bar = $nondefault; | |
529 | } | |
530 | else | |
531 | { | |
532 | # extraneous step. to get here, $bar should be eq to $default anyway. | |
533 | ||
e9ec5455 | 534 | $bar = $default; |
ac083f7a | 535 | } |
536 | ||
e9ec5455 | 537 | return $bar; |
ac083f7a | 538 | } |
c096bf39 | 539 | |
540 | ### absolutePath( $file ) | |
541 | # | |
542 | # converts a given pathname into a canonical path using the abs_path function. | |
543 | # | |
544 | ||
545 | sub absolutePath | |
546 | { | |
547 | my($file) = @_; | |
548 | my $home = $ENV{'HOME'}; | |
549 | $file =~ s!~!$home!; | |
550 | my $startd = cwd(); | |
551 | $file =~ s!^\./!$startd/!; | |
552 | $file = "$startd/$file" if $file !~ m!^\s*/!; | |
553 | $file = abs_path($file); | |
554 | return $file; | |
555 | } |