xref: /openbsd-src/gnu/usr.bin/perl/cpan/libnet/lib/Net/Netrc.pm (revision e068048151d29f2562a32185e21a8ba885482260)
1b8851fccSafresh1# Net::Netrc.pm
2b8851fccSafresh1#
35759b3d2Safresh1# Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
4eac174f2Safresh1# Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
5b8851fccSafresh1# This module is free software; you can redistribute it and/or modify it under
6b8851fccSafresh1# the same terms as Perl itself, i.e. under the terms of either the GNU General
7b8851fccSafresh1# Public License or the Artistic License, as specified in the F<LICENCE> file.
8b8851fccSafresh1
9b8851fccSafresh1package Net::Netrc;
10b8851fccSafresh1
11b8851fccSafresh1use 5.008001;
12b8851fccSafresh1
13b8851fccSafresh1use strict;
14b8851fccSafresh1use warnings;
15b8851fccSafresh1
16b8851fccSafresh1use Carp;
17b8851fccSafresh1use FileHandle;
18b8851fccSafresh1
19*e0680481Safresh1our $VERSION = "3.15";
20b8851fccSafresh1
21b8851fccSafresh1our $TESTING;
22b8851fccSafresh1
23b8851fccSafresh1my %netrc = ();
24b8851fccSafresh1
25b8851fccSafresh1sub _readrc {
26b8851fccSafresh1  my($class, $host) = @_;
27b8851fccSafresh1  my ($home, $file);
28b8851fccSafresh1
29b8851fccSafresh1  if ($^O eq "MacOS") {
30b8851fccSafresh1    $home = $ENV{HOME} || `pwd`;
31b8851fccSafresh1    chomp($home);
32b8851fccSafresh1    $file = ($home =~ /:$/ ? $home . "netrc" : $home . ":netrc");
33b8851fccSafresh1  }
34b8851fccSafresh1  else {
35b8851fccSafresh1
36b8851fccSafresh1    # Some OS's don't have "getpwuid", so we default to $ENV{HOME}
37b8851fccSafresh1    $home = eval { (getpwuid($>))[7] } || $ENV{HOME};
38b8851fccSafresh1    $home ||= $ENV{HOMEDRIVE} . ($ENV{HOMEPATH} || '') if defined $ENV{HOMEDRIVE};
39b8851fccSafresh1    if (-e $home . "/.netrc") {
40b8851fccSafresh1      $file = $home . "/.netrc";
41b8851fccSafresh1    }
42b8851fccSafresh1    elsif (-e $home . "/_netrc") {
43b8851fccSafresh1      $file = $home . "/_netrc";
44b8851fccSafresh1    }
45b8851fccSafresh1    else {
46b8851fccSafresh1      return unless $TESTING;
47b8851fccSafresh1    }
48b8851fccSafresh1  }
49b8851fccSafresh1
50b8851fccSafresh1  my ($login, $pass, $acct) = (undef, undef, undef);
51b8851fccSafresh1  my $fh;
52b8851fccSafresh1  local $_;
53b8851fccSafresh1
54b8851fccSafresh1  $netrc{default} = undef;
55b8851fccSafresh1
56b8851fccSafresh1  # OS/2 and Win32 do not handle stat in a way compatible with this check :-(
57b8851fccSafresh1  unless ($^O eq 'os2'
58b8851fccSafresh1    || $^O eq 'MSWin32'
59b8851fccSafresh1    || $^O eq 'MacOS'
60b8851fccSafresh1    || $^O =~ /^cygwin/)
61b8851fccSafresh1  {
62b8851fccSafresh1    my @stat = stat($file);
63b8851fccSafresh1
64b8851fccSafresh1    if (@stat) {
65b8851fccSafresh1      if ($stat[2] & 077) { ## no critic (ValuesAndExpressions::ProhibitLeadingZeros)
66b8851fccSafresh1        carp "Bad permissions: $file";
67b8851fccSafresh1        return;
68b8851fccSafresh1      }
69b8851fccSafresh1      if ($stat[4] != $<) {
70b8851fccSafresh1        carp "Not owner: $file";
71b8851fccSafresh1        return;
72b8851fccSafresh1      }
73b8851fccSafresh1    }
74b8851fccSafresh1  }
75b8851fccSafresh1
76b8851fccSafresh1  if ($fh = FileHandle->new($file, "r")) {
77b8851fccSafresh1    my ($mach, $macdef, $tok, @tok) = (0, 0);
78b8851fccSafresh1
79b8851fccSafresh1    while (<$fh>) {
80b8851fccSafresh1      undef $macdef if /\A\n\Z/;
81b8851fccSafresh1
82b8851fccSafresh1      if ($macdef) {
83b8851fccSafresh1        push(@$macdef, $_);
84b8851fccSafresh1        next;
85b8851fccSafresh1      }
86b8851fccSafresh1
87b8851fccSafresh1      s/^\s*//;
88b8851fccSafresh1      chomp;
89b8851fccSafresh1
90b8851fccSafresh1      while (length && s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
91b8851fccSafresh1        (my $tok = $+) =~ s/\\(.)/$1/g;
92b8851fccSafresh1        push(@tok, $tok);
93b8851fccSafresh1      }
94b8851fccSafresh1
95b8851fccSafresh1    TOKEN:
96b8851fccSafresh1      while (@tok) {
97b8851fccSafresh1        if ($tok[0] eq "default") {
98b8851fccSafresh1          shift(@tok);
99b8851fccSafresh1          $mach = bless {}, $class;
100b8851fccSafresh1          $netrc{default} = [$mach];
101b8851fccSafresh1
102b8851fccSafresh1          next TOKEN;
103b8851fccSafresh1        }
104b8851fccSafresh1
105b8851fccSafresh1        last TOKEN
106b8851fccSafresh1          unless @tok > 1;
107b8851fccSafresh1
108b8851fccSafresh1        $tok = shift(@tok);
109b8851fccSafresh1
110b8851fccSafresh1        if ($tok eq "machine") {
111b8851fccSafresh1          my $host = shift @tok;
112b8851fccSafresh1          $mach = bless {machine => $host}, $class;
113b8851fccSafresh1
114b8851fccSafresh1          $netrc{$host} = []
115b8851fccSafresh1            unless exists($netrc{$host});
116b8851fccSafresh1          push(@{$netrc{$host}}, $mach);
117b8851fccSafresh1        }
118b8851fccSafresh1        elsif ($tok =~ /^(login|password|account)$/) {
119b8851fccSafresh1          next TOKEN unless $mach;
120b8851fccSafresh1          my $value = shift @tok;
121b8851fccSafresh1
122b8851fccSafresh1          # Following line added by rmerrell to remove '/' escape char in .netrc
123b8851fccSafresh1          $value =~ s/\/\\/\\/g;
124b8851fccSafresh1          $mach->{$1} = $value;
125b8851fccSafresh1        }
126b8851fccSafresh1        elsif ($tok eq "macdef") {
127b8851fccSafresh1          next TOKEN unless $mach;
128b8851fccSafresh1          my $value = shift @tok;
129b8851fccSafresh1          $mach->{macdef} = {}
130b8851fccSafresh1            unless exists $mach->{macdef};
131b8851fccSafresh1          $macdef = $mach->{machdef}{$value} = [];
132b8851fccSafresh1        }
133b8851fccSafresh1      }
134b8851fccSafresh1    }
135b8851fccSafresh1    $fh->close();
136b8851fccSafresh1  }
137b8851fccSafresh1}
138b8851fccSafresh1
139b8851fccSafresh1
140b8851fccSafresh1sub lookup {
141b8851fccSafresh1  my ($class, $mach, $login) = @_;
142b8851fccSafresh1
143b8851fccSafresh1  $class->_readrc()
144b8851fccSafresh1    unless exists $netrc{default};
145b8851fccSafresh1
146b8851fccSafresh1  $mach ||= 'default';
147b8851fccSafresh1  undef $login
148b8851fccSafresh1    if $mach eq 'default';
149b8851fccSafresh1
150b8851fccSafresh1  if (exists $netrc{$mach}) {
151b8851fccSafresh1    if (defined $login) {
152b8851fccSafresh1      foreach my $m (@{$netrc{$mach}}) {
153b8851fccSafresh1        return $m
154b8851fccSafresh1          if (exists $m->{login} && $m->{login} eq $login);
155b8851fccSafresh1      }
156b8851fccSafresh1      return;
157b8851fccSafresh1    }
158b8851fccSafresh1    return $netrc{$mach}->[0];
159b8851fccSafresh1  }
160b8851fccSafresh1
161b8851fccSafresh1  return $netrc{default}->[0]
162b8851fccSafresh1    if defined $netrc{default};
163b8851fccSafresh1
164b8851fccSafresh1  return;
165b8851fccSafresh1}
166b8851fccSafresh1
167b8851fccSafresh1
168b8851fccSafresh1sub login {
169b8851fccSafresh1  my $me = shift;
170b8851fccSafresh1
171b8851fccSafresh1  exists $me->{login}
172b8851fccSafresh1    ? $me->{login}
173b8851fccSafresh1    : undef;
174b8851fccSafresh1}
175b8851fccSafresh1
176b8851fccSafresh1
177b8851fccSafresh1sub account {
178b8851fccSafresh1  my $me = shift;
179b8851fccSafresh1
180b8851fccSafresh1  exists $me->{account}
181b8851fccSafresh1    ? $me->{account}
182b8851fccSafresh1    : undef;
183b8851fccSafresh1}
184b8851fccSafresh1
185b8851fccSafresh1
186b8851fccSafresh1sub password {
187b8851fccSafresh1  my $me = shift;
188b8851fccSafresh1
189b8851fccSafresh1  exists $me->{password}
190b8851fccSafresh1    ? $me->{password}
191b8851fccSafresh1    : undef;
192b8851fccSafresh1}
193b8851fccSafresh1
194b8851fccSafresh1
195b8851fccSafresh1sub lpa {
196b8851fccSafresh1  my $me = shift;
197b8851fccSafresh1  ($me->login, $me->password, $me->account);
198b8851fccSafresh1}
199b8851fccSafresh1
200b8851fccSafresh11;
201b8851fccSafresh1
202b8851fccSafresh1__END__
203b8851fccSafresh1
204b8851fccSafresh1=head1 NAME
205b8851fccSafresh1
206b8851fccSafresh1Net::Netrc - OO interface to users netrc file
207b8851fccSafresh1
208b8851fccSafresh1=head1 SYNOPSIS
209b8851fccSafresh1
210b8851fccSafresh1    use Net::Netrc;
211b8851fccSafresh1
212b8851fccSafresh1    $mach = Net::Netrc->lookup('some.machine');
213b8851fccSafresh1    $login = $mach->login;
214b8851fccSafresh1    ($login, $password, $account) = $mach->lpa;
215b8851fccSafresh1
216b8851fccSafresh1=head1 DESCRIPTION
217b8851fccSafresh1
218b8851fccSafresh1C<Net::Netrc> is a class implementing a simple interface to the .netrc file
219b8851fccSafresh1used as by the ftp program.
220b8851fccSafresh1
221b8851fccSafresh1C<Net::Netrc> also implements security checks just like the ftp program,
222b8851fccSafresh1these checks are, first that the .netrc file must be owned by the user and
223b8851fccSafresh1second the ownership permissions should be such that only the owner has
224b8851fccSafresh1read and write access. If these conditions are not met then a warning is
225b8851fccSafresh1output and the .netrc file is not read.
226b8851fccSafresh1
227eac174f2Safresh1=head2 The F<.netrc> File
228b8851fccSafresh1
229b8851fccSafresh1The .netrc file contains login and initialization information used by the
230b8851fccSafresh1auto-login process.  It resides in the user's home directory.  The following
231b8851fccSafresh1tokens are recognized; they may be separated by spaces, tabs, or new-lines:
232b8851fccSafresh1
233b8851fccSafresh1=over 4
234b8851fccSafresh1
235b8851fccSafresh1=item machine name
236b8851fccSafresh1
237b8851fccSafresh1Identify a remote machine name. The auto-login process searches
238b8851fccSafresh1the .netrc file for a machine token that matches the remote machine
239b8851fccSafresh1specified.  Once a match is made, the subsequent .netrc tokens
240b8851fccSafresh1are processed, stopping when the end of file is reached or an-
241b8851fccSafresh1other machine or a default token is encountered.
242b8851fccSafresh1
243b8851fccSafresh1=item default
244b8851fccSafresh1
245b8851fccSafresh1This is the same as machine name except that default matches
246b8851fccSafresh1any name.  There can be only one default token, and it must be
247b8851fccSafresh1after all machine tokens.  This is normally used as:
248b8851fccSafresh1
249b8851fccSafresh1    default login anonymous password user@site
250b8851fccSafresh1
251b8851fccSafresh1thereby giving the user automatic anonymous login to machines
252b8851fccSafresh1not specified in .netrc.
253b8851fccSafresh1
254b8851fccSafresh1=item login name
255b8851fccSafresh1
256b8851fccSafresh1Identify a user on the remote machine.  If this token is present,
257b8851fccSafresh1the auto-login process will initiate a login using the
258b8851fccSafresh1specified name.
259b8851fccSafresh1
260b8851fccSafresh1=item password string
261b8851fccSafresh1
262b8851fccSafresh1Supply a password.  If this token is present, the auto-login
263b8851fccSafresh1process will supply the specified string if the remote server
264b8851fccSafresh1requires a password as part of the login process.
265b8851fccSafresh1
266b8851fccSafresh1=item account string
267b8851fccSafresh1
268b8851fccSafresh1Supply an additional account password.  If this token is present,
269b8851fccSafresh1the auto-login process will supply the specified string
270b8851fccSafresh1if the remote server requires an additional account password.
271b8851fccSafresh1
272b8851fccSafresh1=item macdef name
273b8851fccSafresh1
274b8851fccSafresh1Define a macro. C<Net::Netrc> only parses this field to be compatible
275b8851fccSafresh1with I<ftp>.
276b8851fccSafresh1
277b8851fccSafresh1=back
278b8851fccSafresh1
279eac174f2Safresh1=head2 Class Methods
280b8851fccSafresh1
281b8851fccSafresh1The constructor for a C<Net::Netrc> object is not called new as it does not
282b8851fccSafresh1really create a new object. But instead is called C<lookup> as this is
283b8851fccSafresh1essentially what it does.
284b8851fccSafresh1
285b8851fccSafresh1=over 4
286b8851fccSafresh1
287eac174f2Safresh1=item C<lookup($machine[, $login])>
288b8851fccSafresh1
289eac174f2Safresh1Lookup and return a reference to the entry for C<$machine>. If C<$login> is given
290eac174f2Safresh1then the entry returned will have the given login. If C<$login> is not given then
291eac174f2Safresh1the first entry in the .netrc file for C<$machine> will be returned.
292b8851fccSafresh1
293b8851fccSafresh1If a matching entry cannot be found, and a default entry exists, then a
294b8851fccSafresh1reference to the default entry is returned.
295b8851fccSafresh1
296b8851fccSafresh1If there is no matching entry found and there is no default defined, or
297b8851fccSafresh1no .netrc file is found, then C<undef> is returned.
298b8851fccSafresh1
299b8851fccSafresh1=back
300b8851fccSafresh1
301eac174f2Safresh1=head2 Object Methods
302b8851fccSafresh1
303b8851fccSafresh1=over 4
304b8851fccSafresh1
305eac174f2Safresh1=item C<login()>
306b8851fccSafresh1
307b8851fccSafresh1Return the login id for the netrc entry
308b8851fccSafresh1
309eac174f2Safresh1=item C<password()>
310b8851fccSafresh1
311b8851fccSafresh1Return the password for the netrc entry
312b8851fccSafresh1
313eac174f2Safresh1=item C<account()>
314b8851fccSafresh1
315b8851fccSafresh1Return the account information for the netrc entry
316b8851fccSafresh1
317eac174f2Safresh1=item C<lpa()>
318b8851fccSafresh1
319b8851fccSafresh1Return a list of login, password and account information for the netrc entry
320b8851fccSafresh1
321b8851fccSafresh1=back
322b8851fccSafresh1
323eac174f2Safresh1=head1 EXPORTS
324b8851fccSafresh1
325eac174f2Safresh1I<None>.
326b8851fccSafresh1
327eac174f2Safresh1=head1 KNOWN BUGS
328eac174f2Safresh1
329eac174f2Safresh1See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
330b8851fccSafresh1
331b8851fccSafresh1=head1 SEE ALSO
332b8851fccSafresh1
333eac174f2Safresh1L<Net::Cmd>.
334eac174f2Safresh1
335eac174f2Safresh1=head1 AUTHOR
336eac174f2Safresh1
337eac174f2Safresh1Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
338eac174f2Safresh1
339eac174f2Safresh1Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
340eac174f2Safresh1libnet as of version 1.22_02.
341b8851fccSafresh1
342b8851fccSafresh1=head1 COPYRIGHT
343b8851fccSafresh1
3445759b3d2Safresh1Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
3455759b3d2Safresh1
346eac174f2Safresh1Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
3475759b3d2Safresh1
3485759b3d2Safresh1=head1 LICENCE
349b8851fccSafresh1
350b8851fccSafresh1This module is free software; you can redistribute it and/or modify it under the
351b8851fccSafresh1same terms as Perl itself, i.e. under the terms of either the GNU General Public
352b8851fccSafresh1License or the Artistic License, as specified in the F<LICENCE> file.
353b8851fccSafresh1
354eac174f2Safresh1=head1 VERSION
355eac174f2Safresh1
356*e0680481Safresh1Version 3.15
357eac174f2Safresh1
358eac174f2Safresh1=head1 DATE
359eac174f2Safresh1
360*e0680481Safresh120 March 2023
361eac174f2Safresh1
362eac174f2Safresh1=head1 HISTORY
363eac174f2Safresh1
364eac174f2Safresh1See the F<Changes> file.
365eac174f2Safresh1
366b8851fccSafresh1=cut
367