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