cgui.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: error.h 1104 2007-01-03 09:21:32Z martin $
00005     begin       : Tue Oct 02 2002
00006     copyright   : (C) 2002 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
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   GWEN_GUI_CGUI *cgui;
00150 
00151   assert(gui);
00152   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00153   assert(cgui);
00154 
00155   return cgui->nonInteractive;
00156 }
00157 
00158 
00159 
00160 void GWEN_Gui_CGui_SetIsNonInteractive(GWEN_GUI *gui, int i) {
00161   GWEN_GUI_CGUI *cgui;
00162 
00163   assert(gui);
00164   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00165   assert(cgui);
00166 
00167   cgui->nonInteractive=i;
00168 }
00169 
00170 
00171 
00172 int GWEN_Gui_CGui_GetAcceptAllValidCerts(const GWEN_GUI *gui) {
00173   GWEN_GUI_CGUI *cgui;
00174 
00175   assert(gui);
00176   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00177   assert(cgui);
00178 
00179   return cgui->acceptAllValidCerts;
00180 }
00181 
00182 
00183 
00184 void GWEN_Gui_CGui_SetAcceptAllValidCerts(GWEN_GUI *gui, int i) {
00185   GWEN_GUI_CGUI *cgui;
00186 
00187   assert(gui);
00188   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00189   assert(cgui);
00190 
00191   cgui->acceptAllValidCerts=i;
00192 }
00193 
00194 
00195 
00196 int GWEN_Gui_CGui__ConvertFromUtf8(GWEN_GUI *gui,
00197                                    const char *text,
00198                                    int len,
00199                                    GWEN_BUFFER *tbuf){
00200   GWEN_GUI_CGUI *cgui;
00201 
00202   assert(gui);
00203   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00204   assert(cgui);
00205 
00206   assert(len);
00207 
00208   if (cgui->charSet) {
00209     if (strcasecmp(cgui->charSet, "utf-8")!=0) {
00210 #ifndef HAVE_ICONV
00211       DBG_INFO(GWEN_LOGDOMAIN,
00212                "iconv not available, can not convert to \"%s\"",
00213                cgui->charSet);
00214 #else
00215       iconv_t ic;
00216 
00217       ic=iconv_open(cgui->charSet, "UTF-8");
00218       if (ic==((iconv_t)-1)) {
00219         DBG_ERROR(GWEN_LOGDOMAIN, "Charset \"%s\" not available",
00220                   cgui->charSet);
00221       }
00222       else {
00223         char *outbuf;
00224         char *pOutbuf;
00225         /* Some systems have iconv in libc, some have it in libiconv
00226            (OSF/1 and those with the standalone portable GNU libiconv
00227            installed). Check which one is available. The define
00228            ICONV_CONST will be "" or "const" accordingly. */
00229         ICONV_CONST char *pInbuf;
00230         size_t inLeft;
00231         size_t outLeft;
00232         size_t done;
00233         size_t space;
00234 
00235         /* convert */
00236         pInbuf=(char*)text;
00237 
00238         outLeft=len*2;
00239         space=outLeft;
00240         outbuf=(char*)malloc(outLeft);
00241         assert(outbuf);
00242 
00243         inLeft=len;
00244         pInbuf=(char*)text;
00245         pOutbuf=outbuf;
00246         done=iconv(ic, &pInbuf, &inLeft, &pOutbuf, &outLeft);
00247         if (done==(size_t)-1) {
00248           DBG_ERROR(GWEN_LOGDOMAIN, "Error in conversion: %s (%d)",
00249                     strerror(errno), errno);
00250           free(outbuf);
00251           iconv_close(ic);
00252           return GWEN_ERROR_GENERIC;
00253         }
00254 
00255         GWEN_Buffer_AppendBytes(tbuf, outbuf, space-outLeft);
00256         free(outbuf);
00257         DBG_DEBUG(GWEN_LOGDOMAIN, "Conversion done.");
00258         iconv_close(ic);
00259         return 0;
00260       }
00261 #endif
00262     }
00263   }
00264 
00265   GWEN_Buffer_AppendBytes(tbuf, text, len);
00266   return 0;
00267 }
00268 
00269 
00270 
00271 void GWEN_Gui_CGui_GetRawText(GWEN_GUI *gui,
00272                               const char *text,
00273                               GWEN_BUFFER *tbuf) {
00274   const char *p;
00275   int rv;
00276 
00277   assert(text);
00278   p=text;
00279   while ((p=strchr(p, '<'))) {
00280     const char *t;
00281 
00282     t=p;
00283     t++;
00284     if (toupper(*t)=='H') {
00285       t++;
00286       if (toupper(*t)=='T') {
00287         t++;
00288         if (toupper(*t)=='M') {
00289           t++;
00290           if (toupper(*t)=='L') {
00291             break;
00292           }
00293         }
00294       }
00295     }
00296     p++;
00297   } /* while */
00298 
00299   if (p)
00300     rv=GWEN_Gui_CGui__ConvertFromUtf8(gui, text, (p-text), tbuf);
00301   else
00302     rv=GWEN_Gui_CGui__ConvertFromUtf8(gui, text, strlen(text), tbuf);
00303   if (rv) {
00304     DBG_ERROR(GWEN_LOGDOMAIN, "Error converting text");
00305     GWEN_Buffer_Reset(tbuf);
00306     if (p)
00307       GWEN_Buffer_AppendBytes(tbuf, text, (p-text));
00308     else
00309       GWEN_Buffer_AppendString(tbuf, text);
00310   }
00311 }
00312 
00313 
00314 
00315 char GWEN_Gui_CGui__readCharFromStdin(int waitFor) {
00316   int chr;
00317 #ifdef HAVE_TERMIOS_H
00318   struct termios OldAttr, NewAttr;
00319   int AttrChanged = 0;
00320 #endif
00321 #if HAVE_DECL_SIGPROCMASK
00322   sigset_t snew, sold;
00323 #endif
00324 
00325   // disable canonical mode to receive a single character
00326 #if HAVE_DECL_SIGPROCMASK
00327   sigemptyset(&snew);
00328   sigaddset(&snew, SIGINT);
00329   sigaddset(&snew, SIGSTOP);
00330   sigprocmask(SIG_BLOCK, &snew, &sold);
00331 #endif
00332 #ifdef HAVE_TERMIOS_H
00333   if (0 == tcgetattr (fileno (stdin), &OldAttr)){
00334     NewAttr = OldAttr;
00335     NewAttr.c_lflag &= ~ICANON;
00336     NewAttr.c_lflag &= ~ECHO;
00337     tcsetattr (fileno (stdin), TCSAFLUSH, &NewAttr);
00338     AttrChanged = !0;
00339   }
00340 #endif
00341 
00342   for (;;) {
00343     chr=getchar();
00344     if (waitFor) {
00345       if (chr==-1 ||
00346           chr==GWEN_GUI_CGUI_CHAR_ABORT ||
00347           chr==GWEN_GUI_CGUI_CHAR_ENTER ||
00348           chr==waitFor)
00349         break;
00350     }
00351     else
00352       break;
00353   }
00354 
00355 #ifdef HAVE_TERMIOS_H
00356   /* re-enable canonical mode (if previously disabled) */
00357   if (AttrChanged)
00358     tcsetattr (fileno (stdin), TCSADRAIN, &OldAttr);
00359 #endif
00360 
00361 #if HAVE_DECL_SIGPROCMASK
00362   sigprocmask(SIG_BLOCK, &sold, 0);
00363 #endif
00364 
00365   return chr;
00366 }
00367 
00368 
00369 
00370 int GWEN_Gui_CGui__input(GWEN_UNUSED GWEN_GUI *gui,
00371                          uint32_t flags,
00372                          char *buffer,
00373                          int minLen,
00374                          int maxLen,
00375                          uint32_t guiid){
00376 #ifdef HAVE_TERMIOS_H
00377   struct termios OldInAttr, NewInAttr;
00378   struct termios OldOutAttr, NewOutAttr;
00379   int AttrInChanged = 0;
00380   int AttrOutChanged = 0;
00381 #endif
00382   int chr;
00383   unsigned int pos;
00384   int rv;
00385 #if HAVE_DECL_SIGPROCMASK
00386   sigset_t snew, sold;
00387 #endif
00388 
00389   /* if possible, disable echo from stdin to stderr during password
00390    * entry */
00391 #if HAVE_DECL_SIGPROCMASK
00392   sigemptyset(&snew);
00393   sigaddset(&snew, SIGINT);
00394   sigaddset(&snew, SIGSTOP);
00395   sigprocmask(SIG_BLOCK, &snew, &sold);
00396 #endif
00397 
00398 #ifdef HAVE_TERMIOS_H
00399   if (0 == tcgetattr (fileno (stdin), &OldInAttr)){
00400     NewInAttr = OldInAttr;
00401     NewInAttr.c_lflag &= ~ECHO;
00402     NewInAttr.c_lflag &= ~ICANON;
00403     tcsetattr (fileno (stdin), TCSAFLUSH, &NewInAttr);
00404     AttrInChanged = !0;
00405   }
00406   if (0 == tcgetattr (fileno (stderr), &OldOutAttr)){
00407     NewOutAttr = OldOutAttr;
00408     NewOutAttr.c_lflag &= ~ICANON;
00409     tcsetattr (fileno (stderr), TCSAFLUSH, &NewOutAttr);
00410     AttrOutChanged = !0;
00411   }
00412 #endif
00413 
00414   pos=0;
00415   rv=0;
00416   for (;;) {
00417     chr=getchar();
00418     if (chr==GWEN_GUI_CGUI_CHAR_DELETE) {
00419       if (pos) {
00420         pos--;
00421         fprintf(stderr, "%c %c", 8, 8);
00422       }
00423     }
00424     else if (chr==GWEN_GUI_CGUI_CHAR_ENTER) {
00425       if (minLen && pos<minLen) {
00426         if (pos==0 && (flags & GWEN_GUI_INPUT_FLAGS_ALLOW_DEFAULT)) {
00427           rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_INFO |
00428                                  GWEN_GUI_MSG_FLAGS_CONFIRM_B1 |
00429                                  GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
00430                                  I18N("Empty Input"),
00431                                  I18N("Your input was empty.\n"
00432                                       "Do you want to use the default?"),
00433                                  I18N("Yes"),
00434                                  I18N("No"),
00435                                  I18N("Abort"), guiid);
00436           if (rv==1) {
00437             rv=GWEN_ERROR_DEFAULT_VALUE;
00438             break;
00439           }
00440           else {
00441             rv=GWEN_ERROR_USER_ABORTED;
00442             break;
00443           }
00444         }
00445         else {
00446           /* too few characters */
00447           fprintf(stderr, "\007");
00448         }
00449       }
00450       else {
00451         fprintf(stderr, "\n");
00452         buffer[pos]=0;
00453         rv=0;
00454         break;
00455       }
00456     }
00457     else {
00458       if (pos<maxLen) {
00459         if (chr==GWEN_GUI_CGUI_CHAR_ABORT) {
00460           DBG_INFO(GWEN_LOGDOMAIN, "User aborted");
00461           rv=GWEN_ERROR_USER_ABORTED;
00462           break;
00463         }
00464         else {
00465           if ((flags & GWEN_GUI_INPUT_FLAGS_NUMERIC) &&
00466               !isdigit(chr)) {
00467             /* bad character */
00468             fprintf(stderr, "\007");
00469           }
00470           else {
00471             if (flags & GWEN_GUI_INPUT_FLAGS_SHOW)
00472               fprintf(stderr, "%c", chr);
00473             else
00474               fprintf(stderr, "*");
00475             buffer[pos++]=chr;
00476             buffer[pos]=0;
00477           }
00478         }
00479       }
00480       else {
00481         /* buffer full */
00482         fprintf(stderr, "\007");
00483       }
00484     }
00485   } /* for */
00486 
00487 #ifdef HAVE_TERMIOS_H
00488   /* re-enable echo (if previously disabled) */
00489   if (AttrOutChanged)
00490     tcsetattr (fileno (stderr), TCSADRAIN, &OldOutAttr);
00491   if (AttrInChanged)
00492     tcsetattr (fileno (stdin), TCSADRAIN, &OldInAttr);
00493 #endif
00494 
00495 #if HAVE_DECL_SIGPROCMASK
00496   sigprocmask(SIG_BLOCK, &sold, 0);
00497 #endif
00498   return rv;
00499 }
00500 
00501 
00502 
00503 int GWEN_Gui_CGui_MessageBox(GWEN_GUI *gui,
00504                              uint32_t flags,
00505                              const char *title,
00506                              const char *text,
00507                              const char *b1,
00508                              const char *b2,
00509                              const char *b3,
00510                              GWEN_UNUSED uint32_t guiid) {
00511   GWEN_GUI_CGUI *cgui;
00512   GWEN_BUFFER *tbuf;
00513   int c;
00514 
00515   assert(gui);
00516   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00517   assert(cgui);
00518 
00519   tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00520   GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00521 
00522   if (cgui->nonInteractive) {
00523     if (GWEN_GUI_MSG_FLAGS_SEVERITY_IS_DANGEROUS(flags)) {
00524       fprintf(stderr,
00525               "Got the following dangerous message:\n%s\n",
00526               GWEN_Buffer_GetStart(tbuf));
00527       GWEN_Buffer_free(tbuf);
00528       return 0;
00529     }
00530     else {
00531       DBG_INFO(GWEN_LOGDOMAIN,
00532                "Auto-answering the following message with %d:\n%s",
00533                GWEN_GUI_MSG_FLAGS_CONFIRM_BUTTON(flags),
00534                GWEN_Buffer_GetStart(tbuf));
00535       GWEN_Buffer_free(tbuf);
00536       return GWEN_GUI_MSG_FLAGS_CONFIRM_BUTTON(flags);
00537     }
00538   }
00539 
00540   fprintf(stderr, "===== %s =====\n", title);
00541   fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00542   GWEN_Buffer_free(tbuf);
00543   tbuf=0;
00544 
00545   if (b1) {
00546     fprintf(stderr, "(1) %s", b1);
00547     if (b2) {
00548       fprintf(stderr, "  (2) %s", b2);
00549       if (b3) {
00550         fprintf(stderr, "  (3) %s", b3);
00551       }
00552     }
00553     fprintf(stderr, "\n");
00554   }
00555   fprintf(stderr, "Please enter your choice: ");
00556   for(;;) {
00557     c=GWEN_Gui_CGui__readCharFromStdin(0);
00558     if (c==EOF) {
00559       fprintf(stderr, "Aborted.\n");
00560       return GWEN_ERROR_USER_ABORTED;
00561     }
00562     if (!b1 && c==13)
00563       return 0;
00564     if (c=='1' && b1) {
00565       fprintf(stderr, "1\n");
00566       return 1;
00567     }
00568     else if (c=='2' && b2) {
00569       fprintf(stderr, "2\n");
00570       return 2;
00571     }
00572     else if (c=='3' && b3) {
00573       fprintf(stderr, "3\n");
00574       return 3;
00575     }
00576     else {
00577       fprintf(stderr, "%c", 7);
00578     }
00579   } /* for */
00580 
00581 }
00582 
00583 
00584 
00585 int GWEN_Gui_CGui_InputBox(GWEN_GUI *gui,
00586                            uint32_t flags,
00587                            const char *title,
00588                            const char *text,
00589                            char *buffer,
00590                            int minLen,
00591                            int maxLen,
00592                            uint32_t guiid) {
00593   int rv;
00594   GWEN_BUFFER *tbuf;
00595 
00596   assert(gui);
00597   tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00598   GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00599 
00600   fprintf(stderr, "===== %s =====\n", title);
00601   fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00602   GWEN_Buffer_free(tbuf);
00603   tbuf=0;
00604 
00605   if (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) {
00606     for (;;) {
00607       char *lbuffer=0;
00608 
00609       lbuffer=(char*)malloc(maxLen);
00610       if (!lbuffer) {
00611         DBG_ERROR(GWEN_LOGDOMAIN, "Not enough memory for %d bytes", maxLen);
00612         return GWEN_ERROR_INVALID;
00613       }
00614       fprintf(stderr, "Input: ");
00615       rv=GWEN_Gui_CGui__input(gui, flags, lbuffer, minLen, maxLen, guiid);
00616       if (rv) {
00617         free(lbuffer);
00618         return rv;
00619       }
00620 
00621       fprintf(stderr, "Again: ");
00622       rv=GWEN_Gui_CGui__input(gui, flags, buffer, minLen, maxLen, guiid);
00623       if (rv) {
00624         free(lbuffer);
00625         return rv;
00626       }
00627       if (strcmp(lbuffer, buffer)!=0) {
00628         fprintf(stderr,
00629                 "ERROR: Entries do not match, please try (again or abort)\n");
00630       }
00631       else {
00632         rv=0;
00633         break;
00634       }
00635 
00636     } /* for */
00637   }
00638   else {
00639     fprintf(stderr, "Input: ");
00640     rv=GWEN_Gui_CGui__input(gui, flags, buffer, minLen, maxLen, guiid);
00641   }
00642 
00643   return rv;
00644 }
00645 
00646 
00647 
00648 uint32_t GWEN_Gui_CGui_ShowBox(GWEN_GUI *gui,
00649                                GWEN_UNUSED uint32_t flags,
00650                                const char *title,
00651                                const char *text,
00652                                GWEN_UNUSED uint32_t guiid) {
00653   GWEN_GUI_CGUI *cgui;
00654   GWEN_BUFFER *tbuf;
00655 
00656   assert(gui);
00657   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00658   assert(cgui);
00659 
00660   tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00661   GWEN_Gui_CGui_GetRawText(gui, text, tbuf);
00662 
00663   fprintf(stderr, "----- %s -----\n", title);
00664   fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(tbuf));
00665   GWEN_Buffer_free(tbuf);
00666   tbuf=0;
00667 
00668   return ++(cgui->nextBoxId);
00669 }
00670 
00671 
00672 
00673 void GWEN_Gui_CGui_HideBox(GWEN_GUI *gui, GWEN_UNUSED uint32_t id) {
00674   GWEN_GUI_CGUI *cgui;
00675 
00676   assert(gui);
00677   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00678   assert(cgui);
00679 
00680   /* nothing to do right now */
00681 }
00682 
00683 
00684 
00685 uint32_t GWEN_Gui_CGui_ProgressStart(GWEN_GUI *gui,
00686                                      uint32_t progressFlags,
00687                                      const char *title,
00688                                      const char *text,
00689                                      uint64_t total,
00690                                      GWEN_UNUSED uint32_t guiid) {
00691   GWEN_GUI_CGUI *cgui;
00692   GWEN_GUI_CPROGRESS *cp;
00693 
00694   assert(gui);
00695   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00696   assert(cgui);
00697 
00698   cp=GWEN_Gui_CProgress_new(gui,
00699                             ++(cgui->nextProgressId),
00700                             progressFlags,
00701                             title,
00702                             text,
00703                             total);
00704   GWEN_Gui_CProgress_List_Insert(cp, cgui->progressList);
00705   return GWEN_Gui_CProgress_GetId(cp);
00706 }
00707 
00708 
00709 
00710 GWEN_GUI_CPROGRESS *GWEN_Gui_CGui__findProgress(GWEN_GUI *gui, uint32_t id) {
00711   GWEN_GUI_CGUI *cgui;
00712   GWEN_GUI_CPROGRESS *cp;
00713 
00714   assert(gui);
00715   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00716   assert(cgui);
00717 
00718   cp=GWEN_Gui_CProgress_List_First(cgui->progressList);
00719   if (id==0)
00720     return cp;
00721   while(cp) {
00722     if (GWEN_Gui_CProgress_GetId(cp)==id)
00723       break;
00724     cp=GWEN_Gui_CProgress_List_Next(cp);
00725   } /* while */
00726 
00727   return cp;
00728 }
00729 
00730 
00731 
00732 int GWEN_Gui_CGui_ProgressAdvance(GWEN_GUI *gui,
00733                                   uint32_t id,
00734                                   uint64_t progress) {
00735   GWEN_GUI_CGUI *cgui;
00736   GWEN_GUI_CPROGRESS *cp;
00737 
00738   assert(gui);
00739   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00740   assert(cgui);
00741 
00742   cp=GWEN_Gui_CGui__findProgress(gui, id);
00743   if (!cp) {
00744     DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00745     return 0;
00746   }
00747   else {
00748     return GWEN_Gui_CProgress_Advance(cp, progress);
00749   }
00750 }
00751 
00752 
00753 
00754 int GWEN_Gui_CGui_ProgressLog(GWEN_GUI *gui,
00755                               uint32_t id,
00756                               GWEN_LOGGER_LEVEL level,
00757                               const char *text) {
00758   GWEN_GUI_CGUI *cgui;
00759   GWEN_GUI_CPROGRESS *cp;
00760 
00761   assert(gui);
00762   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00763   assert(cgui);
00764 
00765   cp=GWEN_Gui_CGui__findProgress(gui, id);
00766   if (!cp) {
00767     DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00768     return 0;
00769   }
00770   else {
00771     return GWEN_Gui_CProgress_Log(cp, level, text);
00772   }
00773 }
00774 
00775 
00776 
00777 int GWEN_Gui_CGui_ProgressEnd(GWEN_GUI *gui,uint32_t id) {
00778   GWEN_GUI_CGUI *cgui;
00779   GWEN_GUI_CPROGRESS *cp;
00780 
00781   assert(gui);
00782   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00783   assert(cgui);
00784 
00785   cp=GWEN_Gui_CGui__findProgress(gui, id);
00786   if (!cp) {
00787     DBG_DEBUG(GWEN_LOGDOMAIN, "Progress object %u not found", id);
00788     return 0;
00789   }
00790   else {
00791     int rv;
00792 
00793     rv=GWEN_Gui_CProgress_End(cp);
00794     GWEN_Gui_CProgress_List_Del(cp);
00795     GWEN_Gui_CProgress_free(cp);
00796     return rv;
00797   }
00798 }
00799 
00800 
00801 
00802 int GWEN_Gui_CGui_Print(GWEN_UNUSED GWEN_GUI *gui,
00803                         GWEN_UNUSED const char *docTitle,
00804                         GWEN_UNUSED const char *docType,
00805                         GWEN_UNUSED const char *descr,
00806                         GWEN_UNUSED const char *text,
00807                         GWEN_UNUSED uint32_t guiid) {
00808   return GWEN_ERROR_NOT_SUPPORTED;
00809 }
00810 
00811 
00812 
00813 int GWEN_Gui_CGui__HashPair(const char *token,
00814                             const char *pin,
00815                             GWEN_BUFFER *buf) {
00816   GWEN_MDIGEST *md;
00817   int rv;
00818 
00819   /* hash token and pin */
00820   md=GWEN_MDigest_Md5_new();
00821   rv=GWEN_MDigest_Begin(md);
00822   if (rv==0)
00823     rv=GWEN_MDigest_Update(md, (const uint8_t*)token, strlen(token));
00824   if (rv==0)
00825     rv=GWEN_MDigest_Update(md, (const uint8_t*)pin, strlen(pin));
00826   if (rv==0)
00827     rv=GWEN_MDigest_End(md);
00828   if (rv<0) {
00829     DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
00830     GWEN_MDigest_free(md);
00831     return rv;
00832   }
00833 
00834   GWEN_Text_ToHexBuffer((const char*)GWEN_MDigest_GetDigestPtr(md),
00835                         GWEN_MDigest_GetDigestSize(md),
00836                         buf,
00837                         0, 0, 0);
00838   GWEN_MDigest_free(md);
00839   return 0;
00840 }
00841 
00842 
00843 
00844 int GWEN_Gui_CGui_CheckCert(GWEN_GUI *gui,
00845                             const GWEN_SSLCERTDESCR *cd,
00846                             GWEN_IO_LAYER *io, uint32_t guiid) {
00847   GWEN_GUI_CGUI *cgui;
00848   const char *hash;
00849   const char *status;
00850   GWEN_BUFFER *hbuf;
00851   int i;
00852 
00853   assert(gui);
00854   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00855   assert(cgui);
00856 
00857   hash=GWEN_SslCertDescr_GetFingerPrint(cd);
00858   status=GWEN_SslCertDescr_GetStatusText(cd);
00859 
00860   hbuf=GWEN_Buffer_new(0, 64, 0, 1);
00861   GWEN_Gui_CGui__HashPair(hash, status, hbuf);
00862 
00863   i=GWEN_DB_GetIntValue(cgui->dbCerts, GWEN_Buffer_GetStart(hbuf), 0, 1);
00864   if (i==0) {
00865     DBG_NOTICE(GWEN_LOGDOMAIN,
00866                "Automatically accepting certificate [%s]",
00867                hash);
00868     GWEN_Buffer_free(hbuf);
00869     return 0;
00870   }
00871 
00872   if (cgui->nonInteractive) {
00873     uint32_t fl;
00874 
00875     fl=GWEN_SslCertDescr_GetStatusFlags(cd);
00876     if (fl==GWEN_SSL_CERT_FLAGS_OK && cgui->acceptAllValidCerts) {
00877       DBG_NOTICE(GWEN_LOGDOMAIN,
00878                  "Automatically accepting valid new certificate [%s]",
00879                  hash);
00880       GWEN_Buffer_free(hbuf);
00881       return 0;
00882     }
00883     else {
00884       DBG_NOTICE(GWEN_LOGDOMAIN,
00885                  "Automatically rejecting certificate [%s] (noninteractive)",
00886                  hash);
00887       GWEN_Buffer_free(hbuf);
00888       return GWEN_ERROR_USER_ABORTED;
00889     }
00890   }
00891 
00892   if (cgui->checkCertFn) {
00893     i=cgui->checkCertFn(gui, cd, io, guiid);
00894     if (i==0) {
00895       GWEN_DB_SetIntValue(cgui->dbCerts, GWEN_DB_FLAGS_OVERWRITE_VARS,
00896                           GWEN_Buffer_GetStart(hbuf), i);
00897     }
00898     GWEN_Buffer_free(hbuf);
00899 
00900     return i;
00901   }
00902   else {
00903     GWEN_Buffer_free(hbuf);
00904     return GWEN_ERROR_NOT_SUPPORTED;
00905   }
00906 }
00907 
00908 
00909 
00910 int GWEN_Gui_CGui_SetPasswordStatus(GWEN_GUI *gui,
00911                                     const char *token,
00912                                     const char *pin,
00913                                     GWEN_GUI_PASSWORD_STATUS status,
00914                                     GWEN_UNUSED uint32_t guiid) {
00915   GWEN_GUI_CGUI *cgui;
00916 
00917   assert(gui);
00918   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00919   assert(cgui);
00920 
00921   if (token==NULL && pin==NULL && status==GWEN_Gui_PasswordStatus_Remove) {
00922     if (cgui->persistentPasswords==0)
00923       GWEN_DB_ClearGroup(cgui->dbPasswords, NULL);
00924   }
00925   else {
00926     GWEN_BUFFER *hbuf;
00927 
00928     hbuf=GWEN_Buffer_new(0, 64, 0, 1);
00929     GWEN_Gui_CGui__HashPair(token, pin, hbuf);
00930     if (status==GWEN_Gui_PasswordStatus_Bad)
00931       GWEN_StringList_AppendString(cgui->badPasswords,
00932                                    GWEN_Buffer_GetStart(hbuf),
00933                                    0, 1);
00934     else if (status==GWEN_Gui_PasswordStatus_Ok ||
00935              status==GWEN_Gui_PasswordStatus_Remove) {
00936       if (cgui->persistentPasswords==0)
00937         GWEN_StringList_RemoveString(cgui->badPasswords,
00938                                      GWEN_Buffer_GetStart(hbuf));
00939     }
00940     GWEN_Buffer_free(hbuf);
00941   }
00942 
00943   return 0;
00944 }
00945 
00946 
00947 
00948 int GWEN_Gui_CGui_GetPassword(GWEN_GUI *gui,
00949                               uint32_t flags,
00950                               const char *token,
00951                               const char *title,
00952                               const char *text,
00953                               char *buffer,
00954                               int minLen,
00955                               int maxLen,
00956                               uint32_t guiid) {
00957   GWEN_GUI_CGUI *cgui;
00958 
00959   assert(gui);
00960   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
00961   assert(cgui);
00962 
00963   if (flags & GWEN_GUI_INPUT_FLAGS_TAN) {
00964     return GWEN_Gui_InputBox(flags,
00965                              title,
00966                              text,
00967                              buffer,
00968                              minLen,
00969                              maxLen,
00970                              guiid);
00971   }
00972   else {
00973     GWEN_BUFFER *buf;
00974     int rv;
00975     const char *s;
00976   
00977     buf=GWEN_Buffer_new(0, 256, 0, 1);
00978     GWEN_Text_EscapeToBufferTolerant(token, buf);
00979 
00980     if (!(flags & GWEN_GUI_INPUT_FLAGS_CONFIRM)) {
00981       s=GWEN_DB_GetCharValue(cgui->dbPasswords,
00982                              GWEN_Buffer_GetStart(buf),
00983                              0, NULL);
00984       if (s) {
00985         int i;
00986 
00987         i=strlen(s);
00988         if (i>=minLen && i<=maxLen) {
00989           memmove(buffer, s, i+1);
00990           GWEN_Buffer_free(buf);
00991           return 0;
00992         }
00993       }
00994     }
00995 
00996     if (cgui->nonInteractive) {
00997       DBG_ERROR(GWEN_LOGDOMAIN,
00998                 "Password for [%s] missing in noninteractive mode, "
00999                 "aborting", token);
01000       GWEN_Buffer_free(buf);
01001       return GWEN_ERROR_USER_ABORTED;
01002     }
01003 
01004     for (;;) {
01005       rv=GWEN_Gui_InputBox(flags,
01006                            title,
01007                            text,
01008                            buffer,
01009                            minLen,
01010                            maxLen,
01011                            guiid);
01012       if (rv) {
01013         GWEN_Buffer_free(buf);
01014         return rv;
01015       }
01016       else {
01017         GWEN_BUFFER *hbuf;
01018         int isBad=0;
01019     
01020         hbuf=GWEN_Buffer_new(0, 64, 0, 1);
01021         GWEN_Gui_CGui__HashPair(token, buffer, hbuf);
01022         isBad=GWEN_StringList_HasString(cgui->badPasswords,
01023                                         GWEN_Buffer_GetStart(hbuf));
01024         if (!isBad) {
01025           GWEN_Buffer_free(hbuf);
01026           break;
01027         }
01028         rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_ERROR |
01029                                GWEN_GUI_MSG_FLAGS_CONFIRM_B1 |
01030                                GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
01031                                I18N("Enforce PIN"),
01032                                I18N(
01033                                     "You entered the same PIN twice.\n"
01034                                     "The PIN is marked as bad, do you want\n"
01035                                     "to use it anyway?"
01036                                     "<html>"
01037                                     "<p>"
01038                                     "You entered the same PIN twice."
01039                                     "</p>"
01040                                     "<p>"
01041                                     "The PIN is marked as <b>bad</b>, "
01042                                     "do you want to use it anyway?"
01043                                     "</p>"
01044                                     "</html>"),
01045                                I18N("Use my input"),
01046                                I18N("Re-enter"),
01047                                0,
01048                                guiid);
01049         if (rv==1) {
01050           /* accept this input */
01051           GWEN_StringList_RemoveString(cgui->badPasswords,
01052                                        GWEN_Buffer_GetStart(hbuf));
01053           GWEN_Buffer_free(hbuf);
01054           break;
01055         }
01056         GWEN_Buffer_free(hbuf);
01057       }
01058     } /* for */
01059   
01060     GWEN_DB_SetCharValue(cgui->dbPasswords, GWEN_DB_FLAGS_OVERWRITE_VARS,
01061                          GWEN_Buffer_GetStart(buf), buffer);
01062     GWEN_Buffer_free(buf);
01063     return 0;
01064   }
01065 }
01066 
01067 
01068 
01069 void GWEN_Gui_CGui_SetPasswordDb(GWEN_GUI *gui,
01070                                  GWEN_DB_NODE *dbPasswords,
01071                                  int persistent) {
01072   GWEN_GUI_CGUI *cgui;
01073 
01074   assert(gui);
01075   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01076   assert(cgui);
01077 
01078   GWEN_DB_Group_free(cgui->dbPasswords);
01079   cgui->dbPasswords=dbPasswords;
01080   cgui->persistentPasswords=persistent;
01081 }
01082 
01083 
01084 
01085 GWEN_DB_NODE *GWEN_Gui_CGui_GetPasswordDb(const GWEN_GUI *gui) {
01086   GWEN_GUI_CGUI *cgui;
01087 
01088   assert(gui);
01089   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01090   assert(cgui);
01091 
01092   return cgui->dbPasswords;
01093 }
01094 
01095 
01096 
01097 void GWEN_Gui_CGui_SetCertDb(GWEN_GUI *gui, GWEN_DB_NODE *dbCerts) {
01098   GWEN_GUI_CGUI *cgui;
01099 
01100   assert(gui);
01101   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01102   assert(cgui);
01103 
01104   GWEN_DB_Group_free(cgui->dbCerts);
01105   cgui->dbCerts=dbCerts;
01106 }
01107 
01108 
01109 
01110 GWEN_DB_NODE *GWEN_Gui_CGui_GetCertDb(const GWEN_GUI *gui) {
01111   GWEN_GUI_CGUI *cgui;
01112 
01113   assert(gui);
01114   cgui=GWEN_INHERIT_GETDATA(GWEN_GUI, GWEN_GUI_CGUI, gui);
01115   assert(cgui);
01116 
01117   return cgui->dbCerts;
01118 }
01119 
01120 

doxygen