net-http-digest_auth-1.4.1/0000755000004100000410000000000013321140324015577 5ustar www-datawww-datanet-http-digest_auth-1.4.1/.travis.yml0000644000004100000410000000037013321140324017710 0ustar www-datawww-data--- after_script: - rake travis:after -t before_script: - gem install hoe-travis --no-rdoc --no-ri - rake travis:before -t language: ruby notifications: email: - drbrain@segment7.net rvm: - 1.8.7 - 1.9.3 - 2.0.0 - ruby-head script: rake travis net-http-digest_auth-1.4.1/test/0000755000004100000410000000000013321140324016556 5ustar www-datawww-datanet-http-digest_auth-1.4.1/test/test_net_http_digest_auth.rb0000644000004100000410000000625513321140324024357 0ustar www-datawww-datarequire 'minitest/autorun' require 'net/http/digest_auth' class TestNetHttpDigestAuth < Minitest::Test def setup @uri = URI.parse "http://www.example.com/" @uri.user = 'user' @uri.password = 'password' @cnonce = '9ea5ff3bd34554a4165bbdc1df91dcff' @header = [ 'Digest qop="auth"', 'realm="www.example.com"', 'nonce="4107baa081a592a6021660200000cd6c5686ff5f579324402b374d83e2c9"' ].join ', ' @expected = [ 'Digest username="user"', 'realm="www.example.com"', 'algorithm=MD5', 'qop=auth', 'uri="/"', 'nonce="4107baa081a592a6021660200000cd6c5686ff5f579324402b374d83e2c9"', 'nc=00000000', 'cnonce="9ea5ff3bd34554a4165bbdc1df91dcff"', 'response="67be92a5e7b38d08679957db04f5da04"' ] @da = Net::HTTP::DigestAuth.new def @da.make_cnonce '9ea5ff3bd34554a4165bbdc1df91dcff' end end def expected @expected.join ', ' end def test_auth_header assert_equal expected, @da.auth_header(@uri, @header, 'GET') @expected[6] = 'nc=00000001' @expected[8] = 'response="1f5f0cd1588690c1303737f081c0b9bb"' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_auth_header_iis @expected[3] = 'qop="auth"' assert_equal expected, @da.auth_header(@uri, @header, 'GET', true) end def test_auth_header_no_qop @header.sub! ' qop="auth",', '' @expected[8] = 'response="32f6ca1631ccf7c42a8075deff44e470"' @expected.delete 'qop=auth' @expected.delete 'cnonce="9ea5ff3bd34554a4165bbdc1df91dcff"' @expected.delete 'nc=00000000' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_auth_header_opaque @expected << 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' @header << 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_auth_header_post @expected[8] = 'response="d82219e1e5430b136bbae1670fa51d48"' assert_equal expected, @da.auth_header(@uri, @header, 'POST') end def test_auth_header_sess @header << ', algorithm=MD5-sess' @expected[2] = 'algorithm=MD5-sess' @expected[8] = 'response="c22c5bd9112a86ca78ddc1ae772daeeb"' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_auth_header_sha1 @expected[2] = 'algorithm=SHA1' @expected[8] = 'response="2cb62fc18f7b0ebdc34543f896bb77686b4115e4"' @header << 'algorithm=SHA1' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_auth_header_unknown_algorithm @header << 'algorithm=bogus' e = assert_raises Net::HTTP::DigestAuth::Error do @da.auth_header @uri, @header, 'GET' end assert_equal 'unknown algorithm "bogus"', e.message end def test_auth_header_quoted_algorithm @header << 'algorithm="MD5"' assert_equal expected, @da.auth_header(@uri, @header, 'GET') end def test_make_cnonce da = Net::HTTP::DigestAuth.new cnonce = da.make_cnonce assert_match %r%\A[a-f\d]{32}\z%, cnonce refute_equal cnonce, da.make_cnonce end def test_next_nonce first = @da.next_nonce assert_equal first + 1, @da.next_nonce end end net-http-digest_auth-1.4.1/data.tar.gz.sig0000444000004100000410000000040013321140324020410 0ustar www-datawww-data=y7#L)aLDgyTtǠ9& 26e-^Xdez7Ѐag[$.#$}ܰ[y6(wZ'(9+tpBA@h >eh} NqJ71;hnkܮH8P:eΡ/֦QE-<&Г+]zb\"D .)O!ouw8*2'\Ϟ\ ; #8iC֍net-http-digest_auth-1.4.1/metadata.gz.sig0000444000004100000410000000040013321140324020472 0ustar www-datawww-dataeTjUaSjSVw,O^xRd/GVWk_u y_ >Sb+UŹcBYe':sI%'NR~r{n$HnYe^O._pD8ë3T3eƍg︈hJRx2ې6o4ӣR]X>MNR`ilbba3zKh1-#-8OO/v+]eoJܳYzB*2net-http-digest_auth-1.4.1/checksums.yaml.gz.sig0000444000004100000410000000040013321140324021640 0ustar www-datawww-datayw^EL\~Qv3~Ɂc'j1*TIyum7cqR=XTG0IV#ؤKTQ+;|yn.]Z`&hṘH;@n5$ 2F $}ע2;#1^V`Z=2$ \с7!`d#X3N Y`i #6XL[ӹ2SoPnP {ثŀaj&net-http-digest_auth-1.4.1/History.txt0000644000004100000410000000241313321140324020001 0ustar www-datawww-data=== 1.4.1 / 2017-02-08 * Bug fix * Set license to MIT in spec, matching README. Issue #9 by Benjamin Fleischer * Allow any digest length per RFC 7616 section 3.4.2. Issue #14 by Joshua Gross. === 1.4 / 2013-07-23 * Minor enhancements * Relaxed parser to accept quoted algorithm to work with Linksys SPA922. Pull request #8 by Ismail Hanli, Issue #5 by bearded === 1.3 / 2012-03-28 * Minor enhancements * The cnonce is regenerated for every request to improve security. * SecureRandom is used to generate the cnonce instead of Kernel#rand * Bug fix * cnonce and nonce-count are no longer sent when qop was not provided per RFC 2617 section 3.2.2. === 1.2.1 / 2012-05-18 * Bug fix * Fixed -sess authentication. This also fixes pull request #4 by joe81 === 1.2 / 2011-11-22 * Minor enhancement * Now thread safe. Issue #2 by chrisochs. === 1.1.1 / 2011-04-03 * Bug fix * Fix syntax error on ruby 1.8 === 1.1 / 2011-03-29 * Minor enhancements * Add support for SHA1, SHA2, SHA256, SHA384, SHA512, RMD160 algorithms * Bug fixes * Support opaque per RFC 2617 3.2.1 * Support MD5-sess per RFC 2617 3.2.2.2 * Support unspecified qop for RFC 2069 compatibility per RFC 2617 3.2.2.1 === 1.0 / 2010-09-10 * Major enhancements * Birthday! net-http-digest_auth-1.4.1/.autotest0000644000004100000410000000016613321140324017453 0ustar www-datawww-data# -*- ruby -*- require 'autotest/restart' Autotest.add_hook :initialize do |at| at.testlib = 'minitest/unit' end net-http-digest_auth-1.4.1/README.txt0000644000004100000410000000317613321140324017304 0ustar www-datawww-data= net-http-digest_auth code :: http://github.com/drbrain/net-http-digest_auth rdoc :: http://docs.seattlerb.org/net-http-digest_auth other :: http://www.rfc-editor.org/rfc/rfc2617.txt == DESCRIPTION: An implementation of RFC 2617 - Digest Access Authentication. At this time the gem does not drop in to Net::HTTP and can be used for with other HTTP clients. In order to use net-http-digest_auth you'll need to perform some request wrangling on your own. See the class documentation at Net::HTTP::DigestAuth for an example. == INSTALL: gem install net-http-digest_auth == LICENSE: (The MIT License) Copyright (c) Eric Hodel 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. net-http-digest_auth-1.4.1/Rakefile0000644000004100000410000000102413321140324017241 0ustar www-datawww-data# -*- ruby -*- require 'rubygems' require 'hoe' Hoe.plugin :git Hoe.plugin :minitest Hoe.plugin :travis Hoe.spec 'net-http-digest_auth' do developer 'Eric Hodel', 'drbrain@segment7.net' rdoc_locations << 'docs.seattlerb.org:/data/www/docs.seattlerb.org/net-http-digest_auth/' rdoc_locations << 'rubyforge.org:/var/www/gforge-projects/seattlerb/net-http-digest_auth/' license 'MIT' dependency 'minitest', '~> 5.0', :development self.spec_extras[:required_ruby_version] = '>= 1.8.7' end # vim: syntax=Ruby net-http-digest_auth-1.4.1/lib/0000755000004100000410000000000013321140324016345 5ustar www-datawww-datanet-http-digest_auth-1.4.1/lib/net/0000755000004100000410000000000013321140324017133 5ustar www-datawww-datanet-http-digest_auth-1.4.1/lib/net/http/0000755000004100000410000000000013321140324020112 5ustar www-datawww-datanet-http-digest_auth-1.4.1/lib/net/http/digest_auth.rb0000644000004100000410000001035213321140324022740 0ustar www-datawww-datarequire 'cgi' require 'digest' require 'monitor' require 'net/http' require 'securerandom' ## # An implementation of RFC 2617 Digest Access Authentication. # # http://www.rfc-editor.org/rfc/rfc2617.txt # # Here is a sample usage of DigestAuth on Net::HTTP: # # require 'uri' # require 'net/http' # require 'net/http/digest_auth' # # digest_auth = Net::HTTP::DigestAuth.new # # uri = URI.parse 'http://localhost:8000/' # uri.user = 'username' # uri.password = 'password' # # h = Net::HTTP.new uri.host, uri.port # # req = Net::HTTP::Get.new uri.request_uri # # res = h.request req # # res is a 401 response with a WWW-Authenticate header # # auth = digest_auth.auth_header uri, res['www-authenticate'], 'GET' # # # create a new request with the Authorization header # req = Net::HTTP::Get.new uri.request_uri # req.add_field 'Authorization', auth # # # re-issue request with Authorization # res = h.request req class Net::HTTP::DigestAuth include MonitorMixin ## # DigestAuth error class class Error < RuntimeError; end ## # Version of Net::HTTP::DigestAuth you are using VERSION = '1.4.1' ## # Creates a new DigestAuth header creator. def initialize ignored = :ignored mon_initialize @nonce_count = -1 end ## # Creates a digest auth header for +uri+ from the +www_authenticate+ header # for HTTP method +method+. # # The result of this method should be sent along with the HTTP request as # the "Authorization" header. In Net::HTTP this will look like: # # request.add_field 'Authorization', digest_auth.auth_header # ... # # See Net::HTTP::DigestAuth for a complete example. # # IIS servers handle the "qop" parameter of digest authentication # differently so you may need to set +iis+ to true for such servers. def auth_header uri, www_authenticate, method, iis = false nonce_count = next_nonce user = CGI.unescape uri.user password = CGI.unescape uri.password www_authenticate =~ /^(\w+) (.*)/ challenge = $2 params = {} challenge.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 } challenge =~ /algorithm="?(.*?)"?([, ]|$)/ params['algorithm'] = $1 || 'MD5' if params['algorithm'] =~ /(.*?)(-sess)?$/ algorithm = case $1 when 'MD5' then Digest::MD5 when 'SHA1' then Digest::SHA1 when 'SHA2' then Digest::SHA2 when 'SHA256' then Digest::SHA256 when 'SHA384' then Digest::SHA384 when 'SHA512' then Digest::SHA512 when 'RMD160' then Digest::RMD160 else raise Error, "unknown algorithm \"#{$1}\"" end sess = $2 end qop = params['qop'] cnonce = make_cnonce if qop or sess a1 = if sess then [ algorithm.hexdigest("#{user}:#{params['realm']}:#{password}"), params['nonce'], cnonce, ].join ':' else "#{user}:#{params['realm']}:#{password}" end ha1 = algorithm.hexdigest a1 ha2 = algorithm.hexdigest "#{method}:#{uri.request_uri}" request_digest = [ha1, params['nonce']] request_digest.push(('%08x' % nonce_count), cnonce, qop) if qop request_digest << ha2 request_digest = request_digest.join ':' header = [ "Digest username=\"#{user}\"", "realm=\"#{params['realm']}\"", "algorithm=#{params['algorithm']}", if qop.nil? then elsif iis then "qop=\"#{qop}\"" else "qop=#{qop}" end, "uri=\"#{uri.request_uri}\"", "nonce=\"#{params['nonce']}\"", if qop then [ "nc=#{'%08x' % @nonce_count}", "cnonce=\"#{cnonce}\"", ] end, "response=\"#{algorithm.hexdigest(request_digest)}\"", if params.key? 'opaque' then "opaque=\"#{params['opaque']}\"" end ].compact header.join ', ' end ## # Creates a client nonce value that is used across all requests based on the # current time, process id and a random number def make_cnonce Digest::MD5.hexdigest [ Time.now.to_i, $$, SecureRandom.random_number(2**32), ].join ':' end def next_nonce synchronize do @nonce_count += 1 end end end net-http-digest_auth-1.4.1/Manifest.txt0000644000004100000410000000026213321140324020106 0ustar www-datawww-data.autotest .travis.yml History.txt Manifest.txt README.txt Rakefile lib/net/http/digest_auth.rb sample/auth_server.rb sample/net_http_example.rb test/test_net_http_digest_auth.rb net-http-digest_auth-1.4.1/sample/0000755000004100000410000000000013321140324017060 5ustar www-datawww-datanet-http-digest_auth-1.4.1/sample/auth_server.rb0000644000004100000410000000170013321140324021732 0ustar www-datawww-datarequire 'webrick' require 'tempfile' class AuthServlet < WEBrick::HTTPServlet::AbstractServlet @instance = nil def self.get_instance server, *options @instance ||= new(server, *options) end def initialize server super server config = {} config[:Realm] = 'net-http-digest_auth' config[:UseOpaque] = false config[:AutoReloadUserDB] = false passwd_file = Tempfile.new 'net-http-digest_auth' passwd_file.close htpasswd = WEBrick::HTTPAuth::Htpasswd.new passwd_file.path htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth htpasswd.set_passwd config[:Realm], 'username', 'password' htpasswd.flush config[:UserDB] = htpasswd @digest_auth = WEBrick::HTTPAuth::DigestAuth.new config end def do_GET req, res @digest_auth.authenticate req, res res.body = 'worked!' end end s = WEBrick::HTTPServer.new :Port => 8000 s.mount '/', AuthServlet trap 'INT' do s.shutdown end s.start net-http-digest_auth-1.4.1/sample/net_http_example.rb0000644000004100000410000000106613321140324022750 0ustar www-datawww-datarequire 'uri' require 'net/http' require 'net/http/digest_auth' uri = URI.parse 'http://localhost:8000/' uri.user = 'username' uri.password = 'password' h = Net::HTTP.new uri.host, uri.port h.set_debug_output $stderr req = Net::HTTP::Get.new uri.request_uri res = h.request req digest_auth = Net::HTTP::DigestAuth.new auth = digest_auth.auth_header uri, res['www-authenticate'], 'GET' req = Net::HTTP::Get.new uri.request_uri req.add_field 'Authorization', auth res = h.request req puts puts "passed" if res.code == '200' puts "failed" if res.code != '200' net-http-digest_auth-1.4.1/net-http-digest_auth.gemspec0000644000004100000410000000702413321140324023210 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: net-http-digest_auth 1.4.1 ruby lib Gem::Specification.new do |s| s.name = "net-http-digest_auth".freeze s.version = "1.4.1" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Eric Hodel".freeze] s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDNjCCAh6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy\nYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu\nZXQwHhcNMTYxMDA1MDQyNTQ0WhcNMTcxMDA1MDQyNTQ0WjBBMRAwDgYDVQQDDAdk\ncmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ\nFgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76\nLV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J\nU5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm\nGj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY\nmUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd\ng62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh\nsCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW\nBBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAFz46xasn\n5Jx0lPqq6EGpijLIWv+jk+m2v3Ps38M2ZmNpiThmYFBHIqfDCS0UJWDPTj6FJX0A\nrspSuifsHq3CQ3RJImdO9Gewvx6p3WL/xZD1LmuRo6ktWH9gZWiZpA38GfFGj3SZ\n2u6n3qOEsaxIfwYcU4lCgeZ61JdVU+WWK+GfZpCz4BnjA5hgwdFaf5Zb560RtW7S\n77pi/SZtblyK/jqz1hgoMcaYZvIJTqZnen0pHaq+lKY1KzGdTuVbwD3DO+Fi1Vu8\nBOJAX2VNKk4wthxdCu0SvPe7e+QMP2rmaZOyuX4ztiDQiGuoJxyeqoG1WiOttINU\nU76tHMFuL0FUYw==\n-----END CERTIFICATE-----\n".freeze] s.date = "2017-02-08" s.description = "An implementation of RFC 2617 - Digest Access Authentication. At this time\nthe gem does not drop in to Net::HTTP and can be used for with other HTTP\nclients.\n\nIn order to use net-http-digest_auth you'll need to perform some request\nwrangling on your own. See the class documentation at Net::HTTP::DigestAuth\nfor an example.".freeze s.email = ["drbrain@segment7.net".freeze] s.extra_rdoc_files = ["History.txt".freeze, "Manifest.txt".freeze, "README.txt".freeze] s.files = [".autotest".freeze, ".travis.yml".freeze, "History.txt".freeze, "Manifest.txt".freeze, "README.txt".freeze, "Rakefile".freeze, "lib/net/http/digest_auth.rb".freeze, "sample/auth_server.rb".freeze, "sample/net_http_example.rb".freeze, "test/test_net_http_digest_auth.rb".freeze] s.homepage = "http://github.com/drbrain/net-http-digest_auth".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--main".freeze, "README.txt".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) s.rubygems_version = "2.5.2.1".freeze s.summary = "An implementation of RFC 2617 - Digest Access Authentication".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q.freeze, ["~> 3.15"]) s.add_development_dependency(%q.freeze, ["~> 5.8"]) s.add_development_dependency(%q.freeze, ["~> 4.0"]) else s.add_dependency(%q.freeze, ["~> 3.15"]) s.add_dependency(%q.freeze, ["~> 5.8"]) s.add_dependency(%q.freeze, ["~> 4.0"]) end else s.add_dependency(%q.freeze, ["~> 3.15"]) s.add_dependency(%q.freeze, ["~> 5.8"]) s.add_dependency(%q.freeze, ["~> 4.0"]) end end