0008-Add-ssh-agent-authentification-options-to-ssh-auth.patch

Jean-Philippe Garcia Ballester, 04/23/2013 10:05 AM

Download (7.53 KB)

View differences:

src/authm_mad/remotes/ssh/ssh_auth.rb
35 35
    #
36 36
    # @param [Hash] default options for path
37 37
    # @option options [String] :public_key public key for the user
38
    # @option options [String] :private_key key private key for the user.
38
    # @option options [String] :private_key key private key for the user
39
    # @option options [Boolean] :ssh_agent use ssh agent
39 40
    def initialize(options={})
40 41
        @private_key = nil
41 42
        @public_key  = nil
42 43

  
43
        @private_key  = read_key(options[:private_key])
44
        @public_key  = read_key(options[:public_key])
45
        if @public_key.nil? and not @private_key.nil?
46
            # Init ssh keys using private key. public key is extracted in a
47
            # format compatible with openssl.
48
            @public_key = @private_key.public_key
44
        if options[:ssh_agent]
45
            @agent, @public_key = read_agent_key(options[:private_key])
46
        else
47
            @private_key  = read_key(options[:private_key])
48
            @public_key  = read_key(options[:public_key])
49
            if @public_key.nil? and not @private_key.nil?
50
                # Init ssh keys using private key. public key is extracted in a
51
                # format compatible with openssl.
52
                @public_key = @private_key.public_key
53
            end
49 54
        end
50 55

  
51 56
        if @private_key.nil? && @public_key.nil?
52
            raise "You have to define at least one of the keys"
57
            raise "You have to define at least one of the keys, or use a ssh agent"
53 58
        end
54 59
    end
55 60

  
......
137 142
        end unless path_or_key.nil?
138 143
    end
139 144

  
145
    # Read a public key from an ssh agent and returns it in OpenSSL::PKey::RSA
146
    # object
147
    # identity_comment is the comment of the public key to retrieve
148
    # if nil, the first key is used
149
    def read_agent_key(identity_comment = nil)
150
        begin
151
            agent = Net::SSH::Authentication::Agent.connect
152
            identities = agent.identities
153
            public_key = if identity_comment
154
                             identities.find do |identity|
155
                                 identity.comment == identity_comment
156
                             end
157
                         else
158
                             identities.first
159
                         end
160
            raise "Cannot find key #{identity_comment} in agent" if public_key.nil? and not identity_comment.nil?
161
            [agent, public_key]
162
        rescue Net::SSH::Authentication::AgentError
163
            raise "Cannot connect to ssh agent"
164
        end
165
    end
166

  
140 167
    # Signs data with the private key of the user and returns
141 168
    # base 64 encoded signature in a single line
142 169
    def sign(data)
143
        sig = @private_key.ssh_do_sign(data)
170
        sig = if @agent
171
                  b = Net::SSH::Buffer.new(@agent.sign(@public_key, data))
172
                  b.read_string # remove description
173
                  b.read_string
174
              else
175
                  @private_key.ssh_do_sign(data)
176
              end
144 177
        Base64::encode64(sig).gsub!(/\n/, '').strip
145 178
    end
146 179

  
src/cli/one_helper/oneuser_helper.rb
59 59
        when OpenNebula::User::SSH_AUTH
60 60
            require 'opennebula/ssh_auth'
61 61

  
62
            options[:key]  ||= ENV['HOME']+'/.ssh/id_rsa'
62
            options[:ssh_agent] ||= true if ENV['SSH_AUTH_SOCK'] and not options[:key]
63
            options[:key]  ||= ENV['HOME']+'/.ssh/id_rsa' unless options[:ssh_agent]
63 64

  
64 65
            begin
65
                auth = OpenNebula::SshAuth.new(:private_key=>options[:key])
66
                auth_options = {}
67
                auth_options[:private_key] = options[:key] unless options[:key].nil?
68
                auth_options[:ssh_agent] = options[:ssh_agent] unless options[:ssh_agent].nil?
69
                auth = OpenNebula::SshAuth.new(auth_options)
66 70
            rescue Exception => e
67 71
                return -1, e.message
68 72
            end
......
93 97
        when OpenNebula::User::SSH_AUTH
94 98
            require 'opennebula/ssh_auth'
95 99

  
96
            options[:key]  ||= ENV['HOME']+'/.ssh/id_rsa'
100
            options[:ssh_agent] ||= true if ENV['SSH_AUTH_SOCK'] and not options[:key]
101
            options[:key]  ||= ENV['HOME']+'/.ssh/id_rsa' unless options[:ssh_agent]
97 102

  
98 103
            begin
99
                auth = OpenNebula::SshAuth.new(:private_key=>options[:key])
104
                auth_options = {}
105
                auth_options[:private_key] = options[:key] unless options[:key].nil?
106
                auth_options[:ssh_agent] = options[:ssh_agent] unless options[:ssh_agent].nil?
107
                auth = OpenNebula::SshAuth.new(auth_options)
100 108
            rescue Exception => e
101 109
                return -1, e.message
102 110
            end
src/cli/oneuser
102 102
        :description => "Path to the Private Key of the User"
103 103
    }
104 104

  
105
    SSH_AGENT={
106
        :name => "ssh-agent",
107
        :large => "--ssh-agent",
108
        :description => "Use an SSH agent to authenticate",
109
        :proc => lambda { |o, options|
110
            options[:ssh_agent] = true
111
        }
112
    }
113

  
105 114
    CERT={
106 115
        :name => "cert",
107 116
        :short => "-c path_to_user_cert_pem",
......
132 141
    }
133 142

  
134 143
    create_options = [READ_FILE, SHA1, SSH, X509, KEY, CERT, DRIVER]
135
    login_options  = [SSH, X509, X509_PROXY, KEY, CERT, PROXY, TIME]
144
    login_options  = [SSH, X509, X509_PROXY, KEY, SSH_AGENT, CERT, PROXY, TIME]
136 145

  
137 146
    ########################################################################
138 147
    # Formatters for arguments
......
308 317
        Creates the Login token for authentication
309 318
        Examples:
310 319
          oneuser login my_user --ssh --key /tmp/id_rsa --time 72000
320
          oneuser login my_user --ssh --ssh-agent --time 72000
321
          oneuser login my_user --ssh --ssh-agent --key /tmp/id_rsa --time 72000
311 322
          oneuser login my_user --x509 --cert /tmp/my_cert.pem
312 323
                                --key /tmp/my_key.pk --time 72000
313 324
          oneuser login my_user --x509_proxy --proxy /tmp/my_cert.pem
......
325 336
        for the SSH authentication mechanism.
326 337
    EOT
327 338

  
328
    command :key, key_desc, :options=>[KEY] do
339
    command :key, key_desc, :options=>[KEY, SSH_AGENT] do
329 340
        options[:driver] = OpenNebula::User::SSH_AUTH
330 341
        helper.password(options)
331 342
    end
332
-