Bug #559670: Aqbanking should not ask for already accepted certificates.

Add support for AqBanking's permanently accepted SSL certificates

This patch fixes part of the problem for AqBanking 4.x (or newer).
The patch queries the certificates that have been accepted during the AqBanking
setup procedure. A hash of every single such certificate is stored by AqBanking
4.x under $HOME/.aqbanking/settings/shared/certs.conf.

For older versions of AqBanking the patch does nothing (yet). The main
difference is where AqBanking stores the hashes for such certificates. I've
added a FIXME comment on the appropriate place where code for older AqBanking
versions should be added.

Patch by Micha Lenk, slightly modified by me.

Signed-off-by: Christian Stimming <stimming@tuhh.de>
BP

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18037 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming 2009-04-10 20:20:11 +00:00
parent 0591867447
commit b810924125
3 changed files with 56 additions and 2 deletions

View File

@ -804,3 +804,24 @@ gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci)
return gnc_gen_trans_list_run(ieci->generic_importer); return gnc_gen_trans_list_run(ieci->generic_importer);
} }
GWEN_DB_NODE *
gnc_ab_get_permanent_certs(void)
{
int rv;
GWEN_DB_NODE *perm_certs = NULL;
AB_BANKING *banking = gnc_AB_BANKING_new();
g_return_val_if_fail(banking, NULL);
#ifdef AQBANKING_VERSION_4_PLUS
rv = AB_Banking_LoadSharedConfig(banking, "certs", &perm_certs, 0);
#else
/* FIXME: Add code for older AqBanking versions */
/* See QBankmanager 0.9.50 in src/kbanking/libs/kbanking.cpp lines 323ff
for a proper example of how to do this */
rv = 0;
#endif
gnc_AB_BANKING_fini(banking);
g_return_val_if_fail(rv >= 0, NULL);
return perm_certs;
}

View File

@ -225,6 +225,14 @@ AB_JOB_LIST2 *gnc_ab_ieci_get_job_list(GncABImExContextImport *ieci);
*/ */
gboolean gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci); gboolean gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci);
/**
* get the GWEN_DB_NODE from AqBanking configuration files
*
* @return a GWEN_DB containing all permanently accepted SSL certificates (hashed).
*/
GWEN_DB_NODE *gnc_ab_get_permanent_certs(void);
G_END_DECLS G_END_DECLS
/** @} */ /** @} */

View File

@ -184,6 +184,7 @@ struct _GncGWENGui {
/* Certificates handling */ /* Certificates handling */
GHashTable *accepted_certs; GHashTable *accepted_certs;
GWEN_DB_NODE *permanently_accepted_certs;
GWEN_GUI_CHECKCERT_FN builtin_checkcert; GWEN_GUI_CHECKCERT_FN builtin_checkcert;
/* Dialogs */ /* Dialogs */
@ -285,6 +286,8 @@ gnc_GWEN_Gui_shutdown(void)
g_hash_table_destroy(gui->passwords); g_hash_table_destroy(gui->passwords);
if (gui->showbox_hash) if (gui->showbox_hash)
g_hash_table_destroy(gui->showbox_hash); g_hash_table_destroy(gui->showbox_hash);
if (gui->permanently_accepted_certs)
GWEN_DB_Group_free(gui->permanently_accepted_certs);
if (gui->accepted_certs) if (gui->accepted_certs)
g_hash_table_destroy(gui->accepted_certs); g_hash_table_destroy(gui->accepted_certs);
gtk_widget_destroy(gui->dialog); gtk_widget_destroy(gui->dialog);
@ -371,6 +374,7 @@ setup_dialog(GncGWENGui *gui)
gui->close_button = glade_xml_get_widget(xml, "close_button"); gui->close_button = glade_xml_get_widget(xml, "close_button");
gui->close_checkbutton = glade_xml_get_widget(xml, "close_checkbutton"); gui->close_checkbutton = glade_xml_get_widget(xml, "close_checkbutton");
gui->accepted_certs = NULL; gui->accepted_certs = NULL;
gui->permanently_accepted_certs = NULL;
gui->showbox_hash = NULL; gui->showbox_hash = NULL;
gui->showbox_id = 1; gui->showbox_id = 1;
@ -448,6 +452,8 @@ reset_dialog(GncGWENGui *gui)
if (!gui->accepted_certs) if (!gui->accepted_certs)
gui->accepted_certs = g_hash_table_new_full( gui->accepted_certs = g_hash_table_new_full(
g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
if (!gui->permanently_accepted_certs)
gui->permanently_accepted_certs = gnc_ab_get_permanent_certs();
LEAVE(" "); LEAVE(" ");
} }
@ -1251,7 +1257,8 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
const gchar *hash, *status; const gchar *hash, *status;
struct md5_ctx md5_context; struct md5_ctx md5_context;
gchar cert_hash[16]; gchar cert_hash[16];
gint retval; gchar *cert_hash_hex;
gint retval, i;
g_return_val_if_fail(gui && gui->accepted_certs, -1); g_return_val_if_fail(gui && gui->accepted_certs, -1);
@ -1266,8 +1273,26 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert,
md5_process_bytes(status, strlen(status), &md5_context); md5_process_bytes(status, strlen(status), &md5_context);
md5_finish_ctx(&md5_context, cert_hash); md5_finish_ctx(&md5_context, cert_hash);
/* Did we get the permanently accepted certs from AqBanking? */
if (gui->permanently_accepted_certs) {
/* Generate a hex string of the cert_hash for usage by AqBanking cert store */
cert_hash_hex = g_new0(gchar, 33);
for (i = 0; i < 16; i++)
g_snprintf(cert_hash_hex+2*i, 3, "%02X", (unsigned char)cert_hash[i]);
retval=GWEN_DB_GetIntValue(gui->permanently_accepted_certs, cert_hash_hex, 0, -1);
g_free(cert_hash_hex);
if (retval == 0) {
/* Certificate is marked as accepted in AqBanking's cert store */
LEAVE("Certificate accepted by AqBanking's permanent cert store");
return 0;
}
} else {
g_warning("Can't check permanently accepted certs from invalid AqBanking cert store.");
}
if (g_hash_table_lookup(gui->accepted_certs, cert_hash)) { if (g_hash_table_lookup(gui->accepted_certs, cert_hash)) {
/* Certificate has been accepted before */ /* Certificate has been accepted by Gnucash before */
LEAVE("Automatically accepting certificate"); LEAVE("Automatically accepting certificate");
return 0; return 0;
} }