netrc-0.11.0/0000755000004100000410000000000012620565300012733 5ustar www-datawww-datanetrc-0.11.0/data/0000755000004100000410000000000012620565300013644 5ustar www-datawww-datanetrc-0.11.0/data/permissive.netrc0000644000004100000410000000011212620565300017061 0ustar www-datawww-data# this is my netrc machine m login l # this is my username password p netrc-0.11.0/data/sample_multi.netrc0000644000004100000410000000024112620565300017371 0ustar www-datawww-data# this is my netrc with multiple machines machine m login lm # this is my m-username password pm machine n login ln # this is my n-username password pn netrc-0.11.0/data/password.netrc0000644000004100000410000000011112620565300016534 0ustar www-datawww-data# this is my password netrc machine m password p # this is my password netrc-0.11.0/data/sample_multi_with_default.netrc0000644000004100000410000000035712620565300022140 0ustar www-datawww-data# this is my netrc with multiple machines and a default machine m login lm # this is my m-username password pm machine n login ln # this is my n-username password pn default login ld # this is my default username password pd netrc-0.11.0/data/sample_with_default.netrc0000644000004100000410000000026012620565300020717 0ustar www-datawww-data# this is my netrc with default machine m login l # this is my username password p default login default_login # this is my default username password default_password netrc-0.11.0/data/newlineless.netrc0000644000004100000410000000011112620565300017222 0ustar www-datawww-data# this is my netrc machine m login l # this is my username password pnetrc-0.11.0/data/sample.netrc0000644000004100000410000000011212620565300016154 0ustar www-datawww-data# this is my netrc machine m login l # this is my username password p netrc-0.11.0/data/login.netrc0000644000004100000410000000010312620565300016003 0ustar www-datawww-data# this is my login netrc machine m login l # this is my username netrc-0.11.0/data/default_only.netrc0000644000004100000410000000014612620565300017367 0ustar www-datawww-data# this is my netrc with only a default default login ld # this is my default username password pd netrc-0.11.0/LICENSE.md0000644000004100000410000000217612620565300014345 0ustar www-datawww-dataThe MIT License (MIT) Copyright (c) 2011-2014 [CONTRIBUTORS.md](https://github.com/geemus/netrc/blob/master/CONTRIBUTORS.md) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. netrc-0.11.0/lib/0000755000004100000410000000000012620565300013501 5ustar www-datawww-datanetrc-0.11.0/lib/netrc.rb0000644000004100000410000001306412620565300015145 0ustar www-datawww-datarequire 'rbconfig' class Netrc VERSION = "0.11.0" # see http://stackoverflow.com/questions/4871309/what-is-the-correct-way-to-detect-if-ruby-is-running-on-windows WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/ CYGWIN = RbConfig::CONFIG["host_os"] =~ /cygwin/ def self.default_path File.join(ENV['NETRC'] || home_path, netrc_filename) end def self.home_path home = Dir.respond_to?(:home) ? Dir.home : ENV['HOME'] if WINDOWS && !CYGWIN home ||= File.join(ENV['HOMEDRIVE'], ENV['HOMEPATH']) if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] home ||= ENV['USERPROFILE'] # XXX: old stuff; most likely unnecessary home = home.tr("\\", "/") unless home.nil? end (home && File.readable?(home)) ? home : Dir.pwd rescue ArgumentError return Dir.pwd end def self.netrc_filename WINDOWS && !CYGWIN ? "_netrc" : ".netrc" end def self.config @config ||= {} end def self.configure yield(self.config) if block_given? self.config end def self.check_permissions(path) perm = File.stat(path).mode & 0777 if perm != 0600 && !(WINDOWS) && !(Netrc.config[:allow_permissive_netrc_file]) raise Error, "Permission bits for '#{path}' should be 0600, but are "+perm.to_s(8) end end # Reads path and parses it as a .netrc file. If path doesn't # exist, returns an empty object. Decrypt paths ending in .gpg. def self.read(path=default_path) check_permissions(path) data = if path =~ /\.gpg$/ decrypted = `gpg --batch --quiet --decrypt #{path}` if $?.success? decrypted else raise Error.new("Decrypting #{path} failed.") unless $?.success? end else File.read(path) end new(path, parse(lex(data.lines.to_a))) rescue Errno::ENOENT new(path, parse(lex([]))) end class TokenArray < Array def take if length < 1 raise Error, "unexpected EOF" end shift end def readto l = [] while length > 0 && ! yield(self[0]) l << shift end return l.join end end def self.lex(lines) tokens = TokenArray.new for line in lines content, comment = line.split(/(\s*#.*)/m) content.each_char do |char| case char when /\s/ if tokens.last && tokens.last[-1..-1] =~ /\s/ tokens.last << char else tokens << char end else if tokens.last && tokens.last[-1..-1] =~ /\S/ tokens.last << char else tokens << char end end end if comment tokens << comment end end tokens end def self.skip?(s) s =~ /^\s/ end # Returns two values, a header and a list of items. # Each item is a tuple, containing some or all of: # - machine keyword (including trailing whitespace+comments) # - machine name # - login keyword (including surrounding whitespace+comments) # - login # - password keyword (including surrounding whitespace+comments) # - password # - trailing chars # This lets us change individual fields, then write out the file # with all its original formatting. def self.parse(ts) cur, item = [], [] unless ts.is_a?(TokenArray) ts = TokenArray.new(ts) end pre = ts.readto{|t| t == "machine" || t == "default"} while ts.length > 0 if ts[0] == 'default' cur << ts.take.to_sym cur << '' else cur << ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take end if ts.include?('login') cur << ts.readto{|t| t == "login"} + ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take end if ts.include?('password') cur << ts.readto{|t| t == "password"} + ts.take + ts.readto{|t| ! skip?(t)} cur << ts.take end cur << ts.readto{|t| t == "machine" || t == "default"} item << cur cur = [] end [pre, item] end def initialize(path, data) @new_item_prefix = '' @path = path @pre, @data = data if @data && @data.last && :default == @data.last[0] @default = @data.pop else @default = nil end end attr_accessor :new_item_prefix def [](k) if item = @data.detect {|datum| datum[1] == k} Entry.new(item[3], item[5]) elsif @default Entry.new(@default[3], @default[5]) end end def []=(k, info) if item = @data.detect {|datum| datum[1] == k} item[3], item[5] = info else @data << new_item(k, info[0], info[1]) end end def length @data.length end def delete(key) datum = nil for value in @data if value[1] == key datum = value break end end @data.delete(datum) end def each(&block) @data.each(&block) end def new_item(m, l, p) [new_item_prefix+"machine ", m, "\n login ", l, "\n password ", p, "\n"] end def save if @path =~ /\.gpg$/ e = IO.popen("gpg -a --batch --default-recipient-self -e", "r+") do |gpg| gpg.puts(unparse) gpg.close_write gpg.read end raise Error.new("Encrypting #{@path} failed.") unless $?.success? File.open(@path, 'w', 0600) {|file| file.print(e)} else File.open(@path, 'w', 0600) {|file| file.print(unparse)} end end def unparse @pre + @data.map do |datum| datum = datum.join unless datum[-1..-1] == "\n" datum << "\n" else datum end end.join end Entry = Struct.new(:login, :password) do alias to_ary to_a end end class Netrc::Error < ::StandardError end netrc-0.11.0/Readme.md0000644000004100000410000000257012620565300014456 0ustar www-datawww-data# Netrc This library reads and writes [`.netrc` files](http://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html). ## API Read a netrc file: n = Netrc.read("sample.netrc") If the file doesn't exist, Netrc.read will return an empty object. If the filename ends in ".gpg", it will be decrypted using [GPG](http://www.gnupg.org/). Read the user's default netrc file. **On Unix:** `$NETRC/.netrc` or `$HOME/.netrc` (whichever is set first). **On Windows:** `%NETRC%\_netrc`, `%HOME%\_netrc`, `%HOMEDRIVE%%HOMEPATH%\_netrc`, or `%USERPROFILE%\_netrc` (whichever is set first). n = Netrc.read Configure netrc to allow permissive files (with permissions other than 0600): Netrc.configure do |config| config[:allow_permissive_netrc_file] = true end Look up a username and password: user, pass = n["example.com"] Write a username and password: n["example.com"] = user, newpass n.save If you make an entry that wasn't there before, it will be appended to the end of the file. Sometimes people want to include a comment explaining that the entry was added automatically. You can do it like this: n.new_item_prefix = "# This entry was added automatically\n" n["example.com"] = user, newpass n.save Have fun! ## Running Tests $ bundle install $ bundle exec ruby -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' netrc-0.11.0/metadata.yml0000644000004100000410000000330412620565300015236 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: netrc version: !ruby/object:Gem::Version version: 0.11.0 platform: ruby authors: - Keith Rarick - geemus (Wesley Beary) autorequire: bindir: bin cert_chain: [] date: 2015-10-29 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: minitest requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' description: This library can read and update netrc files, preserving formatting including comments and whitespace. email: geemus@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - LICENSE.md - Readme.md - changelog.txt - data/default_only.netrc - data/login.netrc - data/newlineless.netrc - data/password.netrc - data/permissive.netrc - data/sample.netrc - data/sample_multi.netrc - data/sample_multi_with_default.netrc - data/sample_with_default.netrc - lib/netrc.rb - test/test_lex.rb - test/test_netrc.rb - test/test_parse.rb homepage: https://github.com/geemus/netrc licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.5.1 signing_key: specification_version: 4 summary: Library to read and write netrc files. test_files: [] netrc-0.11.0/test/0000755000004100000410000000000012620565300013712 5ustar www-datawww-datanetrc-0.11.0/test/test_lex.rb0000644000004100000410000000261512620565300016072 0ustar www-datawww-data$VERBOSE = true require 'minitest/autorun' require File.expand_path("#{File.dirname(__FILE__)}/../lib/netrc") class TestLex < Minitest::Test def test_lex_empty t = Netrc.lex([]) assert_equal([], t) end def test_lex_comment t = Netrc.lex(["# foo\n"]) assert_equal(["# foo\n"], t) end def test_lex_comment_after_space t = Netrc.lex([" # foo\n"]) assert_equal([" # foo\n"], t) end def test_lex_comment_after_word t = Netrc.lex(["x # foo\n"]) assert_equal(["x", " # foo\n"], t) end def test_lex_comment_with_hash t = Netrc.lex(["x # foo # bar\n"]) assert_equal(["x", " # foo # bar\n"], t) end def test_lex_word t = Netrc.lex(["x"]) assert_equal(["x"], t) end def test_lex_two_lines t = Netrc.lex(["x\ny\n"]) assert_equal(["x", "\n", "y", "\n"], t) end def test_lex_word_and_comment t = Netrc.lex(["x\n", "# foo\n"]) assert_equal(["x", "\n", "# foo\n"], t) end def test_lex_six_words t = Netrc.lex(["machine m login l password p\n"]) e = ["machine", " ", "m", " ", "login", " ", "l", " ", "password", " ", "p", "\n"] assert_equal(e, t) end def test_lex_complex t = Netrc.lex(["machine sub.domain.com login email@domain.com password pass\n"]) e = ["machine", " ", "sub.domain.com", " ", "login", " ", "email@domain.com", " ", "password", " ", "pass", "\n"] assert_equal(e, t) end end netrc-0.11.0/test/test_parse.rb0000644000004100000410000000167112620565300016415 0ustar www-datawww-data$VERBOSE = true require 'minitest/autorun' require File.expand_path("#{File.dirname(__FILE__)}/../lib/netrc") class TestParse < Minitest::Test def test_parse_empty pre, items = Netrc.parse([]) assert_equal("", pre) assert_equal([], items) end def test_parse_comment pre, items = Netrc.parse(["# foo\n"]) assert_equal("# foo\n", pre) assert_equal([], items) end def test_parse_item t = ["machine", " ", "m", " ", "login", " ", "l", " ", "password", " ", "p", "\n"] pre, items = Netrc.parse(t) assert_equal("", pre) e = [["machine ", "m", " login ", "l", " password ", "p", "\n"]] assert_equal(e, items) end def test_parse_two_items t = ["machine", " ", "m", " ", "login", " ", "l", " ", "password", " ", "p", "\n"] * 2 pre, items = Netrc.parse(t) assert_equal("", pre) e = [["machine ", "m", " login ", "l", " password ", "p", "\n"]] * 2 assert_equal(e, items) end end netrc-0.11.0/test/test_netrc.rb0000644000004100000410000001651612620565300016422 0ustar www-datawww-data$VERBOSE = true require 'minitest/autorun' require 'fileutils' require File.expand_path("#{File.dirname(__FILE__)}/../lib/netrc") require "rbconfig" class TestNetrc < Minitest::Test def setup Dir.glob('data/*.netrc').each{|f| File.chmod(0600, f)} File.chmod(0644, "data/permissive.netrc") end def teardown Dir.glob('data/*.netrc').each{|f| File.chmod(0644, f)} end def test_parse_empty pre, items = Netrc.parse(Netrc.lex([])) assert_equal("", pre) assert_equal([], items) end def test_parse_file pre, items = Netrc.parse(Netrc.lex(IO.readlines("data/sample.netrc"))) assert_equal("# this is my netrc\n", pre) exp = [["machine ", "m", "\n login ", "l", " # this is my username\n password ", "p", "\n"]] assert_equal(exp, items) end def test_login_file pre, items = Netrc.parse(Netrc.lex(IO.readlines("data/login.netrc"))) assert_equal("# this is my login netrc\n", pre) exp = [["machine ", "m", "\n login ", "l", " # this is my username\n"]] assert_equal(exp, items) end def test_password_file pre, items = Netrc.parse(Netrc.lex(IO.readlines("data/password.netrc"))) assert_equal("# this is my password netrc\n", pre) exp = [["machine ", "m", "\n password ", "p", " # this is my password\n"]] assert_equal(exp, items) end def test_missing_file n = Netrc.read("data/nonexistent.netrc") assert_equal(0, n.length) end def test_permission_error original_windows = Netrc::WINDOWS Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, false) Netrc.read("data/permissive.netrc") assert false, "Should raise an error if permissions are wrong on a non-windows system." rescue Netrc::Error assert true, "" ensure Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, original_windows) end def test_allow_permissive_netrc_file_option Netrc.configure do |config| config[:allow_permissive_netrc_file] = true end original_windows = Netrc::WINDOWS Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, false) Netrc.read("data/permissive.netrc") assert true, "" rescue Netrc::Error assert false, "Should not raise an error if allow_permissive_netrc_file option is set to true" ensure Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, original_windows) Netrc.configure do |config| config[:allow_permissive_netrc_file] = false end end def test_permission_error_windows original_windows = Netrc::WINDOWS Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, true) Netrc.read("data/permissive.netrc") rescue Netrc::Error assert false, "Should not raise an error if permissions are wrong on a non-windows system." ensure Netrc.send(:remove_const, :WINDOWS) Netrc.const_set(:WINDOWS, original_windows) end def test_round_trip n = Netrc.read("data/sample.netrc") assert_equal(IO.read("data/sample.netrc"), n.unparse) end def test_set n = Netrc.read("data/sample.netrc") n["m"] = "a", "b" exp = "# this is my netrc\n"+ "machine m\n"+ " login a # this is my username\n"+ " password b\n" assert_equal(exp, n.unparse) end def test_set_get n = Netrc.read("data/sample.netrc") n["m"] = "a", "b" assert_equal(["a", "b"], n["m"].to_a) end def test_add n = Netrc.read("data/sample.netrc") n.new_item_prefix = "# added\n" n["x"] = "a", "b" exp = "# this is my netrc\n"+ "machine m\n"+ " login l # this is my username\n"+ " password p\n"+ "# added\n"+ "machine x\n"+ " login a\n"+ " password b\n" assert_equal(exp, n.unparse) end def test_add_newlineless n = Netrc.read("data/newlineless.netrc") n.new_item_prefix = "# added\n" n["x"] = "a", "b" exp = "# this is my netrc\n"+ "machine m\n"+ " login l # this is my username\n"+ " password p\n"+ "# added\n"+ "machine x\n"+ " login a\n"+ " password b\n" assert_equal(exp, n.unparse) end def test_add_get n = Netrc.read("data/sample.netrc") n.new_item_prefix = "# added\n" n["x"] = "a", "b" assert_equal(["a", "b"], n["x"].to_a) end def test_get_missing n = Netrc.read("data/sample.netrc") assert_equal(nil, n["x"]) end def test_save n = Netrc.read("data/sample.netrc") n.save assert_equal(File.read("data/sample.netrc"), n.unparse) end def test_save_create FileUtils.rm_f("/tmp/created.netrc") n = Netrc.read("/tmp/created.netrc") n.save unless Netrc::WINDOWS assert_equal(0600, File.stat("/tmp/created.netrc").mode & 0777) end end def test_encrypted_roundtrip if `gpg --list-keys 2> /dev/null` != "" FileUtils.rm_f("/tmp/test.netrc.gpg") n = Netrc.read("/tmp/test.netrc.gpg") n["m"] = "a", "b" n.save assert_equal(0600, File.stat("/tmp/test.netrc.gpg").mode & 0777) netrc = Netrc.read("/tmp/test.netrc.gpg")["m"] assert_equal("a", netrc.login) assert_equal("b", netrc.password) end end def test_missing_environment nil_home = nil ENV["HOME"], nil_home = nil_home, ENV["HOME"] assert_equal File.join(Dir.pwd, '.netrc'), Netrc.default_path ensure ENV["HOME"], nil_home = nil_home, ENV["HOME"] end def test_netrc_environment_variable ENV["NETRC"] = File.join(Dir.pwd, 'data') assert_equal File.join(Dir.pwd, 'data', '.netrc'), Netrc.default_path ensure ENV.delete("NETRC") end def test_read_entry entry = Netrc.read("data/sample.netrc")['m'] assert_equal 'l', entry.login assert_equal 'p', entry.password # hash-style assert_equal 'l', entry[:login] assert_equal 'p', entry[:password] end def test_write_entry n = Netrc.read("data/sample.netrc") entry = n['m'] entry.login = 'new_login' entry.password = 'new_password' n['m'] = entry assert_equal(['new_login', 'new_password'], n['m'].to_a) end def test_entry_splat e = Netrc::Entry.new("user", "pass") user, pass = *e assert_equal("user", user) assert_equal("pass", pass) end def test_entry_implicit_splat e = Netrc::Entry.new("user", "pass") user, pass = e assert_equal("user", user) assert_equal("pass", pass) end def test_with_default netrc = Netrc.read('data/sample_with_default.netrc') assert_equal(['l', 'p'], netrc['m'].to_a) assert_equal(['default_login', 'default_password'], netrc['unknown'].to_a) end def test_multi_without_default netrc = Netrc.read('data/sample_multi.netrc') assert_equal(['lm', 'pm'], netrc['m'].to_a) assert_equal(['ln', 'pn'], netrc['n'].to_a) assert_equal([], netrc['other'].to_a) end def test_multi_with_default netrc = Netrc.read('data/sample_multi_with_default.netrc') assert_equal(['lm', 'pm'], netrc['m'].to_a) assert_equal(['ln', 'pn'], netrc['n'].to_a) assert_equal(['ld', 'pd'], netrc['other'].to_a) end def test_default_only netrc = Netrc.read('data/default_only.netrc') assert_equal(['ld', 'pd'], netrc['m'].to_a) assert_equal(['ld', 'pd'], netrc['other'].to_a) end end netrc-0.11.0/changelog.txt0000644000004100000410000000316612620565300015431 0ustar www-datawww-data0.11.0 10/29/15 =============== Respect NETRC environment variable Fix for JRuby PernGen Space 0.10.3 02/24/15 =============== error when Dir.home is not readable 0.10.2 12/17/14 =============== set file permissions in /data to be world readable after test runs 0.10.1 12/14/14 =============== fix bug for `Dir.home` when can't find home 0.10.0 12/10/14 =============== use `Dir.home` for finding home on Ruby 1.9+ 0.9.0 12/01/14 ============== use HOME or HOMEPATH/HOMEDRIVE to find home on windows 0.8.0 10/16/14 ============== re-revert entry changes with minor bump 0.7.9 10/16/14 ============== revert entry changes for a backwards-compatible version 0.7.8 10/15/14 ============== add entry class to facilitate usage switch gem source to rubygems.org use guard, when available via guardfile add default/read-only behavior add allow_permissive_netrc_file option fix an undefined variable path fix Errno::EACCES error silence const warnings in test 0.7.7 08/15/12 ============== add newline between entries if one is missing 0.7.6 08/15/12 ============== more unified newline handling make entries with login/password parsable 0.7.5 06/25/12 ============== * improved operating system detection 0.7.4 06/04/12 ============== * add support for encrypted files pgp netrc files 0.7.3 06/04/12 ============== * also skip permissions check on cygwin 0.7.2 05/23/12 ============= * use length instead of count on Array, provides compatibility with 1.8.6 0.7.1 03/13/12 ============== * add Gemfile to simplify development * add MIT license * fix test require path * fix unused variable assignment (caused warnings) in tests