]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
charon-cmd: Add --agent option to authenticate using ssh-agent(1)
authorTobias Brunner <tobias@strongswan.org>
Mon, 1 Apr 2013 12:51:09 +0000 (14:51 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 7 May 2013 12:08:51 +0000 (14:08 +0200)
The socket path is read from the SSH_AUTH_SOCK environment variable.
So using this with sudo might require the -E command line (or an appropriate
sudoers config) to preserve the environment.

src/charon-cmd/cmd/cmd_connection.c
src/charon-cmd/cmd/cmd_creds.c
src/charon-cmd/cmd/cmd_options.c
src/charon-cmd/cmd/cmd_options.h

index 0aedf76cea6acd94917a8a6936f7af1279fb5bd7..8b42befe964c07603a4d3074c175f13b0e028c3a 100644 (file)
@@ -387,6 +387,7 @@ METHOD(cmd_connection_t, handle, bool,
                        this->identity = arg;
                        break;
                case CMD_OPT_RSA:
+               case CMD_OPT_AGENT:
                        this->key_seen = TRUE;
                        break;
                case CMD_OPT_LOCAL_TS:
index b704909156424c9d2b897bd9075177d8ac6a580c..178b77d49d2538c14ad3b064127461ad503e27f9 100644 (file)
@@ -47,6 +47,16 @@ struct private_cmd_creds_t {
         * Already prompted for password?
         */
        bool prompted;
+
+       /**
+        * Provide keys via ssh-agent
+        */
+       bool agent;
+
+       /**
+        * Local identity
+        */
+       char *identity;
 };
 
 /**
@@ -119,6 +129,54 @@ static void load_key(private_cmd_creds_t *this, key_type_t type, char *path)
        this->creds->add_key(this->creds, privkey);
 }
 
+/**
+ * Load a private and public key via ssh-agent
+ */
+static void load_agent(private_cmd_creds_t *this)
+{
+       private_key_t *privkey;
+       public_key_t *pubkey;
+       identification_t *id;
+       certificate_t *cert;
+       char *agent;
+
+       agent = getenv("SSH_AUTH_SOCK");
+       if (!agent)
+       {
+               DBG1(DBG_CFG, "ssh-agent socket not found");
+               exit(1);
+       }
+
+       privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+                                                                KEY_RSA, BUILD_AGENT_SOCKET, agent, BUILD_END);
+       if (!privkey)
+       {
+               DBG1(DBG_CFG, "failed to load private key from ssh-agent");
+               exit(1);
+       }
+       pubkey = privkey->get_public_key(privkey);
+       if (!pubkey)
+       {
+               DBG1(DBG_CFG, "failed to load public key from ssh-agent");
+               privkey->destroy(privkey);
+               exit(1);
+       }
+       id = identification_create_from_string(this->identity);
+       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+                                                         CERT_TRUSTED_PUBKEY, BUILD_PUBLIC_KEY, pubkey,
+                                                         BUILD_SUBJECT, id, BUILD_END);
+       pubkey->destroy(pubkey);
+       id->destroy(id);
+       if (!cert)
+       {
+               DBG1(DBG_CFG, "failed to create certificate for ssh-agent public key");
+               privkey->destroy(privkey);
+               exit(1);
+       }
+       this->creds->add_cert(this->creds, TRUE, cert);
+       this->creds->add_key(this->creds, privkey);
+}
+
 METHOD(cmd_creds_t, handle, bool,
        private_cmd_creds_t *this, cmd_option_type_t opt, char *arg)
 {
@@ -130,9 +188,19 @@ METHOD(cmd_creds_t, handle, bool,
                case CMD_OPT_RSA:
                        load_key(this, KEY_RSA, arg);
                        break;
+               case CMD_OPT_IDENTITY:
+                       this->identity = arg;
+                       break;
+               case CMD_OPT_AGENT:
+                       this->agent = TRUE;
+                       break;
                default:
                        return FALSE;
        }
+       if (this->agent && this->identity)
+       {
+               load_agent(this);
+       }
        return TRUE;
 }
 
index 312d12964249cc4e782f446aa02c613befc1f4d6..6b7df6d93e4d3f52a809854f43758a74e7aeb020 100644 (file)
@@ -35,6 +35,8 @@ cmd_option_t cmd_options[CMD_OPT_COUNT] = {
          "trusted certificate, for authentication or trust chain validation" },
        { CMD_OPT_RSA, "rsa", required_argument, "path",
          "RSA private key to use for authentication" },
+       { CMD_OPT_AGENT, "agent", no_argument, "",
+         "use SSH agent for authentication"},
        { CMD_OPT_LOCAL_TS, "local-ts", required_argument, "subnet",
          "additional traffic selector to propose for our side" },
        { CMD_OPT_REMOTE_TS, "remote-ts", required_argument, "subnet",
index addbb50d81ebaf7cdbf2a025c876f3223dc21ffd..a14896f8313ccf4329b73a8ef042a52ea21ad4fe 100644 (file)
@@ -35,6 +35,7 @@ enum cmd_option_type_t {
        CMD_OPT_REMOTE_IDENTITY,
        CMD_OPT_CERT,
        CMD_OPT_RSA,
+       CMD_OPT_AGENT,
        CMD_OPT_LOCAL_TS,
        CMD_OPT_REMOTE_TS,
        CMD_OPT_PROFILE,