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