webrick 1.4.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 679fbeaf42fd0e9df98934eacf8573238f0b32a5bdcab66cb6ded69c3031ca8d
4
- data.tar.gz: 77811219317b65fdbc1a3f703d98dc63c9c6d936ef29775cbef7e1aa1f707007
3
+ metadata.gz: 800e0427bf3a5f03799b0615f21888ef4827fde35a89663bcf90c055bf4e2221
4
+ data.tar.gz: ea2b6bdee1ae775c2946e6b16e73a3dbcd18ab27d910cc11eeb72f6eafdc3242
5
5
  SHA512:
6
- metadata.gz: 4bce582ecef05a51ae39d331f6cf2a3a1f35bd5bde35ea69be01374ec9dc851a536fbb37ea276d37f137d86d8af2258b0caf34b30dce83f3a79d36e88b2cfefc
7
- data.tar.gz: 1c4fa49ececffec80b3d3ab8013960379d157202ba4b81959d6bcd91f0dcc978fcc55d60628d2383b8b80c7d1c4ce6b4dc5ca067ea548d0e20ce643d3cb26067
6
+ metadata.gz: 5d5511564c5ea1ff1eaf936af515acdaff9b157b767093b13e873a38596470bc42cab4a6be97770856e87d91b069ee05716e73dfea88d165a435737e332fb0f4
7
+ data.tar.gz: a2eaabfc8c4e16303a59cf45de503aaf71577824a8fb92dc2ad60cc4f5fc2478e707635062ed9abc138e260fbc7bea0cc999f8033e5a0f59deeb0e697ec47c1a
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Webrick
2
+
3
+ WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server.
4
+
5
+ WEBrick features complete logging of both server operations and HTTP access.
6
+
7
+ WEBrick supports both basic and digest authentication in addition to algorithms not in RFC 2617.
8
+
9
+ A WEBrick server can be composed of multiple WEBrick servers or servlets to provide differing behavior on a per-host or per-path basis. WEBrick includes servlets for handling CGI scripts, ERB pages, Ruby blocks and directory listings.
10
+
11
+ WEBrick also includes tools for daemonizing a process and starting a process at a higher privilege level and dropping permissions.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'webrick'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install webrick
28
+
29
+ ## Usage
30
+
31
+ To create a new WEBrick::HTTPServer that will listen to connections on port 8000 and serve documents from the current user's public_html folder:
32
+
33
+ ```ruby
34
+ require 'webrick'
35
+
36
+ root = File.expand_path '~/public_html'
37
+ server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root
38
+ ```
39
+
40
+ To run the server you will need to provide a suitable shutdown hook as
41
+ starting the server blocks the current thread:
42
+
43
+ ```ruby
44
+ trap 'INT' do server.shutdown end
45
+
46
+ server.start
47
+ ```
48
+
49
+ ## Development
50
+
51
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
52
+
53
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
54
+
55
+ ## Contributing
56
+
57
+ Bug reports and Patch are welcome on https://bugs.ruby-lang.org/.
58
+
59
+ ## License
60
+
61
+ The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test" << "test/lib"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/test_*.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "webrick"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/webrick.rb CHANGED
@@ -15,6 +15,11 @@
15
15
  # WEBrick also includes tools for daemonizing a process and starting a process
16
16
  # at a higher privilege level and dropping permissions.
17
17
  #
18
+ # == Security
19
+ #
20
+ # *Warning:* WEBrick is not recommended for production. It only implements
21
+ # basic security checks.
22
+ #
18
23
  # == Starting an HTTP server
19
24
  #
20
25
  # To create a new WEBrick::HTTPServer that will listen to connections on port
@@ -139,9 +144,9 @@
139
144
  # servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and
140
145
  # WEBrick::HTTPAuth::DigestAuth.
141
146
  #
142
- # == WEBrick as a Production Web Server
147
+ # == WEBrick as a daemonized Web Server
143
148
  #
144
- # WEBrick can be run as a production server for small loads.
149
+ # WEBrick can be run as a daemonized server for small loads.
145
150
  #
146
151
  # === Daemonizing
147
152
  #
@@ -212,7 +217,7 @@ require 'webrick/version.rb'
212
217
  require 'webrick/config.rb'
213
218
  require 'webrick/log.rb'
214
219
  require 'webrick/server.rb'
215
- require 'webrick/utils.rb'
220
+ require_relative 'webrick/utils.rb'
216
221
  require 'webrick/accesslog'
217
222
 
218
223
  require 'webrick/htmlutils.rb'
@@ -149,11 +149,9 @@ module WEBrick
149
149
  # Escapes control characters in +data+
150
150
 
151
151
  def escape(data)
152
- if data.tainted?
153
- data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}.untaint
154
- else
155
- data
156
- end
152
+ data = data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}
153
+ data.untaint if RUBY_VERSION < '2.7'
154
+ data
157
155
  end
158
156
  end
159
157
  end
data/lib/webrick/cgi.rb CHANGED
@@ -8,9 +8,9 @@
8
8
  #
