gwenhywfar  4.6.0beta
gui.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Feb 07 2003
3  copyright : (C) 2003-2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 
33 #ifndef ICONV_CONST
34 # define ICONV_CONST
35 #endif
36 
37 
38 #include "gui_p.h"
39 #include "dlg_input_l.h"
40 #include "dlg_message_l.h"
41 #include "dlg_progress_l.h"
42 #include "dlg_showbox_l.h"
43 #include "i18n_l.h"
44 
45 #include <gwenhywfar/debug.h>
46 #include <gwenhywfar/dialog_be.h>
47 #include <gwenhywfar/mdigest.h>
48 #include <gwenhywfar/text.h>
49 #include <gwenhywfar/url.h>
50 #include <gwenhywfar/syncio_socket.h>
51 #include <gwenhywfar/syncio_buffered.h>
52 #include <gwenhywfar/syncio_tls.h>
53 #include <gwenhywfar/syncio_http.h>
54 
55 #include <stdarg.h>
56 #include <string.h>
57 #include <errno.h>
58 #include <ctype.h>
59 
60 #ifdef HAVE_ICONV_H
61 # include <iconv.h>
62 #endif
63 
64 
65 
67 
68 
70 
71 
72 
74  GWEN_GUI *gui;
75 
78  gui->refCount=1;
79 
80  gui->checkCertFn=GWEN_Gui_CheckCertBuiltIn;
81  gui->getSyncIoFn=GWEN_Gui_Internal_GetSyncIo;
82 
83  gui->getPasswordFn=GWEN_Gui_Internal_GetPassword;
84  gui->setPasswordStatusFn=GWEN_Gui_Internal_SetPasswordStatus;
85 
86  gui->progressDataTree=GWEN_ProgressData_Tree_new();
87  gui->activeDialogs=GWEN_Dialog_List_new();
88 
89  gui->dbPasswords=GWEN_DB_Group_new("passwords");
90  gui->badPasswords=GWEN_StringList_new();
91 
92  gui->minProgressLogLevel=GWEN_LoggerLevel_Info;
93 
94  return gui;
95 }
96 
97 
98 
99 void GWEN_Gui_free(GWEN_GUI *gui) {
100  if (gui) {
101  assert(gui->refCount);
102  if ((--gui->refCount)==0) {
104 
105  GWEN_Dialog_List_free(gui->activeDialogs);
106  GWEN_ProgressData_Tree_free(gui->progressDataTree);
107  free(gui->name);
108  free(gui->charSet);
109 
110  GWEN_StringList_free(gui->badPasswords);
111  GWEN_DB_Group_free(gui->dbPasswords);
112  if (gui->passwdStore)
113  GWEN_PasswordStore_free(gui->passwdStore);
114 
115  GWEN_FREE_OBJECT(gui);
116  }
117  }
118 }
119 
120 
121 
123  assert(gui);
124  DBG_INFO(GWEN_LOGDOMAIN, "Using own callbacks in gui %p", gui);
125  gui->progressStartFn=GWEN_Gui_Internal_ProgressStart;
126  gui->progressAdvanceFn=GWEN_Gui_Internal_ProgressAdvance;
127  gui->progressSetTotalFn=GWEN_Gui_Internal_ProgressSetTotal;
128  gui->progressLogFn=GWEN_Gui_Internal_ProgressLog;
129  gui->progressEndFn=GWEN_Gui_Internal_ProgressEnd;
130  gui->inputBoxFn=GWEN_Gui_Internal_InputBox;
131  gui->messageBoxFn=GWEN_Gui_Internal_MessageBox;
132  gui->showBoxFn=GWEN_Gui_Internal_ShowBox;
133  gui->hideBoxFn=GWEN_Gui_Internal_HideBox;
134 }
135 
136 
137 
139  assert(gui);
140  assert(gui->refCount);
141  gui->refCount++;
142 }
143 
144 
145 
147  if (gui)
148  GWEN_Gui_Attach(gui);
149  if (gwenhywfar_gui)
151  gwenhywfar_gui=gui;
152 }
153 
154 
155 
157  return gwenhywfar_gui;
158 }
159 
160 
161 
162 int GWEN_Gui_ConvertFromUtf8(const GWEN_GUI *gui, const char *text, int len, GWEN_BUFFER *tbuf) {
163  assert(gui);
164  assert(len);
165 
166  if (gui->charSet) {
167  if (strcasecmp(gui->charSet, "utf-8")!=0) {
168 #ifndef HAVE_ICONV
170  "iconv not available, can not convert to \"%s\"",
171  gui->charSet);
172 #else
173  iconv_t ic;
174 
175  ic=iconv_open(gui->charSet, "UTF-8");
176  if (ic==((iconv_t)-1)) {
177  DBG_ERROR(GWEN_LOGDOMAIN, "Charset \"%s\" not available",
178  gui->charSet);
179  }
180  else {
181  char *outbuf;
182  char *pOutbuf;
183  /* Some systems have iconv in libc, some have it in libiconv
184  (OSF/1 and those with the standalone portable GNU libiconv
185  installed). Check which one is available. The define
186  ICONV_CONST will be "" or "const" accordingly. */
187  ICONV_CONST char *pInbuf;
188  size_t inLeft;
189  size_t outLeft;
190  size_t done;
191  size_t space;
192 
193  /* convert */
194  pInbuf=(char*)text;
195 
196  outLeft=len*2;
197  space=outLeft;
198  outbuf=(char*)malloc(outLeft);
199  assert(outbuf);
200 
201  inLeft=len;
202  pInbuf=(char*)text;
203  pOutbuf=outbuf;
204  done=iconv(ic, &pInbuf, &inLeft, &pOutbuf, &outLeft);
205  if (done==(size_t)-1) {
206  DBG_ERROR(GWEN_LOGDOMAIN, "Error in conversion: %s (%d)",
207  strerror(errno), errno);
208  free(outbuf);
209  iconv_close(ic);
210  return GWEN_ERROR_GENERIC;
211  }
212 
213  GWEN_Buffer_AppendBytes(tbuf, outbuf, space-outLeft);
214  free(outbuf);
215  DBG_DEBUG(GWEN_LOGDOMAIN, "Conversion done.");
216  iconv_close(ic);
217  return 0;
218  }
219 #endif
220  }
221  }
222 
223  GWEN_Buffer_AppendBytes(tbuf, text, len);
224  return 0;
225 }
226 
227 
228 
229 void GWEN_Gui_GetRawText(const GWEN_GUI *gui, const char *text, GWEN_BUFFER *tbuf) {
230  const char *p;
231  int rv;
232 
233  assert(text);
234  p=text;
235  while ((p=strchr(p, '<'))) {
236  const char *t;
237 
238  t=p;
239  t++;
240  if (toupper(*t)=='H') {
241  t++;
242  if (toupper(*t)=='T') {
243  t++;
244  if (toupper(*t)=='M') {
245  t++;
246  if (toupper(*t)=='L') {
247  break;
248  }
249  }
250  }
251  }
252  p++;
253  } /* while */
254 
255  if (p)
256  rv=GWEN_Gui_ConvertFromUtf8(gui, text, (p-text), tbuf);
257  else
258  rv=GWEN_Gui_ConvertFromUtf8(gui, text, strlen(text), tbuf);
259  if (rv) {
260  DBG_ERROR(GWEN_LOGDOMAIN, "Error converting text");
261  GWEN_Buffer_Reset(tbuf);
262  if (p)
263  GWEN_Buffer_AppendBytes(tbuf, text, (p-text));
264  else
265  GWEN_Buffer_AppendString(tbuf, text);
266  }
267 }
268 
269 
270 
274 
275  assert(gui);
276  of=gui->messageBoxFn;
277  gui->messageBoxFn=f;
278  return of;
279 }
280 
281 
282 
286 
287  assert(gui);
288  of=gui->inputBoxFn;
289  gui->inputBoxFn=f;
290  return of;
291 }
292 
293 
294 
298 
299  assert(gui);
300  of=gui->showBoxFn;
301  gui->showBoxFn=f;
302  return of;
303 }
304 
305 
306 
310 
311  assert(gui);
312  of=gui->hideBoxFn;
313  gui->hideBoxFn=f;
314  return of;
315 }
316 
317 
318 
322 
323  assert(gui);
324  of=gui->progressStartFn;
325  gui->progressStartFn=f;
326  return of;
327 }
328 
329 
330 
334 
335  assert(gui);
336  of=gui->progressAdvanceFn;
337  gui->progressAdvanceFn=f;
338  return of;
339 }
340 
341 
342 
346 
347  assert(gui);
348  of=gui->progressSetTotalFn;
349  gui->progressSetTotalFn=f;
350  return of;
351 }
352 
353 
354 
358 
359  assert(gui);
360  of=gui->progressLogFn;
361  gui->progressLogFn=f;
362  return of;
363 }
364 
365 
366 
370 
371  assert(gui);
372  of=gui->progressEndFn;
373  gui->progressEndFn=f;
374  return of;
375 }
376 
377 
378 
382 
383  assert(gui);
384  of=gui->printFn;
385  gui->printFn=f;
386  return of;
387 }
388 
389 
390 
394 
395  assert(gui);
396  of=gui->getPasswordFn;
397  gui->getPasswordFn=f;
398  return of;
399 }
400 
401 
402 
407 
408  assert(gui);
409  of=gui->setPasswordStatusFn;
410  gui->setPasswordStatusFn=f;
411  return of;
412 }
413 
414 
415 
419 
420  assert(gui);
421  of=gui->logHookFn;
422  gui->logHookFn=f;
423 
424  return of;
425 }
426 
427 
428 
432 
433  assert(gui);
434  of=gui->waitForSocketsFn;
435  gui->waitForSocketsFn=f;
436 
437  return of;
438 }
439 
440 
441 
444 
445  assert(gui);
446  of=gui->checkCertFn;
447  gui->checkCertFn=f;
448 
449  return of;
450 }
451 
452 
453 
456 
457  assert(gui);
458  of=gui->execDialogFn;
459  gui->execDialogFn=f;
460 
461  return of;
462 }
463 
464 
465 
468 
469  assert(gui);
470  of=gui->openDialogFn;
471  gui->openDialogFn=f;
472 
473  return of;
474 }
475 
476 
477 
480 
481  assert(gui);
482  of=gui->closeDialogFn;
483  gui->closeDialogFn=f;
484 
485  return of;
486 }
487 
488 
489 
492 
493  assert(gui);
494  of=gui->runDialogFn;
495  gui->runDialogFn=f;
496 
497  return of;
498 }
499 
500 
501 
505 
506  assert(gui);
507  of=gui->readDialogPrefsFn;
508  gui->readDialogPrefsFn=f;
509 
510  return of;
511 }
512 
513 
514 
518 
519  assert(gui);
520  of=gui->writeDialogPrefsFn;
521  gui->writeDialogPrefsFn=f;
522 
523  return of;
524 }
525 
526 
527 
530 
531  assert(gui);
532  of=gui->getFileNameFn;
533  gui->getFileNameFn=f;
534 
535  return of;
536 }
537 
538 
539 
542 
543  assert(gui);
544  of=gui->getSyncIoFn;
545  gui->getSyncIoFn=f;
546 
547  return of;
548 }
549 
550 
551 
556 
557  assert(gui);
558  of=gui->keyDataFromTextOpenSslFn;
559  gui->keyDataFromTextOpenSslFn=f;
560 
561  return of;
562 
563 }
564 
565 
566 
567 uint32_t GWEN_Gui_GetFlags(const GWEN_GUI *gui) {
568  assert(gui);
569  return gui->flags;
570 }
571 
572 
573 
574 void GWEN_Gui_SetFlags(GWEN_GUI *gui, uint32_t fl) {
575  assert(gui);
576  gui->flags=fl;
577 }
578 
579 
580 
581 void GWEN_Gui_AddFlags(GWEN_GUI *gui, uint32_t fl) {
582  assert(gui);
583  gui->flags|=fl;
584 }
585 
586 
587 
588 void GWEN_Gui_SubFlags(GWEN_GUI *gui, uint32_t fl) {
589  assert(gui);
590  gui->flags&=~fl;
591 }
592 
593 
594 
595 void GWEN_Gui_SetName(GWEN_GUI *gui, const char *name) {
596  free(gui->name);
597  if (name) gui->name=strdup(name);
598  else gui->name=NULL;
599 }
600 
601 
602 
603 const char *GWEN_Gui_GetName(void) {
604  if (gwenhywfar_gui)
605  return gwenhywfar_gui->name;
606  return NULL;
607 }
608 
609 
610 
611 const char *GWEN_Gui_GetCharSet(const GWEN_GUI *gui) {
612  if (gui)
613  return gui->charSet;
614  return NULL;
615 }
616 
617 
618 
619 void GWEN_Gui_SetCharSet(GWEN_GUI *gui, const char *s) {
620  if (gui) {
621  free(gui->charSet);
622  if (s)
623  gui->charSet=strdup(s);
624  else
625  gui->charSet=NULL;
626  }
627 }
628 
629 
630 
632  if (gui)
633  return gui->passwdStore;
634  return NULL;
635 }
636 
637 
638 
640  if (gui) {
641  if (gui->passwdStore && gui->passwdStore!=sto)
642  GWEN_PasswordStore_free(gui->passwdStore);
643  gui->passwdStore=sto;
644  if (sto)
645  gui->flags|=GWEN_GUI_FLAGS_PERMPASSWORDS;
646  }
647 }
648 
649 
650 
652  GWEN_DB_NODE *dbPasswords,
653  int persistent) {
654  GWEN_DB_Group_free(gui->dbPasswords);
655  gui->dbPasswords=dbPasswords;
656  gui->persistentPasswords=persistent;
657 }
658 
659 
660 
662  return gui->dbPasswords;
663 }
664 
665 
666 
667 
668 
669 
670 
671 
672 
673 
674 
675 
676 int GWEN_Gui_MessageBox(uint32_t flags,
677  const char *title,
678  const char *text,
679  const char *b1,
680  const char *b2,
681  const char *b3,
682  uint32_t guiid) {
683  if (gwenhywfar_gui && gwenhywfar_gui->messageBoxFn)
684  return gwenhywfar_gui->messageBoxFn(gwenhywfar_gui,
685  flags,
686  title,
687  text,
688  b1, b2, b3, guiid);
690 }
691 
692 
693 
694 void GWEN_Gui_ShowError(const char *title, const char *fmt, ...) {
695  va_list list;
696  char msgbuffer[2048];
697  int rv;
698 
699  /* prepare list for va_arg */
700  va_start(list, fmt);
701  rv=vsnprintf(msgbuffer, sizeof(msgbuffer), fmt, list);
702  if (rv<0 || rv>=(int)(sizeof(msgbuffer))) {
703  DBG_WARN(GWEN_LOGDOMAIN, "Internal buffer too small for message, truncating (%d>%d)",
704  rv, (int)(sizeof(msgbuffer)));
705  }
706 
710  title,
711  msgbuffer,
712  I18N("Dismiss"), NULL, NULL, 0);
713 }
714 
715 
716 
717 int GWEN_Gui_InputBox(uint32_t flags,
718  const char *title,
719  const char *text,
720  char *buffer,
721  int minLen,
722  int maxLen,
723  uint32_t guiid) {
724  if (gwenhywfar_gui && gwenhywfar_gui->inputBoxFn)
725  return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui,
726  flags,
727  title,
728  text,
729  buffer,
730  minLen, maxLen, guiid);
732 }
733 
734 
735 
736 uint32_t GWEN_Gui_ShowBox(uint32_t flags,
737  const char *title,
738  const char *text,
739  uint32_t guiid) {
740  if (gwenhywfar_gui && gwenhywfar_gui->showBoxFn)
741  return gwenhywfar_gui->showBoxFn(gwenhywfar_gui,
742  flags,
743  title,
744  text,
745  guiid);
746  return 0;
747 }
748 
749 
750 
751 void GWEN_Gui_HideBox(uint32_t id) {
752  if (gwenhywfar_gui && gwenhywfar_gui->hideBoxFn)
753  return gwenhywfar_gui->hideBoxFn(gwenhywfar_gui, id);
754 }
755 
756 
757 
758 uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags,
759  const char *title,
760  const char *text,
761  uint64_t total,
762  uint32_t guiid) {
763  if (gwenhywfar_gui && gwenhywfar_gui->progressStartFn)
764  return gwenhywfar_gui->progressStartFn(gwenhywfar_gui,
765  progressFlags,
766  title,
767  text,
768  total,
769  guiid);
770  return 0;
771 }
772 
773 
774 
775 int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress) {
776  if (gwenhywfar_gui && gwenhywfar_gui->progressAdvanceFn)
777  return gwenhywfar_gui->progressAdvanceFn(gwenhywfar_gui,
778  id,
779  progress);
780  return 0;
781 }
782 
783 
784 
785 int GWEN_Gui_ProgressSetTotal(uint32_t id, uint64_t total) {
786  if (gwenhywfar_gui && gwenhywfar_gui->progressSetTotalFn)
787  return gwenhywfar_gui->progressSetTotalFn(gwenhywfar_gui,
788  id,
789  total);
790  return 0;
791 }
792 
793 
794 
795 int GWEN_Gui_ProgressLog(uint32_t id,
796  GWEN_LOGGER_LEVEL level,
797  const char *text) {
798  if (gwenhywfar_gui && gwenhywfar_gui->progressLogFn)
799  return gwenhywfar_gui->progressLogFn(gwenhywfar_gui,
800  id, level, text);
801  return 0;
802 }
803 
804 
805 
806 int GWEN_Gui_ProgressLog2(uint32_t id,
807  GWEN_LOGGER_LEVEL level,
808  const char *fmt, ...) {
809  va_list list;
810  char msgbuffer[2048];
811  int rv;
812 
813  /* prepare list for va_arg */
814  va_start(list, fmt);
815  rv=vsnprintf(msgbuffer, sizeof(msgbuffer), fmt, list);
816  if (rv<0 || rv>=(int)(sizeof(msgbuffer))) {
817  DBG_WARN(GWEN_LOGDOMAIN, "Internal buffer too small for message, truncating (%d>%d)",
818  rv, (int)(sizeof(msgbuffer)));
819  }
820 
821  return GWEN_Gui_ProgressLog(id, level, msgbuffer);
822 }
823 
824 
825 
826 int GWEN_Gui_ProgressEnd(uint32_t id) {
827  if (gwenhywfar_gui && gwenhywfar_gui->progressEndFn)
828  return gwenhywfar_gui->progressEndFn(gwenhywfar_gui, id);
830 }
831 
832 
833 
834 int GWEN_Gui_Print(const char *docTitle,
835  const char *docType,
836  const char *descr,
837  const char *text,
838  uint32_t guiid) {
839  if (gwenhywfar_gui && gwenhywfar_gui->printFn)
840  return gwenhywfar_gui->printFn(gwenhywfar_gui,
841  docTitle,
842  docType,
843  descr,
844  text,
845  guiid);
847 }
848 
849 
850 
851 int GWEN_Gui_GetPassword(uint32_t flags,
852  const char *token,
853  const char *title,
854  const char *text,
855  char *buffer,
856  int minLen,
857  int maxLen,
858  uint32_t guiid) {
859  if (gwenhywfar_gui) {
860  if (gwenhywfar_gui->getPasswordFn)
861  return gwenhywfar_gui->getPasswordFn(gwenhywfar_gui,
862  flags,
863  token,
864  title,
865  text,
866  buffer,
867  minLen,
868  maxLen,
869  guiid);
870  else
871  if (gwenhywfar_gui->inputBoxFn)
872  return gwenhywfar_gui->inputBoxFn(gwenhywfar_gui,
873  flags,
874  title,
875  text,
876  buffer,
877  minLen,
878  maxLen,
879  guiid);
880  }
882 }
883 
884 
885 
886 int GWEN_Gui_SetPasswordStatus(const char *token,
887  const char *pin,
889  uint32_t guiid) {
890  if (gwenhywfar_gui && gwenhywfar_gui->setPasswordStatusFn)
891  return gwenhywfar_gui->setPasswordStatusFn(gwenhywfar_gui,
892  token, pin, status, guiid);
894 }
895 
896 
897 
898 int GWEN_Gui_LogHook(const char *logDomain,
899  GWEN_LOGGER_LEVEL priority, const char *s) {
900  if (gwenhywfar_gui && gwenhywfar_gui->logHookFn) {
901  if (priority>=GWEN_LoggerLevel_Debug &&
902  logDomain &&
903  strcasecmp(logDomain, "gwenhywfar")==0)
904  /* don't send possibly sensitive data to the log function because
905  * some application tend to store the messages indiscriminately.
906  * In some cases sensitive information can be send to this function
907  * which we don't want the application to store */
908  return 0;
909  else {
910  int rv;
911 
912  if (gwenhywfar_gui->inLogHook==0) {
913  /* otherwise the log message seems to be uncritical, convey it */
914  gwenhywfar_gui->inLogHook++;
915  rv=gwenhywfar_gui->logHookFn(gwenhywfar_gui, logDomain, priority, s);
916  gwenhywfar_gui->inLogHook--;
917  return rv;
918  }
919  else
920  /* loghook recursion, don't convey */
921  return 0;
922  }
923  }
924  else
925  /* handle as usual */
926  return 0;
927 }
928 
929 
930 
931 int GWEN_Gui_WaitForSockets(GWEN_SOCKET_LIST2 *readSockets,
932  GWEN_SOCKET_LIST2 *writeSockets,
933  uint32_t guiid,
934  int msecs) {
935  if (gwenhywfar_gui && gwenhywfar_gui->waitForSocketsFn)
936  return gwenhywfar_gui->waitForSocketsFn(gwenhywfar_gui, readSockets, writeSockets, guiid, msecs);
937  else {
938  uint32_t pid;
939  time_t t0;
940  int wt;
941  int dist;
942 
943  t0=time(0);
944  if (msecs==GWEN_TIMEOUT_NONE) {
945  wt=0;
946  dist=0;
947  }
948  else if (msecs==GWEN_TIMEOUT_FOREVER) {
949  wt=0;
950  dist=500;
951  }
952  else {
953  wt=msecs/1000;
954  dist=500;
955  }
956 
961  I18N("Waiting for Data"),
962  "Waiting for data to become available",
963  wt,
964  0);
965  while(1) {
966  GWEN_SOCKETSET *rset;
967  GWEN_SOCKETSET *wset;
968  GWEN_SOCKET_LIST2_ITERATOR *sit;
969 
970  rset=GWEN_SocketSet_new();
971  wset=GWEN_SocketSet_new();
972 
973  /* fill read socket set */
974  if (readSockets) {
975  sit=GWEN_Socket_List2_First(readSockets);
976  if (sit) {
977  GWEN_SOCKET *s;
978 
979  s=GWEN_Socket_List2Iterator_Data(sit);
980  assert(s);
981 
982  while(s) {
983  GWEN_SocketSet_AddSocket(rset, s);
984  s=GWEN_Socket_List2Iterator_Next(sit);
985  }
986  GWEN_Socket_List2Iterator_free(sit);
987  }
988  }
989 
990  /* fill write socket set */
991  if (writeSockets) {
992  sit=GWEN_Socket_List2_First(writeSockets);
993  if (sit) {
994  GWEN_SOCKET *s;
995 
996  s=GWEN_Socket_List2Iterator_Data(sit);
997  assert(s);
998 
999  while(s) {
1000  GWEN_SocketSet_AddSocket(wset, s);
1001  s=GWEN_Socket_List2Iterator_Next(sit);
1002  }
1003  GWEN_Socket_List2Iterator_free(sit);
1004  }
1005  }
1006 
1007  if (GWEN_SocketSet_GetSocketCount(rset)==0 &&
1008  GWEN_SocketSet_GetSocketCount(wset)==0) {
1009  /* no sockets to wait for, sleep for a few ms to keep cpu load down */
1010  GWEN_SocketSet_free(wset);
1011  GWEN_SocketSet_free(rset);
1012 
1013  if (msecs) {
1014  /* only sleep if a timeout was given */
1015  DBG_DEBUG(GWEN_LOGDOMAIN, "Sleeping (no socket)");
1017  }
1018  GWEN_Gui_ProgressEnd(pid);
1019  return GWEN_ERROR_TIMEOUT;
1020  }
1021  else {
1022  int rv;
1023  int v=0;
1024 
1025  rv=GWEN_Socket_Select(rset, wset, NULL, dist);
1026  GWEN_SocketSet_free(wset);
1027  GWEN_SocketSet_free(rset);
1028 
1029  if (rv!=GWEN_ERROR_TIMEOUT) {
1030  GWEN_Gui_ProgressEnd(pid);
1031  return rv;
1032  }
1033 
1034  if (wt) {
1035  time_t t1;
1036 
1037  t1=time(0);
1038  v=(int) difftime(t1, t0);
1039  if (v>wt) {
1040  GWEN_Gui_ProgressEnd(pid);
1041  return GWEN_ERROR_TIMEOUT;
1042  }
1043  }
1044  rv=GWEN_Gui_ProgressAdvance(pid, v);
1045  if (rv==GWEN_ERROR_USER_ABORTED) {
1046  GWEN_Gui_ProgressEnd(pid);
1047  return rv;
1048  }
1049  }
1050  } /* loop */
1051  }
1052 }
1053 
1054 
1055 
1056 int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cd, GWEN_SYNCIO *sio, uint32_t guiid) {
1057  if (gwenhywfar_gui && gwenhywfar_gui->checkCertFn)
1058  return gwenhywfar_gui->checkCertFn(gwenhywfar_gui, cd, sio, guiid);
1059  else
1061 }
1062 
1063 
1064 
1066  const GWEN_SSLCERTDESCR *cd,
1067  GWEN_UNUSED GWEN_SYNCIO *sio, uint32_t guiid) {
1068  int rv;
1069  int isError;
1070  const char *hash;
1071  const char *status;
1072  const char *ipAddr;
1073  const char *statusOn;
1074  const char *statusOff;
1075  char varName[128];
1076  char dbuffer1[32];
1077  char dbuffer2[32];
1078  char buffer[8192];
1079  const GWEN_TIME *ti;
1080  const char *unknown;
1081  const char *commonName;
1082  const char *organizationName;
1083  const char *organizationalUnitName;
1084  const char *countryName;
1085  const char *localityName;
1086  const char *stateOrProvinceName;
1087 
1088  char *msg=I18S(
1089  "The following certificate has been received:\n"
1090  "Name : %s\n"
1091  "Organisation: %s\n"
1092  "Department : %s\n"
1093  "Country : %s\n"
1094  "City : %s\n"
1095  "State : %s\n"
1096  "Valid after : %s\n"
1097  "Valid until : %s\n"
1098  "Hash : %s\n"
1099  "Status : %s\n"
1100  "Do you wish to accept this certificate?"
1101 
1102  "<html>"
1103  " <p>"
1104  " The following certificate has been received:"
1105  " </p>"
1106  " <table>"
1107  " <tr><td>Name</td><td>%s</td></tr>"
1108  " <tr><td>Organisation</td><td>%s</td></tr>"
1109  " <tr><td>Department</td><td>%s</td></tr>"
1110  " <tr><td>Country</td><td>%s</td></tr>"
1111  " <tr><td>City</td><td>%s</td></tr>"
1112  " <tr><td>State</td><td>%s</td></tr>"
1113  " <tr><td>Valid after</td><td>%s</td></tr>"
1114  " <tr><td>Valid until</td><td>%s</td></tr>"
1115  " <tr><td>Hash</td><td>%s</td></tr>"
1116  " <tr><td>Status</td><td>%s%s%s</td></tr>"
1117  " </table>"
1118  " <p>"
1119  " Do you wish to accept this certificate?"
1120  " </p>"
1121  "</html>"
1122  );
1123 
1124  memset(dbuffer1, 0, sizeof(dbuffer1));
1125  memset(dbuffer2, 0, sizeof(dbuffer2));
1126  memset(varName, 0, sizeof(varName));
1127 
1128  isError=GWEN_SslCertDescr_GetIsError(cd);
1129 
1132  ipAddr=GWEN_SslCertDescr_GetIpAddress(cd);
1133 
1135  if (ti) {
1136  GWEN_BUFFER *tbuf;
1137 
1138  tbuf=GWEN_Buffer_new(0, 32, 0, 1);
1139  /* TRANSLATORS: This string is used as a template string to
1140  convert a given time into your local translated timeformat. The
1141  following characters are accepted in the template string: Y -
1142  digit of the year, M - digit of the month, D - digit of the day
1143  of month, h - digit of the hour, m - digit of the minute, s-
1144  digit of the second. All other characters are left unchanged. */
1145  if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) {
1147  "Could not convert beforeDate to string");
1148  abort();
1149  }
1150  strncpy(dbuffer1, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer1)-1);
1151  GWEN_Buffer_free(tbuf);
1152  }
1153 
1155  if (ti) {
1156  GWEN_BUFFER *tbuf;
1157 
1158  tbuf=GWEN_Buffer_new(0, 32, 0, 1);
1159  if (GWEN_Time_toString(ti, I18N("YYYY/MM/DD hh:mm:ss"), tbuf)) {
1161  "Could not convert untilDate to string");
1162  abort();
1163  }
1164  strncpy(dbuffer2, GWEN_Buffer_GetStart(tbuf), sizeof(dbuffer2)-1);
1165  GWEN_Buffer_free(tbuf);
1166  }
1167 
1168  if (isError) {
1169  statusOn="<font color=red>";
1170  statusOff="</font>";
1171  }
1172  else {
1173  statusOn="<font color=green>";
1174  statusOff="</font>";
1175  }
1176 
1177  unknown=I18N("unknown");
1178  commonName=GWEN_SslCertDescr_GetCommonName(cd);
1179  if (!commonName)
1180  commonName=unknown;
1181  organizationName=GWEN_SslCertDescr_GetOrganizationName(cd);
1182  if (!organizationName)
1183  organizationName=unknown;
1184  organizationalUnitName=GWEN_SslCertDescr_GetOrganizationalUnitName(cd);
1185  if (!organizationalUnitName)
1186  organizationalUnitName=unknown;
1187  countryName=GWEN_SslCertDescr_GetCountryName(cd);
1188  if (!countryName)
1189  countryName=unknown;
1190  localityName=GWEN_SslCertDescr_GetLocalityName(cd);
1191  if (!localityName)
1192  localityName=unknown;
1193  stateOrProvinceName=GWEN_SslCertDescr_GetStateOrProvinceName(cd);
1194  if (!stateOrProvinceName)
1195  stateOrProvinceName=unknown;
1196  if (!status)
1197  status=unknown;
1198 
1199  snprintf(buffer, sizeof(buffer)-1,
1200  I18N(msg),
1201  commonName,
1202  organizationName,
1203  organizationalUnitName,
1204  countryName,
1205  localityName,
1206  stateOrProvinceName,
1207  dbuffer1, dbuffer2,
1208  hash,
1209  status,
1210  /* the same again for HTML */
1211  commonName,
1212  organizationName,
1213  organizationalUnitName,
1214  countryName,
1215  localityName,
1216  stateOrProvinceName,
1217  dbuffer1, dbuffer2,
1218  hash,
1219  statusOn,
1220  status,
1221  statusOff
1222  );
1223 
1227  I18N("Certificate Received"),
1228  buffer,
1229  I18N("Yes"), I18N("No"), 0, guiid);
1230  if (rv==1) {
1231  return 0;
1232  }
1233  else {
1234  DBG_NOTICE(GWEN_LOGDOMAIN, "User rejected certificate");
1235 
1236  return GWEN_ERROR_SSL_SECURITY;
1237  }
1238 }
1239 
1240 
1241 
1243  unsigned char *buffer,
1244  unsigned int bufLength) {
1245  if (gwenhywfar_gui && gwenhywfar_gui->keyDataFromTextOpenSslFn)
1246  return gwenhywfar_gui->keyDataFromTextOpenSslFn(gwenhywfar_gui,
1247  text,
1248  buffer,
1249  bufLength);
1251 }
1252 
1253 
1254 
1255 int GWEN_Gui_ExecDialog(GWEN_DIALOG *dlg, uint32_t guiid) {
1256  if (gwenhywfar_gui && gwenhywfar_gui->execDialogFn)
1257  return gwenhywfar_gui->execDialogFn(gwenhywfar_gui, dlg, guiid);
1259 }
1260 
1261 
1262 
1263 int GWEN_Gui_OpenDialog(GWEN_DIALOG *dlg, uint32_t guiid) {
1264  if (gwenhywfar_gui && gwenhywfar_gui->openDialogFn)
1265  return gwenhywfar_gui->openDialogFn(gwenhywfar_gui, dlg, guiid);
1267 }
1268 
1269 
1270 
1272  if (gwenhywfar_gui && gwenhywfar_gui->closeDialogFn)
1273  return gwenhywfar_gui->closeDialogFn(gwenhywfar_gui, dlg);
1275 }
1276 
1277 
1278 
1279 int GWEN_Gui_RunDialog(GWEN_DIALOG *dlg, int untilEnd) {
1280  if (gwenhywfar_gui && gwenhywfar_gui->runDialogFn)
1281  return gwenhywfar_gui->runDialogFn(gwenhywfar_gui, dlg, untilEnd);
1283 }
1284 
1285 
1286 
1287 
1288 int GWEN_Gui_GetFileName(const char *caption,
1290  uint32_t flags,
1291  const char *patterns,
1292  GWEN_BUFFER *pathBuffer,
1293  uint32_t guiid) {
1294  if (gwenhywfar_gui && gwenhywfar_gui->getFileNameFn)
1295  return gwenhywfar_gui->getFileNameFn(gwenhywfar_gui,
1296  caption,
1297  fnt,
1298  flags,
1299  patterns,
1300  pathBuffer,
1301  guiid);
1303 }
1304 
1305 
1306 
1307 int GWEN_Gui_ReadDialogPrefs(const char *groupName,
1308  const char *altName,
1309  GWEN_DB_NODE **pDb) {
1310  if (gwenhywfar_gui && gwenhywfar_gui->readDialogPrefsFn)
1311  return gwenhywfar_gui->readDialogPrefsFn(gwenhywfar_gui, groupName, altName, pDb);
1313 }
1314 
1315 
1316 
1317 int GWEN_Gui_WriteDialogPrefs(const char *groupName,
1318  GWEN_DB_NODE *db) {
1319  if (gwenhywfar_gui && gwenhywfar_gui->writeDialogPrefsFn)
1320  return gwenhywfar_gui->writeDialogPrefsFn(gwenhywfar_gui, groupName, db);
1322 }
1323 
1324 
1325 
1326 int GWEN_Gui_GetSyncIo(const char *url,
1327  const char *defaultProto,
1328  int defaultPort,
1329  GWEN_SYNCIO **pSio) {
1330  if (gwenhywfar_gui && gwenhywfar_gui->getSyncIoFn)
1331  return gwenhywfar_gui->getSyncIoFn(gwenhywfar_gui, url, defaultProto, defaultPort, pSio);
1333 }
1334 
1335 
1336 
1337 
1338 
1339 
1340 
1341 
1342 
1343 
1345  GWEN_PROGRESS_DATA *highest=NULL;
1346  GWEN_PROGRESS_DATA *t;
1347  GWEN_DIALOG *dlg=NULL;
1348 
1349  assert(gwenhywfar_gui);
1350 
1351  t=pd;
1352  while(t) {
1353  highest=t;
1354  t=GWEN_ProgressData_Tree_GetParent(t);
1355  }
1356 
1357  /* highest must always be visible */
1358  if (GWEN_ProgressData_GetShown(highest)==0)
1359  GWEN_ProgressData_SetShown(highest, 1);
1360 
1361  dlg=GWEN_ProgressData_GetDialog(highest);
1362  if (dlg==NULL) {
1363  int rv;
1364 
1365  /* need to create dialog for it */
1366  dlg=GWEN_DlgProgress_new();
1367  if (dlg==NULL) {
1368  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create progress dialog, maybe data not installed?");
1369  return GWEN_ERROR_INTERNAL;
1370  }
1373 
1376 
1377  rv=GWEN_Gui_OpenDialog(dlg, 0);
1378  if (rv<0) {
1379  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to openDialog: %d", rv);
1380  GWEN_Dialog_free(dlg);
1381  return rv;
1382  }
1383 
1384  DBG_INFO(GWEN_LOGDOMAIN, "Setting new firstprogress: %08x",
1386  GWEN_DlgProgress_SetFirstProgress(dlg, highest);
1387  GWEN_ProgressData_SetDialog(highest, dlg);
1388  }
1389 
1390  if (pd!=highest) {
1391  DBG_INFO(GWEN_LOGDOMAIN, "Setting new second progress: %08x",
1394  GWEN_ProgressData_SetDialog(pd, dlg);
1396  }
1397 
1398  GWEN_Gui_RunDialog(dlg, 0);
1399 
1400  return 0;
1401 }
1402 
1403 
1404 
1406  if (GWEN_ProgressData_GetShown(pd)==0) {
1408  double dt;
1409  time_t t1;
1410 
1411  t1=time(0);
1412  dt=difftime(t1, GWEN_ProgressData_GetStartTime(pd));
1413  if ((int)dt>=GWEN_GUI_DELAY_SECS) {
1414  DBG_INFO(GWEN_LOGDOMAIN, "Progress %08x open for %d secs, showing",
1415  GWEN_ProgressData_GetId(pd), (int) dt);
1417  }
1418  }
1419  else
1421  }
1422 
1423  if (GWEN_ProgressData_GetShown(pd)==1) {
1424  if (GWEN_ProgressData_GetDialog(pd)==NULL) {
1426  }
1427  }
1428 }
1429 
1430 
1431 
1433  uint32_t progressFlags,
1434  const char *title,
1435  const char *text,
1436  uint64_t total,
1437  uint32_t guiid) {
1438  GWEN_PROGRESS_DATA *pdParent=NULL;
1439  GWEN_PROGRESS_DATA *pd;
1440  uint32_t id;
1441 
1442  id=++(gui->nextProgressId);
1443 
1444  DBG_DEBUG(GWEN_LOGDOMAIN, "ProgressStart: flags=%08x, title=[%s], total=%08x, guiid=%08x",
1445  progressFlags, title?title:"(none)", (uint32_t) total, guiid);
1446 
1447  if (guiid==0) {
1448  guiid=gui->lastProgressId;
1449  }
1450 
1451  if (guiid) {
1452  pdParent=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, guiid);
1453  if (pdParent==NULL) {
1454  DBG_WARN(GWEN_LOGDOMAIN, "Parent progress by id %08x not found", guiid);
1455  DBG_DEBUG(GWEN_LOGDOMAIN, "Title: [%s], Text: [%s]",
1456  title?title:"no title",
1457  text?text:"no text");
1458  }
1459  }
1460 
1461  pd=GWEN_ProgressData_new(gui, id, progressFlags, title, text, total);
1462  assert(pd);
1463  GWEN_ProgressData_SetPreviousId(pd, gui->lastProgressId);
1464  if (pdParent)
1465  GWEN_ProgressData_Tree_AddChild(pdParent, pd);
1466  else
1467  GWEN_ProgressData_Tree_Add(gui->progressDataTree, pd);
1468 
1469  GWEN_Gui_Internal_CheckShow(gui, pd);
1470 
1471  gui->lastProgressId=id;
1472 
1473  return id;
1474 }
1475 
1476 
1477 
1478 int GWEN_Gui_Internal_ProgressEnd(GWEN_GUI *gui, uint32_t pid) {
1479  GWEN_PROGRESS_DATA *pd;
1480  uint32_t parentPid=0;
1481 
1482  DBG_DEBUG(GWEN_LOGDOMAIN, "ProgressEnd: guiid=%08x", pid);
1483 
1484  if (pid==0) {
1485  pid=gui->lastProgressId;
1486  if (pid==0) {
1487  DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available");
1488  return GWEN_ERROR_INVALID;
1489  }
1490  }
1491 
1492  pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid);
1493  if (pd==NULL) {
1494  DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid);
1495  return GWEN_ERROR_INVALID;
1496  }
1497  else {
1498  GWEN_DIALOG *dlg;
1499  GWEN_PROGRESS_DATA *previousPd;
1500 
1501  /* set previous progress id */
1502  gui->lastProgressId=GWEN_ProgressData_GetPreviousId(pd);
1503 
1504  /* find next highest active progress */
1505  previousPd=GWEN_ProgressData_Tree_GetParent(pd);
1506  if (previousPd)
1507  parentPid=GWEN_ProgressData_GetId(previousPd);
1508  while(previousPd) {
1509  if (GWEN_ProgressData_GetShown(previousPd))
1510  break;
1511  previousPd=GWEN_ProgressData_Tree_GetParent(previousPd);
1512  }
1513 
1515  if (dlg) {
1516  GWEN_PROGRESS_DATA *primary;
1517  GWEN_PROGRESS_DATA *secondary;
1518 
1519  primary=GWEN_DlgProgress_GetFirstProgress(dlg);
1520  secondary=GWEN_DlgProgress_GetSecondProgress(dlg);
1521 
1522  /* force update of progress bar */
1523  GWEN_DlgProgress_Advanced(dlg, pd);
1524  GWEN_Gui_RunDialog(dlg, 0);
1525 
1526  if (primary==pd) {
1527  int rv;
1528 
1529  DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x is primary, closing dialog",
1531 
1532  if (secondary) {
1533  DBG_WARN(GWEN_LOGDOMAIN, "There is still a secondary progress!");
1535  GWEN_ProgressData_SetDialog(secondary, NULL);
1536  }
1537 
1538  /* this is the primary progress, with this closed we can also
1539  * close the dialog */
1540  DBG_INFO(GWEN_LOGDOMAIN, "Closing progress dialog");
1541  GWEN_DlgProgress_AddLogText(dlg, GWEN_LoggerLevel_Info, I18N("Operation finished, you can now close this window."));
1542 
1543  // run dialog until end, close then
1545  if (GWEN_DlgProgress_GetStayOpen(dlg)) {
1546  rv=GWEN_Gui_RunDialog(dlg, 1);
1547  if (rv<0) {
1548  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to runDialog: %d", rv);
1549  /*GWEN_Dialog_free(dlg);
1550  return rv;*/
1551  }
1552  }
1553 
1554  rv=GWEN_Gui_CloseDialog(dlg);
1555  if (rv<0) {
1556  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to closeDialog: %d", rv);
1557  GWEN_Dialog_free(dlg);
1558  return rv;
1559  }
1560  GWEN_Dialog_free(dlg);
1561  }
1562  else if (secondary==pd) {
1563  /* t is maybe the next higher progress, it will become the second progress */
1564  if (previousPd && previousPd!=GWEN_DlgProgress_GetFirstProgress(dlg)) {
1565  DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x becomes new second progress",
1566  GWEN_ProgressData_GetId(previousPd));
1568  GWEN_ProgressData_SetDialog(pd, dlg);
1569  }
1570  else {
1571  DBG_INFO(GWEN_LOGDOMAIN, "No next secondary progress");
1573  }
1574  }
1575  else {
1576  DBG_ERROR(GWEN_LOGDOMAIN, "Progress %08x is neither primary nor secondary, SNH",
1578  }
1579  }
1580  else {
1581  DBG_DEBUG(GWEN_LOGDOMAIN, "Progress %08x has no dialog", GWEN_ProgressData_GetId(pd));
1582  }
1583 
1585  GWEN_ProgressData_Tree_Del(pd);
1587  }
1588 
1589  return 0;
1590 }
1591 
1592 
1593 
1594 int GWEN_Gui_Internal_ProgressAdvance(GWEN_GUI *gui, uint32_t pid, uint64_t progress) {
1595  GWEN_PROGRESS_DATA *pd;
1596  int aborted=0;
1597 
1598  if (pid==0) {
1599  pid=gui->lastProgressId;
1600  if (pid==0) {
1601  DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available");
1602  return GWEN_ERROR_INVALID;
1603  }
1604  }
1605 
1606  pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid);
1607  if (pd==NULL) {
1608  DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid);
1609  return GWEN_ERROR_INVALID;
1610  }
1611  else {
1612  GWEN_DIALOG *dlg;
1613 
1614  if (progress==GWEN_GUI_PROGRESS_ONE)
1615  progress=GWEN_ProgressData_GetCurrent(pd)+1;
1616  else if (progress==GWEN_GUI_PROGRESS_NONE)
1617  progress=GWEN_ProgressData_GetCurrent(pd);
1618  GWEN_ProgressData_SetCurrent(pd, progress);
1619  GWEN_Gui_Internal_CheckShow(gui, pd);
1620 
1622  if (dlg) {
1623  time_t t0;
1624  time_t t1;
1625 
1627  t1=time(0);
1628  if (t0!=t1) {
1629  GWEN_DlgProgress_Advanced(dlg, pd);
1630  GWEN_Gui_RunDialog(dlg, 0);
1632  }
1633  }
1634  aborted=GWEN_ProgressData_GetAborted(pd);
1635  }
1636 
1637  if (aborted)
1638  return GWEN_ERROR_USER_ABORTED;
1639  return 0;
1640 }
1641 
1642 
1643 
1644 int GWEN_Gui_Internal_ProgressSetTotal(GWEN_GUI *gui, uint32_t pid, uint64_t total) {
1645  GWEN_PROGRESS_DATA *pd;
1646  int aborted=0;
1647 
1648  if (pid==0) {
1649  pid=gui->lastProgressId;
1650  if (pid==0) {
1651  DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available");
1652  return GWEN_ERROR_INVALID;
1653  }
1654  }
1655 
1656  pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid);
1657  if (pd==NULL) {
1658  DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid);
1659  return GWEN_ERROR_INVALID;
1660  }
1661  else {
1662  GWEN_DIALOG *dlg;
1663 
1664  GWEN_ProgressData_SetTotal(pd, total);
1665  GWEN_Gui_Internal_CheckShow(gui, pd);
1666 
1668  if (dlg) {
1669  time_t t0;
1670  time_t t1;
1671 
1673  t1=time(0);
1674  if (t0!=t1) {
1676  GWEN_Gui_RunDialog(dlg, 0);
1678  }
1679  }
1680  aborted=GWEN_ProgressData_GetAborted(pd);
1681  }
1682 
1683  if (aborted)
1684  return GWEN_ERROR_USER_ABORTED;
1685  return 0;
1686 }
1687 
1688 
1689 
1691  uint32_t pid,
1692  GWEN_LOGGER_LEVEL level,
1693  const char *text) {
1694  assert(gui);
1695 
1696  /* only show messages with log level lower or equal threshold */
1697  if (level<=gui->minProgressLogLevel) {
1698  GWEN_PROGRESS_DATA *pd;
1699  int aborted=0;
1700 
1701  if (pid==0) {
1702  pid=gui->lastProgressId;
1703  if (pid==0) {
1704  DBG_INFO(GWEN_LOGDOMAIN, "Last active progress not available");
1705  return GWEN_ERROR_INVALID;
1706  }
1707  }
1708 
1709  pd=GWEN_ProgressData_Tree_FindProgressById(gui->progressDataTree, pid);
1710  if (pd==NULL) {
1711  DBG_ERROR(GWEN_LOGDOMAIN, "Progress by id %08x not found", pid);
1712  return GWEN_ERROR_INVALID;
1713  }
1714  else {
1715  GWEN_DIALOG *dlg;
1716 
1717  if (level<=GWEN_LoggerLevel_Notice)
1719  if (level<=GWEN_LoggerLevel_Warning)
1721  GWEN_Gui_Internal_CheckShow(gui, pd);
1722 
1724  if (dlg) {
1725  if (level<=GWEN_LoggerLevel_Warning) {
1728  }
1729 
1730  GWEN_DlgProgress_AddLogText(dlg, level, text);
1731  GWEN_Gui_RunDialog(dlg, 0);
1732  }
1733  else
1734  GWEN_ProgressData_AddLogText(pd, level, text);
1735 
1736  aborted=GWEN_ProgressData_GetAborted(pd);
1737  }
1738 
1739  if (aborted)
1740  return GWEN_ERROR_USER_ABORTED;
1741  }
1742  return 0;
1743 }
1744 
1745 
1746 
1748  uint32_t flags,
1749  const char *title,
1750  const char *text,
1751  char *buffer,
1752  int minLen,
1753  int maxLen,
1754  uint32_t guiid) {
1755  GWEN_DIALOG *dlg;
1756  int rv;
1757 
1758  dlg=GWEN_DlgInput_new(flags, title, text, minLen, maxLen);
1759  if (dlg==NULL) {
1760  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog");
1761  return GWEN_ERROR_INTERNAL;
1762  }
1763 
1764  rv=GWEN_Gui_ExecDialog(dlg, 0);
1765  if (rv==1) {
1766  rv=GWEN_DlgInput_CopyInput(dlg, buffer, maxLen);
1767  if (rv<0) {
1768  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1769  GWEN_Dialog_free(dlg);
1770  return rv;
1771  }
1773  rv=1;
1774  else
1775  rv=0;
1776  GWEN_Dialog_free(dlg);
1777  return rv;
1778  }
1779  else {
1780  DBG_ERROR(GWEN_LOGDOMAIN, "User aborted");
1781  GWEN_Dialog_free(dlg);
1782  return GWEN_ERROR_USER_ABORTED;
1783  }
1784 }
1785 
1786 
1787 
1789  uint32_t flags,
1790  const char *title,
1791  const char *text,
1792  const char *b1,
1793  const char *b2,
1794  const char *b3,
1795  uint32_t guiid) {
1796  GWEN_DIALOG *dlg;
1797  int rv;
1798 
1799  dlg=GWEN_DlgMessage_new(flags, title, text, b1, b2, b3);
1800  if (dlg==NULL) {
1801  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog");
1802  return GWEN_ERROR_INTERNAL;
1803  }
1804 
1805  GWEN_Gui_ExecDialog(dlg, 0);
1807  GWEN_Dialog_free(dlg);
1808  return rv;
1809 }
1810 
1811 
1812 
1814  uint32_t flags,
1815  const char *title,
1816  const char *text,
1817  uint32_t guiid) {
1818  GWEN_DIALOG *dlg;
1819  int rv;
1820  uint32_t id;
1821 
1822  id=++(gui->nextDialogId);
1823 
1824  dlg=GWEN_DlgShowBox_new(flags, title, text);
1825  if (dlg==NULL) {
1826  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create dialog");
1827  return 0;
1828  }
1829 
1830  GWEN_Dialog_SetGuiId(dlg, id);
1831 
1832  rv=GWEN_Gui_OpenDialog(dlg, guiid);
1833  if (rv<0) {
1834  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1835  GWEN_Dialog_free(dlg);
1836  return 0;
1837  }
1838 
1839  GWEN_Dialog_List_Add(dlg, gui->activeDialogs);
1840 
1841  return id;
1842 }
1843 
1844 
1845 
1846 void GWEN_Gui_Internal_HideBox(GWEN_GUI *gui, uint32_t id) {
1847  GWEN_DIALOG *dlg;
1848 
1849  if (id) {
1850  dlg=GWEN_Dialog_List_First(gui->activeDialogs);
1851  while(dlg) {
1852  if (GWEN_Dialog_GetGuiId(dlg)==id)
1853  break;
1854  dlg=GWEN_Dialog_List_Next(dlg);
1855  }
1856  }
1857  else
1858  dlg=GWEN_Dialog_List_Last(gui->activeDialogs);
1859 
1860  if (dlg) {
1861  int rv;
1862 
1863  rv=GWEN_Gui_CloseDialog(dlg);
1864  if (rv<0) {
1865  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1866  }
1867  GWEN_Dialog_List_Del(dlg);
1868  GWEN_Dialog_free(dlg);
1869  }
1870 }
1871 
1872 
1873 
1875  const char *url,
1876  const char *defaultProto,
1877  int defaultPort,
1878  GWEN_SYNCIO **pSio) {
1879  GWEN_URL *u;
1880  const char *s;
1881  int port;
1882  const char *addr;
1883 
1884  if (!(url && *url)) {
1885  DBG_ERROR(GWEN_LOGDOMAIN, "Empty URL");
1886  return GWEN_ERROR_INVALID;
1887  }
1888 
1889  u=GWEN_Url_fromString(url);
1890  if (u==NULL) {
1891  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid URL [%s]", url);
1892  return GWEN_ERROR_INVALID;
1893  }
1894 
1895  /* determine protocol and port */
1896  s=GWEN_Url_GetProtocol(u);
1897  if (!(s && *s))
1898  s=defaultProto;
1899  if (!(s && *s))
1900  s="http";
1901  port=GWEN_Url_GetPort(u);
1902  if (port<1)
1903  port=defaultPort;
1904  if (port<1)
1905  port=80;
1906  addr=GWEN_Url_GetServer(u);
1907  if (!(addr && *addr)) {
1908  DBG_ERROR(GWEN_LOGDOMAIN, "Missing server in URL [%s]", url);
1909  GWEN_Url_free(u);
1910  return GWEN_ERROR_INVALID;
1911  }
1912 
1913  if (strcasecmp(s, "http")==0 ||
1914  strcasecmp(s, "https")==0) {
1915  GWEN_SYNCIO *sio;
1916  GWEN_SYNCIO *baseLayer;
1917  GWEN_DB_NODE *db;
1918  GWEN_BUFFER *tbuf;
1919  int rv;
1920 
1921  /* create base io */
1923  if (sio==NULL) {
1924  DBG_INFO(GWEN_LOGDOMAIN, "here");
1925  GWEN_Url_free(u);
1926  return GWEN_ERROR_GENERIC;
1927  }
1928 
1929  GWEN_SyncIo_Socket_SetAddress(sio, addr);
1930  GWEN_SyncIo_Socket_SetPort(sio, port);
1931  baseLayer=sio;
1932 
1933  if (strcasecmp(s, "https")==0) {
1934  /* create TLS layer */
1935  sio=GWEN_SyncIo_Tls_new(baseLayer);
1936  if (sio==NULL) {
1937  DBG_INFO(GWEN_LOGDOMAIN, "here");
1938  GWEN_SyncIo_free(baseLayer);
1939  GWEN_Url_free(u);
1940  return GWEN_ERROR_GENERIC;
1941  }
1943  baseLayer=sio;
1944  }
1945 
1946  /* create buffered layer as needed for HTTP */
1947  sio=GWEN_SyncIo_Buffered_new(baseLayer);
1948  if (sio==NULL) {
1949  DBG_INFO(GWEN_LOGDOMAIN, "here");
1950  GWEN_SyncIo_free(baseLayer);
1951  GWEN_Url_free(u);
1952  return GWEN_ERROR_GENERIC;
1953  }
1954  baseLayer=sio;
1955 
1956  /* create HTTP layer */
1957  sio=GWEN_SyncIo_Http_new(baseLayer);
1958  if (sio==NULL) {
1959  DBG_INFO(GWEN_LOGDOMAIN, "here");
1960  GWEN_SyncIo_free(baseLayer);
1961  GWEN_Url_free(u);
1962  return GWEN_ERROR_GENERIC;
1963  }
1964 
1965  /* setup default command and header */
1966  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
1968 
1969  /* get command string (e.g. server-relative path plus variables) */
1970  rv=GWEN_Url_toCommandString(u, tbuf);
1971  if (rv<0) {
1972  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid path in URL, ignoring (%d)", rv);
1973  }
1974  else
1976  GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", "GET");
1977  GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", "HTTP/1.0");
1978 
1979  /* preset some headers */
1982  GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close");
1983 
1984  /* done */
1985  GWEN_Url_free(u);
1986  *pSio=sio;
1987  return 0;
1988  }
1989  else {
1990  GWEN_SYNCIO *sio;
1991 
1992  /* create base io */
1994  if (sio==NULL) {
1995  DBG_INFO(GWEN_LOGDOMAIN, "here");
1996  GWEN_Url_free(u);
1997  return GWEN_ERROR_GENERIC;
1998  }
1999  GWEN_SyncIo_Socket_SetAddress(sio, addr);
2000  GWEN_SyncIo_Socket_SetPort(sio, port);
2001 
2002  /* done */
2003  GWEN_Url_free(u);
2004  *pSio=sio;
2005  return 0;
2006  }
2007 
2008 }
2009 
2010 
2011 
2012 static int GWEN_Gui__HashPair(const char *token, const char *pin, GWEN_BUFFER *buf) {
2013  GWEN_MDIGEST *md;
2014  int rv;
2015 
2016  /* hash token and pin */
2017  md=GWEN_MDigest_Md5_new();
2018  rv=GWEN_MDigest_Begin(md);
2019  if (rv==0)
2020  rv=GWEN_MDigest_Update(md, (const uint8_t*)token, strlen(token));
2021  if (rv==0)
2022  rv=GWEN_MDigest_Update(md, (const uint8_t*)pin, strlen(pin));
2023  if (rv==0)
2024  rv=GWEN_MDigest_End(md);
2025  if (rv<0) {
2026  DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
2027  GWEN_MDigest_free(md);
2028  return rv;
2029  }
2030 
2033  buf,
2034  0, 0, 0);
2035  GWEN_MDigest_free(md);
2036  return 0;
2037 }
2038 
2039 
2040 
2041 
2043  uint32_t flags,
2044  const char *token,
2045  const char *title,
2046  const char *text,
2047  char *buffer,
2048  int minLen,
2049  int maxLen,
2050  uint32_t guiid) {
2051  if ((flags & GWEN_GUI_INPUT_FLAGS_TAN) ||
2052  (flags & GWEN_GUI_INPUT_FLAGS_DIRECT) ||
2053  (gui->dbPasswords==NULL)
2054  ) {
2055  return GWEN_Gui_InputBox(flags,
2056  title,
2057  text,
2058  buffer,
2059  minLen,
2060  maxLen,
2061  guiid);
2062  }
2063  else {
2064  GWEN_BUFFER *buf;
2065  int rv;
2066  const char *s;
2067 
2068  buf=GWEN_Buffer_new(0, 256, 0, 1);
2070 
2071  if (!(flags & GWEN_GUI_INPUT_FLAGS_CONFIRM)) {
2072  s=GWEN_DB_GetCharValue(gui->dbPasswords,
2073  GWEN_Buffer_GetStart(buf),
2074  0, NULL);
2075  if (s) {
2076  int i;
2077 
2078  i=strlen(s);
2079  if (i>=minLen && i < maxLen) {
2080  memmove(buffer, s, i+1);
2081  GWEN_Buffer_free(buf);
2082  return 0;
2083  }
2084  else {
2085  DBG_ERROR(GWEN_LOGDOMAIN, "Stored password [%s] is not within size limits (%d), rejecting.",
2086  GWEN_Buffer_GetStart(buf), i);
2087  }
2088  }
2089  }
2090 
2091  /* passwd not in password cache, look for it in password storage */
2092  if (gui->passwdStore) {
2093  rv=GWEN_PasswordStore_GetPassword(gui->passwdStore, token, buffer, minLen, maxLen);
2094  if (rv<0) {
2095  if (rv==GWEN_ERROR_NOT_FOUND || rv==GWEN_ERROR_NO_DATA) {
2096  DBG_INFO(GWEN_LOGDOMAIN, "Password not found in PasswordStore");
2097  }
2098  else {
2099  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2100  GWEN_Buffer_free(buf);
2101  return rv;
2102  }
2103  }
2104  else {
2105  /* got password */
2106  return 0;
2107  }
2108  }
2109 
2110  if (gui->flags & GWEN_GUI_FLAGS_NONINTERACTIVE) {
2112  "Password for [%s] missing in noninteractive mode, "
2113  "aborting", GWEN_Buffer_GetStart(buf));
2114  GWEN_Buffer_free(buf);
2115  return GWEN_ERROR_USER_ABORTED;
2116  }
2117 
2118  for (;;) {
2119  int rv2;
2120 
2121  rv=GWEN_Gui_InputBox(flags,
2122  title,
2123  text,
2124  buffer,
2125  minLen,
2126  maxLen,
2127  guiid);
2128  if (rv<0) {
2129  GWEN_Buffer_free(buf);
2130  return rv;
2131  }
2132  else {
2133  GWEN_BUFFER *hbuf;
2134  int isBad=0;
2135 
2136  hbuf=GWEN_Buffer_new(0, 64, 0, 1);
2137  GWEN_Gui__HashPair(token, buffer, hbuf);
2138  isBad=GWEN_StringList_HasString(gui->badPasswords,
2139  GWEN_Buffer_GetStart(hbuf));
2140  if (!isBad) {
2141  GWEN_Buffer_free(hbuf);
2142  break;
2143  }
2147  I18N("Enforce PIN"),
2148  I18N(
2149  "You entered the same PIN twice.\n"
2150  "The PIN is marked as bad, do you want\n"
2151  "to use it anyway?"
2152  "<html>"
2153  "<p>"
2154  "You entered the same PIN twice."
2155  "</p>"
2156  "<p>"
2157  "The PIN is marked as <b>bad</b>, "
2158  "do you want to use it anyway?"
2159  "</p>"
2160  "</html>"),
2161  I18N("Yes, use anyway"),
2162  I18N("Re-enter"),
2163  0,
2164  guiid);
2165  if (rv2==1) {
2166  /* accept this input */
2167  GWEN_StringList_RemoveString(gui->badPasswords,
2168  GWEN_Buffer_GetStart(hbuf));
2169  GWEN_Buffer_free(hbuf);
2170  break;
2171  }
2172  GWEN_Buffer_free(hbuf);
2173  }
2174  } /* for */
2175 
2176  /* store in temporary cache */
2178  GWEN_Buffer_GetStart(buf), buffer);
2179 
2180  /* only store passwd in storage if allowed by the user */
2181  if (rv==1 && gui->passwdStore) {
2182  rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, buffer);
2183  if (rv<0) {
2184  DBG_WARN(GWEN_LOGDOMAIN, "Could not store password (%d)", rv);
2185  }
2186  }
2187 
2188  GWEN_Buffer_free(buf);
2189  return 0;
2190  }
2191 }
2192 
2193 
2194 
2196  const char *token,
2197  const char *pin,
2198  GWEN_GUI_PASSWORD_STATUS status,
2199  GWEN_UNUSED uint32_t guiid) {
2200  if (token==NULL && pin==NULL && status==GWEN_Gui_PasswordStatus_Remove) {
2201  if (gui->passwdStore)
2202  GWEN_PasswordStore_ClearStoragePasswd(gui->passwdStore);
2203  if (gui->persistentPasswords==0)
2204  GWEN_DB_ClearGroup(gui->dbPasswords, NULL);
2205  }
2206  else {
2207  GWEN_BUFFER *hbuf;
2208 
2209  hbuf=GWEN_Buffer_new(0, 64, 0, 1);
2210  GWEN_Gui__HashPair(token, pin, hbuf);
2211  if (status==GWEN_Gui_PasswordStatus_Bad) {
2212  GWEN_StringList_AppendString(gui->badPasswords,
2213  GWEN_Buffer_GetStart(hbuf),
2214  0, 1);
2215  /* remove from permanent passwd storage */
2216  if (gui->passwdStore) {
2217  int rv;
2218 
2219  rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, NULL);
2220  if (rv<0) {
2221  DBG_WARN(GWEN_LOGDOMAIN, "Could not remove password from storage (%d)", rv);
2222  }
2223  }
2224  }
2225  else if (status==GWEN_Gui_PasswordStatus_Ok ||
2227  if (gui->persistentPasswords==0)
2228  GWEN_StringList_RemoveString(gui->badPasswords, GWEN_Buffer_GetStart(hbuf));
2229  }
2230  GWEN_Buffer_free(hbuf);
2231  }
2232 
2233  return 0;
2234 }
2235 
2236 
2237 
2238 
2240  assert(gui);
2241  return gui->minProgressLogLevel;
2242 }
2243 
2244 
2245 
2247  assert(gui);
2248  gui->minProgressLogLevel=ll;
2249 }
2250 
2251 
2252 
2253