gwenhywfar 4.0.3

cgui.c

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