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