From b81092412549e1dd8f44d11343cc525b7c105efe Mon Sep 17 00:00:00 2001 From: Christian Stimming Date: Fri, 10 Apr 2009 20:20:11 +0000 Subject: [PATCH] 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 BP git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18037 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/import-export/aqbanking/gnc-ab-utils.c | 21 ++++++++++++++++ src/import-export/aqbanking/gnc-ab-utils.h | 8 ++++++ src/import-export/aqbanking/gnc-gwen-gui.c | 29 ++++++++++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/import-export/aqbanking/gnc-ab-utils.c b/src/import-export/aqbanking/gnc-ab-utils.c index 348079c18d..f0a2c1e34c 100644 --- a/src/import-export/aqbanking/gnc-ab-utils.c +++ b/src/import-export/aqbanking/gnc-ab-utils.c @@ -804,3 +804,24 @@ gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci) 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; +} diff --git a/src/import-export/aqbanking/gnc-ab-utils.h b/src/import-export/aqbanking/gnc-ab-utils.h index 7f0125acfd..0ebb22de1c 100644 --- a/src/import-export/aqbanking/gnc-ab-utils.h +++ b/src/import-export/aqbanking/gnc-ab-utils.h @@ -225,6 +225,14 @@ AB_JOB_LIST2 *gnc_ab_ieci_get_job_list(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 /** @} */ diff --git a/src/import-export/aqbanking/gnc-gwen-gui.c b/src/import-export/aqbanking/gnc-gwen-gui.c index a2c80e43e8..701f40e2d9 100644 --- a/src/import-export/aqbanking/gnc-gwen-gui.c +++ b/src/import-export/aqbanking/gnc-gwen-gui.c @@ -184,6 +184,7 @@ struct _GncGWENGui { /* Certificates handling */ GHashTable *accepted_certs; + GWEN_DB_NODE *permanently_accepted_certs; GWEN_GUI_CHECKCERT_FN builtin_checkcert; /* Dialogs */ @@ -285,6 +286,8 @@ gnc_GWEN_Gui_shutdown(void) g_hash_table_destroy(gui->passwords); if (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) g_hash_table_destroy(gui->accepted_certs); 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_checkbutton = glade_xml_get_widget(xml, "close_checkbutton"); gui->accepted_certs = NULL; + gui->permanently_accepted_certs = NULL; gui->showbox_hash = NULL; gui->showbox_id = 1; @@ -448,6 +452,8 @@ reset_dialog(GncGWENGui *gui) if (!gui->accepted_certs) gui->accepted_certs = g_hash_table_new_full( 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(" "); } @@ -1251,7 +1257,8 @@ checkcert_cb(GWEN_GUI *gwen_gui, const GWEN_SSLCERTDESCR *cert, const gchar *hash, *status; struct md5_ctx md5_context; gchar cert_hash[16]; - gint retval; + gchar *cert_hash_hex; + gint retval, i; 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_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)) { - /* Certificate has been accepted before */ + /* Certificate has been accepted by Gnucash before */ LEAVE("Automatically accepting certificate"); return 0; }