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