9
9
  # $Id$
10
10
 
11
- require "webrick/httprequest"
12
- require "webrick/httpresponse"
13
- require "webrick/config"
11
+ require_relative "httprequest"
12
+ require_relative "httpresponse"
13
+ require_relative "config"
14
14
  require "stringio"
15
15
 
16
16
  module WEBrick
@@ -265,6 +265,10 @@ module WEBrick
265
265
  @out_port << data
266
266
  end
267
267
 
268
+ def write(data)
269
+ @out_port.write(data)
270
+ end
271
+
268
272
  def cert
269
273
  return nil unless defined?(OpenSSL)
270
274
  if pem = @env["SSL_SERVER_CERT"]
@@ -9,11 +9,11 @@
9
9
  #
10
10
  # $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $
11
11
 
12
- require 'webrick/version'
13
- require 'webrick/httpversion'
14
- require 'webrick/httputils'
15
- require 'webrick/utils'
16
- require 'webrick/log'
12
+ require_relative 'version'
13
+ require_relative 'httpversion'
14
+ require_relative 'httputils'
15
+ require_relative 'utils'
16
+ require_relative 'log'
17
17
 
18
18
  module WEBrick
19
19
  module Config
@@ -10,7 +10,7 @@
10
10
  # $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $
11
11
 
12
12
  require 'time'
13
- require 'webrick/httputils'
13
+ require_relative 'httputils'
14
14
 
15
15
  module WEBrick
16
16
 
@@ -9,11 +9,11 @@
9
9
  #
10
10
  # $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $
11
11
 
12
- require 'webrick/httpauth/basicauth'
13
- require 'webrick/httpauth/digestauth'
14
- require 'webrick/httpauth/htpasswd'
15
- require 'webrick/httpauth/htdigest'
16
- require 'webrick/httpauth/htgroup'
12
+ require_relative 'httpauth/basicauth'
13
+ require_relative 'httpauth/digestauth'
14
+ require_relative 'httpauth/htpasswd'
15
+ require_relative 'httpauth/htdigest'
16
+ require_relative 'httpauth/htgroup'
17
17
 
18
18
  module WEBrick
19
19
 
@@ -85,7 +85,7 @@ module WEBrick
85
85
  def log(meth, fmt, *args)
86
86
  msg = format("%s %s: ", @auth_scheme, @realm)
87
87
  msg << fmt % args
88
- @logger.send(meth, msg)
88
+ @logger.__send__(meth, msg)
89
89
  end
90
90
 
91
91
  def error(fmt, *args)
@@ -8,9 +8,9 @@
8
8
  #
9
9
  # $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
10
10
 
11
- require 'webrick/config'
12
- require 'webrick/httpstatus'
13
- require 'webrick/httpauth/authenticator'
11
+ require_relative '../config'
12
+ require_relative '../httpstatus'
13
+ require_relative 'authenticator'
14
14
 
15
15
  module WEBrick
16
16
  module HTTPAuth
@@ -24,7 +24,7 @@ module WEBrick
24
24
  #
25
25
  # config = { :Realm => 'BasicAuth example realm' }
26
26
  #
27
- # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
27
+ # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file', password_hash: :bcrypt
28
28
  # htpasswd.set_passwd config[:Realm], 'username', 'password'
29
29
  # htpasswd.flush
30
30
  #
@@ -81,7 +81,15 @@ module WEBrick
81
81
  error("%s: the user is not allowed.", userid)
82
82
  challenge(req, res)
83
83
  end
84
- if password.crypt(encpass) != encpass
84
+
85
+ case encpass
86
+ when /\A\$2[aby]\$/
87
+ password_matches = BCrypt::Password.new(encpass.sub(/\A\$2[aby]\$/, '$2a$')) == password
88
+ else
89
+ password_matches = password.crypt(encpass) == encpass
90
+ end
91
+
92
+ unless password_matches
85
93
  error("%s: password unmatch.", userid)
86
94
  challenge(req, res)
87
95
  end
@@ -12,9 +12,9 @@
12
12
  #
13
13
  # $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $
14
14
 
15
- require 'webrick/config'
16
- require 'webrick/httpstatus'
17
- require 'webrick/httpauth/authenticator'
15
+ require_relative '../config'
16
+ require_relative '../httpstatus'
17
+ require_relative 'authenticator'
18
18
  require 'digest/md5'
19
19
  require 'digest/sha1'
20
20
 
@@ -235,9 +235,11 @@ module WEBrick
235
235
  ha2 = hexdigest(req.request_method, auth_req['uri'])
236
236
  ha2_res = hexdigest("", auth_req['uri'])
237
237
  elsif auth_req['qop'] == "auth-int"
238
- ha2 = hexdigest(req.request_method, auth_req['uri'],
239
- hexdigest(req.body))
240
- ha2_res = hexdigest("", auth_req['uri'], hexdigest(res.body))
238
+ body_digest = @h.new
239
+ req.body { |chunk| body_digest.update(chunk) }
240
+ body_digest = body_digest.hexdigest
241
+ ha2 = hexdigest(req.request_method, auth_req['uri'], body_digest)
242
+ ha2_res = hexdigest("", auth_req['uri'], body_digest)
241
243
  end
