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