This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Synch with CPAN distribution libnet-3.12
[perl5.git] / cpan / libnet / lib / Net / Config.pm
1 # Net::Config.pm
2 #
3 # Copyright (C) 2000 Graham Barr.  All rights reserved.
4 # Copyright (C) 2013-2014, 2016, 2020 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
9 package Net::Config;
10
11 use 5.008001;
12
13 use strict;
14 use warnings;
15
16 use Exporter;
17 use Socket qw(inet_aton inet_ntoa);
18
19 our @EXPORT  = qw(%NetConfig);
20 our @ISA     = qw(Net::LocalCfg Exporter);
21 our $VERSION = "3.12";
22
23 our($CONFIGURE, $LIBNET_CFG);
24
25 eval {
26   local @INC = @INC;
27   pop @INC if $INC[-1] eq '.';
28   local $SIG{__DIE__};
29   require Net::LocalCfg;
30 };
31
32 our %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;
54 use Mac::InternetConfig;
55
56 {
57 my %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 }
72 TRY_INTERNET_CONFIG
73 }
74
75 my $file = __FILE__;
76 my $ref;
77 $file =~ s/Config.pm/libnet.cfg/;
78 if (-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 }
85 if ($< == $> 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 }
95 my ($k, $v);
96 while (($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
104 sub 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
132 1;
133
134 __END__
135
136 =head1 NAME
137
138 Net::Config - Local configuration data for libnet
139
140 =head1 SYNOPSIS
141
142     use Net::Config qw(%NetConfig);
143
144 =head1 DESCRIPTION
145
146 C<Net::Config> holds configuration data for the modules in the libnet
147 distribution. During installation you will be asked for these values.
148
149 The configuration data is held globally in a file in the perl installation
150 tree, but a user may override any of these values by providing their own. This
151 can be done by having a C<.libnetrc> file in their home directory. This file
152 should return a reference to a HASH containing the keys described below.
153 For example
154
155     # .libnetrc
156     {
157         nntp_hosts => [ "my_preferred_host" ],
158         ph_hosts   => [ "my_ph_server" ],
159     }
160     __END__
161
162 =head2 Class Methods
163
164 C<Net::Config> defines the following methods. They are methods as they are
165 invoked as class methods. This is because C<Net::Config> inherits from
166 C<Net::LocalCfg> so you can override these methods if you want.
167
168 =over 4
169
170 =item C<requires_firewall($host)>
171
172 Attempts to determine if a given host is outside your firewall. Possible
173 return 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
179 This is done by using hostname lookup and the C<local_netmask> entry in
180 the configuration data.
181
182 =back
183
184 =head2 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
202 Each is a reference to an array of hostnames (in order of preference),
203 which should be used for the given protocol
204
205 =item inet_domain
206
207 Your internet domain name
208
209 =item ftp_firewall
210
211 If you have an FTP proxy firewall (B<NOT> an HTTP or SOCKS firewall)
212 then this value should be set to the firewall hostname. If your firewall
213 does not listen to port 21, then this value should be set to
214 C<"hostname:port"> (eg C<"hostname:99">)
215
216 =item ftp_firewall_type
217
218 There are many different ftp firewall products available. But unfortunately
219 there is no standard for how to traverse a firewall.  The list below shows the
220 sequence 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
232 There 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
287 FTP servers can work in passive or active mode. Active mode is when
288 you want to transfer data you have to tell the server the address and
289 port to connect to.  Passive mode is when the server provide the
290 address and port and you establish the connection.
291
292 With some firewalls active mode does not work as the server cannot
293 connect to your machine (because you are behind a firewall) and the firewall
294 does not re-write the command. In this case you should set C<ftp_ext_passive>
295 to a I<true> value.
296
297 Some servers are configured to only work in passive mode. If you have
298 one of these you can force C<Net::FTP> to always transfer in passive
299 mode; when not going via a firewall, by setting C<ftp_int_passive> to
300 a I<true> value.
301
302 =item local_netmask
303
304 A reference to a list of netmask strings in the form C<"134.99.4.0/24">.
305 These are used by the C<requires_firewall> function to determine if a given
306 host is inside or outside your firewall.
307
308 =back
309
310 The following entries are used during installation & testing on the
311 libnet package
312
313 =over 4
314
315 =item test_hosts
316
317 If true then C<make test> may attempt to connect to hosts given in the
318 configuration.
319
320 =item test_exists
321
322 If true then C<Configure> will check each hostname given that it exists
323
324 =back
325
326 =head1 EXPORTS
327
328 The following symbols are, or can be, exported by this module:
329
330 =over 4
331
332 =item Default Exports
333
334 C<%NetConfig>.
335
336 =item Optional Exports
337
338 I<None>.
339
340 =item Export Tags
341
342 I<None>.
343
344 =back
345
346 =head1 KNOWN BUGS
347
348 I<None>.
349
350 =head1 AUTHOR
351
352 Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
353
354 Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
355 libnet as of version 1.22_02.
356
357 =head1 COPYRIGHT
358
359 Copyright (C) 2000 Graham Barr.  All rights reserved.
360
361 Copyright (C) 2013-2014, 2016, 2020 Steve Hay.  All rights reserved.
362
363 =head1 LICENCE
364
365 This module is free software; you can redistribute it and/or modify it under the
366 same terms as Perl itself, i.e. under the terms of either the GNU General Public
367 License or the Artistic License, as specified in the F<LICENCE> file.
368
369 =head1 VERSION
370
371 Version 3.12
372
373 =head1 DATE
374
375 09 Dec 2020
376
377 =head1 HISTORY
378
379 See the F<Changes> file.
380
381 =cut