15 |
15 |
#--------------------------------------------------------------------------- #
|
16 |
16 |
|
17 |
17 |
|
|
18 |
require 'rubygems'
|
|
19 |
require 'net/ssh'
|
|
20 |
|
18 |
21 |
require 'pp'
|
19 |
22 |
require 'openssl'
|
20 |
23 |
require 'base64'
|
... | ... | |
67 |
70 |
# Generate security token
|
68 |
71 |
time = Time.now.to_i + expire.to_i
|
69 |
72 |
|
70 |
|
secret_plain = "#{user}:#{time}"
|
71 |
|
secret_crypted = encrypt(secret_plain)
|
|
73 |
secret_plain = "#{user};#{time}"
|
|
74 |
secret_signature = sign(secret_plain)
|
|
75 |
secret = "#{secret_plain}@#{secret_signature}"
|
72 |
76 |
|
73 |
|
proxy = "#{user}:#{secret_crypted}"
|
|
77 |
proxy = "#{user}:#{secret}"
|
74 |
78 |
|
75 |
79 |
file = File.open(LOGIN_PATH, "w")
|
76 |
80 |
file.write(proxy)
|
... | ... | |
78 |
82 |
|
79 |
83 |
File.chmod(0600,LOGIN_PATH)
|
80 |
84 |
|
81 |
|
secret_crypted
|
|
85 |
secret
|
82 |
86 |
end
|
83 |
87 |
|
84 |
88 |
# Returns a valid password string to create a user using this auth driver.
|
... | ... | |
92 |
96 |
# Checks the proxy created with the login method
|
93 |
97 |
def authenticate(user, token)
|
94 |
98 |
begin
|
95 |
|
token_plain = decrypt(token)
|
96 |
|
_user, time = token_plain.split(':')
|
|
99 |
plain_data, signed_data = token.split('@')
|
|
100 |
valid_sig = verify(signed_data, plain_data)
|
|
101 |
_user, time = plain_data.split(';')
|
97 |
102 |
|
98 |
|
if user == _user
|
|
103 |
if valid_sig && user == _user
|
99 |
104 |
if Time.now.to_i >= time.to_i
|
100 |
105 |
return "ssh proxy expired, login again to renew it"
|
101 |
106 |
else
|
... | ... | |
132 |
137 |
end unless path_or_key.nil?
|
133 |
138 |
end
|
134 |
139 |
|
135 |
|
# Encrypts data with the private key of the user and returns
|
136 |
|
# base 64 encoded output in a single line
|
137 |
|
def encrypt(data)
|
138 |
|
Base64::encode64(@private_key.private_encrypt(data)).gsub!(/\n/, '').strip
|
|
140 |
# Signs data with the private key of the user and returns
|
|
141 |
# base 64 encoded signature in a single line
|
|
142 |
def sign(data)
|
|
143 |
sig = if @agent
|
|
144 |
b = Net::SSH::Buffer.new(@agent.sign(@public_key, data))
|
|
145 |
b.read_string # remove description
|
|
146 |
b.read_string
|
|
147 |
else
|
|
148 |
@private_key.ssh_do_sign(data)
|
|
149 |
end
|
|
150 |
Base64::encode64(sig).gsub!(/\n/, '').strip
|
139 |
151 |
end
|
140 |
152 |
|
141 |
|
# Decrypts base 64 encoded data with pub_key (public key)
|
142 |
|
def decrypt(data)
|
143 |
|
@public_key.public_decrypt(Base64::decode64(data))
|
|
153 |
# Verify base 64 encoded signature of data with the public key of the
|
|
154 |
# user and returns true if signature is valid
|
|
155 |
def verify(sig, data)
|
|
156 |
@public_key.ssh_do_verify(Base64::decode64(sig), data)
|
144 |
157 |
end
|
145 |
158 |
end
|
146 |
|
-
|