root/fwknop/tags/fwknop-1.8.2-pre6/install.pl

Revision 731, 53.8 kB (checked in by mbr, 1 year ago)

fwknop-1.8.2-pre6

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2 #
3 #############################################################################
4 #
5 # File: install.pl
6 #
7 # URL: http://www.cipherdyne.org/fwknop
8 #
9 # Purpose: Installer for fwknop
10 #
11 # Credits:  (see the CREDITS file)
12 #
13 # Copyright (C) 2004-2007 Michael Rash (mbr@cipherdyne.org)
14 #
15 # License (GNU Public License):
16 #
17 #    This program is distributed in the hope that it will be useful,
18 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 #    GNU General Public License for more details.
21 #
22 #    You should have received a copy of the GNU General Public License
23 #    along with this program; if not, write to the Free Software
24 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
25 #    USA
26 #
27 #############################################################################
28 #
29 # $Id$
30 #
31
32 use Cwd;
33 use File::Copy;
34 use File::Path;
35 use Getopt::Long;
36 use Sys::Hostname;
37 use strict;
38
39 #========================== config ===========================
40 my $INIT_DIR    = '/etc/init.d';
41 my $USRBIN_DIR  = '/usr/bin';
42 my $URRSBIN_DIR = '/usr/sbin';
43
44 my $RUNLEVEL;    ### This should only be set if install.pl
45                  ### cannot determine the correct runlevel
46
47 ### only used it $ENV{'HOME'} is not set for some reason
48 my $config_homedir = '';
49
50 my $fwknop_conf_file = 'fwknop.conf';
51
52 ### system binaries
53 my $chkconfigCmd = '/sbin/chkconfig';
54 my $rcupdateCmd  = '/sbin/rc-update'### Gentoo
55 my $makeCmd      = '/usr/bin/make';
56 my $perlCmd      = '/usr/bin/perl';
57 my $gzipCmd      = '/bin/gzip';
58 my $killallCmd   = '/usr/bin/killall';
59 my $mknodCmd     = '/bin/mknod';
60 my $ifconfigCmd  = '/sbin/ifconfig';
61 #======================== end config =========================
62
63 ### main configuration hash
64 my %config = ();
65
66 my $client_install = 0;
67 my $bsd_install    = 0;
68 my $osx_install    = 0;
69 my $cygwin_install = 0;
70 my $homedir = '';
71 my $distro  = '';
72 my $print_help  = 0;
73 my $uninstall   = 0;
74 my $syslog_conf = '';
75 my $data_method = '';
76 my $runlevel;
77 my $force_install_re  = '';
78 my $force_path_update = 0;
79 my $cmdline_force_install = 0;
80 my $skip_module_install   = 0;
81 my $force_defaults  = 0;
82 my $cmdline_os_type = '';
83 my $os_type = 0;
84
85 my $OS_LINUX  = 1;
86 my $OS_CYGWIN = 2;
87 my $OS_DARWIN = 3;  ### Mac OS X
88
89 my %exclude_cmds = (
90     'mail'        => '',
91     'fwknop'      => '',
92     'fwknopd'     => '',
93     'fwknop_serv' => '',
94     'knopmd'      => '',
95     'knoptm'      => '',
96     'knopwatchd'  => '',
97 );
98
99 ### perl module directories
100 my @required_perl_modules = (
101     {   'module'              =>'Class::MethodMaker', ### GnuPG::Interface dependency
102         'force-install'       => 0,
103         'client-mode-install' => 1,
104         'mod-dir'             => 'Class-MethodMaker'
105     },
106     {   'module'              => 'GnuPG::Interface',
107         'force-install'       => 0,
108         'client-mode-install' => 1,
109         'mod-dir'             => 'GnuPG-Interface'
110     },
111     {   'module'              => 'Unix::Syslog',
112         'force-install'       => 0,
113         'client-mode-install' => 0,
114         'mod-dir'             => 'Unix-Syslog'
115     },
116     {   'module'              => 'Net::IPv4Addr',
117         'force-install'       => 0,
118         'client-mode-install' => 1,
119         'mod-dir'             => 'Net-IPv4Addr'
120     },
121     {   'module'              => 'Net::Pcap',
122         'force-install'       => 0,
123         'client-mode-install' => 0,
124         'mod-dir'             => 'Net-Pcap'
125     },
126     {   'module'              => 'List::MoreUtils'### Net::RawIP dependency
127         'force-install'       => 0,
128         'client-mode-install' => 1,
129         'mod-dir'             => 'List-MoreUtils'
130     },
131     {   'module'              => 'Net::RawIP',
132         'force-install'       => 0,
133         'client-mode-install' => 1,
134         'mod-dir'             => 'Net-RawIP'
135     },
136     {   'module'              => 'Net::Ping::External',
137         'force-install'       => 0,
138         'client-mode-install' => 1,
139         'mod-dir'             => 'Net-Ping-External'
140     },
141     {   'module'              => 'Crypt::Rijndael',
142         'force-install'       => 0,
143         'client-mode-install' => 1,
144         'mod-dir'             => 'Crypt-Rijndael'
145     },
146     {   'module'              => 'Crypt::CBC',
147         'force-install'       => 0,
148         'client-mode-install' => 1,
149         'mod-dir'             => 'Crypt-CBC'
150     },
151     {   'module'              => 'Term::ReadKey',
152         'force-install'       => 0,
153         'client-mode-install' => 1,
154         'mod-dir'             => 'TermReadKey'
155     },
156     {   'module'              => 'IPTables::Parse',
157         'force-install'       => 1,
158         'client-mode-install' => 0,
159         'mod-dir'             => 'IPTables-Parse'
160     },
161     {   'module'              => 'IPTables::ChainMgr',
162         'force-install'       => 1,
163         'client-mode-install' => 0,
164         'mod-dir'             => 'IPTables-ChainMgr'
165     }
166 );
167
168 my %cmds = (
169     'make'     => $makeCmd,
170     'perl'     => $perlCmd,
171     'gzip'     => $gzipCmd,
172     'killall'  => $killallCmd,
173     'mknod'    => $mknodCmd,
174     'ifconfig' => $ifconfigCmd,
175 );
176
177 my @cmd_search_paths = qw(
178     /bin
179     /sbin
180     /usr/bin
181     /usr/sbin
182     /usr/local/bin
183     /usr/local/sbin
184 );
185
186 ### for user answers
187 my $ACCEPT_YES_DEFAULT = 1;
188 my $ACCEPT_NO_DEFAULT  = 2;
189 my $NO_ANS_DEFAULT     = 0;
190
191 ### make Getopts case sensitive
192 Getopt::Long::Configure('no_ignore_case');
193
194 &usage(1) unless (GetOptions(
195     'force-mod-install' => \$cmdline_force_install,  ### force install of all modules
196     'Force-mod-regex=s' => \$force_install_re, ### force specific mod install with regex
197     'Skip-mod-install'  => \$skip_module_install,
198     'OS-type=s'         => \$cmdline_os_type,
199     'Cygwin-install'    => \$cygwin_install,
200     'BSD-install'   => \$bsd_install,
201     'Defaults'      => \$force_defaults,
202     'client-only'   => \$client_install, # Force client-only installation
203     'path-update'   => \$force_path_update,
204     'uninstall'     => \$uninstall,      # Uninstall fwknop.
205     'syslog-conf=s' => \$syslog_conf,    # Specify path to syslog config file.
206     'help'          => \$print_help      # Display help.
207 ));
208 &usage(0) if $print_help;
209
210 if ($bsd_install and $cygwin_install) {
211     die "[*] Cannot use --BSD-install and --Cygwin-install at the same time.";
212 }
213
214 ### import paths from default fwknopd.conf
215 &import_config();
216
217 ### check to see if we are installing on an ipfw system (freebsd, etc.)
218 if (&is_ipfw()) {
219
220     print
221 "[+] It looks like you are installing fwknop on a *BSD system. Installation\n",
222 "    of iptables perl modules will be skipped.\n";
223     $bsd_install = 1;
224
225 } elsif (&is_cygwin()) { ### check to see if we are installing on Cygwin
226
227     print
228 "[+] It looks like you are installing fwknop in a Cygwin environment, so the\n",
229 "    fwknop client will be installed (the fwknopd server does not yet\n",
230 "    function with a Windows-based firewall).\n\n";
231
232     $client_install = 1;
233
234 }
235
236 ### check to see if we are installing as a non-root user
237 &check_non_root_user() unless $client_install;
238
239 if ($client_install) {
240
241     ### we are installing as a normal user instead of root, so see
242     ### if it is ok to install within the user's home directory
243     $homedir = '';
244     if ($config_homedir) {
245         $homedir = $config_homedir;
246     } else {
247         $homedir = $ENV{'HOME'} or die '[*] Could not get home ',
248             "directory, set the $config_homedir var.";
249     }
250
251     print
252 "    The fwknop client will be installed at $homedir/bin/fwknop, and a few\n",
253 "    perl modules needed by fwknop will be installed in $homedir/lib/fwknop/.\n\n",
254
255     $config{'FWKNOP_MOD_DIR'} = "$homedir/lib/fwknop";
256     $USRBIN_DIR = "$homedir/bin";
257
258 } else {
259
260     unless ($bsd_install) {
261
262         $distro = &get_distro();
263
264         if ($distro eq 'redhat' or $distro eq 'fedora') {
265             ### add chkconfig only if we are runing on a redhat distro
266             $cmds{'chkconfig'} = $chkconfigCmd;
267         } elsif ($distro eq 'gentoo') {
268             ### add rc-update if we are running on a gentoo distro
269             $cmds{'rc-update'} = $rcupdateCmd;
270         }
271     }
272 }
273
274 ### make sure the system binaries are where we expect
275 ### them to be.
276 &check_commands();
277
278 my $hostname = hostname();
279
280 my $src_dir = getcwd() or die "[*] Could not get current working directory.";
281
282 if (not $uninstall) {
283     &install();
284 } else {
285     &uninstall();
286 }
287 exit 0;
288 #======================= end main ==========================
289
290 sub install() {
291     print "[+] Installing fwknop on $hostname\n";
292
293     my $preserve_rv = 0;
294     unless ($client_install) {
295         if (&ask_to_stop_fwknop()) {
296             &stop_fwknop();
297         }
298
299         for my $dir qw| /usr/lib /var/run /var/log /var/lib | {
300             unless (-d $dir) {
301                 mkdir $dir or die "[*] Could not mkdir $dir: $!";
302             }
303         }
304         unless (-d $URRSBIN_DIR) {
305             mkdir $URRSBIN_DIR or die "[*] Could not mkdir $URRSBIN_DIR: $!";
306         }
307         for my $dir qw/FWKNOP_RUN_DIR FWKNOP_LIB_DIR FWKNOP_MOD_DIR/ {
308             unless (-d $config{$dir}) {
309                 mkdir $config{$dir} or
310                     die "[*] Could not mkdir $config{$dir}: $!";
311             }
312         }
313     }
314     unless (-d $USRBIN_DIR) {
315         print "[+] Creating: $USRBIN_DIR\n";
316         mkdir $USRBIN_DIR or die "[*] Could not mkdir $USRBIN_DIR: $!";
317     }
318
319     ### config directory
320     unless ($client_install) {
321         if (-d $config{'FWKNOP_CONF_DIR'}) {
322             print "[-] Config directory ",
323                 "$config{'FWKNOP_CONF_DIR'} already exists.\n";
324         } else {
325             ### Note that root will only be able to view files in
326             ### /etc/fwknop since fwknop only needs to view fwknop.conf
327             ### when being run as a daemon.
328             print "[+] Creating config directory: ",
329                 "$config{'FWKNOP_CONF_DIR'}\n";
330             mkdir $config{'FWKNOP_CONF_DIR'}, 0500
331                 or die "[*] Could not mkdir $config{'FWKNOP_CONF_DIR'}: $!";
332         }
333
334         if (-d $config{'FWKNOP_DIR'}) {
335             print "[-] Cache directory $config{'FWKNOP_DIR'} already exists.\n";
336         } else {
337             print "[+] Creating cache directory: $config{'FWKNOP_DIR'}\n";
338             mkdir $config{'FWKNOP_DIR'}, 0500
339                 or die "[*] Could not mkdir $config{'FWKNOP_DIR'}: $!";
340         }
341
342         ### archive directory for previously installed config files
343         if (-d "$config{'FWKNOP_CONF_DIR'}/archive") {
344             print "[-] Archive directory ",
345                 "$config{'FWKNOP_CONF_DIR'}/archive already exists.\n";
346         } else {
347             print "[+] Creating config{'FWKNOP_CONF_DIR'}/archive ",
348                 "directory: $config{'FWKNOP_CONF_DIR'}/archive\n";
349             mkdir "$config{'FWKNOP_CONF_DIR'}/archive", 0500 or die
350                 "[*] Could not mkdir $config{'FWKNOP_CONF_DIR'}/archive: $!";
351         }
352     }
353
354     print "[+] Several perl modules needed by fwknop will be installed in\n",
355         "    $config{'FWKNOP_MOD_DIR'}. Installing them here will keep the ",
356         "system perl\n    library tree clean.\n";
357
358     ### make our library directory (for perl modules)
359     if ($client_install) {
360         if (-d "$homedir/lib") {
361             print "[-] Directory $homedir/lib already exists.\n";
362         } else {
363             print "[+] Creating directory $homedir/lib\n";
364             mkdir "$homedir/lib", 0755
365                 or die "[*] Could not mkdir $homedir/lib: $!";
366         }
367     }
368     if (-d $config{'FWKNOP_MOD_DIR'}) {
369         print "[-] Lib directory $config{'FWKNOP_MOD_DIR'} already exists.\n";
370     } else {
371         print "[+] Creating directory $config{'FWKNOP_MOD_DIR'}\n";
372         mkdir $config{'FWKNOP_MOD_DIR'}, 0755
373             or die "[*] Could not mkdir $config{'FWKNOP_MOD_DIR'}: $!";
374     }
375
376     ### install perl modules
377     unless ($skip_module_install) {
378         for my $mod_href (@required_perl_modules) {
379             &install_perl_module($mod_href);
380         }
381     }
382
383     ### special case the NetPacket::<proto> modules since the NetPacket
384     ### directory is just for the base class, and we need to make sure
385     ### we have each of the NetPacket::IP, NetPacket::ICMP, NetPacket::UDP,
386     ### and NetPacket::TCP modules.
387     unless ($skip_module_install or $client_install) {
388         chdir 'NetPacket' or die "[*] Could not chdir NetPacket directory: $!";
389         unless (-e 'Makefile.PL') {
390             die "[*] Your NetPacket source directory appears to be incomplete!\n",
391                 "    Download the latest sources from ",
392                 "http://www.cipherdyne.org\n";
393         }
394         system "$cmds{'make'} clean" if -e 'Makefile';
395         system "$cmds{'perl'} Makefile.PL PREFIX=$config{'FWKNOP_MOD_DIR'} " .
396             "LIB=$config{'FWKNOP_MOD_DIR'}";
397         system $cmds{'make'};
398 #        system "$cmds{'make'} test";
399         system "$cmds{'make'} install";
400         chdir $src_dir or die "[*] Could not chdir $src_dir: $!";
401     }
402
403     unless ($client_install) {
404
405         ### install man pages
406         &install_manpage('knopmd.8');
407         &install_manpage('knopwatchd.8');
408         &install_manpage('fwknop.8');
409         &install_manpage('fwknopd.8');
410
411         if (-e "$config{'FWKNOP_CONF_DIR'}/fwknop.conf") {
412             $preserve_rv = &query_preserve_config();
413         }
414
415         print "[+] Compiling knopmd and knopwatchd daemons:\n";
416
417         ### remove any previously compiled knopmd
418         unlink 'knopmd' if -e 'knopmd';
419
420         ### remove any previously compiled knopwatchd
421         unlink 'knopwatchd' if -e 'knopwatchd';
422
423         ### compile the C fwknop daemons
424         system $cmds{'make'};
425
426         unless (-e 'knopmd' and -e 'knopwatchd') {
427             die "[*] Compilation failed.";
428         }
429
430         ### install fwknop server-side daemons/programs
431         for my $daemon qw(fwknopd knopmd knopwatchd knoptm fwknop_serv) {
432             if ($daemon eq 'fwknopd' or $daemon eq 'knoptm') {
433                 unless (((system "$cmds{'perl'} -c $daemon")>>8) == 0) {
434                     die "[*] $daemon does not compile with \"perl -c\".  ",
435                         "Download the latest sources ",
436                         "from:\n\nhttp://www.cipherdyne.org/\n";
437                 }
438             }
439             print "[+] Copying $daemon -> $URRSBIN_DIR\n";
440             copy $daemon, $URRSBIN_DIR or
441                 die "[*] Could not cp $daemon to $URRSBIN_DIR: $!";
442             chmod 0500, "$URRSBIN_DIR/$daemon" or
443                 die "[*] Could not chmod 500 $URRSBIN_DIR/$daemon: $!";
444         }
445     }
446
447     print "[+] Copying fwknop -> $USRBIN_DIR\n";
448     copy 'fwknop', $USRBIN_DIR or
449         die "[*] Could not cp fwknop to $USRBIN_DIR: $!";
450
451     if ($client_install) {
452         open F, "< $USRBIN_DIR/fwknop" or die "[*] Could not open ",
453             "$USRBIN_DIR/fwknop: $!";
454         my @lines = <F>;
455         close F;
456         open P, "> $USRBIN_DIR/fwknop.tmp" or die "[*] Could not open ",
457             "$USRBIN_DIR/fwknop.tmp: $!";
458         for my $line (@lines) {
459             ### change the lib dir to new homedir path
460             if ($line =~ m|^\s*use\s+lib\s+\'/usr/lib/fwknop\';|) {
461                 print P "use lib '", $config{'FWKNOP_MOD_DIR'}, "';\n";
462             } else {
463                 print P $line;
464             }
465         }
466         close P;
467         move "$USRBIN_DIR/fwknop.tmp", "$USRBIN_DIR/fwknop" or die "[*] Could ",
468             "not move $USRBIN_DIR/fwknop.tmp -> $USRBIN_DIR/fwknop: $!";
469         chmod 0700, "$USRBIN_DIR/fwknop" or
470             die "[*] Could not chmod 755 $USRBIN_DIR/fwknop: $!";
471     } else {
472         chmod 0755, "$USRBIN_DIR/fwknop" or
473             die "[*] Could not chmod 755 $USRBIN_DIR/fwknop: $!";
474     }
475
476     unless (((system "$cmds{'perl'} -c $USRBIN_DIR/fwknop")>>8) == 0) {
477         die "[*] $USRBIN_DIR/fwknop does not compile with \"perl -c\".  ",
478             "Download the latest sources ",
479             "from:\n\nhttp://www.cipherdyne.org/\n";
480     }
481
482
483     if ($client_install) {
484         print
485 "\n[+] fwknop has been installed at $USRBIN_DIR/fwknop.  Since this is a\n",
486 "    client-only install, the man pages could not be installed.  For more\n",
487 "    information about how to use fwknop, execute \"$USRBIN_DIR/fwknop -h\" or\n",
488 "    refer to:\n\n",
489 "        http://www.cipherdyne.org/fwknop/docs/manpages/index.html\n\n";
490
491     } else {
492
493         ### install config and access files
494         for my $file qw(fwknop.conf access.conf pf.os) {
495             if (-e "$config{'FWKNOP_CONF_DIR'}/$file") {
496                 &archive("$config{'FWKNOP_CONF_DIR'}/$file");
497                 if ($preserve_rv) {
498                     if ($file eq 'access.conf') {
499                         ### access.conf can have missing fields (i.e.
500                         ### REQUIRE_OS_REGEX and REQUIRE_USERNAME),
501                         ### and also it can have multiple sequences
502                         ### defined.  Hence we just use the old one.
503                         print "[+] Using original access.conf\n";
504                     } elsif ($file ne 'pf.os') {
505                         &preserve_config($file);
506                     }
507                 } else {
508                     print "[+] Copying $file -> $config{'FWKNOP_CONF_DIR'}\n";
509                     copy $file, $config{'FWKNOP_CONF_DIR'} or
510                         die "[*] Could not cp $file to $config{'FWKNOP_CONF_DIR'}";
511                 }
512             } else {
513                 print "[+] Copying $file -> $config{'FWKNOP_CONF_DIR'}\n";
514                 copy $file, $config{'FWKNOP_CONF_DIR'} or
515                     die "[*] Could not cp $file to $config{'FWKNOP_CONF_DIR'}";
516             }
517
518             if ($force_path_update or not $preserve_rv) {
519                 &update_command_paths("$config{'FWKNOP_CONF_DIR'}/$file")
520                     if ($file eq 'fwknop.conf');
521             }
522
523             if ($file eq 'fwknop.conf') {
524                 &set_hostname("$config{'FWKNOP_CONF_DIR'}/$file");
525             }
526             chmod 0600, "$config{'FWKNOP_CONF_DIR'}/$file" or die
527                 "[*] Could not chmod(600, $config{'FWKNOP_CONF_DIR'}/$file: $!";
528             chown 0, 0, "$config{'FWKNOP_CONF_DIR'}/$file" or die
529                 "[*] Could not chown 0,0, $config{'FWKNOP_CONF_DIR'}/$file: $!";
530         }
531
532         ### get data acquisition method (e.g. syslogd, sysylog-ng, ulogd
533         ### or pcap)
534         $data_method = &query_data_method();
535
536         if ($data_method =~ /syslog/) {
537
538             ### create the named pipe
539             unless (-e $config{'KNOPMD_FIFO'} and -p $config{'KNOPMD_FIFO'}) {
540                 unlink $config{'KNOPMD_FIFO'} if -e $config{'KNOPMD_FIFO'};
541                 print "[+] Creating named pipe $config{'KNOPMD_FIFO'}\n";
542                 my $created_pipe = 1;
543                 unless (((system "$cmds{'mknod'} -m 600 $config{'KNOPMD_FIFO'} p")>>8)
544                         == 0) {
545                     $created_pipe = 0;
546                 }
547                 unless (-e $config{'KNOPMD_FIFO'} and -p $config{'KNOPMD_FIFO'}) {
548                     $created_pipe = 0;
549                 }
550                 unless ($created_pipe) {
551                     die
552 "[*] Could not create the named pipe \"$config{'KNOPMD_FIFO'}\"!\n",
553 "[*] fwknop requires this file to exist!  Aborting install.\n";
554                 }
555             }
556
557             unless (-e "$config{'FW_DATA_FILE'}") {
558                 print "[+] Creating $config{'FW_DATA_FILE'} file\n";
559                 open F, "> $config{'FW_DATA_FILE'}" or die "[*] Could not open ",
560                     "$config{'FW_DATA_FILE'}: $!";
561                 close F;
562                 chmod 0600, "$config{'FW_DATA_FILE'}";
563                 &perms_ownership("$config{'FW_DATA_FILE'}", 0600);
564             }
565
566             ### we are acquiring data via syslog
567             &put_string('AUTH_MODE', 'KNOCK',
568                 "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
569
570             if ($bsd_install) {
571                 ### update to use the ipfw firewall on *BSD systems
572                 &put_string('FIREWALL_TYPE', 'ipfw',
573                     "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
574             }
575
576             &put_string('SYSLOG_DAEMON', $data_method,
577                 "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
578
579             my $restarted_syslog = 0;
580             if ($data_method eq 'syslogd') {
581                 if (-e $syslog_conf) {
582                     &append_fifo_syslog($syslog_conf);
583                     if (((system "$cmds{'killall'} -HUP syslogd " .
584                             "2> /dev/null")>>8) == 0) {
585                         print "[+] HUP signal sent to syslogd.\n";
586                         $restarted_syslog = 1;
587                     }
588                 }
589             } elsif ($data_method eq 'syslog-ng') {
590                 if (-e $syslog_conf) {
591                     &append_fifo_syslog_ng($syslog_conf);
592                     if (((system "$cmds{'killall'} -HUP syslog-ng " .
593                             "2> /dev/null")>>8) == 0) {
594                         print "[+] HUP signal sent to syslog-ng.\n";
595                         $restarted_syslog = 1;
596                     }
597                 }
598             }
599
600             unless ($restarted_syslog) {
601                 print "[-] Could not restart any syslog daemons.\n";
602             }
603         } elsif ($data_method =~ /pcap/i or $data_method =~ /ulog/i) {
604
605             if ($bsd_install) {
606                 ### update to use the ipfw firewall on *BSD systems
607                 &put_string('FIREWALL_TYPE', 'ipfw',
608                     "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
609             }
610
611             ### we are using a pcap method
612             if ($data_method eq 'ulogd' or $data_method eq 'file_pcap') {
613                 print
614 "[+] By default, fwknop uses the file /var/log/sniff.pcap in order to\n",
615 "    acquire packet data logged via a sniffer (or ulogd) to a pcap file,\n",
616 "    but this path may be changed by altering the PCAP_PKT_FILE keyword\n",
617 "    in $config{'FWKNOP_CONF_DIR'}/fwknop.conf.\n\n";
618
619                 if ($data_method eq 'file_pcap') {
620                     &put_string('AUTH_MODE', 'FILE_PCAP',
621                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
622                 } else {
623                     &put_string('AUTH_MODE', 'ULOG_PCAP',
624                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
625                 }
626             } else {
627                 my $intf = &get_pcap_intf();
628                 if ($intf) {
629                     &put_string('PCAP_INTF', $intf,
630                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
631                 } else {
632 print "[-] Could not get sniffing interface, need to set this manually in\n",
633     "    config{'FWKNOP_CONF_DIR'}/fwknop.conf\n";
634                 }
635             }
636         } else {
637             ### it is a client-only install, so don't reconfigure syslog
638             ### or anything.
639         }
640
641         unless ($preserve_rv) {
642             my $email_str = &query_email();
643             if ($email_str) {
644                 for my $file qw(fwknop.conf) {
645                     &put_string('EMAIL_ADDRESSES', $email_str,
646                         "$config{'FWKNOP_CONF_DIR'}/$file");
647                 }
648             }
649         }
650
651         &get_init_dir();
652
653         if (-d $INIT_DIR) {
654             &enable_fwknop_at_boot($distro) unless $data_method =~ /client/i;
655         }
656
657         if ($data_method =~ /client/i) {
658             print "\n[+] fwknop has been installed!\n\n";
659         } else {
660             print
661 "\n[+] fwknop has been installed!  To start in server mode, run\n\n",
662 "    \"/etc/init.d/fwknop start\"\n\n",
663 "    Note: You will need to edit $config{'FWKNOP_CONF_DIR'}/access.conf for fwknop to\n",
664 "    function properly in server mode.  More information can be found in\n",
665 "    the fwknop manpage.\n\n";
666             if ($bsd_install) {
667                 print
668 "    You may need to update your /etc/syslog.conf file to log local info\n",
669 "    messages to a file in the /var/log/ directory in order to see syslog\n",
670 "    messages from the fwknop daemons.\n\n";
671             }
672         }
673
674     }
675     return;
676 }
677
678 sub uninstall() {
679
680     print "[+] Uninstalling fwknop\n";
681
682     ### stop any running fwknop daemons.
683     &stop_fwknop();
684
685     ### get the init directory
686     &get_init_dir();
687
688     unlink "$USRBIN_DIR/fwknop" if -e "$USRBIN_DIR/fwknop";
689     unlink "$URRSBIN_DIR/knopmd" if -e "$URRSBIN_DIR/knopmd";
690     unlink "$URRSBIN_DIR/knopwatchd" if -e "$URRSBIN_DIR/knopwatchd";
691     unlink "$INIT_DIR/fwknop" if -e "$INIT_DIR/fwknop";
692     rmtree $config{'FWKNOP_CONF_DIR'}, 1, 1 if -d $config{'FWKNOP_CONF_DIR'};
693     rmtree $config{'FWKNOP_LIB_DIR'}, 1, 1 if -d $config{'FWKNOP_LIB_DIR'};
694     rmtree $config{'FWKNOP_MOD_DIR'}, 1, 1 if -d $config{'FWKNOP_MOD_DIR'};
695
696     return;
697 }
698
699 sub get_init_dir() {
700     return if $client_install;
701
702     if ($osx_install) {
703         $INIT_DIR = '/Libraries/'### FIXME
704         return;
705     }
706
707     unless (-d $INIT_DIR) {
708         if (-d '/etc/rc.d/init.d') {
709             $INIT_DIR = '/etc/rc.d/init.d';
710         } elsif (-d '/etc/rc.d') {  ### for Slackware
711             $INIT_DIR = '/etc/rc.d';
712         } elsif (-d '/etc/init.d') {
713             $INIT_DIR = '/etc/init.d';
714         } else {
715             die "[*] Cannot find the init script directory, edit ",
716                 "the \$INIT_DIR variable.\n";
717         }
718     }
719     return;
720 }
721
722 ### check paths to commands and attempt to correct if any are wrong.
723 sub check_commands() {
724
725     return if $client_install;
726
727     unless ($bsd_install) {
728         $exclude_cmds{'ipfw'} = '';
729     }
730
731     CMD: for my $cmd (keys %cmds) {
732         if ($bsd_install) {
733             next CMD if $cmd eq 'iptables';
734         }
735         next CMD if defined $exclude_cmds{$cmd};
736         unless (-x $cmds{$cmd}) {
737             my $found = 0;
738             PATH: for my $dir (@cmd_search_paths) {
739                 if (-x "${dir}/${cmd}") {
740                     $cmds{$cmd} = "${dir}/${cmd}";
741                     $found = 1;
742                     last PATH;
743                 }
744             }
745             unless ($found) {
746                 die "[*] Could not find $cmd anywhere!!!  ",
747                     "Please edit the config section to include the path to ",
748                     "$cmd.\n";
749             }
750