root/fwknop/tags/fwknop-1.9.3/install.pl

Revision 1009, 58.9 kB (checked in by mbr, 9 months ago)

This is a major commit to add support for the usage of multiple digest
algorithm for replay attack detection and for message integrity.

- (SPAPICT Group) Submitted patches to include support for the SHA1 digest
algorithm for SPA packet replay attack detection. I modified these
patches for maximum configurability (see the --digest-alg argument on
the fwknop command line), and the ability to use the SHA256 algorithm as
well. The default path to the /var/log/fwknop/md5sums file has been
changed to /var/log/fwknop/digest.cache, and the default digest
algorithm is now SHA256 (but this is tunable via the DIGEST_TYPE
variable in the fwknop.conf file).
- Added the Digest::SHA perl module in support of the SHA1 and SHA256
digest algorithms for replay attack detection and SPA message integrity.
- (Test suite) Added several tests for configurable digest algorithms in
support for the SHA256, SHA1, and MD5 digest changes made by the SPAPICT
Group.
- Bugfix in install.pl to not test for the iptable command on non-Linux
systems, and to not test for the ipfw command on systems that are Linux.

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