]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/perl | |
2 | # | |
3 | # setup-openssh.pl | |
4 | # | |
5 | # Adapts the installed gsi-ssh environment to the current machine, | |
6 | # performing actions that originally occurred during the package's | |
7 | # 'make install' phase. | |
8 | # | |
9 | # Parts adapted from 'fixpath', a tool found in openssh-3.0.2p1. | |
10 | # | |
11 | # Send comments/fixes/suggestions to: | |
12 | # Chase Phillips <cphillip@ncsa.uiuc.edu> | |
13 | # | |
14 | ||
15 | printf("setup-openssh.pl: Configuring gsi-openssh package\n"); | |
16 | ||
17 | # | |
18 | # Get user's GPT_LOCATION since we may be installing this using a new(er) | |
19 | # version of GPT. | |
20 | # | |
21 | ||
22 | $gptpath = $ENV{GPT_LOCATION}; | |
23 | ||
24 | # | |
25 | # And the old standby.. | |
26 | # | |
27 | ||
28 | $gpath = $ENV{GLOBUS_LOCATION}; | |
29 | if (!defined($gpath)) | |
30 | { | |
31 | die "GLOBUS_LOCATION needs to be set before running this script" | |
32 | } | |
33 | ||
34 | # | |
35 | # i'm including this because other perl scripts in the gpt setup directories | |
36 | # do so | |
37 | # | |
38 | ||
39 | if (defined($gptpath)) | |
40 | { | |
41 | @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl"); | |
42 | } | |
43 | else | |
44 | { | |
45 | @INC = (@INC, "$gpath/lib/perl"); | |
46 | } | |
47 | ||
48 | require Grid::GPT::Setup; | |
49 | ||
50 | my $globusdir = $gpath; | |
51 | my $setupdir = "$globusdir/setup/globus"; | |
52 | my $myname = "setup-openssh.pl"; | |
53 | ||
54 | # | |
55 | # Set up path prefixes for use in the path translations | |
56 | # | |
57 | ||
58 | $prefix = ${globusdir}; | |
59 | $exec_prefix = "${prefix}"; | |
60 | $bindir = "${exec_prefix}/bin"; | |
61 | $sbindir = "${exec_prefix}/sbin"; | |
62 | $mandir = "${prefix}/man"; | |
63 | $mansubdir = "man"; | |
64 | $libexecdir = "${exec_prefix}/libexec"; | |
65 | $sysconfdir = "/etc/ssh"; | |
66 | $piddir = "/var/run"; | |
67 | $xauth_path = "/usr/bin/X11/xauth"; | |
68 | ||
69 | # | |
70 | # Backup-related variables | |
71 | # | |
72 | ||
73 | $curr_time = time(); | |
74 | $backupdir = "/etc/ssh/globus_backup_${curr_time}"; | |
75 | ||
76 | # | |
77 | # Check that we are running as root | |
78 | # | |
79 | ||
80 | $uid = $>; | |
81 | ||
82 | if ($uid != 0) | |
83 | { | |
84 | print "--> NOTE: You must be root to run this script! <--\n"; | |
85 | exit 0; | |
86 | } | |
87 | ||
88 | # | |
89 | # We need to make sure it's okay to copy our setup files (if some files are already | |
90 | # present). If we do copy any files, we backup the old files so the user can (possibly) | |
91 | # reverse any damage. | |
92 | # | |
93 | ||
94 | sub test_dirs | |
95 | { | |
96 | print "\nPreparatory: Checking for existence of critical directories..\n"; | |
97 | ||
98 | # | |
99 | # Remember to put in check for /etc | |
100 | # | |
101 | ||
102 | # | |
103 | # Test for /etc/ssh | |
104 | # | |
105 | ||
106 | if ( ! -d "$sysconfdir" ) | |
107 | { | |
108 | print "Could not find directory: '${sysconfdir}'.. creating.\n"; | |
109 | mkdir($sysconfdir, 16877); | |
110 | # 16877 should be 755, or drwxr-xr-x | |
111 | } | |
112 | ||
113 | # | |
114 | # Test for /etc/ssh/globus_backup_<curr> | |
115 | # | |
116 | ||
117 | if ( ! -d "${backupdir}" ) | |
118 | { | |
119 | print "Could not find directory: '${backupdir}'.. creating.\n"; | |
120 | mkdir($backupdir, 16877); | |
121 | } | |
122 | ||
123 | return 0; | |
124 | } | |
125 | ||
126 | sub backup_files | |
127 | { | |
128 | print "\nStage 1: Backing up configuration files to '${backupdir}/'..\n"; | |
129 | ||
130 | if ( -e "${sysconfdir}/ssh_config" ) | |
131 | { | |
132 | action("cp ${sysconfdir}/ssh_config ${backupdir}/ssh_config"); | |
133 | } | |
134 | else | |
135 | { | |
136 | print "${sysconfdir}/ssh_config does not exist.\n"; | |
137 | } | |
138 | ||
139 | if ( -e "${sysconfdir}/sshd_config" ) | |
140 | { | |
141 | action("cp ${sysconfdir}/sshd_config ${backupdir}/sshd_config"); | |
142 | } | |
143 | else | |
144 | { | |
145 | print "${sysconfdir}/sshd_config does not exist.\n"; | |
146 | } | |
147 | ||
148 | if ( -e "${sysconfdir}/moduli" ) | |
149 | { | |
150 | action("cp ${sysconfdir}/moduli ${backupdir}/moduli"); | |
151 | } | |
152 | else | |
153 | { | |
154 | print "${sysconfdir}/moduli does not exist.\n"; | |
155 | } | |
156 | } | |
157 | ||
158 | sub copy_setup_files | |
159 | { | |
160 | my $response; | |
161 | ||
162 | print "\nStage 2: Copying configuration files into '${sysconfdir}'..\n"; | |
163 | ||
164 | action("cp ${globusdir}/setup/globus/ssh_config ${sysconfdir}/ssh_config"); | |
165 | action("cp ${globusdir}/setup/globus/sshd_config ${sysconfdir}/sshd_config"); | |
166 | action("cp ${globusdir}/setup/globus/moduli ${sysconfdir}/moduli"); | |
167 | } | |
168 | ||
169 | sub runkeygen | |
170 | { | |
171 | print "\nStage 3: Generating ssh host keys..\n"; | |
172 | ||
173 | if ( ! -d "${sysconfdir}" ) | |
174 | { | |
175 | print "Could not find ${sysconfdir} directory... creating\n"; | |
176 | mkdir($sysconfdir, 16877); | |
177 | # 16877 should be 755, or drwxr-xr-x | |
178 | } | |
179 | ||
180 | if ( -e "${sysconfdir}/ssh_host_key" ) | |
181 | { | |
182 | print "${sysconfdir}/ssh_host_key already exists, skipping.\n"; | |
183 | } | |
184 | else | |
185 | { | |
186 | # if $sysconfdir/ssh_host_key doesn't exist.. | |
187 | action("$bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N \"\""); | |
188 | } | |
189 | ||
190 | if ( -e "${sysconfdir}/ssh_host_dsa_key" ) | |
191 | { | |
192 | print "${sysconfdir}/ssh_host_dsa_key already exists, skipping.\n"; | |
193 | } | |
194 | else | |
195 | { | |
196 | # if $sysconfdir/ssh_host_dsa_key doesn't exist.. | |
197 | action("$bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N \"\""); | |
198 | } | |
199 | ||
200 | if ( -e "${sysconfdir}/ssh_host_rsa_key" ) | |
201 | { | |
202 | print "${sysconfdir}/ssh_host_rsa_key already exists, skipping.\n"; | |
203 | } | |
204 | else | |
205 | { | |
206 | # if $sysconfdir/ssh_host_rsa_key doesn't exist.. | |
207 | action("$bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N \"\""); | |
208 | } | |
209 | ||
210 | return 0; | |
211 | } | |
212 | ||
213 | sub fixpaths | |
214 | { | |
215 | my $g, $h; | |
216 | ||
217 | print "\nStage 4: Translating strings in config and man files..\n"; | |
218 | ||
219 | # | |
220 | # Set up path translations for the installation files | |
221 | # | |
222 | ||
223 | %def = ( | |
224 | "/etc/ssh_config" => "${sysconfdir}/ssh_config", | |
225 | "/etc/ssh_known_hosts" => "${sysconfdir}/ssh_known_hosts", | |
226 | "/etc/sshd_config" => "${sysconfdir}/sshd_config", | |
227 | "/usr/libexec" => "${libexecdir}", | |
228 | "/etc/shosts.equiv" => "${sysconfdir}/shosts.equiv", | |
229 | "/etc/ssh_host_key" => "${sysconfdir}/ssh_host_key", | |
230 | "/etc/ssh_host_dsa_key" => "${sysconfdir}/ssh_host_dsa_key", | |
231 | "/etc/ssh_host_rsa_key" => "${sysconfdir}/ssh_host_rsa_key", | |
232 | "/var/run/sshd.pid" => "${piddir}/sshd.pid", | |
233 | "/etc/moduli" => "${sysconfdir}/moduli", | |
234 | "/etc/sshrc" => "${sysconfdir}/sshrc", | |
235 | "/usr/X11R6/bin/xauth" => "${xauth_path}", | |
236 | "/usr/bin:/bin:/usr/sbin:/sbin" => "/usr/bin:/bin:/usr/sbin:/sbin:${bindir}", | |
237 | ); | |
238 | ||
239 | # | |
240 | # Files on which to perform path translations | |
241 | # | |
242 | ||
243 | @files = ( | |
244 | "${sysconfdir}/ssh_config", | |
245 | "${sysconfdir}/sshd_config", | |
246 | "${sysconfdir}/moduli", | |
247 | "${mandir}/${mansubdir}1/scp.1", | |
248 | "${mandir}/${mansubdir}1/ssh-add.1", | |
249 | "${mandir}/${mansubdir}1/ssh-agent.1", | |
250 | "${mandir}/${mansubdir}1/ssh-keygen.1", | |
251 | "${mandir}/${mansubdir}1/ssh-keyscan.1", | |
252 | "${mandir}/${mansubdir}1/ssh.1", | |
253 | "${mandir}/${mansubdir}8/sshd.8", | |
254 | "${mandir}/${mansubdir}8/sftp-server.8", | |
255 | "${mandir}/${mansubdir}1/sftp.1", | |
256 | ); | |
257 | ||
258 | for my $f (@files) | |
259 | { | |
260 | $f =~ /(.*\/)*(.*)$/; | |
261 | ||
262 | # | |
263 | # we really should create a random filename and make sure that it | |
264 | # doesn't already exist (based off current time_t or something) | |
265 | # | |
266 | ||
267 | $g = "$f.tmp"; | |
268 | ||
269 | # | |
270 | # What is $f's filename? (taken from the qualified path) | |
271 | # | |
272 | ||
273 | $h = $f; | |
274 | $h =~ s#^.*/##; | |
275 | ||
276 | # | |
277 | # Grab the current mode/uid/gid for use later | |
278 | # | |
279 | ||
280 | $mode = (stat($f))[2]; | |
281 | $uid = (stat($f))[4]; | |
282 | $gid = (stat($f))[5]; | |
283 | ||
284 | # | |
285 | # Move $f into a .tmp file for the translation step | |
286 | # | |
287 | ||
288 | $result = system("mv $f $g 2>&1"); | |
289 | if ($result or $?) | |
290 | { | |
291 | die "ERROR: Unable to execute command: $!\n"; | |
292 | } | |
293 | ||
294 | open(IN, "<$g") || die ("$0: input file $g missing!\n"); | |
295 | open(OUT, ">$f") || die ("$0: unable to open output file $f!\n"); | |
296 | ||
297 | while (<IN>) | |
298 | { | |
299 | for $s (keys(%def)) | |
300 | { | |
301 | s#$s#$def{$s}#; | |
302 | } # for $s | |
303 | print OUT "$_"; | |
304 | } # while <IN> | |
305 | ||
306 | close(OUT); | |
307 | close(IN); | |
308 | ||
309 | # | |
310 | # Remove the old .tmp file | |
311 | # | |
312 | ||
313 | $result = system("rm $g 2>&1"); | |
314 | ||
315 | if ($result or $?) | |
316 | { | |
317 | die "ERROR: Unable to execute command: $!\n"; | |
318 | } | |
319 | ||
320 | # | |
321 | # An attempt to revert the new file back to the original file's | |
322 | # mode/uid/gid | |
323 | # | |
324 | ||
325 | chmod($mode, $f); | |
326 | chown($uid, $gid, $f); | |
327 | ||
328 | print "$h\n"; | |
329 | } # for $f | |
330 | ||
331 | return 0; | |
332 | } | |
333 | ||
334 | print "---------------------------------------------------------------\n"; | |
335 | print "Hi, I'm the setup script for the gsi_openssh package! There\n"; | |
336 | print "are some last minute details that I've got to set straight\n"; | |
337 | print "in the config and man files, along with generating the ssh keys\n"; | |
338 | print "for this machine (if it doesn't already have them).\n"; | |
339 | print "\n"; | |
340 | print "I like to install my config-related files in:\n"; | |
341 | print " ${sysconfdir}/\n"; | |
342 | print "\n"; | |
343 | print "These files may overwrite your previously existing configuration\n"; | |
344 | print "files. If you choose to continue, you will find a backup of\n"; | |
345 | print "those original files in:\n"; | |
346 | print " ${backupdir}/\n"; | |
347 | print "\n"; | |
348 | print "Your host keys will remain untouched if they are already present.\n"; | |
349 | print "If they aren't present, this script will generate them for you.\n"; | |
350 | print "\n"; | |
351 | ||
352 | $response = query_boolean("Do you wish to continue with the setup package?","y"); | |
353 | ||
354 | if ($response eq "n") | |
355 | { | |
356 | print "\n"; | |
357 | print "Okay.. exiting gsi_openssh setup.\n"; | |
358 | ||
359 | exit 0; | |
360 | } | |
361 | ||
362 | test_dirs(); | |
363 | backup_files(); | |
364 | copy_setup_files(); | |
365 | runkeygen(); | |
366 | fixpaths(); | |
367 | ||
368 | my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup"); | |
369 | ||
370 | $metadata->finish(); | |
371 | ||
372 | print "\n"; | |
373 | print "$myname: Finished configuring package 'gsi_openssh'.\n"; | |
374 | print "\n"; | |
375 | print "I see that you have your GLOBUS_LOCATION environmental variable\n"; | |
376 | print "set to:\n"; | |
377 | print " $gpath\n"; | |
378 | print "\n"; | |
379 | print "Remember to keep this variable set (correctly) when you want\n"; | |
380 | print "to use the executables that came with this package.\n"; | |
381 | print "\n"; | |
382 | print "Additionally, you may need to set LD_LIBRARY_PATH to point to\n"; | |
383 | print "the location in which your globus libraries reside. For example:\n"; | |
384 | print "\n"; | |
385 | print " export LD_LIBRARY_PATH=\"$gpath/lib\"\n"; | |
386 | print "\n"; | |
387 | print "---------------------------------------------------------------\n"; | |
388 | ||
389 | # | |
390 | # Just need a minimal action() subroutine for now.. | |
391 | # | |
392 | ||
393 | sub action | |
394 | { | |
395 | my ($command) = @_; | |
396 | ||
397 | printf "$command\n"; | |
398 | ||
399 | my $result = system("$command 2>&1"); | |
400 | ||
401 | if (($result or $?) and $command !~ m!patch!) | |
402 | { | |
403 | die "ERROR: Unable to execute command: $!\n"; | |
404 | } | |
405 | } | |
406 | ||
407 | sub query_boolean | |
408 | { | |
409 | my ($query_text, $default) = @_; | |
410 | my $nondefault, $foo, $bar; | |
411 | ||
412 | # | |
413 | # Set $nondefault to the boolean opposite of $default. | |
414 | # | |
415 | ||
416 | if ($default eq "n") | |
417 | { | |
418 | $nondefault = "y"; | |
419 | } | |
420 | else | |
421 | { | |
422 | $nondefault = "n"; | |
423 | } | |
424 | ||
425 | print "${query_text} "; | |
426 | print "[$default] "; | |
427 | ||
428 | $foo = <STDIN>; | |
429 | ($bar) = split //, $foo; | |
430 | ||
431 | if ( grep(/\s/, $bar) ) | |
432 | { | |
433 | # this is debatable. all whitespace means 'default' | |
434 | ||
435 | $bar = $default; | |
436 | } | |
437 | elsif ($bar ne $default) | |
438 | { | |
439 | # everything else means 'nondefault'. | |
440 | ||
441 | $bar = $nondefault; | |
442 | } | |
443 | else | |
444 | { | |
445 | # extraneous step. to get here, $bar should be eq to $default anyway. | |
446 | ||
447 | $bar = $default; | |
448 | } | |
449 | ||
450 | return $bar; | |
451 | } |