| 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 |  | -  |