00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #else
00032 # define ICONV_CONST
00033 #endif
00034
00035
00036 #include "cgui_p.h"
00037 #include "i18n_l.h"
00038
00039 #include <gwenhywfar/gui_be.h>
00040 #include <gwenhywfar/inherit.h>
00041 #include <gwenhywfar/debug.h>
00042 #include <gwenhywfar/misc.h>
00043 #include <gwenhywfar/db.h>
00044 #include <gwenhywfar/gwentime.h>
00045 #include <gwenhywfar/mdigest.h>
00046 #include <gwenhywfar/text.h>
00047
00048
00049 #include <stdlib.h>
00050 #include <string.h>
00051 #include <ctype.h>
00052 #ifdef HAVE_TERMIOS_H
00053 # include <termios.h>
00054 #endif
00055 #include <unistd.h>
00056 #include <fcntl.h>
00057 #include <stdio.h>
00058 #include <errno.h>
00059
00060 #ifdef HAVE_SIGNAL_H
00061 # include <signal.h>
00062 #endif
00063 #ifdef HAVE_ICONV_H
00064 # include <iconv.h>
00065 #endif
00066
00067
00068
00069 GWEN_INHERIT(GWEN_GUI, GWEN_GUI_CGUI)
00070
00071
00072
00073
00074 GWEN_GUI *GWEN_Gui_CGui_new() {
00075 GWEN_GUI *gui;
00076 GWEN_GUI_CGUI *cgui;
00077
00078 gui=GWEN_Gui_new();
00079 GWEN_NEW_OBJECT(GWEN_GUI_CGUI, cgui);
00080 cgui->progressList=GWEN_Gui_CProgress_List_new();
00081 GWEN_INHERIT_SETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui, cgui,
00082 GWEN_Gui_CGui_FreeData);
00083
00084 GWEN_Gui_SetMessageBoxFn(gui, GWEN_Gui_CGui_MessageBox);
00085 GWEN_Gui_SetInputBoxFn(gui, GWEN_Gui_CGui_InputBox);
00086 GWEN_Gui_SetShowBoxFn(gui, GWEN_Gui_CGui_ShowBox);
00087 GWEN_Gui_SetHideBoxFn(gui, GWEN_Gui_CGui_HideBox);
00088 GWEN_Gui_SetProgressStartFn(gui, GWEN_Gui_CGui_ProgressStart);
00089 GWEN_Gui_SetProgressAdvanceFn(gui, GWEN_Gui_CGui_ProgressAdvance);
00090 GWEN_Gui_SetProgressLogFn(gui, GWEN_Gui_CGui_ProgressLog);
00091 GWEN_Gui_SetProgressEndFn(gui, GWEN_Gui_CGui_ProgressEnd);
00092 GWEN_Gui_SetSetPasswordStatusFn(gui, GWEN_Gui_CGui_SetPasswordStatus);
00093 GWEN_Gui_SetGetPasswordFn(gui, GWEN_Gui_CGui_GetPassword);
00094
00095 cgui->checkCertFn=GWEN_Gui_SetCheckCertFn(gui, GWEN_Gui_CGui_CheckCert);
00096
00097 cgui->dbPasswords=GWEN_DB_Group_new("passwords");
00098 cgui->dbCerts=GWEN_DB_Group_new("certs");
00099 cgui->badPasswords=GWEN_StringList_new();
00100
00101 return gui;
00102 }
00103
00104
00105
00106 void GWENHYWFAR_CB GWEN_Gui_CGui_FreeData(GWEN_UNUSED void *bp, void *p) {
00107 GWEN_GUI_CGUI *cgui;
00108
00109 cgui=(GWEN_GUI_CGUI*)p;
00110 GWEN_Gui_CProgress_List_free(cgui->progressList);
00111 free(cgui->charSet);
00112 GWEN_StringList_free(cgui->badPasswords);
00113 GWEN_DB_Group_free(cgui->dbCerts);
00114 GWEN_DB_Group_free(cgui->dbPasswords);
00115 GWEN_FREE_OBJECT(cgui);
00116 }
00117
00118
00119
00120 const char *GWEN_Gui_CGui_GetCharSet(const GWEN_GUI *gui) {
00121 GWEN_GUI_CGUI *cgui;
00122
00123 assert(gui);
00124 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00125 assert(cgui);
00126
00127 return cgui->charSet;
00128 }
00129
00130
00131
00132 void GWEN_Gui_CGui_SetCharSet(GWEN_GUI *gui, const char *s) {
00133 GWEN_GUI_CGUI *cgui;
00134
00135 assert(gui);
00136 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00137 assert(cgui);
00138
00139 free(cgui->charSet);
00140 if (s)
00141 cgui->charSet=strdup(s);
00142 else
00143 cgui->charSet=NULL;
00144 }
00145
00146
00147
00148 int GWEN_Gui_CGui_GetIsNonInteractive(const GWEN_GUI *gui) {
00149 return GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_NONINTERACTIVE;
00150 }
00151
00152
00153
00154 void GWEN_Gui_CGui_SetIsNonInteractive(GWEN_GUI *gui, int i) {
00155 if (i)
00156 GWEN_Gui_AddFlags(gui, GWEN_GUI_FLAGS_NONINTERACTIVE);
00157 else
00158 GWEN_Gui_SubFlags(gui, GWEN_GUI_FLAGS_NONINTERACTIVE);
00159 }
00160
00161
00162
00163 int GWEN_Gui_CGui_GetAcceptAllValidCerts(const GWEN_GUI *gui) {
00164 return GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_ACCEPTVALIDCERTS;
00165 }
00166
00167
00168
00169 void GWEN_Gui_CGui_SetAcceptAllValidCerts(GWEN_GUI *gui, int i) {
00170 if (i)
00171 GWEN_Gui_AddFlags(gui, GWEN_GUI_FLAGS_ACCEPTVALIDCERTS);
00172 else
00173 GWEN_Gui_SubFlags(gui, GWEN_GUI_FLAGS_ACCEPTVALIDCERTS);
00174 }
00175
00176
00177
00178 int GWEN_Gui_CGui__ConvertFromUtf8(GWEN_GUI *gui,
00179 const char *text,
00180 int len,
00181 GWEN_BUFFER *tbuf){
00182 GWEN_GUI_CGUI *cgui;
00183
00184 assert(gui);
00185 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00186 assert(cgui);
00187
00188 assert(len);
00189
00190 if (cgui->charSet) {
00191 if (strcasecmp(cgui->charSet, "utf-8")!=0) {
00192 #ifndef HAVE_ICONV
00193 DBG_INFO(GWEN_LOGDOMAIN,
00194 "iconv not available, can not convert to \"%s\"",
00195 cgui->charSet);
00196 #else
00197 iconv_t ic;
00198
00199 ic=iconv_open(cgui->charSet, "UTF-8");
00200 if (ic==((iconv_t)-1)) {
00201 DBG_ERROR(GWEN_LOGDOMAIN, "Charset \"%s\" not available",
00202 cgui->charSet);
00203 }
00204 else {
00205 char *outbuf;
00206 char *pOutbuf;
00207
00208
00209
00210
00211 ICONV_CONST char *pInbuf;
00212 size_t inLeft;
00213 size_t outLeft;
00214 size_t done;
00215 size_t space;
00216
00217
00218 pInbuf=(char*)text;
00219
00220 outLeft=len*2;
00221 space=outLeft;
00222 outbuf=(char*)malloc(outLeft);
00223 assert(outbuf);
00224
00225 inLeft=len;
00226 pInbuf=(char*)text;
00227 pOutbuf=outbuf;
00228 done=iconv(ic, &pInbuf, &inLeft, &pOutbuf, &outLeft);
00229 if (done==(size_t)-1) {
00230 DBG_ERROR(GWEN_LOGDOMAIN, "Error in conversion: %s (%d)",
00231 strerror(errno), errno);
00232 free(outbuf);
00233 iconv_close(ic);
00234 return GWEN_ERROR_GENERIC;
00235 }
00236
00237 GWEN_Buffer_AppendBytes(tbuf, outbuf, space-outLeft);
00238 free(outbuf);
00239 DBG_DEBUG(GWEN_LOGDOMAIN, "Conversion done.");
00240 iconv_close(ic);
00241 return 0;
00242 }
00243 #endif
00244 }
00245 }
00246
00247 GWEN_Buffer_AppendBytes(tbuf, text, len);
00248 return 0;
00249 }
00250
00251
00252
00253 void GWEN_Gui_CGui_GetRawText(GWEN_GUI *gui,
00254 const char *text,
00255 GWEN_BUFFER *tbuf) {
00256 const char *p;
00257 int rv;
00258
00259 assert(text);
00260 p=text;
00261 while ((p=strchr(p, '<'))) {
00262 const char *t;
00263
00264 t=p;
00265 t++;
00266 if (toupper(*t)=='H') {
00267 t++;
00268 if (toupper(*t)=='T') {
00269 t++;
00270 if (toupper(*t)=='M') {
00271 t++;
00272 if (toupper(*t)=='L') {
00273 break;
00274 }
00275 }
00276 }
00277 }
00278 p++;
00279 }
00280
00281 if (p)
00282 rv=GWEN_Gui_CGui__ConvertFromUtf8(gui, text, (p-text), tbuf);
00283 else
00284 rv=GWEN_Gui_CGui__ConvertFromUtf8(gui, text, strlen(text), tbuf);
00285 if (rv) {
00286 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting text");
00287 GWEN_Buffer_Reset(tbuf);
00288 if (p)
00289 GWEN_Buffer_AppendBytes(tbuf, text, (p-text));
00290 else
00291 GWEN_Buffer_AppendString(tbuf, text);
00292 }
00293 }
00294
00295
00296
00297 char GWEN_Gui_CGui__readCharFromStdin(int waitFor) {
00298 int chr;
00299 #ifdef HAVE_TERMIOS_H
00300 struct termios OldAttr, NewAttr;
00301 int AttrChanged = 0;
00302 #endif
00303 #if HAVE_DECL_SIGPROCMASK
00304 sigset_t snew, sold;
00305 #endif
00306
00307
00308 #if HAVE_DECL_SIGPROCMASK
00309 sigemptyset(&snew);
00310 sigaddset(&snew, SIGINT);
00311 sigaddset(&snew, SIGSTOP);
00312 sigprocmask(SIG_BLOCK, &snew, &sold);
00313 #endif
00314 #ifdef HAVE_TERMIOS_H
00315 if (0 == tcgetattr (fileno (stdin), &OldAttr)){
00316 NewAttr = OldAttr;
00317 NewAttr.c_lflag &= ~ICANON;
00318 NewAttr.c_lflag &= ~ECHO;
00319 tcsetattr (fileno (stdin), TCSAFLUSH, &NewAttr);
00320 AttrChanged = !0;
00321 }
00322 #endif
00323
00324 for (;;) {
00325 chr=getchar();
00326 if (waitFor) {
00327 if (chr==-1 ||
00328 chr==GWEN_GUI_CGUI_CHAR_ABORT ||
00329 chr==GWEN_GUI_CGUI_CHAR_ENTER ||
00330 chr==waitFor)
00331 break;
00332 }
00333 else
00334 break;
00335 }
00336
00337 #ifdef HAVE_TERMIOS_H
00338
00339 if (AttrChanged)
00340 tcsetattr (fileno (stdin), TCSADRAIN, &OldAttr);
00341 #endif
00342
00343 #if HAVE_DECL_SIGPROCMASK
00344 sigprocmask(SIG_BLOCK, &sold, 0);
00345 #endif
00346
00347 return chr;
00348 }
00349
00350
00351
00352 int GWEN_Gui_CGui__input(GWEN_UNUSED GWEN_GUI *gui,
00353 uint32_t flags,
00354 char *buffer,
00355 int minLen,
00356 int maxLen,
00357 uint32_t guiid){
00358 #ifdef HAVE_TERMIOS_H
00359 struct termios OldInAttr, NewInAttr;
00360 struct termios OldOutAttr, NewOutAttr;
00361 int AttrInChanged = 0;
00362 int AttrOutChanged = 0;
00363 #endif
00364 int chr;
00365 unsigned int pos;
00366 int rv;
00367 #if HAVE_DECL_SIGPROCMASK
00368 sigset_t snew, sold;
00369 #endif
00370
00371
00372
00373 #if HAVE_DECL_SIGPROCMASK
00374 sigemptyset(&snew);
00375 sigaddset(&snew, SIGINT);
00376 sigaddset(&snew, SIGSTOP);
00377 sigprocmask(SIG_BLOCK, &snew, &sold);
00378 #endif
00379
00380 #ifdef HAVE_TERMIOS_H
00381 if (0 == tcgetattr (fileno (stdin), &OldInAttr)){
00382 NewInAttr = OldInAttr;
00383 NewInAttr.c_lflag &= ~ECHO;
00384 NewInAttr.c_lflag &= ~ICANON;
00385 tcsetattr (fileno (stdin), TCSAFLUSH, &NewInAttr);
00386 AttrInChanged = !0;
00387 }
00388 if (0 == tcgetattr (fileno (stderr), &OldOutAttr)){
00389 NewOutAttr = OldOutAttr;
00390 NewOutAttr.c_lflag &= ~ICANON;
00391 tcsetattr (fileno (stderr), TCSAFLUSH, &NewOutAttr);
00392 AttrOutChanged = !0;
00393 }
00394 #endif
00395
00396 pos=0;
00397 rv=0;
00398 for (;;) {
00399 chr=getchar();
00400 if (chr==GWEN_GUI_CGUI_CHAR_DELETE) {
00401 if (pos) {
00402 pos--;
00403 fprintf(stderr, "%c %c", 8, 8);
00404 }
00405 }
00406 else if (chr==GWEN_GUI_CGUI_CHAR_ENTER) {
00407 if (minLen && pos<minLen) {
00408 if (pos==0 && (flags & GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT)) {
00409 rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_INFO |
00410 GWEN_GUI_MSG_FLAGS_CONFIRM_B1 |
00411 GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
00412 I18N("Empty Input"),
00413 I18N("Your input was empty.\n"
00414 "Do you want to use the default?"),
00415 I18N("Yes"),
00416 I18N("No"),
00417 I18N("Abort"), guiid);
00418 if (rv==1) {
00419 rv=GWEN_ERROR_DEFAULT_VALUE;
00420 break;
00421 }
00422 else {
00423 rv=GWEN_ERROR_USER_ABORTED;
00424 break;
00425 }
00426 }
00427 else {
00428
00429 fprintf(stderr, "\007");
00430 }
00431 }
00432 else {
00433 fprintf(stderr, "\n");
00434 buffer[pos]=0;
00435 rv=0;
00436 break;
00437 }
00438 }
00439 else {
00440 if (pos<maxLen) {
00441 if (chr==GWEN_GUI_CGUI_CHAR_ABORT) {
00442 DBG_INFO(GWEN_LOGDOMAIN, "User aborted");
00443 rv=GWEN_ERROR_USER_ABORTED;
00444 break;
00445 }
00446 else {
00447 if ((flags & GWEN_GUI_INPUT_FLAGS_NUMERIC) &&
00448 !isdigit(chr)) {
00449
00450 fprintf(stderr, "\007");
00451 }
00452 else {
00453 if (flags & GWEN_GUI_INPUT_FLAGS_SHOW)
00454 fprintf(stderr, "%c", chr);
00455 else
00456 fprintf(stderr, "*");
00457 buffer[pos++]=chr;
00458 buffer[pos]=0;
00459 }
00460 }
00461 }
00462 else {
00463
00464 fprintf(stderr, "\007");
00465 }
00466 }
00467 }
00468
00469 #ifdef HAVE_TERMIOS_H
00470
00471 if (AttrOutChanged)
00472 tcsetattr (fileno (stderr), TCSADRAIN, &OldOutAttr);
00473 if (AttrInChanged)
00474 tcsetattr (fileno (stdin), TCSADRAIN, &OldInAttr);
00475 #endif
00476
00477 #if HAVE_DECL_SIGPROCMASK
00478 sigprocmask(SIG_BLOCK, &sold, 0);
00479 #endif
00480 return rv;
00481 }
00482
00483
00484
00485 int GWEN_Gui_CGui_MessageBox(GWEN_GUI *gui,
00486 uint32_t flags,
00487 const char *title,
00488 const char *text,
00489 const char *b1,
00490 const char *b2,
00491 const char *b3,
00492 GWEN_UNUSED uint32_t guiid) {
00493 GWEN_GUI_CGUI *cgui;
00494 GWEN_BUFFER *tbuf;
00495 int c;
00496
00497 assert(gui);
00498 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00499 assert(cgui);
00500
00501 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00502 GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00503
00504 if (GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_NONINTERACTIVE) {
00505 if (GWEN_GUI_MSG_FLAGS_SEVERITY_IS_DANGEROUS(flags)) {
00506 fprintf(stderr,
00507 "Got the following dangerous message:\n%s\n",
00508 GWEN_Buffer_GetStart(tbuf));
00509 GWEN_Buffer_free(tbuf);
00510 return 0;
00511 }
00512 else {
00513 DBG_INFO(GWEN_LOGDOMAIN,
00514 "Auto-answering the following message with %d:\n%s",
00515 GWEN_GUI_MSG_FLAGS_CONFIRM_BUTTON(flags),
00516 GWEN_Buffer_GetStart(tbuf));
00517 GWEN_Buffer_free(tbuf);
00518 return GWEN_GUI_MSG_FLAGS_CONFIRM_BUTTON(flags);
00519 }
00520 }
00521
00522 fprintf(stderr, "===== %s =====\n", title);
00523 fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00524 GWEN_Buffer_free(tbuf);
00525 tbuf=0;
00526
00527 if (b1) {
00528 fprintf(stderr, "(1) %s", b1);
00529 if (b2) {
00530 fprintf(stderr, " (2) %s", b2);
00531 if (b3) {
00532 fprintf(stderr, " (3) %s", b3);
00533 }
00534 }
00535 fprintf(stderr, "\n");
00536 }
00537 fprintf(stderr, "Please enter your choice: ");
00538 for(;;) {
00539 c=GWEN_Gui_CGui__readCharFromStdin(0);
00540 if (c==EOF) {
00541 fprintf(stderr, "Aborted.\n");
00542 return GWEN_ERROR_USER_ABORTED;
00543 }
00544 if (!b1 && c==13)
00545 return 0;
00546 if (c=='1' && b1) {
00547 fprintf(stderr, "1\n");
00548 return 1;
00549 }
00550 else if (c=='2' && b2) {
00551 fprintf(stderr, "2\n");
00552 return 2;
00553 }
00554 else if (c=='3' && b3) {
00555 fprintf(stderr, "3\n");
00556 return 3;
00557 }
00558 else {
00559 fprintf(stderr, "%c", 7);
00560 }
00561 }
00562
00563 }
00564
00565
00566
00567 int GWEN_Gui_CGui_InputBox(GWEN_GUI *gui,
00568 uint32_t flags,
00569 const char *title,
00570 const char *text,
00571 char *buffer,
00572 int minLen,
00573 int maxLen,
00574 uint32_t guiid) {
00575 int rv;
00576 GWEN_BUFFER *tbuf;
00577
00578 assert(gui);
00579 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00580 GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00581
00582 fprintf(stderr, "===== %s =====\n", title);
00583 fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00584 GWEN_Buffer_free(tbuf);
00585 tbuf=0;
00586
00587 if (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) {
00588 for (;;) {
00589 char *lbuffer=0;
00590
00591 lbuffer=(char*)malloc(maxLen);
00592 if (!lbuffer) {
00593 DBG_ERROR(GWEN_LOGDOMAIN, "Not enough memory for %d bytes", maxLen);
00594 return GWEN_ERROR_INVALID;
00595 }
00596 fprintf(stderr, "Input: ");
00597 rv=GWEN_Gui_CGui__input(gui, flags, lbuffer, minLen, maxLen, guiid);
00598 if (rv) {
00599 free(lbuffer);
00600 return rv;
00601 }
00602
00603 fprintf(stderr, "Again: ");
00604 rv=GWEN_Gui_CGui__input(gui, flags, buffer, minLen, maxLen, guiid);
00605 if (rv) {
00606 free(lbuffer);
00607 return rv;
00608 }
00609 if (strcmp(lbuffer, buffer)!=0) {
00610 fprintf(stderr,
00611 "ERROR: Entries do not match, please try (again or abort)\n");
00612 }
00613 else {
00614 rv=0;
00615 break;
00616 }
00617
00618 }
00619 }
00620 else {
00621 fprintf(stderr, "Input: ");
00622 rv=GWEN_Gui_CGui__input(gui, flags, buffer, minLen, maxLen, guiid);
00623 }
00624
00625 return rv;
00626 }
00627
00628
00629
00630 uint32_t GWEN_Gui_CGui_ShowBox(GWEN_GUI *gui,
00631 GWEN_UNUSED uint32_t flags,
00632 const char *title,
00633 const char *text,
00634 GWEN_UNUSED uint32_t guiid) {
00635 GWEN_GUI_CGUI *cgui;
00636 GWEN_BUFFER *tbuf;
00637
00638 assert(gui);
00639 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00640 assert(cgui);
00641
00642 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00643 GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00644
00645 fprintf(stderr, "----- %s -----\n", title);
00646 fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00647 GWEN_Buffer_free(tbuf);
00648 tbuf=0;
00649
00650 return ++(cgui->nextBoxId);
00651 }
00652
00653
00654
00655 void GWEN_Gui_CGui_HideBox(GWEN_GUI *gui, GWEN_UNUSED uint32_t id) {
00656 GWEN_GUI_CGUI *cgui;
00657
00658 assert(gui);
00659 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00660 assert(cgui);
00661
00662
00663 }
00664
00665
00666
00667 uint32_t GWEN_Gui_CGui_ProgressStart(GWEN_GUI *gui,
00668 uint32_t progressFlags,
00669 const char *title,
00670 const char *text,
00671 uint64_t total,
00672 GWEN_UNUSED uint32_t guiid) {
00673 GWEN_GUI_CGUI *cgui;
00674 GWEN_GUI_CPROGRESS *cp;
00675
00676 assert(gui);
00677 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00678 assert(cgui);
00679
00680 cp=GWEN_Gui_CProgress_new(gui,
00681 ++(cgui->nextProgressId),
00682 progressFlags,
00683 title,
00684 text,
00685 total);
00686 GWEN_Gui_CProgress_List_Insert(cp, cgui->progressList);
00687 return GWEN_Gui_CProgress_GetId(cp);
00688 }
00689
00690
00691
00692 GWEN_GUI_CPROGRESS *GWEN_Gui_CGui__findProgress(GWEN_GUI *gui, uint32_t id) {
00693 GWEN_GUI_CGUI *cgui;
00694 GWEN_GUI_CPROGRESS *cp;
00695
00696 assert(gui);
00697 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00698 assert(cgui);
00699
00700 cp=GWEN_Gui_CProgress_List_First(cgui->progressList);
00701 if (id==0)
00702 return cp;
00703 while(cp) {
00704 if (GWEN_Gui_CProgress_GetId(cp)==id)
00705 break;
00706 cp=GWEN_Gui_CProgress_List_Next(cp);
00707 }
00708
00709 return cp;
00710 }
00711
00712
00713
00714 int GWEN_Gui_CGui_ProgressAdvance(GWEN_GUI *gui,
00715 uint32_t id,
00716 uint64_t progress) {
00717 GWEN_GUI_CGUI *cgui;
00718 GWEN_GUI_CPROGRESS *cp;
00719
00720 assert(gui);
00721 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00722 assert(cgui);
00723
00724 cp=GWEN_Gui_CGui__findProgress(gui, id);
00725 if (!cp) {
00726 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00727 return 0;
00728 }
00729 else {
00730 return GWEN_Gui_CProgress_Advance(cp, progress);
00731 }
00732 }
00733
00734
00735
00736 int GWEN_Gui_CGui_ProgressLog(GWEN_GUI *gui,
00737 uint32_t id,
00738 GWEN_LOGGER_LEVEL level,
00739 const char *text) {
00740 GWEN_GUI_CGUI *cgui;
00741 GWEN_GUI_CPROGRESS *cp;
00742
00743 assert(gui);
00744 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00745 assert(cgui);
00746
00747 cp=GWEN_Gui_CGui__findProgress(gui, id);
00748 if (!cp) {
00749 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00750 return 0;
00751 }
00752 else {
00753 return GWEN_Gui_CProgress_Log(cp, level, text);
00754 }
00755 }
00756
00757
00758
00759 int GWEN_Gui_CGui_ProgressEnd(GWEN_GUI *gui,uint32_t id) {
00760 GWEN_GUI_CGUI *cgui;
00761 GWEN_GUI_CPROGRESS *cp;
00762
00763 assert(gui);
00764 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00765 assert(cgui);
00766
00767 cp=GWEN_Gui_CGui__findProgress(gui, id);
00768 if (!cp) {
00769 DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00770 return 0;
00771 }
00772 else {
00773 int rv;
00774
00775 rv=GWEN_Gui_CProgress_End(cp);
00776 GWEN_Gui_CProgress_List_Del(cp);
00777 GWEN_Gui_CProgress_free(cp);
00778 return rv;
00779 }
00780 }
00781
00782
00783
00784 int GWEN_Gui_CGui_Print(GWEN_UNUSED GWEN_GUI *gui,
00785 GWEN_UNUSED const char *docTitle,
00786 GWEN_UNUSED const char *docType,
00787 GWEN_UNUSED const char *descr,
00788 GWEN_UNUSED const char *text,
00789 GWEN_UNUSED uint32_t guiid) {
00790 return GWEN_ERROR_NOT_SUPPORTED;
00791 }
00792
00793
00794
00795 int GWEN_Gui_CGui__HashPair(const char *token,
00796 const char *pin,
00797 GWEN_BUFFER *buf) {
00798 GWEN_MDIGEST *md;
00799 int rv;
00800
00801
00802 md=GWEN_MDigest_Md5_new();
00803 rv=GWEN_MDigest_Begin(md);
00804 if (rv==0)
00805 rv=GWEN_MDigest_Update(md, (const uint8_t*)token, strlen(token));
00806 if (rv==0)
00807 rv=GWEN_MDigest_Update(md, (const uint8_t*)pin, strlen(pin));
00808 if (rv==0)
00809 rv=GWEN_MDigest_End(md);
00810 if (rv<0) {
00811 DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
00812 GWEN_MDigest_free(md);
00813 return rv;
00814 }
00815
00816 GWEN_Text_ToHexBuffer((const char*)GWEN_MDigest_GetDigestPtr(md),
00817 GWEN_MDigest_GetDigestSize(md),
00818 buf,
00819 0, 0, 0);
00820 GWEN_MDigest_free(md);
00821 return 0;
00822 }
00823
00824
00825
00826 int GWEN_Gui_CGui_CheckCert(GWEN_GUI *gui,
00827 const GWEN_SSLCERTDESCR *cd,
00828 GWEN_IO_LAYER *io, uint32_t guiid) {
00829 GWEN_GUI_CGUI *cgui;
00830 const char *hash;
00831 const char *status;
00832 GWEN_BUFFER *hbuf;
00833 int i;
00834
00835 assert(gui);
00836 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00837 assert(cgui);
00838
00839 hash=GWEN_SslCertDescr_GetFingerPrint(cd);
00840 status=GWEN_SslCertDescr_GetStatusText(cd);
00841
00842 hbuf=GWEN_Buffer_new(0, 64, 0, 1);
00843 GWEN_Gui_CGui__HashPair(hash, status, hbuf);
00844
00845 i=GWEN_DB_GetIntValue(cgui->dbCerts, GWEN_Buffer_GetStart(hbuf), 0, 1);
00846 if (i==0) {
00847 DBG_NOTICE(GWEN_LOGDOMAIN,
00848 "Automatically accepting certificate [%s]",
00849 hash);
00850 GWEN_Buffer_free(hbuf);
00851 return 0;
00852 }
00853
00854 if (GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_NONINTERACTIVE) {
00855 uint32_t fl;
00856
00857 fl=GWEN_SslCertDescr_GetStatusFlags(cd);
00858 if (fl==GWEN_SSL_CERT_FLAGS_OK && (GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_ACCEPTVALIDCERTS)) {
00859 DBG_NOTICE(GWEN_LOGDOMAIN,
00860 "Automatically accepting valid new certificate [%s]",
00861 hash);
00862 GWEN_Buffer_free(hbuf);
00863 return 0;
00864 }
00865 else {
00866 DBG_NOTICE(GWEN_LOGDOMAIN,
00867 "Automatically rejecting certificate [%s] (noninteractive)",
00868 hash);
00869 GWEN_Buffer_free(hbuf);
00870 return GWEN_ERROR_USER_ABORTED;
00871 }
00872 }
00873
00874 if (cgui->checkCertFn) {
00875 i=cgui->checkCertFn(gui, cd, io, guiid);
00876 if (i==0) {
00877 GWEN_DB_SetIntValue(cgui->dbCerts, GWEN_DB_FLAGS_OVERWRITE_VARS,
00878 GWEN_Buffer_GetStart(hbuf), i);
00879 }
00880 GWEN_Buffer_free(hbuf);
00881
00882 return i;
00883 }
00884 else {
00885 GWEN_Buffer_free(hbuf);
00886 return GWEN_ERROR_NOT_SUPPORTED;
00887 }
00888 }
00889
00890
00891
00892 int GWEN_Gui_CGui_SetPasswordStatus(GWEN_GUI *gui,
00893 const char *token,
00894 const char *pin,
00895 GWEN_GUI_PASSWORD_STATUS status,
00896 GWEN_UNUSED uint32_t guiid) {
00897 GWEN_GUI_CGUI *cgui;
00898
00899 assert(gui);
00900 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00901 assert(cgui);
00902
00903 if (token==NULL && pin==NULL && status==GWEN_Gui_PasswordStatus_Remove) {
00904 if (cgui->persistentPasswords==0)
00905 GWEN_DB_ClearGroup(cgui->dbPasswords, NULL);
00906 }
00907 else {
00908 GWEN_BUFFER *hbuf;
00909
00910 hbuf=GWEN_Buffer_new(0, 64, 0, 1);
00911 GWEN_Gui_CGui__HashPair(token, pin, hbuf);
00912 if (status==GWEN_Gui_PasswordStatus_Bad)
00913 GWEN_StringList_AppendString(cgui->badPasswords,
00914 GWEN_Buffer_GetStart(hbuf),
00915 0, 1);
00916 else if (status==GWEN_Gui_PasswordStatus_Ok ||
00917 status==GWEN_Gui_PasswordStatus_Remove) {
00918 if (cgui->persistentPasswords==0)
00919 GWEN_StringList_RemoveString(cgui->badPasswords,
00920 GWEN_Buffer_GetStart(hbuf));
00921 }
00922 GWEN_Buffer_free(hbuf);
00923 }
00924
00925 return 0;
00926 }
00927
00928
00929
00930 int GWEN_Gui_CGui_GetPassword(GWEN_GUI *gui,
00931 uint32_t flags,
00932 const char *token,
00933 const char *title,
00934 const char *text,
00935 char *buffer,
00936 int minLen,
00937 int maxLen,
00938 uint32_t guiid) {
00939 GWEN_GUI_CGUI *cgui;
00940
00941 assert(gui);
00942 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00943 assert(cgui);
00944
00945 if (flags & GWEN_GUI_INPUT_FLAGS_TAN) {
00946 return GWEN_Gui_InputBox(flags,
00947 title,
00948 text,
00949 buffer,
00950 minLen,
00951 maxLen,
00952 guiid);
00953 }
00954 else {
00955 GWEN_BUFFER *buf;
00956 int rv;
00957 const char *s;
00958
00959 buf=GWEN_Buffer_new(0, 256, 0, 1);
00960 GWEN_Text_EscapeToBufferTolerant(token, buf);
00961
00962 if (!(flags & GWEN_GUI_INPUT_FLAGS_CONFIRM)) {
00963 s=GWEN_DB_GetCharValue(cgui->dbPasswords,
00964 GWEN_Buffer_GetStart(buf),
00965 0, NULL);
00966 if (s) {
00967 int i;
00968
00969 i=strlen(s);
00970 if (i>=minLen && i<=maxLen) {
00971 memmove(buffer, s, i+1);
00972 GWEN_Buffer_free(buf);
00973 return 0;
00974 }
00975 }
00976 }
00977
00978 if (GWEN_Gui_GetFlags(gui) & GWEN_GUI_FLAGS_NONINTERACTIVE) {
00979 DBG_ERROR(GWEN_LOGDOMAIN,
00980 "Password for [%s] missing in noninteractive mode, "
00981 "aborting", token);
00982 GWEN_Buffer_free(buf);
00983 return GWEN_ERROR_USER_ABORTED;
00984 }
00985
00986 for (;;) {
00987 rv=GWEN_Gui_InputBox(flags,
00988 title,
00989 text,
00990 buffer,
00991 minLen,
00992 maxLen,
00993 guiid);
00994 if (rv) {
00995 GWEN_Buffer_free(buf);
00996 return rv;
00997 }
00998 else {
00999 GWEN_BUFFER *hbuf;
01000 int isBad=0;
01001
01002 hbuf=GWEN_Buffer_new(0, 64, 0, 1);
01003 GWEN_Gui_CGui__HashPair(token, buffer, hbuf);
01004 isBad=GWEN_StringList_HasString(cgui->badPasswords,
01005 GWEN_Buffer_GetStart(hbuf));
01006 if (!isBad) {
01007 GWEN_Buffer_free(hbuf);
01008 break;
01009 }
01010 rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_ERROR |
01011 GWEN_GUI_MSG_FLAGS_CONFIRM_B1 |
01012 GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
01013 I18N("Enforce PIN"),
01014 I18N(
01015 "You entered the same PIN twice.\n"
01016 "The PIN is marked as bad, do you want\n"
01017 "to use it anyway?"
01018 "<html>"
01019 "<p>"
01020 "You entered the same PIN twice."
01021 "</p>"
01022 "<p>"
01023 "The PIN is marked as <b>bad</b>, "
01024 "do you want to use it anyway?"
01025 "</p>"
01026 "</html>"),
01027 I18N("Use my input"),
01028 I18N("Re-enter"),
01029 0,
01030 guiid);
01031 if (rv==1) {
01032
01033 GWEN_StringList_RemoveString(cgui->badPasswords,
01034 GWEN_Buffer_GetStart(hbuf));
01035 GWEN_Buffer_free(hbuf);
01036 break;
01037 }
01038 GWEN_Buffer_free(hbuf);
01039 }
01040 }
01041
01042 GWEN_DB_SetCharValue(cgui->dbPasswords, GWEN_DB_FLAGS_OVERWRITE_VARS,
01043 GWEN_Buffer_GetStart(buf), buffer);
01044 GWEN_Buffer_free(buf);
01045 return 0;
01046 }
01047 }
01048
01049
01050
01051 void GWEN_Gui_CGui_SetPasswordDb(GWEN_GUI *gui,
01052 GWEN_DB_NODE *dbPasswords,
01053 int persistent) {
01054 GWEN_GUI_CGUI *cgui;
01055
01056 assert(gui);
01057 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01058 assert(cgui);
01059
01060 GWEN_DB_Group_free(cgui->dbPasswords);
01061 cgui->dbPasswords=dbPasswords;
01062 cgui->persistentPasswords=persistent;
01063 }
01064
01065
01066
01067 GWEN_DB_NODE *GWEN_Gui_CGui_GetPasswordDb(const GWEN_GUI *gui) {
01068 GWEN_GUI_CGUI *cgui;
01069
01070 assert(gui);
01071 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01072 assert(cgui);
01073
01074 return cgui->dbPasswords;
01075 }
01076
01077
01078
01079 void GWEN_Gui_CGui_SetCertDb(GWEN_GUI *gui, GWEN_DB_NODE *dbCerts) {
01080 GWEN_GUI_CGUI *cgui;
01081
01082 assert(gui);
01083 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01084 assert(cgui);
01085
01086 GWEN_DB_Group_free(cgui->dbCerts);
01087 cgui->dbCerts=dbCerts;
01088 }
01089
01090
01091
01092 GWEN_DB_NODE *GWEN_Gui_CGui_GetCertDb(const GWEN_GUI *gui) {
01093 GWEN_GUI_CGUI *cgui;
01094
01095 assert(gui);
01096 cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01097 assert(cgui);
01098
01099 return cgui->dbCerts;
01100 }
01101
01102