242
244
 
243
245
  if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
@@ -288,23 +290,8 @@ module WEBrick
288
290
 
289
291
  def split_param_value(string)
290
292
  ret = {}
291
- while string.bytesize != 0
292
- case string
293
- when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/
294
- key = $1
295
- matched = $2
296
- string = $'
297
- ret[key] = matched.gsub(/\\(.)/, "\\1")
298
- when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/
299
- key = $1
300
- matched = $2
301
- string = $'
302
- ret[key] = matched.clone
303
- when /^s*^,/
304
- string = $'
305
- else
306
- break
307
- end
293
+ string.scan(/\G\s*([\w\-.*%!]+)=\s*(?:\"((?>\\.|[^\"])*)\"|([^,\"]*))\s*,?/) do
294
+ ret[$1] = $3 || $2.gsub(/\\(.)/, "\\1")
308
295
  end
309
296
  ret
310
297
  end
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
10
10
 
11
- require 'webrick/httpauth/userdb'
12
- require 'webrick/httpauth/digestauth'
11
+ require_relative 'userdb'
12
+ require_relative 'digestauth'
13
13
  require 'tempfile'
14
14
 
15
15
  module WEBrick
@@ -63,15 +63,18 @@ module WEBrick
63
63
 
64
64
  def flush(output=nil)
65
65
  output ||= @path
66
- tmp = Tempfile.new("htgroup", File::dirname(output))
66
+ tmp = Tempfile.create("htgroup", File::dirname(output))
67
67
  begin
68
68
  @group.keys.sort.each{|group|
69
69
  tmp.puts(format("%s: %s", group, self.members(group).join(" ")))
70
70
  }
71
+ ensure
71
72
  tmp.close
72
- File::rename(tmp.path, output)
73
- rescue
74
- tmp.close(true)
73
+ if $!
74
+ File.unlink(tmp.path)
75
+ else
76
+ return File.rename(tmp.path, output)
77
+ end
75
78
  end
76
79
  end
77
80
 
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
10
10
 
11
- require 'webrick/httpauth/userdb'
12
- require 'webrick/httpauth/basicauth'
11
+ require_relative 'userdb'
12
+ require_relative 'basicauth'
13
13
  require 'tempfile'
14
14
 
15
15
  module WEBrick
@@ -35,11 +35,29 @@ module WEBrick
35
35
  ##
36
36
  # Open a password database at +path+
37
37
 
38
- def initialize(path)
38
+ def initialize(path, password_hash: nil)
39
39
  @path = path
40
40
  @mtime = Time.at(0)
41
41
  @passwd = Hash.new
42
42
  @auth_type = BasicAuth
43
+ @password_hash = password_hash
44
+
45
+ case @password_hash
46
+ when nil
47
+ # begin
48
+ # require "string/crypt"
49
+ # rescue LoadError
50
+ # warn("Unable to load string/crypt, proceeding with deprecated use of String#crypt, consider using password_hash: :bcrypt")
51
+ # end
52
+ @password_hash = :crypt
53
+ when :crypt
54
+ # require "string/crypt"
55
+ when :bcrypt
56
+ require "bcrypt"
57
+ else
58
+ raise ArgumentError, "only :crypt and :bcrypt are supported for password_hash keyword argument"
59
+ end
60
+
43
61
  File.open(@path,"a").close unless File.exist?(@path)
44
62
  reload
45
63
  end
@@ -56,6 +74,14 @@ module WEBrick
56
74
  line.chomp!
57
75
  case line
58
76
  when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z!
77
+ if @password_hash == :bcrypt
78
+ raise StandardError, ".htpasswd file contains crypt password, only bcrypt passwords supported"
79
+ end
80
+ user, pass = line.split(":")
81
+ when %r!\A[^:]+:\$2[aby]\$\d{2}\$.{53}\z!
82
+ if @password_hash == :crypt
83
+ raise StandardError, ".htpasswd file contains bcrypt password, only crypt passwords supported"
84
+ end
59
85
  user, pass = line.split(":")
60
86
  when /:\$/, /:{SHA}/
61
87
  raise NotImplementedError,
@@ -102,7 +128,14 @@ module WEBrick
102
128
  # Sets a password in the database for +user+ in +realm+ to +pass+.
103
129
 
104
130
  def set_passwd(realm, user, pass)
105
- @passwd[user] = make_passwd(realm, user, pass)
131
+ if @password_hash == :bcrypt
132
+ # Cost of 5 to match Apache default, and because the
133
+ # bcrypt default of 10 will introduce significant delays
134
+ # for every request.
135
+ @passwd[user] = BCrypt::Password.create(pass, :cost=>5)
136
+ else
137
+ @passwd[user] = make_passwd(realm, user, pass)
138
+ end
106
139
  end
107
140
 
108
141
  ##