]>
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) = @_; | |
210 | ||
712b003f | 211 | if (@$gen_keys) |
1a1f62a4 | 212 | { |
712b003f | 213 | print "Generating ssh host keys...\n"; |
214 | ||
215 | for my $k (@$gen_keys) | |
216 | { | |
217 | $keyfile = $keyfiles->{$k}; | |
95f536ac | 218 | |
712b003f | 219 | # if $sysconfdir/$keyfile doesn't exist.. |
220 | action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\""); | |
221 | } | |
1a1f62a4 | 222 | } |
223 | ||
224 | return 0; | |
225 | } | |
226 | ||
20d3226a | 227 | sub fixpaths |
228 | { | |
7e12c9a7 | 229 | my $g, $h; |
823981ba | 230 | |
95f536ac | 231 | print "Fixing sftp-server path in sshd_config...\n"; |
232 | ||
233 | $f = "$gpath/etc/ssh/sshd_config"; | |
234 | $g = "$f.tmp"; | |
235 | ||
236 | if ( ! -f "$f" ) | |
237 | { | |
238 | die("Cannot find $f!"); | |
239 | } | |
e9ec5455 | 240 | |
20d3226a | 241 | # |
95f536ac | 242 | # Grab the current mode/uid/gid for use later |
20d3226a | 243 | # |
244 | ||
95f536ac | 245 | $mode = (stat($f))[2]; |
246 | $uid = (stat($f))[4]; | |
247 | $gid = (stat($f))[5]; | |
20d3226a | 248 | |
20d3226a | 249 | # |
95f536ac | 250 | # Move $f into a .tmp file for the translation step |
20d3226a | 251 | # |
252 | ||
95f536ac | 253 | $result = system("mv $f $g 2>&1"); |
254 | if ($result or $?) | |
20d3226a | 255 | { |
95f536ac | 256 | die "ERROR: Unable to execute command: $!\n"; |
257 | } | |
7536fc6f | 258 | |
95f536ac | 259 | open(IN, "<$g") || die ("$0: input file $g missing!\n"); |
260 | open(OUT, ">$f") || die ("$0: unable to open output file $f!\n"); | |
20d3226a | 261 | |
95f536ac | 262 | while (<IN>) |
263 | { | |
6193a4af | 264 | # |
265 | # sorry for the whacky regex, but i need to verify a whole line | |
266 | # | |
267 | ||
268 | if ( /^\s*Subsystem\s+sftp\s+\S+\s*$/ ) | |
e9ec5455 | 269 | { |
95f536ac | 270 | $_ = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n"; |
271 | $_ =~ s:/+:/:g; | |
7c96a399 | 272 | } |
95f536ac | 273 | print OUT "$_"; |
274 | } # while <IN> | |
7c96a399 | 275 | |
95f536ac | 276 | close(OUT); |
277 | close(IN); | |
7c96a399 | 278 | |
95f536ac | 279 | # |
280 | # Remove the old .tmp file | |
281 | # | |
7c96a399 | 282 | |
95f536ac | 283 | $result = system("rm $g 2>&1"); |
7536fc6f | 284 | |
95f536ac | 285 | if ($result or $?) |
286 | { | |
287 | die "ERROR: Unable to execute command: $!\n"; | |
288 | } | |
7536fc6f | 289 | |
95f536ac | 290 | # |
291 | # An attempt to revert the new file back to the original file's | |
292 | # mode/uid/gid | |
293 | # | |
7e12c9a7 | 294 | |
95f536ac | 295 | chmod($mode, $f); |
296 | chown($uid, $gid, $f); | |
20d3226a | 297 | |
298 | return 0; | |
299 | } | |
300 | ||
d58b3a33 | 301 | sub alterFileGlobusLocation |
a26c150d | 302 | { |
20bb6dc8 | 303 | my ($in, $out) = @_; |
d58b3a33 | 304 | |
20bb6dc8 | 305 | if ( ! -e $out ) |
306 | { | |
307 | $data = readFile($in); | |
308 | $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g; | |
309 | writeFile($out, $data); | |
310 | } | |
d58b3a33 | 311 | } |
312 | ||
313 | sub alterFiles | |
314 | { | |
9cc10d0e | 315 | alterFileGlobusLocation("$setupdir/SXXsshd.in", "$sbindir/SXXsshd"); |
a26c150d | 316 | } |
317 | ||
318 | ### readFile( $filename ) | |
319 | # | |
320 | # reads and returns $filename's contents | |
321 | # | |
322 | ||
323 | sub readFile | |
324 | { | |
325 | my ($filename) = @_; | |
326 | my $data; | |
327 | ||
328 | open (IN, "$filename") || die "Can't open '$filename': $!"; | |
329 | $/ = undef; | |
330 | $data = <IN>; | |
331 | $/ = "\n"; | |
332 | close(IN); | |
333 | ||
334 | return $data; | |
335 | } | |
336 | ||
337 | ### writeFile( $filename, $fileinput ) | |
338 | # | |
339 | # create the inputs to the ssl program at $filename, appending the common name to the | |
340 | # stream in the process | |
341 | # | |
342 | ||
343 | sub writeFile | |
344 | { | |
345 | my ($filename, $fileinput) = @_; | |
346 | ||
347 | # | |
348 | # test for a valid $filename | |
349 | # | |
350 | ||
351 | if ( !defined($filename) || (length($filename) lt 1) ) | |
352 | { | |
353 | die "Filename is undefined"; | |
354 | } | |
355 | ||
356 | if ( ( -e "$filename" ) && ( ! -w "$filename" ) ) | |
357 | { | |
358 | die "Cannot write to filename '$filename'"; | |
359 | } | |
360 | ||
361 | # | |
362 | # write the output to $filename | |
363 | # | |
364 | ||
365 | open(OUT, ">$filename"); | |
366 | print OUT "$fileinput"; | |
367 | close(OUT); | |
368 | } | |
369 | ||
6e9c7232 | 370 | print "---------------------------------------------------------------------\n"; |
823981ba | 371 | print "Hi, I'm the setup script for the gsi_openssh package! There\n"; |
372 | print "are some last minute details that I've got to set straight\n"; | |
95f536ac | 373 | print "in the sshd config file, along with generating the ssh keys\n"; |
823981ba | 374 | print "for this machine (if it doesn't already have them).\n"; |
375 | print "\n"; | |
95f536ac | 376 | print "If I find a pair of host keys in /etc/ssh, I will copy them into\n"; |
6e9c7232 | 377 | print "\$GLOBUS_LOCATION/etc/ssh. If they aren't present, I will generate\n"; |
378 | print "them for you.\n"; | |
823981ba | 379 | print "\n"; |
380 | ||
381 | $response = query_boolean("Do you wish to continue with the setup package?","y"); | |
e9d69a89 | 382 | if ($response eq "n") |
823981ba | 383 | { |
384 | print "\n"; | |
385 | print "Okay.. exiting gsi_openssh setup.\n"; | |
386 | ||
387 | exit 0; | |
388 | } | |
e9ec5455 | 389 | |
9e979a2a | 390 | print "\n"; |
391 | ||
95f536ac | 392 | $keyhash = determineKeys(); |
393 | runKeyGen($keyhash->{gen}); | |
394 | copyKeyFiles($keyhash->{copy}); | |
11b9a41c | 395 | fixpaths(); |
20bb6dc8 | 396 | alterFiles(); |
ad71c979 | 397 | |
472ec086 | 398 | my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup"); |
4f276ad7 | 399 | |
53a54c67 | 400 | $metadata->finish(); |
9ef2f439 | 401 | |
b0441584 | 402 | print "\n"; |
6e9c7232 | 403 | print "Additional Notes:\n"; |
404 | print "\n"; | |
405 | print " o I see that you have your GLOBUS_LOCATION environmental variable\n"; | |
406 | print " set to:\n"; | |
407 | print "\n"; | |
408 | print " \t\"$gpath\"\n"; | |
b0441584 | 409 | print "\n"; |
6e9c7232 | 410 | print " Remember to keep this variable set (correctly) when you want to\n"; |
411 | print " use the executables that came with this package.\n"; | |
5002372c | 412 | print "\n"; |
6e9c7232 | 413 | print " o You may need to set LD_LIBRARY_PATH to point to the location in\n"; |
414 | print " which your globus libraries reside. For example:\n"; | |
5002372c | 415 | print "\n"; |
6e9c7232 | 416 | print " \t\$ LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; \\\n"; |
417 | print " \t export LD_LIBRARY_PATH\n"; | |
5002372c | 418 | print "\n"; |
753002f8 | 419 | print " If you wish, you may run, e.g.:\n"; |
420 | print "\n"; | |
421 | print " \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n"; | |
422 | print "\n"; | |
423 | print " to prepare your environment for running the gsi_openssh\n"; | |
424 | print " executables.\n"; | |
425 | print "\n"; | |
6e9c7232 | 426 | print "---------------------------------------------------------------------\n"; |
9e979a2a | 427 | print "$myname: Finished configuring package 'gsi_openssh'.\n"; |
ac083f7a | 428 | |
429 | # | |
430 | # Just need a minimal action() subroutine for now.. | |
431 | # | |
432 | ||
433 | sub action | |
434 | { | |
435 | my ($command) = @_; | |
436 | ||
437 | printf "$command\n"; | |
438 | ||
8b73e3d0 | 439 | my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1"); |
ac083f7a | 440 | |
441 | if (($result or $?) and $command !~ m!patch!) | |
442 | { | |
443 | die "ERROR: Unable to execute command: $!\n"; | |
444 | } | |
445 | } | |
446 | ||
447 | sub query_boolean | |
448 | { | |
449 | my ($query_text, $default) = @_; | |
450 | my $nondefault, $foo, $bar; | |
451 | ||
452 | # | |
453 | # Set $nondefault to the boolean opposite of $default. | |
454 | # | |
455 | ||
456 | if ($default eq "n") | |
457 | { | |
458 | $nondefault = "y"; | |
459 | } | |
460 | else | |
461 | { | |
462 | $nondefault = "n"; | |
463 | } | |
464 | ||
465 | print "${query_text} "; | |
466 | print "[$default] "; | |
467 | ||
e9ec5455 | 468 | $foo = <STDIN>; |
469 | ($bar) = split //, $foo; | |
470 | ||
e9d69a89 | 471 | if ( grep(/\s/, $bar) ) |
ac083f7a | 472 | { |
e9d69a89 | 473 | # this is debatable. all whitespace means 'default' |
474 | ||
475 | $bar = $default; | |
476 | } | |
477 | elsif ($bar ne $default) | |
478 | { | |
479 | # everything else means 'nondefault'. | |
480 | ||
481 | $bar = $nondefault; | |
482 | } | |
483 | else | |
484 | { | |
485 | # extraneous step. to get here, $bar should be eq to $default anyway. | |
486 | ||
e9ec5455 | 487 | $bar = $default; |
ac083f7a | 488 | } |
489 | ||
e9ec5455 | 490 | return $bar; |
ac083f7a | 491 | } |