1 /*************************************************************************** 2 begin : Tue Oct 02 2002 3 copyright : (C) 2002-2010 by Martin Preuss 4 email : martin@libchipcard.de 5 6 *************************************************************************** 7 * * 8 * This library is free software; you can redistribute it and/or * 9 * modify it under the terms of the GNU Lesser General Public * 10 * License as published by the Free Software Foundation; either * 11 * version 2.1 of the License, or (at your option) any later version. * 12 * * 13 * This library is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 16 * Lesser General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU Lesser General Public * 19 * License along with this library; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 21 * MA 02111-1307 USA * 22 * * 23 ***************************************************************************/ 24 25 #ifndef GWENHYWFAR_GUI_GUI_H 26 #define GWENHYWFAR_GUI_GUI_H 27 28 29 30 #include <gwenhywfar/inherit.h> 31 #include <gwenhywfar/logger.h> 32 #include <gwenhywfar/inetsocket.h> 33 #include <gwenhywfar/ssl_cert_descr.h> 34 #include <gwenhywfar/syncio.h> 35 #include <gwenhywfar/dialog.h> 36 #include <gwenhywfar/passwdstore.h> 37 38 #include <inttypes.h> 39 40 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 47 48 49 /** @defgroup MOD_GUI Graphical User Interface 50 * 51 * @brief This module contains the definition of GWEN_GUI. 52 * 53 * The concept of this module is to have a single GWEN_GUI object per 54 * application which is created at the start of your application. 55 * This GWEN_GUI object tells Gwenhywfar (and libraries using the GWEN_GUI-mechanism) how to handle user interaction. 56 * 57 * The GWEN_GUI object contains callbacks for message display, user 58 * input, progress reports, SSL certificate checking etc. 59 * 60 * There are implementations of GWEN_GUI based on console, QT4, QT5 and FOX. 61 * 62 * GWEN_GUI uses flags to tell implementations what the caller needs of the GUI 63 * implementation. 64 * 65 * Callbacks which might create windows when using graphical user interfaces like 66 * QT or FOX return GUI IDs (like @ref GWEN_Gui_ProgressStart()). These ids can be 67 * used to create window stacks. The implementation can freely choose how to generate those 68 * ids. The only fixed definition is that a GUIID of 0 refers to the last opened context (opened by 69 * e.g. @ref GWEN_Gui_ProgressStart()). 70 * 71 * A simple example of how GWEN_GUI is used: 72 * 73 * @code 74 * uint32_t pid; 75 * 76 * pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_SHOW_PROGRESS, 77 * "Progress-Title", 78 * "This is an example progress with 2 steps", 79 * 2, 80 * 0); 81 * GWEN_Gui_ProgressAdvance(pid, 1); 82 * rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_INFO, 83 * "MessageBox-Title", 84 * "This message box should appear in the context of the open progress dialog", 85 * "Button1", 86 * "Button2", 87 * "Button3", 88 * pid); 89 * GWEN_Gui_ProgressAdvance(pid, 2); 90 * GWEN_Gui_ProgressEnd(pid); 91 * @endcode 92 * 93 * In this example a progress context is started (with the GUIID stored in the variable pid). Then in this context 94 * a message box is opened and finally the progress context is closed. 95 * 96 * As seen in the example above the GUI ID returned by @ref GWEN_Gui_ProgressStart() is used as argument GUIID of the 97 * function @ref GWEN_Gui_MessageBox(). Effectively this makes the message box appear in the context of the open progress. 98 * 99 * An implementation which uses a graphical interface (QT, FOX) will most probably use windows for 100 * @ref GWEN_Gui_ProgressStart() and @ref GWEN_Gui_MessageBox(). In such a case the GUI IDs shown above can be used to 101 * establish a parental relationship between those windows. In the example above the message box will have the open 102 * progress dialog as parent window. 103 * 104 * However applications can use additional mechanisms to determine parent windows. QBankManager for example uses its own 105 * GWEN_GUI implementation based on QT3. It contains methods for maintaining a stack of parent windows. 106 * So whenever QBankManager wants GWEN_GUI user interaction to appear in a special window it calls QGui::pushParentWidget() 107 * just before calling Gwenhywfar or AqBanking functions which might need user interaction and QGui::popParentWidget() 108 * directly therafter. 109 * 110 * This mechanism makes it unnecessary to have multiple GUI objects. In fact using multiple GWEN_GUI objects is strongly 111 * discouraged. The implementation should use the GUIID parameter of each callback instead to establish a relationship 112 * between multiple windows. 113 */ 114 /*@{*/ 115 116 117 118 /** @defgroup MOD_GUI_PASSWORD_METHOD Password Methods 119 * 120 * The pasword entry function is used by homebanking apps/libraries for input of passwords for keyfiles, 121 * for pin input and for tan input. 122 * FinTS in Germany uses several methods to get a tan; some just ask for transaction number (TAN) from a previously 123 * mailed list. Others ask you to hold a special tan generator device to the monitor to let it read a special 124 * flicker graphic. Some show an image to the user from which he must derive the tan in some way. 125 * Therefore the password entry function needed to be extended to allow for a more generic way to ask the user 126 * for a password. Previously, some specific data was included in the text parameter, from which the GUI implementation 127 * needed to extract that data (i.e. "$OBEGIN" and "$OEND" for optical data). 128 * 129 * Therefore we define methods of pin/tan/password entry here with the matching method parameters. 130 */ 131 /*@{*/ 132 133 /** @defgroup MOD_GUI_PASSWORD_METHOD_TEXT Textual Input 134 * 135 * This method doesn't need any parameters except those which are already defined by the function 136 * prototype (i.e. min/max length etc.) 137 * 138 */ 139 140 /** @defgroup MOD_GUI_PASSWORD_METHOD_OPTICALHHD Optical Input (i.e. flicker code) 141 * 142 * This method uses a so-called "challenge" which is chiefly a row of digits which are encoded in a 143 * flicker graphic which is then read by a specific card reader device which is held to the monitor to read 144 * that code. 145 * The possible contents of the methodParams are: 146 * <ul> 147 * <li>char challenge: Hex code in ASCII form with a row of bytes to be converted to a flicker code (e.g. "123456789ABC" </li> 148 * <li>char methodName: Name of the method (optional)</li> 149 * <li>char methodDescription: Description of the method (optional)</li> 150 * </ul> 151 * 152 */ 153 154 155 /** 156 * Password/pin/tan entry method. 157 * The method id uses the higher 16 bits of a 32 bit word to define the method. 158 * The lower 16 bits are used to define the version of the method. E.g. the method for 159 * input using optical data (i.e. flicker code) knows multiple versions, currently 1.3 and 1.4. 160 * So the complete method id for optical input method HHD version 1.4 would be 0x20104. 161 * Use @ref GWEN_Gui_PasswordMethod_Mask to get the basic method id. 162 */ 163 typedef enum { 164 GWEN_Gui_PasswordMethod_Unknown =0, 165 GWEN_Gui_PasswordMethod_Mask =0xffff0000, 166 GWEN_Gui_PasswordMethod_Text =0x10000, 167 GWEN_Gui_PasswordMethod_OpticalHHD=0x20000, 168 } GWEN_GUI_PASSWORD_METHOD; 169 170 171 /*@}*/ 172 173 174 175 176 typedef struct GWEN_GUI GWEN_GUI; 177 GWEN_INHERIT_FUNCTION_LIB_DEFS(GWEN_GUI, GWENHYWFAR_API) 178 179 180 #define GWEN_GUI_CPU_TIMEOUT 200 181 182 #define GWEN_GUI_CHECK_PERIOD 750 183 #define GWEN_GUI_DELAY_SECS 2 184 185 186 /** @name Flags For GWEN_Gui_ProgressStart 187 * 188 * These flags are given to @ref GWEN_Gui_ProgressStart to modify its 189 * behaviour. 190 */ 191 /*@{*/ 192 #define GWEN_GUI_PROGRESS_DELAY 0x00000001 193 #define GWEN_GUI_PROGRESS_SHOW_LOG 0x00000002 194 #define GWEN_GUI_PROGRESS_SHOW_ABORT 0x00000004 195 #define GWEN_GUI_PROGRESS_ALLOW_SUBLEVELS 0x00000008 196 #define GWEN_GUI_PROGRESS_ALLOW_EMBED 0x00000010 197 #define GWEN_GUI_PROGRESS_SHOW_PROGRESS 0x00000020 198 #define GWEN_GUI_PROGRESS_KEEP_OPEN 0x00000040 199 #define GWEN_GUI_PROGRESS_ALWAYS_SHOW_LOG 0x00000080 200 /*@}*/ 201 202 203 204 /** @name Flags For GWEN_Gui_InputBox 205 * 206 * These flags are given to @ref GWEN_Gui_InputBox to modify its 207 * behaviour. 208 */ 209 /*@{*/ 210 /** input must be confirmed (e.g. by asking for the same input twice) */ 211 #define GWEN_GUI_INPUT_FLAGS_CONFIRM 0x00000001 212 /** input may be shown (otherwise it should be hidden, e.g. for passwords) */ 213 #define GWEN_GUI_INPUT_FLAGS_SHOW 0x00000002 214 /** numeric input is requested (e.g. for PINs) */ 215 #define GWEN_GUI_INPUT_FLAGS_NUMERIC 0x00000004 216 /** if set then this is a retry (esp. when getting a PIN) */ 217 #define GWEN_GUI_INPUT_FLAGS_RETRY 0x00000008 218 /** allow a default value to be used instead of an entered one. 219 * A graphical UI should add a "default" button to the dialog. */ 220 #define GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT 0x00000010 221 /** The input is a TAN (this is used by @ref GWEN_Gui_GetPassword) */ 222 #define GWEN_GUI_INPUT_FLAGS_TAN 0x00000020 223 /** The input contains optical data encapsuled in "$OBEGIN$" and "$OEND$" (this is used by @ref GWEN_Gui_GetPassword) */ 224 #define GWEN_GUI_INPUT_FLAGS_OPTICAL 0x00000040 225 /** The input MUST come via user input, not from some sort of password cache */ 226 #define GWEN_GUI_INPUT_FLAGS_DIRECT 0x00000080 227 228 /*@}*/ 229 230 231 /** @name Flags For GWEN_Gui_MessageBox 232 * 233 * These flags are given to @ref GWEN_Gui_MessageBox to modify its 234 * behaviour. You may OR-combine the flags.<br> 235 * Examples: 236 * <ul> 237 * <li> 238 * normal error message, multiple buttons, first button confirms 239 * @code 240 * (GWEN_GUI_MSG_FLAGS_TYPE_ERROR | 241 * GWEN_GUI_MSG_FLAGS_CONFIRM_B1 | 242 * GWEN_GUI_MSG_FLAGS_SEVERITY_NORMAL) 243 * @endcode 244 * </li> 245 * <li> 246 * dangerous error message, multiple buttons, first button confirms 247 * @code 248 * (GWEN_GUI_MSG_FLAGS_TYPE_ERROR | 249 * GWEN_GUI_MSG_FLAGS_CONFIRM_B1 | 250 * GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS) 251 * @endcode 252 * </li> 253 * </ul> 254 * <p> 255 * A note about <i>confirmation buttons</i>: Gwenhywfar has been designed with 256 * non-interactive applications in mind. For such an application it is 257 * important to know what button-press it has to simulate upon catching of a 258 * messagebox callback. This is what the confimation button flags are for. 259 * For informative messages the application may simply return the number of 260 * the confirmation button and be done. 261 * </p> 262 * <p> 263 * However, non-interactive applications should return an error (value 0) 264 * for messages classified as <b>dangerous</b> 265 * (see @ref GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS) to avoid data loss. 266 * </p> 267 */ 268 /*@{*/ 269 /** 270 * Defines the mask to catch the message type. E.g. a check whether a 271 * message is a warning could be performed by: 272 * @code 273 * if ( ( flags & GWEN_GUI_MSG_FLAGS_TYPE_MASK) == 274 * GWEN_GUI_MSG_FLAGS_TYPE_WARN) { 275 * fprintf(stderr, "This is a warning.\n"); 276 * } 277 * @endcode 278 */ 279 #define GWEN_GUI_MSG_FLAGS_TYPE_MASK 0x07 280 /** The message is a simple information. */ 281 #define GWEN_GUI_MSG_FLAGS_TYPE_INFO 0 282 /** check whether the given flags represent an info message */ 283 #define GWEN_GUI_MSG_FLAGS_TYPE_IS_INFO(fl) \ 284 ((fl & GWEN_GUI_MSG_FLAGS_TYPE_MASK)==GWEN_GUI_MSG_FLAGS_TYPE_INFO) 285 286 /** The message is a warning */ 287 #define GWEN_GUI_MSG_FLAGS_TYPE_WARN 1 288 /** check whether the given flags represent a warning message */ 289 #define GWEN_GUI_MSG_FLAGS_TYPE_IS_WARN(fl) \ 290 ((fl & GWEN_GUI_MSG_FLAGS_TYPE_MASK)==GWEN_GUI_MSG_FLAGS_TYPE_WARN) 291 292 /** The message is a error message */ 293 #define GWEN_GUI_MSG_FLAGS_TYPE_ERROR 2 294 /** check whether the given flags represent an error message */ 295 #define GWEN_GUI_MSG_FLAGS_TYPE_IS_ERROR \ 296 ((fl & GWEN_GUI_MSG_FLAGS_TYPE_MASK)==GWEN_GUI_MSG_FLAGS_TYPE_ERROR) 297 298 /** button 1 is the confirmation button */ 299 #define GWEN_GUI_MSG_FLAGS_CONFIRM_B1 (1<<3) 300 /** button 2 is the confirmation button */ 301 #define GWEN_GUI_MSG_FLAGS_CONFIRM_B2 (2<<3) 302 /** button 3 is the confirmation button */ 303 #define GWEN_GUI_MSG_FLAGS_CONFIRM_B3 (3<<3) 304 /** Determine which button is the confirmation button */ 305 #define GWEN_GUI_MSG_FLAGS_CONFIRM_BUTTON(fl) (((fl)>>3) & 0x3) 306 307 308 /** 309 * <p> 310 * Check for the severity of the message. This allows non-interactive 311 * backends to react on the message accordingly. 312 * The backend calling this function thus allows the frontend to detect 313 * when the message is important regarding data security. 314 * E.g. a message like "Shall I delete this file" should be considered 315 * dangerous (since this might result in a data loss). However, the message 316 * "Application started" is not that dangerous ;-) 317 * </p> 318 * <p> 319 * The following example allows to determine whether a message is 320 * dangerous: 321 * @code 322 * if ( ( flags & GWEN_GUI_MSG_FLAGS_SEVERITY_MASK) == 323 * GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS) { 324 * fprintf(stderr, "This is dangerous.\n"); 325 * } 326 * @endcode 327 * </p> 328 */ 329 #define GWEN_GUI_MSG_FLAGS_SEVERITY_MASK (0x7<<5) 330 /** Message does not affect security or induce any problem to the system */ 331 #define GWEN_GUI_MSG_FLAGS_SEVERITY_NORMAL (0x0<<5) 332 #define GWEN_GUI_MSG_FLAGS_SEVERITY_IS_NORMAL(fl) \ 333 ((fl & GWEN_GUI_MSG_FLAGS_SEVERITY_MASK)==\ 334 GWEN_GUI_MSG_FLAGS_SEVERITY_NORMAL) 335 /** Message is considered dangerous and thus should be attended to by a 336 * humanoid ;-) */ 337 #define GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS (0x1<<5) 338 #define GWEN_GUI_MSG_FLAGS_SEVERITY_IS_DANGEROUS(fl) \ 339 ((fl & GWEN_GUI_MSG_FLAGS_SEVERITY_MASK)==\ 340 GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS) 341 /*@}*/ 342 343 344 /** @name Flags For GWEN_Gui_ShowBox 345 * 346 */ 347 /*@{*/ 348 /** 349 * Make the frontend beep. This should rarely be used, and only in situations 350 * where it is very important to get the users attention (e.g. when asking 351 * for a PIN on a card reader). 352 */ 353 #define GWEN_GUI_SHOWBOX_FLAGS_BEEP 0x00000001 354 /*@}*/ 355 356 357 358 /** @name Special Progress Values for GWEN_Gui_ProgressAdvance 359 * 360 */ 361 /*@{*/ 362 /** 363 * This value is used with @ref GWEN_Gui_ProgressAdvance to flag that 364 * there really was no progress since the last call to that function but 365 * that that function should simply check for user interaction (without 366 * the need of updating the progress bar). 367 */ 368 #define GWEN_GUI_PROGRESS_NONE (0xffffffffUL) 369 370 /** 371 * This value is used when the total number of steps is not known to the 372 * caller and he just wants to advance the progress by one (e.g. backends 373 * use this value when a job has been finished, but the backends do not know 374 * how many jobs there still are in AqBanking's queue). 375 */ 376 #define GWEN_GUI_PROGRESS_ONE (0xfffffffeUL) 377 /*@}*/ 378 379 380 381 /** 382 * This status is used for passwords, pins and tans, e.g. by the CryptToken 383 * code. 384 * It can be used by implementations to mark bad pins, used/unused tans etc. 385 */ 386 typedef enum { 387 GWEN_Gui_PasswordStatus_Bad=-1, 388 GWEN_Gui_PasswordStatus_Unknown, 389 GWEN_Gui_PasswordStatus_Ok, 390 GWEN_Gui_PasswordStatus_Used, 391 GWEN_Gui_PasswordStatus_Unused, 392 GWEN_Gui_PasswordStatus_Remove 393 } GWEN_GUI_PASSWORD_STATUS; 394 395 396 397 /** @name Constructor, Destructor etc 398 * 399 */ 400 /*@{*/ 401 GWENHYWFAR_API 402 GWEN_GUI *GWEN_Gui_new(void); 403 404 GWENHYWFAR_API 405 void GWEN_Gui_free(GWEN_GUI *gui); 406 407 GWENHYWFAR_API 408 void GWEN_Gui_Attach(GWEN_GUI *gui); 409 410 GWENHYWFAR_API 411 void GWEN_Gui_SetGui(GWEN_GUI *gui); 412 413 GWENHYWFAR_API 414 GWEN_GUI *GWEN_Gui_GetGui(void); 415 416 /*@}*/ 417 418 419 420 /** @name Character Set 421 * 422 * All messages and texts can be converted from UTF8 automatically. 423 * This needs the name of the destination character set. 424 * See output of <i>iconv --list</i> for a list of supported 425 * character sets. 426 */ 427 /*@{*/ 428 GWENHYWFAR_API 429 const char *GWEN_Gui_GetCharSet(const GWEN_GUI *gui); 430 431 GWENHYWFAR_API 432 void GWEN_Gui_SetCharSet(GWEN_GUI *gui, const char *s); 433 434 GWENHYWFAR_API 435 int GWEN_Gui_ConvertString(const char *text, size_t len, GWEN_BUFFER *tbuf, 436 const char *fromCs, const char *toCs); 437 438 439 /*@}*/ 440 441 442 443 444 445 446 /** @name Virtual User Interaction Functions 447 * 448 * <p> 449 * All text passed to the frontend via one of the following functions 450 * is expected to be an UTF-8 string which may contain newlines but no other 451 * control characters. 452 * Text delivered as argument called <i>text</i> throughout the documentation 453 * in this group may contain HTML tags. 454 * If it does a non-HTML version must be supplied, too. 455 * The text MUST begin with the non-HTML version, so that a frontend not 456 * capable of parsing HTML can simply exclude the HTML part by cutting 457 * before "<html". 458 * 459 * </p> 460 * <p> 461 * This is an example for HTML and non-HTML text: 462 * </p> 463 * @code 464 * const char *text; 465 * 466 * text="This is the non-HTML text" 467 * "<html>" 468 * "And this is the <b>HTML</b> version." 469 * "</html>" 470 * @endcode 471 * <p> 472 * Frontends capable of parsing HTML (such as the KDE frontend) will 473 * extract the HTML information and show only that part of the string. 474 * </p> 475 * <p> 476 * Other frontends have to extract the non-HTML information and show only 477 * that. 478 * </p> 479 */ 480 /*@{*/ 481 482 /** 483 * <p> 484 * Show a message box with optional buttons. 485 * The message box may either contain 1, 2 or three buttons. 486 * If only one button is wanted then b1 should hold a pointer to the button 487 * text (b2 and b3 must be NULL) 488 * In two-button mode b1 and b2 must be valid (b3 must be NULL) 489 * In three-button-mode b1, b2 and b3 must be valid pointers. 490 * The return value tells which button the user pressed: 491 * <ul> 492 * <li>1: button 1</li> 493 * <li>2: button 2</li> 494 * <li>3: button 3</li> 495 * </ul> 496 * If the frontend can not determine which button has been pressed (e.g. if 497 * no button was pressed but the user rather aborted the dialog by simply 498 * closing the box) it should return @b 0. 499 * </p> 500 * <p> 501 * This function is blocking. 502 * </p> 503 * @return the number of the button pressed (1=b1, 2=b2, 3=b3), any other 504 * value should be considered an error, including 0) 505 * @param flags flags, see @ref GWEN_GUI_MSG_FLAGS_TYPE_MASK ff. 506 * @param title title of the message box 507 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 508 * @param b1 text for the first button (required), should be something 509 * like "Ok" (see text restrictions note above) 510 * @param b2 text for the optional second button 511 * @param b3 text for the optional third button 512 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 513 */ 514 GWENHYWFAR_API 515 int GWEN_Gui_MessageBox(uint32_t flags, 516 const char *title, 517 const char *text, 518 const char *b1, 519 const char *b2, 520 const char *b3, 521 uint32_t guiid); 522 523 /** 524 * This is a convenience function which calls @ref GWEN_Gui_MessageBox showing the given 525 * message and a single "Close" button. 526 * It is especially well suited to show an error message. 527 */ 528 GWENHYWFAR_API 529 void GWEN_Gui_ShowError(const char *title, const char *text, ...); 530 531 532 /** 533 * <p> 534 * Ask the user for input. 535 * </p> 536 * <p> 537 * This function is blocking. 538 * </p> 539 * @param flags flags, see @ref GWEN_GUI_INPUT_FLAGS_CONFIRM ff. 540 * @param title title of the input box 541 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 542 * @param buffer buffer to store the response in. Must have at least room for 543 * @b maxLen bytes 544 * @param minLen minimal length of input (if 0 then there is no low limit) 545 * @param maxLen size of the buffer including the trailing NULL character. 546 * This means that if you want to ask the user for a PIN of at most 4 547 * characters you need to supply a buffer of at least @b 5 bytes and provide 548 * a 5 as maxLen. 549 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 550 * 551 * @return Zero on success, less than zero when the user requested abort or there was 552 * any error. The special value AB_ERROR_DEFAULT_VALUE should be returned if 553 * the flag GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT was given and the user has 554 * chosen to use the default value (e.g. pressed the "default" button in a 555 * GUI). 556 * A return value of "1" means the result may be stored by the application. This value is 557 * returned when the user ticks the checkbox "Store permanently". 558 */ 559 GWENHYWFAR_API 560 int GWEN_Gui_InputBox(uint32_t flags, 561 const char *title, 562 const char *text, 563 char *buffer, 564 int minLen, 565 int maxLen, 566 uint32_t guiid); 567 568 /** 569 * <p> 570 * Shows a box with the given text. This function should return immediately, 571 * it should especially NOT wait for user input. This is used to show very 572 * important notices the user should see but which don't need user 573 * interaction. The message box will be removed later via 574 * @ref GWEN_Gui_HideBox. It is ok to allow the user to prematurely 575 * close the box. 576 * </p> 577 * <p> 578 * It is required for every call to this function to be followed later 579 * by a corresponding call to @ref GWEN_Gui_HideBox. 580 * </p> 581 * <p> 582 * This function MUST return immediately (non-blocking). 583 * </p> 584 * @return returns an id to be presented to @ref GWEN_Gui_HideBox. 585 * @param flags flags, see @ref GWEN_GUI_SHOWBOX_FLAGS_BEEP ff 586 * @param title title of the box 587 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 588 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 589 */ 590 GWENHYWFAR_API 591 uint32_t GWEN_Gui_ShowBox(uint32_t flags, 592 const char *title, 593 const char *text, 594 uint32_t guiid); 595 596 /** 597 * Hides a message box previously shown by a call to @ref GWEN_Gui_ShowBox. 598 * <p> 599 * This function MUST return immediately (non-blocking). 600 * </p> 601 * @param id id returned by @ref GWEN_Gui_ShowBox. If @b 0 then the last 602 * message shown is referred to. 603 */ 604 GWENHYWFAR_API 605 void GWEN_Gui_HideBox(uint32_t id); 606 607 608 /** 609 * <p> 610 * This function is called when a long term operation is started. 611 * Theoretically nesting is allowed, however, you should refrain from 612 * opening multiple progress dialogs to avoid confusion of the user. 613 * </p> 614 * <p> 615 * This function must return immediately (i.e. it MUST NOT wait for 616 * user interaction). 617 * </p> 618 * <p> 619 * On graphical user interfaces such a dialog should contain a widget 620 * for the text presented here, a progress bar, a text widget to 621 * collect the log messages received via @ref GWEN_Gui_ProgressLog and 622 * a button to allow the user to abort the current operation monitored by 623 * this dialog window. 624 * </p> 625 * <p> 626 * Between a call to this function and one to @ref GWEN_Gui_ProgressEnd 627 * the user should not be allowed to close the dialog window. 628 * </p> 629 * <p> 630 * This function MUST return immediately (non-blocking). 631 * </p> 632 * @return id to be used with the other GWEN_Gui_Progress functions. 633 * @param title title of the dialog 634 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 635 * @param total total number of steps of the operation started (i.e. value 636 * which represents 100%) 637 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 638 */ 639 GWENHYWFAR_API 640 uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags, 641 const char *title, 642 const char *text, 643 uint64_t total, 644 uint32_t guiid); 645 646 /** 647 * <p> 648 * Advances the progress bar an application might present to the user and 649 * checks whether the user wants to abort the operation currently in progress. 650 * </p> 651 * <p> 652 * On graphical user interfaces this function should also check for user 653 * interaction and/or update the GUI (e.g. by calling qApp->processEvents() 654 * when using QT/KDE). 655 * </p> 656 * <p> 657 * This function MUST return immediately (non-blocking). 658 * </p> 659 * @return 0 if ok, !=0 if the current operation is to be aborted 660 * @param id id assigned by @ref GWEN_Gui_ProgressStart (if 0 then the 661 * last started progress dialog is referred to) 662 * @param progress new value for progress. A special value is 663 * GWEN_GUI_PROGRESS_NONE which means that the progress is unchanged. 664 * This might be used as a keepalive call to a GUI. 665 */ 666 GWENHYWFAR_API 667 int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress); 668 669 GWENHYWFAR_API 670 int GWEN_Gui_ProgressSetTotal(uint32_t id, uint64_t total); 671 672 /** 673 * Adds a log message to the referred process dialog. 674 * <p> 675 * This function MUST return immediately (non-blocking). 676 * </p> 677 * @param id id assigned by @ref GWEN_Gui_ProgressStart (if 0 then the 678 * last started progress dialog is referred to) 679 * @param level log level (see @ref GWEN_Gui_LogLevelPanic ff.) 680 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 681 */ 682 GWENHYWFAR_API 683 int GWEN_Gui_ProgressLog(uint32_t id, 684 GWEN_LOGGER_LEVEL level, 685 const char *text); 686 687 /** 688 * Adds a log message to the referred process dialog and returns immediately. 689 * 690 * This is a convenience function to be used with variable number of arguments (like 691 * printf). It uses the given arguments to prepare a buffer which is then handed to 692 * @ref GWEN_Gui_ProgressLog. 693 * @param id id assigned by @ref GWEN_Gui_ProgressStart (if 0 then the 694 * last started progress dialog is referred to) 695 * @param level log level (see @ref GWEN_Gui_LogLevelPanic ff.) 696 * @param text Text of the box (possibly including printf format string characters): UTF-8, with both a normal text 697 * and a HTML variant of the text in the same string. See text restrictions note above. 698 */ 699 GWENHYWFAR_API 700 int GWEN_Gui_ProgressLog2(uint32_t id, 701 GWEN_LOGGER_LEVEL level, 702 const char *text, ...); 703 704 /** 705 * <p> 706 * Flags the end of the current operation. In graphical user interfaces 707 * this call should allow the user to close the progress dialog window. 708 * </p> 709 * <p> 710 * On graphical user interfaces a call to this function should disable the 711 * <i>abort</i> button. It would be best not to close the dialog on 712 * receiption of this call but to simply enable a dialog closing (otherwise 713 * the user will not be able to see the log messages). 714 * </p> 715 * <p> 716 * Whether this function is blocking or not depends on the status of the 717 * progress dialog and its initial flags. If the dialog needs to stay open 718 * for the user to read the log messages etc then this function only needs to 719 * return after the user manually closes the dialog. 720 * </p> 721 * <p> 722 * If there is no reason to keep the dialog open then this function should simply 723 * close the dialog window and return immediately. 724 * </p> 725 * @param id id assigned by @ref GWEN_Gui_ProgressStart (if 0 then the 726 * last started progress dialog is referred to) 727 */ 728 GWENHYWFAR_API 729 int GWEN_Gui_ProgressEnd(uint32_t id); 730 731 732 /** 733 * This function makes the application print something. 734 * @param docTitle title of the document. This might be presented to the user 735 * @param docType an unique identifier of the document to be printed. This can 736 * be used by the application to separate printer settings for different 737 * document types. The name itself has no meaning and can be choosen freely 738 * by the caller. However, backends should append their name and a colon 739 * to keep this argument unique. This argument should not be translated. 740 * @param descr an optional description about what the document contains. This 741 * might be shown to the user (see text restriction notes above). 742 * @param text text to be printed (see text restriction notes above). 743 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 744 */ 745 GWENHYWFAR_API 746 int GWEN_Gui_Print(const char *docTitle, 747 const char *docType, 748 const char *descr, 749 const char *text, 750 uint32_t guiid); 751 752 /** 753 * This function retrieves a password or pin. The implementation might want to use a cache or 754 * a password file. The default implementation simply asks the user for input. 755 * The function @ref GWEN_Gui_SetPasswordStatus() is used to communicate the status of a password. 756 * So if this function here uses a password cache then the callback for @ref GWEN_Gui_SetPasswordStatus() 757 * should also be implemented. 758 * 759 * NOTE: 760 * AqBanking uses GWEN_Gui_PasswordMethod_OpticalHHD as methodId for all optical TAN input methods like 761 * "chipTAN optisch" and others. To determine which optical method is actually requested see the DB variable 762 * "tanMethodId" inside the methodParams parameter. 763 * The data to send to the TAN generator can be found in the toplevel variable "challenge". 764 * 765 * @param flags flags, see @ref GWEN_GUI_INPUT_FLAGS_CONFIRM ff. 766 * @param token unique identification for the password or pin. This can be used to read the password from a cache or file. 767 * @param title title of the input box 768 * @param text Text of the box: UTF-8, with both a normal text and a HTML variant of the text in the same string. See text restrictions note above. 769 * @param buffer buffer to store the response in. Must have at least room for 770 * @b maxLen bytes 771 * @param minLen minimal length of the password (if 0 then there is no low limit) 772 * @param maxLen size of the buffer including the trailing NULL character. 773 * This means that if you want to ask the user for a PIN of at most 4 774 * characters you need to supply a buffer of at least @b 5 bytes and provide 775 * a 5 as maxLen. 776 * @param methodId Id of the pin/password/tan entry. 777 * @param methodParams additional parameters for the pin/password/tan entry, content depends on 778 * the methodId (my be NULL for simple text input) 779 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 780 */ 781 GWENHYWFAR_API 782 int GWEN_Gui_GetPassword(uint32_t flags, 783 const char *token, 784 const char *title, 785 const char *text, 786 char *buffer, 787 int minLen, 788 int maxLen, 789 GWEN_GUI_PASSWORD_METHOD methodId, 790 GWEN_DB_NODE *methodParams, 791 uint32_t guiid); 792 793 /** 794 * This functions sets the status of a password. 795 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 796 */ 797 GWENHYWFAR_API 798 int GWEN_Gui_SetPasswordStatus(const char *token, 799 const char *pin, 800 GWEN_GUI_PASSWORD_STATUS status, 801 uint32_t guiid); 802 803 /** 804 * This function is called internally by @ref GWEN_Logger_Log. 805 * <b>PLEASE NOTE:</b> If you save the information in a file make sure to ignore 806 * messages from the log domain "gwenhywfar" with log level debug or higher, because 807 * those might contain sensitive information! Information of that level is not supposed 808 * to be saved to a file! 809 * @param logDomain logdomain of the given log message (e.g. "gwenhywfar") 810 * @param priority priority of the message 811 * @param s string to log 812 */ 813 GWENHYWFAR_API 814 int GWEN_Gui_LogHook(const char *logDomain, 815 GWEN_LOGGER_LEVEL priority, 816 const char *s); 817 818 819 /** 820 * This function waits for activity on the given sockets. it is called by @ref GWEN_Io_Manager_Wait(). 821 * The default implementation uses GWEN_Socket_Select() for this purpose. 822 * @param readSockets list of sockets to wait for to become readable 823 * @param writeSockets list of sockets to wait for to become writeable 824 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 825 * @param msecs time in milliseconds to wait for at max 826 */ 827 GWENHYWFAR_API 828 int GWEN_Gui_WaitForSockets(GWEN_SOCKET_LIST2 *readSockets, 829 GWEN_SOCKET_LIST2 *writeSockets, 830 uint32_t guiid, 831 int msecs); 832 833 /** 834 * This function creates a base layer GWEN_SYNCIO. 835 * The idea is to allow applications to implement their own PROXY handling. 836 * @param url url to which the caller wants to connect to. You should call @ref GWEN_Url_fromString() 837 * to get the information required to determine the protocol and destination. 838 * @param defaultProto default protocol name if not specified by the url (e.g. "http", "https", "hbci") 839 * @param defaultPort default port if not specified by the url 840 * @param pSio pointer to a variable to receive the created GWEN_SYNCIO. 841 */ 842 GWENHYWFAR_API 843 int GWEN_Gui_GetSyncIo(const char *url, 844 const char *defaultProto, 845 int defaultPort, 846 GWEN_SYNCIO **pSio); 847 848 849 /** 850 * This function checks the given certificate. 851 * The default implementation just shows the given certificate to the user and asks whether to 852 * accept it. 853 * @param cert certificate description 854 * @param io IO layer from which the certificate was received 855 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart or @ref GWEN_Gui_ShowBox) 856 */ 857 GWENHYWFAR_API 858 int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cert, 859 GWEN_SYNCIO *sio, 860 uint32_t guiid); 861 862 863 /** 864 * This function is not officially part of the API but is needed for some ancient OpenHBCI 865 * keyfiles. 866 * License issues forbid us to link against OpenSSL so we leave it up to the application 867 * to implement this function. A converter tool might use this function once to convert 868 * an anciant OpenHBCI key file. 869 * @param text phrase to generate a key from 870 * @param buffer buffer to write the keydata generated from the given passphrase 871 * @param bufLengthr size of that buffer 872 */ 873 GWENHYWFAR_API 874 int GWEN_Gui_KeyDataFromText_OpenSSL(const char *text, 875 unsigned char *buffer, 876 unsigned int bufLength); 877 878 879 /*@}*/ 880 881 882 /** @name Dialogs 883 * 884 * Providing dialog functionality is optional for the implementation. 885 * The internal implementations of the password and message box functions 886 * internally use dialog functions, so if your implementation of GWEN_GUI 887 * also implements the dialogs API then you're already set for most of the 888 * interactive callbacks. 889 */ 890 /*@{*/ 891 892 /** 893 * This function shows and executes the given dialog and returns the result. 894 * See @ref MOD_GUI_DIALOG for a description of the dialog framework. 895 * 896 * @return <0: error code, 0: aborted, 1: accepted (e.g. "Ok" pressed) 897 * @param dlg pointer to the dialog object 898 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart, @ref GWEN_Gui_ShowBox or as can be found 899 * via @ref GWEN_Dialog_GetGuiId()) 900 */ 901 GWENHYWFAR_API 902 int GWEN_Gui_ExecDialog(GWEN_DIALOG *dlg, uint32_t guiid); 903 904 905 /** 906 * Open a dialog. 907 * This function should create all the necessary dialog resources (=windows) and return. 908 * 909 * @return <0: error code 910 * @param dlg pointer to the dialog object 911 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart, @ref GWEN_Gui_ShowBox or as can be found 912 * via @ref GWEN_Dialog_GetGuiId()) 913 */ 914 GWENHYWFAR_API 915 int GWEN_Gui_OpenDialog(GWEN_DIALOG *dlg, uint32_t guiid); 916 917 918 /** 919 * Close a dialog. 920 * This function should hide the given dialog and release all its resources. 921 * 922 * @return <0: error code 923 * @param dlg pointer to the dialog object 924 * @param guiid id as returned by @ref GWEN_Gui_ProgressStart, @ref GWEN_Gui_ShowBox or as can be found 925 * via @ref GWEN_Dialog_GetGuiId()) 926 */ 927 GWENHYWFAR_API 928 int GWEN_Gui_CloseDialog(GWEN_DIALOG *dlg); 929 930 931 /** 932 * Run a dialog. 933 * This function should run the given dialog and return when the user is done with it. 934 * 935 * @return <0: error code, 0: aborted, 1: accepted (e.g. "Ok" pressed) 936 * @param dlg pointer to the dialog object 937 * @param untilEnd if not zero, the dialog should run until completely finished (e.g. "OK" pressed) 938 */ 939 GWENHYWFAR_API 940 int GWEN_Gui_RunDialog(GWEN_DIALOG *dlg, int untilEnd); 941 942 943 typedef enum { 944 GWEN_Gui_FileNameType_OpenFileName=0, 945 GWEN_Gui_FileNameType_SaveFileName, 946 GWEN_Gui_FileNameType_OpenDirectory 947 948 } GWEN_GUI_FILENAME_TYPE; 949 950 /** 951 * This function is used to get the path and name of a single file or folder. 952 * 953 * @param caption title for the dialog 954 * @param fnt type of the operation (see @ref GWEN_Gui_FileNameType_OpenFileName and following) 955 * @param flags currently reserved, use 0 956 * @param patterns multiple tab-separated entries like in: 957 * "All Files (*)\tC++ Sources (*.cpp,*.cc)\tC++ Headers (*.hpp,*.hh,*.h)" 958 * @param pathBuffer upon call this may contain a preselected path/filename, upon return 959 * this will contain the selected name 960 * 961 * @return 0 if ok, !=0 on error 962 */ 963 GWENHYWFAR_API 964 int GWEN_Gui_GetFileName(const char *caption, 965 GWEN_GUI_FILENAME_TYPE fnt, 966 uint32_t flags, 967 const char *patterns, 968 GWEN_BUFFER *pathBuffer, 969 uint32_t guiid); 970 971 /*@}*/ 972 973 974 975 976 977 978 /** @name Flags 979 * 980 * Functions in this group influence the behaviour of GWEN_GUI implementations. 981 * These functions operate on a specific GUI object which applications create. 982 */ 983 /*@{*/ 984 985 /** GUI is non-interactive */ 986 #define GWEN_GUI_FLAGS_NONINTERACTIVE 0x00000001 987 /** GUI automatically accepts valid certs */ 988 #define GWEN_GUI_FLAGS_ACCEPTVALIDCERTS 0x00000002 989 /** GUI automatically rejects invalid certs */ 990 #define GWEN_GUI_FLAGS_REJECTINVALIDCERTS 0x00000004 991 /** GUI uses permanent password storage */ 992 #define GWEN_GUI_FLAGS_PERMPASSWORDS 0x00000008 993 994 /** GUI implementation supports dialogs (see @ref MOD_GUI_DIALOG) */ 995 #define GWEN_GUI_FLAGS_DIALOGSUPPORTED 0x80000000 996 997 GWENHYWFAR_API uint32_t GWEN_Gui_GetFlags(const GWEN_GUI *gui); 998 GWENHYWFAR_API void GWEN_Gui_SetFlags(GWEN_GUI *gui, uint32_t fl); 999 GWENHYWFAR_API void GWEN_Gui_AddFlags(GWEN_GUI *gui, uint32_t fl); 1000 GWENHYWFAR_API void GWEN_Gui_SubFlags(GWEN_GUI *gui, uint32_t fl); 1001 /*@}*/ 1002 1003 1004 GWENHYWFAR_API const char *GWEN_Gui_GetName(void); 1005 1006 1007 1008 /** @name Password Cache 1009 * 1010 * This implementation provides a password cache. This will be 1011 * consulted upon @ref GWEN_Gui_GetPassword. The implementation of 1012 * @ref GWEN_Gui_SetPasswordStatus also accesses this password cache. 1013 * 1014 * Normally this cache is filled from password files (like those 1015 * specified via option <i>-P</i> of <i>aqbanking-cli</i>). 1016 */ 1017 /**@{*/ 1018 /** 1019 * Set the password DB. Takes over the given DB. 1020 * @param gui GUI object 1021 * @param dbPasswords password cache 1022 * @param persistent if !=0 then the passwords come from a password file 1023 * and a request to clear the password cache will be ignored. 1024 */ 1025 GWENHYWFAR_API 1026 void GWEN_Gui_SetPasswordDb(GWEN_GUI *gui, 1027 GWEN_DB_NODE *dbPasswords, 1028 int persistent); 1029 1030 /** 1031 * Returns a pointer to the internally used password cache. The GUI 1032 * object remains the owner of the object returned (if any). 1033 */ 1034 GWENHYWFAR_API 1035 GWEN_DB_NODE *GWEN_Gui_GetPasswordDb(const GWEN_GUI *gui); 1036 /*@}*/ 1037 1038 1039 1040 /** @name Password Store 1041 * This is the second level password storage. It can be used to safely store passwords 1042 * in an encrypted file. This is used when a pin/password is requested which is not already 1043 * in the password db (see Password Cache). This store is consulted if a given password is 1044 * not found in the current pasword db (see @ref GWEN_Gui_SetPasswordDb). 1045 */ 1046 /**@{*/ 1047 1048 GWENHYWFAR_API GWEN_PASSWD_STORE *GWEN_Gui_GetPasswdStore(const GWEN_GUI *gui); 1049 GWENHYWFAR_API void GWEN_Gui_SetPasswdStore(GWEN_GUI *gui, GWEN_PASSWD_STORE *sto); 1050 /*@}*/ 1051 1052 1053 1054 /** Returns the minimum log level needed to show progress logs */ 1055 GWENHYWFAR_API GWEN_LOGGER_LEVEL GWEN_Gui_GetMinProgressLogLevel(const GWEN_GUI *gui); 1056 GWENHYWFAR_API void GWEN_Gui_SetMinProgressLogLevel(GWEN_GUI *gui, GWEN_LOGGER_LEVEL ll); 1057 1058 1059 1060 /** 1061 * Stack sync io layers above the given base layer. 1062 * 1063 * This is a convenience function to extend a base layer (e.g. created by @ref GWEN_SyncIo_Socket_new) 1064 * to support HTTP or HTTPS over the given base layer. 1065 * 1066 * You can use this function to allow for e.g. HTTPS over a socket created by 1067 * functions @ref GWEN_Socket_Accept and @ref GWEN_SyncIo_Socket_TakeOver. 1068 * 1069 * The caller is responsible for freeing the object returned (if any). 1070 * 1071 * @return syncio object supporting the given protocol (e.g. HTTP, HTTPS), NULL on error 1072 * @param url url to which the caller wants to connect to. You should call @ref GWEN_Url_fromString() 1073 * to get the information required to determine the protocol and destination. 1074 * @param defaultProto default protocol name if not specified by the url (e.g. "http", "https") 1075 * @param defaultPort default port if not specified by the url 1076 * @param baseSio base layer to extend (e.g. created by @ref GWEN_SyncIo_Socket_new) 1077 */ 1078 GWEN_SYNCIO *GWEN_Gui_ExtendSyncIo(const char *url, 1079 const char *defaultProto, 1080 int defaultPort, 1081 GWEN_SYNCIO *baseSio); 1082 1083 1084 #ifdef __cplusplus 1085 } 1086 #endif 1087 1088 /*@}*/ 1089 1090 1091 #endif 1092 1093 1094 1095 1096