1# Net::Config.pm
2#
3# Copyright (C) 2000 Graham Barr.  All rights reserved.
4# Copyright (C) 2013-2014, 2016 Steve Hay.  All rights reserved.
5# This module is free software; you can redistribute it and/or modify it under
6# the same terms as Perl itself, i.e. under the terms of either the GNU General
7# Public License or the Artistic License, as specified in the F<LICENCE> file.
8
9package Net::Config;
10
11use 5.008001;
12
13use strict;
14use warnings;
15
16use Exporter;
17use Socket qw(inet_aton inet_ntoa);
18
19our @EXPORT  = qw(%NetConfig);
20our @ISA     = qw(Net::LocalCfg Exporter);
21our $VERSION = "3.11";
22
23our($CONFIGURE, $LIBNET_CFG);
24
25eval {
26  local @INC = @INC;
27  pop @INC if $INC[-1] eq '.';
28  local $SIG{__DIE__};
29  require Net::LocalCfg;
30};
31
32our %NetConfig = (
33  nntp_hosts      => [],
34  snpp_hosts      => [],
35  pop3_hosts      => [],
36  smtp_hosts      => [],
37  ph_hosts        => [],
38  daytime_hosts   => [],
39  time_hosts      => [],
40  inet_domain     => undef,
41  ftp_firewall    => undef,
42  ftp_ext_passive => 1,
43  ftp_int_passive => 1,
44  test_hosts      => 1,
45  test_exist      => 1,
46);
47
48#
49# Try to get as much configuration info as possible from InternetConfig
50#
51{
52## no critic (BuiltinFunctions::ProhibitStringyEval)
53$^O eq 'MacOS' and eval <<TRY_INTERNET_CONFIG;
54use Mac::InternetConfig;
55
56{
57my %nc = (
58    nntp_hosts      => [ \$InternetConfig{ kICNNTPHost() } ],
59    pop3_hosts      => [ \$InternetConfig{ kICMailAccount() } =~ /\@(.*)/ ],
60    smtp_hosts      => [ \$InternetConfig{ kICSMTPHost() } ],
61    ftp_testhost    => \$InternetConfig{ kICFTPHost() } ? \$InternetConfig{ kICFTPHost()} : undef,
62    ph_hosts        => [ \$InternetConfig{ kICPhHost() }   ],
63    ftp_ext_passive => \$InternetConfig{"646F676F\xA5UsePassiveMode"} || 0,
64    ftp_int_passive => \$InternetConfig{"646F676F\xA5UsePassiveMode"} || 0,
65    socks_hosts     =>
66        \$InternetConfig{ kICUseSocks() }    ? [ \$InternetConfig{ kICSocksHost() }    ] : [],
67    ftp_firewall    =>
68        \$InternetConfig{ kICUseFTPProxy() } ? [ \$InternetConfig{ kICFTPProxyHost() } ] : [],
69);
70\@NetConfig{keys %nc} = values %nc;
71}
72TRY_INTERNET_CONFIG
73}
74
75my $file = __FILE__;
76my $ref;
77$file =~ s/Config.pm/libnet.cfg/;
78if (-f $file) {
79  $ref = eval { local $SIG{__DIE__}; do $file };
80  if (ref($ref) eq 'HASH') {
81    %NetConfig = (%NetConfig, %{$ref});
82    $LIBNET_CFG = $file;
83  }
84}
85if ($< == $> and !$CONFIGURE) {
86  my $home = eval { local $SIG{__DIE__}; (getpwuid($>))[7] } || $ENV{HOME};
87  $home ||= $ENV{HOMEDRIVE} . ($ENV{HOMEPATH} || '') if defined $ENV{HOMEDRIVE};
88  if (defined $home) {
89    $file      = $home . "/.libnetrc";
90    $ref       = eval { local $SIG{__DIE__}; do $file } if -f $file;
91    %NetConfig = (%NetConfig, %{$ref})
92      if ref($ref) eq 'HASH';
93  }
94}
95my ($k, $v);
96while (($k, $v) = each %NetConfig) {
97  $NetConfig{$k} = [$v]
98    if ($k =~ /_hosts$/ and $k ne "test_hosts" and defined($v) and !ref($v));
99}
100
101# Take a hostname and determine if it is inside the firewall
102
103
104sub requires_firewall {
105  shift;    # ignore package
106  my $host = shift;
107
108  return 0 unless defined $NetConfig{'ftp_firewall'};
109
110  $host = inet_aton($host) or return -1;
111  $host = inet_ntoa($host);
112
113  if (exists $NetConfig{'local_netmask'}) {
114    my $quad = unpack("N", pack("C*", split(/\./, $host)));
115    my $list = $NetConfig{'local_netmask'};
116    $list = [$list] unless ref($list);
117    foreach (@$list) {
118      my ($net, $bits) = (m#^(\d+\.\d+\.\d+\.\d+)/(\d+)$#) or next;
119      my $mask = ~0 << (32 - $bits);
120      my $addr = unpack("N", pack("C*", split(/\./, $net)));
121
122      return 0 if (($addr & $mask) == ($quad & $mask));
123    }
124    return 1;
125  }
126
127  return 0;
128}
129
130*is_external = \&requires_firewall;
131
1321;
133
134__END__
135
136=head1 NAME
137
138Net::Config - Local configuration data for libnet
139
140=head1 SYNOPSIS
141
142    use Net::Config qw(%NetConfig);
143
144=head1 DESCRIPTION
145
146C<Net::Config> holds configuration data for the modules in the libnet
147distribution. During installation you will be asked for these values.
148
149The configuration data is held globally in a file in the perl installation
150tree, but a user may override any of these values by providing their own. This
151can be done by having a C<.libnetrc> file in their home directory. This file
152should return a reference to a HASH containing the keys described below.
153For example
154
155    # .libnetrc
156    {
157        nntp_hosts => [ "my_preferred_host" ],
158        ph_hosts   => [ "my_ph_server" ],
159    }
160    __END__
161
162=head1 METHODS
163
164C<Net::Config> defines the following methods. They are methods as they are
165invoked as class methods. This is because C<Net::Config> inherits from
166C<Net::LocalCfg> so you can override these methods if you want.
167
168=over 4
169
170=item requires_firewall ( HOST )
171
172Attempts to determine if a given host is outside your firewall. Possible
173return values are.
174
175  -1  Cannot lookup hostname
176   0  Host is inside firewall (or there is no ftp_firewall entry)
177   1  Host is outside the firewall
178
179This is done by using hostname lookup and the C<local_netmask> entry in
180the configuration data.
181
182=back
183
184=head1 NetConfig VALUES
185
186=over 4
187
188=item nntp_hosts
189
190=item snpp_hosts
191
192=item pop3_hosts
193
194=item smtp_hosts
195
196=item ph_hosts
197
198=item daytime_hosts
199
200=item time_hosts
201
202Each is a reference to an array of hostnames (in order of preference),
203which should be used for the given protocol
204
205=item inet_domain
206
207Your internet domain name
208
209=item ftp_firewall
210
211If you have an FTP proxy firewall (B<NOT> an HTTP or SOCKS firewall)
212then this value should be set to the firewall hostname. If your firewall
213does not listen to port 21, then this value should be set to
214C<"hostname:port"> (eg C<"hostname:99">)
215
216=item ftp_firewall_type
217
218There are many different ftp firewall products available. But unfortunately
219there is no standard for how to traverse a firewall.  The list below shows the
220sequence of commands that Net::FTP will use
221
222  user        Username for remote host
223  pass        Password for remote host
224  fwuser      Username for firewall
225  fwpass      Password for firewall
226  remote.host The hostname of the remote ftp server
227
228=over 4
229
230=item 0Z<>
231
232There is no firewall
233
234=item 1Z<>
235
236     USER user@remote.host
237     PASS pass
238
239=item 2Z<>
240
241     USER fwuser
242     PASS fwpass
243     USER user@remote.host
244     PASS pass
245
246=item 3Z<>
247
248     USER fwuser
249     PASS fwpass
250     SITE remote.site
251     USER user
252     PASS pass
253
254=item 4Z<>
255
256     USER fwuser
257     PASS fwpass
258     OPEN remote.site
259     USER user
260     PASS pass
261
262=item 5Z<>
263
264     USER user@fwuser@remote.site
265     PASS pass@fwpass
266
267=item 6Z<>
268
269     USER fwuser@remote.site
270     PASS fwpass
271     USER user
272     PASS pass
273
274=item 7Z<>
275
276     USER user@remote.host
277     PASS pass
278     AUTH fwuser
279     RESP fwpass
280
281=back
282
283=item ftp_ext_passive
284
285=item ftp_int_passive
286
287FTP servers can work in passive or active mode. Active mode is when
288you want to transfer data you have to tell the server the address and
289port to connect to.  Passive mode is when the server provide the
290address and port and you establish the connection.
291
292With some firewalls active mode does not work as the server cannot
293connect to your machine (because you are behind a firewall) and the firewall
294does not re-write the command. In this case you should set C<ftp_ext_passive>
295to a I<true> value.
296
297Some servers are configured to only work in passive mode. If you have
298one of these you can force C<Net::FTP> to always transfer in passive
299mode; when not going via a firewall, by setting C<ftp_int_passive> to
300a I<true> value.
301
302=item local_netmask
303
304A reference to a list of netmask strings in the form C<"134.99.4.0/24">.
305These are used by the C<requires_firewall> function to determine if a given
306host is inside or outside your firewall.
307
308=back
309
310The following entries are used during installation & testing on the
311libnet package
312
313=over 4
314
315=item test_hosts
316
317If true then C<make test> may attempt to connect to hosts given in the
318configuration.
319
320=item test_exists
321
322If true then C<Configure> will check each hostname given that it exists
323
324=back
325
326=head1 AUTHOR
327
328Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
329
330Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
3311.22_02.
332
333=head1 COPYRIGHT
334
335Copyright (C) 1998-2011 Graham Barr.  All rights reserved.
336
337Copyright (C) 2013-2014, 2016 Steve Hay.  All rights reserved.
338
339=head1 LICENCE
340
341This module is free software; you can redistribute it and/or modify it under the
342same terms as Perl itself, i.e. under the terms of either the GNU General Public
343License or the Artistic License, as specified in the F<LICENCE> file.
344
345=cut
346