]> andersk Git - gssapi-openssh.git/blob - setup/setup-openssh.pl
o Update output of the setup script to make the user aware of the
[gssapi-openssh.git] / setup / setup-openssh.pl
1 #!/usr/bin/perl
2 #
3 # setup-openssh.pl
4 #
5 # Adapts the installed gsi-openssh environment to the current machine,
6 # performing actions that originally occurred during the package's
7 # 'make install' phase.
8 #
9 # Send comments/fixes/suggestions to:
10 # Chase Phillips <cphillip@ncsa.uiuc.edu>
11 #
12
13 printf("setup-openssh.pl: Configuring gsi-openssh package\n");
14
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
26 $gpath = $ENV{GLOBUS_LOCATION};
27 if (!defined($gpath))
28 {
29     die "GLOBUS_LOCATION needs to be set before running this script"
30 }
31
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
44 #
45 # i'm including this because other perl scripts in the gpt setup directories
46 # do so
47 #
48
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 }
57
58 require Grid::GPT::Setup;
59
60 my $globusdir = $gpath;
61 my $myname = "setup-openssh.pl";
62
63 #
64 # Set up path prefixes for use in the path translations
65 #
66
67 $prefix = ${globusdir};
68 $exec_prefix = "${prefix}";
69 $bindir = "${exec_prefix}/bin";
70 $sysconfdir = "$prefix/etc/ssh";
71 $localsshdir = "/etc/ssh";
72
73 my $keyfiles = {
74                  "dsa" => "ssh_host_dsa_key",
75                  "rsa" => "ssh_host_rsa_key",
76                  "rsa1" => "ssh_host_key",
77                };
78
79 sub copyKeyFiles
80 {
81     my($copylist) = @_;
82     my($regex, $basename);
83
84     if (@$copylist)
85     {
86         print "Copying ssh host keys...\n";
87
88         for my $f (@$copylist)
89         {
90             $f =~ s:/+:/:g;
91
92             if (length($f) > 0)
93             {
94                 $keyfile = "$f";
95                 $pubkeyfile = "$f.pub";
96
97                 action("cp $localsshdir/$keyfile $sysconfdir/$keyfile");
98                 action("cp $localsshdir/$pubkeyfile $sysconfdir/$pubkeyfile");
99             }
100         }
101     }
102 }
103
104 sub isReadable
105 {
106     my($file) = @_;
107
108     if ( ( -e $file ) && ( -r $file ) )
109     {
110         return 1;
111     }
112     else
113     {
114         return 0;
115     }
116 }
117
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
132 sub determineKeys
133 {
134     my($keyhash, $keylist);
135     my($count);
136
137     #
138     # initialize our variables
139     #
140
141     $count = 0;
142
143     $keyhash = {};
144     $keyhash->{gen} = [];   # a list of keytypes to generate
145     $keyhash->{copy} = [];  # a list of files to copy from the 
146
147     $genlist = $keyhash->{gen};
148     $copylist = $keyhash->{copy};
149
150     #
151     # loop over our keytypes and determine what we need to do for each of them
152     #
153
154     for my $keytype (keys %$keyfiles)
155     {
156         $basekeyfile = $keyfiles->{$keytype};
157
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) )
166         {
167             next;
168         }
169
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) )
179         {
180             push(@$copylist, $basekeyfile);
181             $count++;
182             next;
183         }
184
185         #
186         # otherwise, we need to generate the key
187         #
188
189         push(@$genlist, $keytype);
190         $count++;
191     }
192
193     if ($count > 0)
194     {
195         if ( ! -d $sysconfdir )
196         {
197             print "Could not find ${sysconfdir} directory... creating\n";
198             action("mkdir -p $sysconfdir");
199         }
200     }
201
202     return $keyhash;
203 }
204
205 sub runKeyGen
206 {
207     my($gen_keys) = @_;
208
209     if (@$gen_keys)
210     {
211         print "Generating ssh host keys...\n";
212
213         for my $k (@$gen_keys)
214         {
215             $keyfile = $keyfiles->{$k};
216
217             # if $sysconfdir/$keyfile doesn't exist..
218             action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
219         }
220     }
221
222     return 0;
223 }
224
225 sub fixpaths
226 {
227     my $g, $h;
228
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     }
238
239     #
240     # Grab the current mode/uid/gid for use later
241     #
242
243     $mode = (stat($f))[2];
244     $uid = (stat($f))[4];
245     $gid = (stat($f))[5];
246
247     #
248     # Move $f into a .tmp file for the translation step
249     #
250
251     $result = system("mv $f $g 2>&1");
252     if ($result or $?)
253     {
254         die "ERROR: Unable to execute command: $!\n";
255     }
256
257     open(IN, "<$g") || die ("$0: input file $g missing!\n");
258     open(OUT, ">$f") || die ("$0: unable to open output file $f!\n");
259
260     while (<IN>)
261     {
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*$/ )
267         {
268             $_ = "Subsystem\tsftp\t$gpath/libexec/sftp-server\n";
269             $_ =~ s:/+:/:g;
270         }
271         print OUT "$_";
272     } # while <IN>
273
274     close(OUT);
275     close(IN);
276
277     #
278     # Remove the old .tmp file
279     #
280
281     $result = system("rm $g 2>&1");
282
283     if ($result or $?)
284     {
285         die "ERROR: Unable to execute command: $!\n";
286     }
287
288     #
289     # An attempt to revert the new file back to the original file's
290     # mode/uid/gid
291     #
292
293     chmod($mode, $f);
294     chown($uid, $gid, $f);
295
296     return 0;
297 }
298
299 sub alterFileGlobusLocation
300 {
301     my ($file) = @_;
302
303     $data = readFile($file);
304     $data =~ s|\@GSI_OPENSSH_GLOBUS_LOCATION\@|$gpath|g;
305     writeFile($file, $data);
306 }
307
308 sub alterFiles
309 {
310     my (@files);
311
312     @files = (
313         "$gosharedir/contrib/caldera/sshd.init",
314              );
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
369 print "---------------------------------------------------------------------\n";
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";
372 print "in the sshd config file, along with generating the ssh keys\n";
373 print "for this machine (if it doesn't already have them).\n";
374 print "\n";
375 print "If I find a pair of host keys in /etc/ssh, I will copy them into\n";
376 print "\$GLOBUS_LOCATION/etc/ssh.  If they aren't present, I will generate\n";
377 print "them for you.\n";
378 print "\n";
379
380 $response = query_boolean("Do you wish to continue with the setup package?","y");
381 if ($response eq "n")
382 {
383     print "\n";
384     print "Okay.. exiting gsi_openssh setup.\n";
385
386     exit 0;
387 }
388
389 print "\n";
390
391 $keyhash = determineKeys();
392 runKeyGen($keyhash->{gen});
393 copyKeyFiles($keyhash->{copy});
394 fixpaths();
395
396 my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup");
397
398 $metadata->finish();
399
400 print "\n";
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";
407 print "\n";
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";
410 print "\n";
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";
413 print "\n";
414 print "    \t\$ LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; \\\n";
415 print "    \t     export LD_LIBRARY_PATH\n";
416 print "\n";
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";
424 print "---------------------------------------------------------------------\n";
425 print "$myname: Finished configuring package 'gsi_openssh'.\n";
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
437     my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
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
466     $foo = <STDIN>;
467     ($bar) = split //, $foo;
468
469     if ( grep(/\s/, $bar) )
470     {
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
485         $bar = $default;
486     }
487
488     return $bar;
489 }
This page took 0.086822 seconds and 5 git commands to generate.