Module: WEBrick::Utils

Defined in:
lib/webrick/ssl.rb,
lib/webrick/utils.rb

Constant Summary collapse

RAND_CHARS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"0123456789" +
"abcdefghijklmnopqrstuvwxyz"

Class Method Summary collapse

Class Method Details

.create_listeners(address, port, logger = nil) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/webrick/utils.rb', line 59

def create_listeners(address, port, logger=nil)
  unless port
    raise ArgumentError, "must specify port"
  end
  res = Socket::getaddrinfo(address, port,
                            Socket::AF_UNSPEC,   # address family
                            Socket::SOCK_STREAM, # socket type
                            0,                   # protocol
                            Socket::AI_PASSIVE)  # flag
  last_error = nil
  sockets = []
  res.each{|ai|
    begin
      logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger
      sock = TCPServer.new(ai[3], port)
      port = sock.addr[1] if port == 0
      Utils::set_close_on_exec(sock)
      sockets << sock
    rescue => ex
      logger.warn("TCPServer Error: #{ex}") if logger
      last_error  = ex
    end
  }
  raise last_error if sockets.empty?
  return sockets
end

.create_self_signed_cert(bits, cn, comment) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/webrick/ssl.rb', line 39

def create_self_signed_cert(bits, cn, comment)
  rsa = OpenSSL::PKey::RSA.new(bits){|p, n|
    case p
    when 0; $stderr.putc "."  # BN_generate_prime
    when 1; $stderr.putc "+"  # BN_generate_prime
    when 2; $stderr.putc "*"  # searching good prime,  
                              # n = #of try,
                              # but also data from BN_generate_prime
    when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
                              # but also data from BN_generate_prime
    else;   $stderr.putc "*"  # BN_generate_prime
    end
  }
  cert = OpenSSL::X509::Certificate.new
  cert.version = 3
  cert.serial = 0
  name = OpenSSL::X509::Name.new(cn)
  cert.subject = name
  cert.issuer = name
  cert.not_before = Time.now
  cert.not_after = Time.now + (365*24*60*60)
  cert.public_key = rsa.public_key

  ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
  ef.issuer_certificate = cert
  cert.extensions = [
    ef.create_extension("basicConstraints","CA:FALSE"),
    ef.create_extension("keyUsage", "keyEncipherment"),
    ef.create_extension("subjectKeyIdentifier", "hash"),
    ef.create_extension("extendedKeyUsage", "serverAuth"),
    ef.create_extension("nsComment", comment),
  ]
  aki = ef.create_extension("authorityKeyIdentifier",
                            "keyid:always,issuer:always")
  cert.add_extension(aki)
  cert.sign(rsa, OpenSSL::Digest::SHA1.new)

  return [ cert, rsa ]
end

.getservernameObject



49
50
51
52
53
54
55
56
# File 'lib/webrick/utils.rb', line 49

def getservername
  host = Socket::gethostname
  begin
    Socket::gethostbyname(host)[0]
  rescue
    host
  end
end

.random_string(len) ⇒ Object



91
92
93
94
95
96
# File 'lib/webrick/utils.rb', line 91

def random_string(len)
  rand_max = RAND_CHARS.size
  ret = "" 
  len.times{ ret << RAND_CHARS[rand(rand_max)] }
  ret 
end

.set_close_on_exec(io) ⇒ Object



30
31
32
33
34
# File 'lib/webrick/utils.rb', line 30

def set_close_on_exec(io)
  if defined?(Fcntl::FD_CLOEXEC)
    io.fcntl(Fcntl::FD_CLOEXEC, 1)
  end
end

.set_non_blocking(io) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/webrick/utils.rb', line 21

def set_non_blocking(io)
  flag = File::NONBLOCK
  if defined?(Fcntl::F_GETFL)
    flag |= io.fcntl(Fcntl::F_GETFL)
  end
  io.fcntl(Fcntl::F_SETFL, flag)
end

.su(user) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/webrick/utils.rb', line 37

def su(user)
  if defined?(Etc)
    pw = Etc.getpwnam(user)
    Process::initgroups(user, pw.gid)
    Process::Sys::setgid(pw.gid)
    Process::Sys::setuid(pw.uid)
  else
    warn("WEBrick::Utils::su doesn't work on this platform")
  end
end