Partly fixes bug 667490. It implements the presentation of static optical TAN challenges (photoTAN and QR) inside the enter TAN dialogue.

This commit is contained in:
Ingo Haschler 2019-09-26 22:03:05 +02:00
parent 84cfc5743b
commit 3e8c9ad807
2 changed files with 117 additions and 3 deletions

View File

@ -664,6 +664,22 @@
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkImage" id="optical_challenge">
<property name="name">optical_challenge</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child> <child>
<object class="GtkGrid" id="grid1"> <object class="GtkGrid" id="grid1">
<property name="visible">True</property> <property name="visible">True</property>
@ -751,7 +767,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -170,9 +170,16 @@ static gboolean keep_alive(GncGWENGui *gui);
static void cm_close_handler(gpointer user_data); static void cm_close_handler(gpointer user_data);
static void erase_password(gchar *password); static void erase_password(gchar *password);
static gchar *strip_html(gchar *text); static gchar *strip_html(gchar *text);
#ifndef AQBANKING6
static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title, static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, gchar **input, gint min_len, const gchar *text, gchar **input, gint min_len,
gint max_len); gint max_len);
#else
static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, const char *mimeType,
const char *pChallenge, uint32_t lChallenge,
gchar **input, gint min_len, gint max_len);
#endif
static gint messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title, static gint messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
const gchar *text, const gchar *b1, const gchar *b2, const gchar *text, const gchar *b1, const gchar *b2,
const gchar *b3, guint32 guiid); const gchar *b3, guint32 guiid);
@ -190,7 +197,7 @@ static gint progress_advance_cb(GWEN_GUI *gwen_gui, uint32_t id,
static gint progress_log_cb(GWEN_GUI *gwen_gui, guint32 id, static gint progress_log_cb(GWEN_GUI *gwen_gui, guint32 id,
GWEN_LOGGER_LEVEL level, const gchar *text); GWEN_LOGGER_LEVEL level, const gchar *text);
static gint progress_end_cb(GWEN_GUI *gwen_gui, guint32 id); static gint progress_end_cb(GWEN_GUI *gwen_gui, guint32 id);
#ifndef GWENHYWFAR5 #ifndef AQBANKING6
static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *token, const gchar *token,
const gchar *title, const gchar *title,
@ -977,8 +984,15 @@ strip_html(gchar *text)
} }
static void static void
#ifndef AQBANKING6
get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text, get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
gchar **input, gint min_len, gint max_len) gchar **input, gint min_len, gint max_len)
#else
get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, const char *mimeType,
const char *pChallenge, uint32_t lChallenge,
gchar **input, gint min_len, gint max_len)
#endif
{ {
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *dialog; GtkWidget *dialog;
@ -987,6 +1001,7 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
GtkWidget *confirm_entry; GtkWidget *confirm_entry;
GtkWidget *confirm_label; GtkWidget *confirm_label;
GtkWidget *remember_pin_checkbutton; GtkWidget *remember_pin_checkbutton;
GtkImage *optical_challenge;
const gchar *internal_input, *internal_confirmed; const gchar *internal_input, *internal_confirmed;
gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0; gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0;
gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0; gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
@ -1006,6 +1021,14 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
confirm_entry = GTK_WIDGET(gtk_builder_get_object (builder, "confirm_entry")); confirm_entry = GTK_WIDGET(gtk_builder_get_object (builder, "confirm_entry"));
confirm_label = GTK_WIDGET(gtk_builder_get_object (builder, "confirm_label")); confirm_label = GTK_WIDGET(gtk_builder_get_object (builder, "confirm_label"));
remember_pin_checkbutton = GTK_WIDGET(gtk_builder_get_object (builder, "remember_pin")); remember_pin_checkbutton = GTK_WIDGET(gtk_builder_get_object (builder, "remember_pin"));
optical_challenge = GTK_IMAGE(gtk_builder_get_object (builder, "optical_challenge"));
gtk_widget_set_visible(GTK_WIDGET(optical_challenge), FALSE);
#ifdef AQBANKING6
if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
{
gtk_widget_set_visible(GTK_WIDGET(optical_challenge), TRUE);
}
#endif
if (is_tan) if (is_tan)
{ {
gtk_widget_hide(remember_pin_checkbutton); gtk_widget_hide(remember_pin_checkbutton);
@ -1035,6 +1058,35 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
g_free(raw_text); g_free(raw_text);
} }
#ifdef AQBANKING6
//if (optical_challenge)
if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
{
// convert PNG and load into widget
// TBD: check mimeType?
guchar *gudata = (guchar*)pChallenge;
GError *error = NULL;
GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_mime_type(mimeType, &error);
GdkPixbuf *pixbuf;
if(error != NULL)
{
PERR("Pixbuf loader not loaded: %s, perhaps MIME type %s isn't supported.", error->message, mimeType);
}
gdk_pixbuf_loader_write(loader, gudata, lChallenge, NULL);
gdk_pixbuf_loader_close(loader, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
g_object_ref(pixbuf);
g_object_unref(loader);
gtk_image_set_from_pixbuf(optical_challenge, pixbuf);
}
#endif
if (*input) if (*input)
{ {
gtk_entry_set_text(GTK_ENTRY(input_entry), *input); gtk_entry_set_text(GTK_ENTRY(input_entry), *input);
@ -1170,7 +1222,11 @@ inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
ENTER("gui=%p, flags=%d", gui, flags); ENTER("gui=%p, flags=%d", gui, flags);
#ifndef AQBANKING6
get_input(gui, flags, title, text, &input, min_len, max_len); get_input(gui, flags, title, text, &input, min_len, max_len);
#else
get_input(gui, flags, title, text, NULL, NULL, 0, &input, min_len, max_len);
#endif
if (input) if (input)
{ {
@ -1406,7 +1462,7 @@ progress_end_cb(GWEN_GUI *gwen_gui, guint32 id)
} }
static gint GNC_GWENHYWFAR_CB static gint GNC_GWENHYWFAR_CB
#ifndef GWENHYWFAR5 #ifndef AQBANKING6
getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token, getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
const gchar *title, const gchar *text, gchar *buffer, const gchar *title, const gchar *text, gchar *buffer,
gint min_len, gint max_len, guint32 guiid) gint min_len, gint max_len, guint32 guiid)
@ -1421,8 +1477,46 @@ getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
gchar *password = NULL; gchar *password = NULL;
gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0; gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
#ifdef AQBANKING6
int opticalMethodId;
const char *mimeType = NULL;
const char *pChallenge = NULL;
uint32_t lChallenge = 0;
#endif
g_return_val_if_fail(gui, -1); g_return_val_if_fail(gui, -1);
#ifdef AQBANKING6
// cf. https://www.aquamaniac.de/rdm/projects/aqbanking/wiki/ImplementTanMethods
if(is_tan && methodId == GWEN_Gui_PasswordMethod_OpticalHHD)
{
/**
* TODO: How to handle Flicker code (use WebView and JS???)
*
* use GWEN_Gui_PasswordMethod_Mask to get the basic method id
* cf. gui/gui.h of gwenhywfar
*/
opticalMethodId=GWEN_DB_GetIntValue(methodParams, "tanMethodId", 0, AB_BANKING_TANMETHOD_TEXT);
switch(opticalMethodId)
{
case AB_BANKING_TANMETHOD_PHOTOTAN:
case AB_BANKING_TANMETHOD_CHIPTAN_QR:
/**
* image data is in methodParams
*/
mimeType=GWEN_DB_GetCharValue(methodParams, "mimeType", 0, NULL);
pChallenge=(const char*) GWEN_DB_GetBinValue(methodParams, "imageData", 0, NULL, 0, &lChallenge);
if (!(pChallenge && lChallenge)) {
/* empty optical data */
return GWEN_ERROR_NO_DATA;
}
break;
default:
break;
}
}
#endif
ENTER("gui=%p, flags=%d, token=%s", gui, flags, token ? token : "(null"); ENTER("gui=%p, flags=%d, token=%s", gui, flags, token ? token : "(null");
/* Check remembered passwords, excluding TANs */ /* Check remembered passwords, excluding TANs */
@ -1450,7 +1544,11 @@ getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
} }
} }
#ifndef AQBANKING6
get_input(gui, flags, title, text, &password, min_len, max_len); get_input(gui, flags, title, text, &password, min_len, max_len);
#else
get_input(gui, flags, title, text, mimeType, pChallenge, lChallenge, &password, min_len, max_len);
#endif
if (password) if (password)
{ {