stroke: Cache passwords so the user is not prompted multiple times for the same password
authorTobias Brunner <tobias@strongswan.org>
Wed, 17 Apr 2013 13:54:23 +0000 (15:54 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 May 2013 13:02:41 +0000 (15:02 +0200)
To verify/decrypt a PKCS#12 container a password might be needed
multiple times.  If it was entered correctly we don't want to bother the
user again with another password prompt.
The passwords for MAC creation and encryption could be different so the
user might be prompted multiple times after all.

src/libcharon/plugins/stroke/stroke_cred.c

index 84d2262..5f8911f 100644 (file)
@@ -600,6 +600,8 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line)
  * Data for passphrase callback
  */
 typedef struct {
+       /** cached passphrases */
+       mem_cred_t *cache;
        /** socket we use for prompting */
        FILE *prompt;
        /** type of secret to unlock */
@@ -618,6 +620,7 @@ static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
                                                                   identification_t *other, id_match_t *match_me,
                                                                   id_match_t *match_other)
 {
+       shared_key_t *shared;
        chunk_t secret;
        char buf[256];
 
@@ -654,7 +657,10 @@ static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
                        {
                                *match_other = ID_MATCH_NONE;
                        }
-                       return shared_key_create(SHARED_PRIVATE_KEY_PASS, chunk_clone(secret));
+                       shared = shared_key_create(SHARED_PRIVATE_KEY_PASS,
+                                                                          chunk_clone(secret));
+                       data->cache->add_shared(data->cache, shared->get_ref(shared), NULL);
+                       return shared;
                }
        }
        return NULL;
@@ -885,6 +891,10 @@ static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
                        *result = NULL;
                        return TRUE;
                }
+               /* add cache first so if valid passphrases are needed multiple times
+                * the callback is not called anymore */
+               pp_data.cache = mem_cred_create();
+               lib->credmgr->add_local_set(lib->credmgr, &pp_data.cache->set, FALSE);
                /* use callback credential set to prompt for the passphrase */
                cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
                lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
@@ -894,6 +904,8 @@ static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
 
                lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
                cb->destroy(cb);
+               lib->credmgr->remove_local_set(lib->credmgr, &pp_data.cache->set);
+               pp_data.cache->destroy(pp_data.cache);
        }
        else
        {