Class: Net::Netrc

Inherits:
Object
  • Object
show all
Defined in:
lib/net/netrc.rb

Overview

Net::Netrc provides an interface to the ftp(1) .netrc file containing login information for FTP (or other) servers.

Example Usage

require 'net/netrc'

rc = Net::Netrc.locate('ftp.example.com') or
  raise ".netrc missing or no entry found"
puts rc.
puts rc.password
puts rc.name

The .netrc File

The .netrc file is a plain text file containing login information. It is typically located in the user’s home directory. (See #rcname for specific details on how the .netrc file is located.)

On Unix platforms, the .netrc must be owned by the process’ effective user id and must not be group- or world-writable, or a SecurityError will be raised.

The .netrc file contains whitespace-separated tokens. Tokens containing whitespace must be enclosed in double quotes. The following tokens are recognized:

machine name

Identifies a remote machine name. #locate searches sequentially for a matching machine token. Once a match is found, subsequent tokens are processed until either EOF is reached or another machine (or default) token is parsed.

login name

Identifies remote user name.

password string

Supplies remote password.

account string

Supplies an additional account password.

macdef name

Begins a macro definition, which ends with the next blank line encountered. Ignored by Net::Netrc.

default

Defines default account information. The login information here will be returned if a matching machine token is not found during parsing. If supplied, default must appear after any machine entries.

Sample .netrc file

The following is an example of a .netrc file:

machine host1.austin.century.com 
   fred 
  password bluebonnet

default  john password ranger

Constant Summary collapse

VERSION_MAJOR =
0
VERSION_MINOR =
2
VERSION_PATCH =
2
VERSION =
"#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_PATCH}"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#accountObject

account name (nil if none)



104
105
106
# File 'lib/net/netrc.rb', line 104

def 
  @account
end

#loginObject

login name (nil if none)



98
99
100
# File 'lib/net/netrc.rb', line 98

def 
  @login
end

#machineObject

machine name, or nil if default entry



95
96
97
# File 'lib/net/netrc.rb', line 95

def machine
  @machine
end

#passwordObject

password (nil if none)



101
102
103
# File 'lib/net/netrc.rb', line 101

def password
  @password
end

Class Method Details

.locate(mach, io = nil) ⇒ Object

given a machine name, returns a Net::Netrc object containing the matching entry for that name, or the default entry. If no match is found and no default entry exists, nil is returned.

The returned object’s #machine, #login, #password, and #account attributes will be set to the corresponding values from the .netrc file entry. #machine will be nil if the default .netrc entry was used. The other attributes will be nil if the corresponding token in the .netrc file was not present.

io is a previously-opened IO object. If not supplied, #rcopen is called to locate and open the .netrc file. io will be closed when this method returns.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/net/netrc.rb', line 186

def Netrc.locate(mach, io = nil)
  need_close = false
  if io.nil?
    io = rcopen or return nil
    need_close = true
  end
  entry = nil
  key = nil
  inmacdef = false
  begin
    while line = io.gets
      if inmacdef
        inmacdef = false if line.strip.empty?
        next
      end
      toks = line.scan(/"((?:\\.|[^"])*)"|((?:\\.|\S)+)/).flatten.compact
      toks.each { |t| t.gsub!(/\\(.)/, '\1') }
      while toks.length > 0
        tok = toks.shift
        if key
          entry = new if key == 'machine' && tok == mach
          entry.send "#{key}=", tok if entry
          key = nil
        end
        case tok
        when 'default'
          return entry if entry
          entry = new
        when 'machine'
          return entry if entry
          key = 'machine'
        when 'login', 'password', 'account'
          key = tok
        when 'macdef'
          inmacdef = true
          break
        end
      end
    end
  ensure
    io.close if need_close
  end
  entry
end

.rcnameObject

Returns name of .netrc file

If the environment variable NETRC is set, it is used as the name of the .netrc file. Otherwise, a search is made for .netrc (and _netrc on Windows) in the following locations. The first existing file found will be returned.

  • User’s home directory as returned by Etc.getpwuid

  • ENV['HOME'] directory

On Windows platforms, the following additional locations are checked:

  • ENV['USERPROFILE']

  • ENV['HOMEPATH']

  • ENV['HOMEDRIVE'] + ENV['HOMEDIR']



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/net/netrc.rb', line 122

def Netrc.rcname

  # use file indicated by NETRC environment variable if defined
  return ENV['NETRC'] if ENV['NETRC']

  dirs = []
  files = ['.netrc']

  # build candidate list of directories to check
  pw = Etc.getpwuid
  dirs << pw.dir if pw
  dirs << ENV['HOME']
  if IS_WIN32
    dirs << ENV['USERPROFILE']
    dirs << ENV['HOMESHARE']
    dirs << ENV['HOMEDRIVE'] + ENV['HOMEPATH'] || '' if ENV['HOMEDRIVE']
    files << '_netrc'
  end

  # return first found file
  dirs.compact.each do |dir|
    files.each do |file|
      name = File.join(dir, file)
      return name if File.exist?(name)
    end
  end

  # nothing found
  nil
end

.rcopen(name = nil) ⇒ Object

opens .netrc file, returning File object if successful. name is the name of the .netrc file to open. If omitted, #rcname is used to locate the file.

returns nil if the file does not exist.

On non-Windows platforms, raises SecurityError if the file is not owned by the current user or if it is readable or writable by other than the current user.



162
163
164
165
166
167
168
169
170
171
# File 'lib/net/netrc.rb', line 162

def Netrc.rcopen(name = nil)
  name ||= rcname or return nil
  return nil unless File.exist?(name)
  unless IS_WIN32
    s = File.stat(name)
    raise SecurityError, "Not owner: #{name}" unless s.owned?
    raise SecurityError, "Bad permissions: #{name}" if s.mode & 077 != 0
  end
  File.open(name, 'r')
end