1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
| | # -*- encoding: binary -*-
class Kgio::SSL
# Returns an array of klass objects from a PEM file in path.
# klass should either be OpenSSL::X509::Certificate or OpenSSL::RSA::PKey
# This method is used internally by Flipper.ssl_context. We may change or
# remove it in the future; do not rely on it directly
def self.split_pem(klass, path) # :nodoc:
rv = []
IO.read(path).gsub!(/^-----BEGIN.+?-----END[^\n]+-----$/m) do |m|
rv << klass.new(m)
end
rv
end
# See Kgio::PipeMethods#kgio_write
def kgio_write(string)
case rc = kgio_trywrite(string)
when :wait_writable
@to_io.kgio_wait_writable
when :wait_readable
@to_io.kgio_wait_readable
when nil
return
when String
string = rc
end while true
end
# See Kgio::PipeMethods#kgio_peek
def kgio_peek(maxlen, buffer = "")
case rc = kgio_trypeek(maxlen, buffer)
when :wait_writable
@to_io.kgio_wait_writable
when :wait_readable
@to_io.kgio_wait_readable
else
return rc
end while true
end
# See Kgio::PipeMethods#kgio_read
def kgio_read(maxlen, buffer = "")
case rc = kgio_tryread(maxlen, buffer)
when :wait_writable
@to_io.kgio_wait_writable
when :wait_readable
@to_io.kgio_wait_readable
else
return rc
end while true
end
# See Kgio::PipeMethods#kgio_read!
def kgio_read!(maxlen, buffer = "")
kgio_read(maxlen, buffer) || raise(EOFError, "end of file reached", [])
end
# Synchronously closes the SSL connection, waiting up to +limit+
# seconds for an orderly shutdown before doing a hard shutdown.
#
# Returns +nil+ on success, will raise IOError if descriptor is
# already closed.
def kgio_close(limit = 30)
expires = Time.now + limit
case kgio_tryclose
when :wait_readable
limit = expires - Time.now
0 > limit and return @to_io.close
@to_io.kgio_wait_readable(limit)
when :wait_writable
limit = expires - Time.now
0 > limit and return @to_io.close
@to_io.kgio_wait_writable(limit)
else # nil or false, return nil regardless for IO#close compat
return
end while true
end
# :stopdoc:
# constants for garbage reduction
HEXFMT = "%02X"
HEXPACK = "H*"
LFTAB = "\n\t"
# :startdoc:
# Returns the SSL client certificate serial number as a hexadecimal string
# Raises NoMethodError if client did not send a peer certificate
# This matches the nginx variable of the same name.
def ssl_client_serial
sprintf(HEXFMT, peer_cert.serial.to_i)
end
# Returns the subject Distinguished Name of the client peer certificate
# Raises NoMethodError if client did not send a peer certificate
# This matches the nginx variable of the same name.
def ssl_client_s_dn
peer_cert.subject.to_s
end
# Returns the issuer Distinguished Name of the client peer certificate
# Raises NoMethodError if client did not send a peer certificate
# This matches the nginx variable of the same name.
def ssl_client_i_dn
peer_cert.issuer.to_s
end
# Returns a hex-encoded string representing the SSL session ID
# This matches the nginx variable of the same name.
def ssl_session_id
session.to_der.unpack(HEXPACK)[0]
end
# Returns the client certificate in PEM format.
# Raises NoMethodError if client did not send a peer certificate
# This matches the nginx variable of the same name.
def ssl_client_raw_cert
peer_cert.to_pem
end
# Returns the client certificate in PEM format in a format suitable for
# including in HTTP headers
# Raises NoMethodError if client did not send a peer certificate
# This matches the nginx variable of the same name.
def ssl_client_cert
ssl_client_raw_cert.gsub!(/\n/, LFTAB)
end
end
|