]>
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 | ||
95f536ac | 134 | sub determineKeys |
823981ba | 135 | { |
95f536ac | 136 | my($keyhash, $keylist); |
137 | my($count); | |
823981ba | 138 | |
712b003f | 139 | # |
140 | # initialize our variables | |
141 | # | |
142 | ||
95f536ac | 143 | $count = 0; |
823981ba | 144 | |
95f536ac | 145 | $keyhash = {}; |
146 | $keyhash->{gen} = []; # a list of keytypes to generate | |
147 | $keyhash->{copy} = []; # a list of files to copy from the | |
712b003f | 148 | |
95f536ac | 149 | $genlist = $keyhash->{gen}; |
150 | $copylist = $keyhash->{copy}; | |
e9ec5455 | 151 | |
712b003f | 152 | # |
153 | # loop over our keytypes and determine what we need to do for each of them | |
154 | # | |
155 | ||
95f536ac | 156 | for my $keytype (keys %$keyfiles) |
1a1f62a4 | 157 | { |
95f536ac | 158 | $basekeyfile = $keyfiles->{$keytype}; |
1a1f62a4 | 159 | |
712b003f | 160 | # |
161 | # if the key's are already present, we don't need to bother with this rigamarole | |
162 | # | |
163 | ||
164 | $gkeyfile = "$sysconfdir/$basekeyfile"; | |
165 | $gpubkeyfile = "$sysconfdir/$basekeyfile.pub"; | |
166 | ||
167 | if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) ) | |
95f536ac | 168 | { |
712b003f | 169 | next; |
95f536ac | 170 | } |
1a1f62a4 | 171 | |
712b003f | 172 | # |
173 | # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's | |
174 | # globus location | |
175 | # | |
176 | ||
177 | $mainkeyfile = "$localsshdir/$basekeyfile"; | |
178 | $mainpubkeyfile = "$localsshdir/$basekeyfile.pub"; | |
179 | ||
180 | if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) ) | |
95f536ac | 181 | { |
712b003f | 182 | push(@$copylist, $basekeyfile); |
95f536ac | 183 | $count++; |
712b003f | 184 | next; |
95f536ac | 185 | } |
712b003f | 186 | |
187 | # | |
188 | # otherwise, we need to generate the key | |
189 | # | |
190 | ||
191 | push(@$genlist, $keytype); | |
192 | $count++; | |
1a1f62a4 | 193 | } |
194 | ||
95f536ac | 195 | if ($count > 0) |
1a1f62a4 | 196 | { |
95f536ac | 197 | if ( ! -d $sysconfdir ) |
198 | { | |
199 | print "Could not find ${sysconfdir} directory... creating\n"; | |
200 | action("mkdir -p $sysconfdir"); | |
201 | } | |
1a1f62a4 | 202 | } |
95f536ac | 203 | |
204 | return $keyhash; | |
205 | } | |
206 | ||
207 | sub runKeyGen | |
208 | { | |
209 | my($gen_keys) = @_; | |
ce935927 | 210 | my $keygen = "$bindir/ssh-keygen"; |
95f536ac | 211 | |
ce935927 | 212 | if (@$gen_keys && -x $keygen) |
1a1f62a4 | 213 | { |
712b003f | 214 | print "Generating ssh host keys...\n"; |
215 | ||
216 | for my $k (@$gen_keys) | |
217 | { | |
218 | $keyfile = $keyfiles->{$k}; | |
95f536ac | 219 | |
712b003f | 220 | # if $sysconfdir/$keyfile doesn't exist.. |
221 | action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\""); | |
222 | } | |
1a1f62a4 | 223 | } |
224 | ||
225 | return 0; | |
226 | } | |
227 | ||
5b105785 | 228 | ### fixpaths( ) |
229 | # | |
230 | # this subroutine 'edits' the paths in sshd_config to suit them to the current environment | |
231 | # in which the setup script is being run. | |
232 | # | |
233 | ||
20d3226a | 234 | sub fixpaths |
235 | { | |
5b105785 | 236 | my($fileInput, $fileOutput); |
237 | my($mode, $uid, $gid); | |
238 | my($line, $newline); | |
823981ba | 239 | |
5b105785 | 240 | print "Fixing paths in sshd_config...\n"; |
95f536ac | 241 | |
5b105785 | 242 | $fileInput = "$setupdir/sshd_config.in"; |
243 | $fileOutput = "$sysconfdir/sshd_config"; | |
95f536ac | 244 | |
5b105785 | 245 | if ( ! -f "$fileInput" ) |
95f536ac | 246 | { |
5b105785 | 247 | printf("Cannot find $fileInput!\n"); |
248 | die(); | |
249 | } | |
250 | ||
251 | if ( -e "$fileOutput" ) | |
252 | { | |
253 | printf("$fileOutput already exists!\n"); | |
254 | die(); | |
95f536ac | 255 | } |
e9ec5455 | 256 | |
20d3226a | 257 | # |
95f536ac | 258 | # Grab the current mode/uid/gid for use later |
20d3226a | 259 | # |
260 | ||
5b105785 | 261 | $mode = (stat($fileInput))[2]; |
262 | $uid = (stat($fileInput))[4]; | |
263 | $gid = (stat($fileInput))[5]; | |
20d3226a | 264 | |
20d3226a | 265 | # |
5b105785 | 266 | # Open the files for reading and writing, and loop over the input's contents |
20d3226a | 267 | # |
268 | ||
5b105785 | 269 | open(IN, "<$fileInput") || die ("$0: input file $fileInput missing!\n"); |
270 | open(OUT, ">$fileOutput") || die ("$0: unable to open output file $fileOutput!\n"); | |
20d3226a | 271 | |
95f536ac | 272 | while (<IN>) |
273 | { | |
6193a4af | 274 | # |
275 | # sorry for the whacky regex, but i need to verify a whole line | |
276 | # | |
277 | ||
eb4172f6 | 278 | $line = $_; |
279 | if ( $line =~ /^\s*Subsystem\s+sftp\s+\S+\s*$/ ) | |
e9ec5455 | 280 | { |
eb4172f6 | 281 | $newline = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n"; |
282 | $newline =~ s:/+:/:g; | |
7c96a399 | 283 | } |
eb4172f6 | 284 | elsif ( $line =~ /^\s*PidFile.*$/ ) |
285 | { | |
286 | $newline = "PidFile\t$gpath/var/sshd.pid\n"; | |
287 | $newline =~ s:/+:/:g; | |
288 | } | |
289 | else | |
290 | { | |
291 | $newline = $line; | |
292 | } | |
293 | ||
294 | print OUT "$newline"; | |
95f536ac | 295 | } # while <IN> |
7c96a399 | 296 | |
95f536ac | 297 | close(OUT); |
298 | close(IN); | |
7c96a399 | 299 | |
95f536ac | 300 | # |
301 | # An attempt to revert the new file back to the original file's | |
302 | # mode/uid/gid | |
303 | # | |
7e12c9a7 | 304 | |
5b105785 | 305 | chmod($mode, $fileOutput); |
306 | chown($uid, $gid, $fileOutput); | |
20d3226a | 307 | |
308 | return 0; | |
309 | } | |
310 | ||
5b105785 | 311 | ### copyConfigFiles( ) |
312 | # | |
313 | # subroutine that copies some extra config files to their proper location in | |
314 | # $GLOBUS_LOCATION/etc/ssh. | |
315 | # | |
316 | ||
317 | sub copyConfigFiles | |
318 | { | |
319 | print "Copying ssh_config and moduli to their proper location...\n"; | |
320 | ||
321 | action("cp $setupdir/ssh_config $sysconfdir/ssh_config"); | |
322 | action("cp $setupdir/moduli $sysconfdir/moduli"); | |
323 | } | |
324 | ||
d58b3a33 | 325 | sub alterFileGlobusLocation |
a26c150d | 326 | { |
20bb6dc8 | 327 | my ($in, $out) = @_; |
d58b3a33 | 328 | |
4e865698 | 329 | if ( -r $in ) |
20bb6dc8 | 330 | { |
4e865698 | 331 | if ( ( -w $out ) || ( ! -e $out ) ) |
332 | { | |
333 | $data = readFile($in); | |
334 | $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g; | |
335 | writeFile($out, $data); | |
336 | action("chmod 755 $out"); | |
337 | } | |
20bb6dc8 | 338 | } |
d58b3a33 | 339 | } |
340 | ||
341 | sub alterFiles | |
342 | { | |
9cc10d0e | 343 | alterFileGlobusLocation("$setupdir/SXXsshd.in", "$sbindir/SXXsshd"); |
a26c150d | 344 | } |
345 | ||
346 | ### readFile( $filename ) | |
347 | # | |
348 | # reads and returns $filename's contents | |
349 | # | |
350 | ||
351 | sub readFile | |
352 | { | |
353 | my ($filename) = @_; | |
354 | my $data; | |
355 | ||
356 | open (IN, "$filename") || die "Can't open '$filename': $!"; | |
357 | $/ = undef; | |
358 | $data = <IN>; | |
359 | $/ = "\n"; | |
360 | close(IN); | |
361 | ||
362 | return $data; | |
363 | } | |
364 | ||
365 | ### writeFile( $filename, $fileinput ) | |
366 | # | |
367 | # create the inputs to the ssl program at $filename, appending the common name to the | |
368 | # stream in the process | |
369 | # | |
370 | ||
371 | sub writeFile | |
372 | { | |
373 | my ($filename, $fileinput) = @_; | |
374 | ||
375 | # | |
376 | # test for a valid $filename | |
377 | # | |
378 | ||
379 | if ( !defined($filename) || (length($filename) lt 1) ) | |
380 | { | |
381 | die "Filename is undefined"; | |
382 | } | |
383 | ||
384 | if ( ( -e "$filename" ) && ( ! -w "$filename" ) ) | |
385 | { | |
386 | die "Cannot write to filename '$filename'"; | |
387 | } | |
388 | ||
389 | # | |
390 | # write the output to $filename | |
391 | # | |
392 | ||
393 | open(OUT, ">$filename"); | |
394 | print OUT "$fileinput"; | |
395 | close(OUT); | |
396 | } | |
397 | ||
6e9c7232 | 398 | print "---------------------------------------------------------------------\n"; |
823981ba | 399 | print "Hi, I'm the setup script for the gsi_openssh package! There\n"; |
400 | print "are some last minute details that I've got to set straight\n"; | |
95f536ac | 401 | print "in the sshd config file, along with generating the ssh keys\n"; |
823981ba | 402 | print "for this machine (if it doesn't already have them).\n"; |
403 | print "\n"; | |
95f536ac | 404 | print "If I find a pair of host keys in /etc/ssh, I will copy them into\n"; |
6e9c7232 | 405 | print "\$GLOBUS_LOCATION/etc/ssh. If they aren't present, I will generate\n"; |
406 | print "them for you.\n"; | |
823981ba | 407 | print "\n"; |
408 | ||
409 | $response = query_boolean("Do you wish to continue with the setup package?","y"); | |
e9d69a89 | 410 | if ($response eq "n") |
823981ba | 411 | { |
412 | print "\n"; | |
413 | print "Okay.. exiting gsi_openssh setup.\n"; | |
414 | ||
415 | exit 0; | |
416 | } | |
e9ec5455 | 417 | |
9e979a2a | 418 | print "\n"; |
419 | ||
95f536ac | 420 | $keyhash = determineKeys(); |
421 | runKeyGen($keyhash->{gen}); | |
422 | copyKeyFiles($keyhash->{copy}); | |
11b9a41c | 423 | fixpaths(); |
5b105785 | 424 | copyConfigFiles(); |
20bb6dc8 | 425 | alterFiles(); |
ad71c979 | 426 | |
472ec086 | 427 | my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup"); |
4f276ad7 | 428 | |
53a54c67 | 429 | $metadata->finish(); |
9ef2f439 | 430 | |
b0441584 | 431 | print "\n"; |
6e9c7232 | 432 | print "Additional Notes:\n"; |
433 | print "\n"; | |
434 | print " o I see that you have your GLOBUS_LOCATION environmental variable\n"; | |
435 | print " set to:\n"; | |
436 | print "\n"; | |
437 | print " \t\"$gpath\"\n"; | |
b0441584 | 438 | print "\n"; |
6e9c7232 | 439 | print " Remember to keep this variable set (correctly) when you want to\n"; |
440 | print " use the executables that came with this package.\n"; | |
5002372c | 441 | print "\n"; |
5b105785 | 442 | print " After that you may run, e.g.:\n"; |
753002f8 | 443 | print "\n"; |
444 | print " \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n"; | |
445 | print "\n"; | |
446 | print " to prepare your environment for running the gsi_openssh\n"; | |
447 | print " executables.\n"; | |
448 | print "\n"; | |
6e9c7232 | 449 | print "---------------------------------------------------------------------\n"; |
9e979a2a | 450 | print "$myname: Finished configuring package 'gsi_openssh'.\n"; |
ac083f7a | 451 | |
452 | # | |
453 | # Just need a minimal action() subroutine for now.. | |
454 | # | |
455 | ||
456 | sub action | |
457 | { | |
458 | my ($command) = @_; | |
459 | ||
460 | printf "$command\n"; | |
461 | ||
8b73e3d0 | 462 | my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1"); |
ac083f7a | 463 | |
464 | if (($result or $?) and $command !~ m!patch!) | |
465 | { | |
466 | die "ERROR: Unable to execute command: $!\n"; | |
467 | } | |
468 | } | |
469 | ||
470 | sub query_boolean | |
471 | { | |
472 | my ($query_text, $default) = @_; | |
473 | my $nondefault, $foo, $bar; | |
474 | ||
475 | # | |
476 | # Set $nondefault to the boolean opposite of $default. | |
477 | # | |
478 | ||
479 | if ($default eq "n") | |
480 | { | |
481 | $nondefault = "y"; | |
482 | } | |
483 | else | |
484 | { | |
485 | $nondefault = "n"; | |
486 | } | |
487 | ||
488 | print "${query_text} "; | |
489 | print "[$default] "; | |
490 | ||
e9ec5455 | 491 | $foo = <STDIN>; |
492 | ($bar) = split //, $foo; | |
493 | ||
e9d69a89 | 494 | if ( grep(/\s/, $bar) ) |
ac083f7a | 495 | { |
e9d69a89 | 496 | # this is debatable. all whitespace means 'default' |
497 | ||
498 | $bar = $default; | |
499 | } | |
500 | elsif ($bar ne $default) | |
501 | { | |
502 | # everything else means 'nondefault'. | |
503 | ||
504 | $bar = $nondefault; | |
505 | } | |
506 | else | |
507 | { | |
508 | # extraneous step. to get here, $bar should be eq to $default anyway. | |
509 | ||
e9ec5455 | 510 | $bar = $default; |
ac083f7a | 511 | } |
512 | ||
e9ec5455 | 513 | return $bar; |
ac083f7a | 514 | } |