gwenhywfar  5.14.1
gui_passwd.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Feb 07 2003
3  copyright : (C) 2023 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 /* included from gui.c */
26 
27 
28 static int _tryReadStoredPasswd(GWEN_GUI *gui,
29  const char *pwName,
30  uint32_t flags,
31  const char *token,
32  char *buffer,
33  int minLen,
34  int maxLen);
35 static int _tryReadCachedPasswd(GWEN_GUI *gui, const char *pwName, char *buffer, int minLen, int maxLen);
36 static int _tryReadPasswdViaInputBox(GWEN_GUI *gui,
37  uint32_t flags,
38  const char *token,
39  const char *title,
40  const char *text,
41  char *buffer,
42  int minLen,
43  int maxLen,
44  uint32_t guiid);
46  const char *pwName,
47  const char *token,
48  const char *pwBuffer,
49  int userWantsToStorePasswd);
50 
51 
52 
53 static int GWEN_Gui__HashPair(const char *token, const char *pin, GWEN_BUFFER *buf)
54 {
55  GWEN_MDIGEST *md;
56  int rv;
57 
58  /* hash token and pin */
60  rv=GWEN_MDigest_Begin(md);
61  if (rv==0)
62  rv=GWEN_MDigest_Update(md, (const uint8_t *)token, strlen(token));
63  if (rv==0)
64  rv=GWEN_MDigest_Update(md, (const uint8_t *)pin, strlen(pin));
65  if (rv==0)
66  rv=GWEN_MDigest_End(md);
67  if (rv<0) {
68  DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
70  return rv;
71  }
72 
75  buf,
76  0, 0, 0);
78  return 0;
79 }
80 
81 
82 
83 
85  uint32_t flags,
86  const char *token,
87  const char *title,
88  const char *text,
89  char *pwBuffer,
90  int minLen,
91  int maxLen,
93  GWEN_UNUSED GWEN_DB_NODE *methodParams,
94  uint32_t guiid)
95 {
96  if ((flags & GWEN_GUI_INPUT_FLAGS_TAN) || (flags & GWEN_GUI_INPUT_FLAGS_DIRECT) || (gui->dbPasswords==NULL)) {
97  return GWEN_Gui_InputBox(flags, title, text, pwBuffer, minLen, maxLen, guiid);
98  }
99  else {
100  GWEN_BUFFER *bufPasswdName;
101  int rv;
102 
103  bufPasswdName=GWEN_Buffer_new(0, 256, 0, 1);
104  GWEN_Text_EscapeToBufferTolerant(token, bufPasswdName);
105 
106  rv=_tryReadStoredPasswd(gui, GWEN_Buffer_GetStart(bufPasswdName), flags, token, pwBuffer, minLen, maxLen);
107  if (rv!=0) {
108  GWEN_Buffer_free(bufPasswdName);
109  if (rv<0) {
110  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
111  return rv;
112  }
113  else if (rv>0) {
114  /* got password */
115  return 0;
116  }
117  }
118 
119  if (gui->flags & GWEN_GUI_FLAGS_NONINTERACTIVE) {
120  DBG_ERROR(GWEN_LOGDOMAIN, "Password for [%s] missing in noninteractive mode, aborting", GWEN_Buffer_GetStart(bufPasswdName));
121  GWEN_Buffer_free(bufPasswdName);
123  }
124 
125  rv=_tryReadPasswdViaInputBox(gui, flags, token, title, text, pwBuffer, minLen, maxLen, guiid);
126  if (rv<0) {
127  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
128  GWEN_Buffer_free(bufPasswdName);
129  return rv;
130  }
131 
132  _tryStorePasswdInCacheAndStorage(gui, GWEN_Buffer_GetStart(bufPasswdName), token, pwBuffer, (rv==1)?1:0);
133 
134  GWEN_Buffer_free(bufPasswdName);
135  return 0;
136  }
137 }
138 
139 
140 
141 int _tryReadStoredPasswd(GWEN_GUI *gui, const char *pwName, uint32_t flags, const char *token, char *buffer, int minLen, int maxLen)
142 {
143  int rv;
144 
145  /* look into password cache */
146  if (!(flags & GWEN_GUI_INPUT_FLAGS_CONFIRM)) {
147  rv=_tryReadCachedPasswd(gui, pwName, buffer, minLen, maxLen);
148  if (rv<0) {
149  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
150  return rv;
151  }
152  else if (rv>0) {
153  /* got password */
154  return 1;
155  }
156 
157  /* look into password storage */
158  if (gui->passwdStore) {
159  rv=GWEN_PasswordStore_GetPassword(gui->passwdStore, token, buffer, minLen, maxLen);
160  if (rv<0) {
161  if (rv==GWEN_ERROR_NOT_FOUND || rv==GWEN_ERROR_NO_DATA) {
162  DBG_INFO(GWEN_LOGDOMAIN, "Password not found in PasswordStore");
163  }
164  else {
165  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
166  return rv;
167  }
168  }
169  else {
170  /* got password */
171  return 1;
172  }
173  }
174  }
175  return 0;
176 }
177 
178 
179 
180 int _tryReadCachedPasswd(GWEN_GUI *gui, const char *pwName, char *buffer, int minLen, int maxLen)
181 {
182  const char *s;
183 
184  s=GWEN_DB_GetCharValue(gui->dbPasswords, pwName, 0, NULL);
185  if (s) {
186  int i;
187 
188  i=strlen(s);
189  if (i>=minLen && i < maxLen) {
190  memmove(buffer, s, i+1);
191  return 1;
192  }
193  else {
194  DBG_ERROR(GWEN_LOGDOMAIN, "Stored password [%s] is not within size limits (%d), rejecting.", pwName, i);
195  }
196  }
197  return 0;
198 }
199 
200 
201 
203  uint32_t flags,
204  const char *token,
205  const char *title,
206  const char *text,
207  char *buffer,
208  int minLen,
209  int maxLen,
210  uint32_t guiid)
211 {
212  for (;;) {
213  int rv;
214  int rv2;
215 
216  rv=GWEN_Gui_InputBox(flags, title, text, buffer, minLen, maxLen, guiid);
217  if (rv<0) {
218  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
219  return rv;
220  }
221  else {
222  GWEN_BUFFER *hbuf;
223  int isBad=0;
224 
225  hbuf=GWEN_Buffer_new(0, 64, 0, 1);
226  GWEN_Gui__HashPair(token, buffer, hbuf);
227  isBad=GWEN_StringList_HasString(gui->badPasswords, GWEN_Buffer_GetStart(hbuf));
228  if (!isBad) {
229  /* password not marked as bad, return it */
230  GWEN_Buffer_free(hbuf);
231  return rv; /* return rv from GWEN_Gui_InputBox */
232  }
236  I18N("Enforce PIN"),
237  I18N(
238  "You entered the same PIN twice.\n"
239  "The PIN is marked as bad, do you want\n"
240  "to use it anyway?"
241  "<html>"
242  "<p>"
243  "You entered the same PIN twice."
244  "</p>"
245  "<p>"
246  "The PIN is marked as <b>bad</b>, "
247  "do you want to use it anyway?"
248  "</p>"
249  "</html>"),
250  I18N("Yes, use anyway"),
251  I18N("Re-enter"),
252  0,
253  guiid);
254  if (rv2==1) {
255  /* accept this input */
256  GWEN_StringList_RemoveString(gui->badPasswords, GWEN_Buffer_GetStart(hbuf));
257  GWEN_Buffer_free(hbuf);
258  return rv; /* return rv from GWEN_Gui_InputBox */
259  }
260  GWEN_Buffer_free(hbuf);
261  }
262  } /* for */
263  /* should not get here */
264  return GWEN_ERROR_INTERNAL;
265 }
266 
267 
268 
270  const char *pwName,
271  const char *token,
272  const char *pwBuffer,
273  int userWantsToStorePasswd)
274 {
275  /* store in temporary cache */
276  GWEN_DB_SetCharValue(gui->dbPasswords, GWEN_DB_FLAGS_OVERWRITE_VARS, pwName, pwBuffer);
277 
278  /* only store passwd in storage if allowed by the user */
279  if (userWantsToStorePasswd && gui->passwdStore) {
280  int rv;
281 
282  DBG_INFO(GWEN_LOGDOMAIN, "Storing password \"%s\"", pwName);
283  rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, pwBuffer);
284  if (rv<0) {
285  DBG_WARN(GWEN_LOGDOMAIN, "Could not store password (%d)", rv);
286  }
287  }
288 }
289 
290 
291 
293  const char *token,
294  const char *pin,
296  GWEN_UNUSED uint32_t guiid)
297 {
298  if (token==NULL && pin==NULL && status==GWEN_Gui_PasswordStatus_Remove) {
299  /* complete cleaning is requested */
300  if (gui->passwdStore)
301  GWEN_PasswordStore_ClearStoragePasswd(gui->passwdStore);
302  if (gui->persistentPasswords==0)
303  GWEN_DB_ClearGroup(gui->dbPasswords, NULL);
304  }
305  else {
306  GWEN_BUFFER *hbuf;
307 
308  /* setting ststus of a specific password/pin */
309  hbuf=GWEN_Buffer_new(0, 64, 0, 1);
310  GWEN_Gui__HashPair(token, pin, hbuf);
311  if (status==GWEN_Gui_PasswordStatus_Bad) {
312  GWEN_StringList_AppendString(gui->badPasswords,
313  GWEN_Buffer_GetStart(hbuf),
314  0, 1);
315  /* remove from permanent passwd storage */
316  if (gui->passwdStore) {
317  int rv;
318 
319  DBG_INFO(GWEN_LOGDOMAIN, "Removing password \"%s\" from store", token);
320  rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, NULL);
321  if (rv<0) {
322  DBG_WARN(GWEN_LOGDOMAIN, "Could not remove password from storage (%d)", rv);
323  }
324  }
325 
326  if (gui->dbPasswords) {
327  GWEN_BUFFER *buf;
328 
329  buf=GWEN_Buffer_new(0, 256, 0, 1);
331 
332  GWEN_DB_DeleteVar(gui->dbPasswords, GWEN_Buffer_GetStart(buf));
333  }
334  }
335  else if (status==GWEN_Gui_PasswordStatus_Ok ||
337  if (gui->persistentPasswords==0)
338  GWEN_StringList_RemoveString(gui->badPasswords, GWEN_Buffer_GetStart(hbuf));
339  }
340  GWEN_Buffer_free(hbuf);
341  }
342 
343  return 0;
344 }
345 
346 
347 
348 int GWEN_Gui_GetPassword(uint32_t flags,
349  const char *token,
350  const char *title,
351  const char *text,
352  char *buffer,
353  int minLen,
354  int maxLen,
355  GWEN_GUI_PASSWORD_METHOD methodId,
356  GWEN_DB_NODE *methodParams,
357  uint32_t guiid)
358 {
359  GWEN_GUI *gui;
360 
361  gui=GWEN_Gui_GetGui();
362  if (gui) {
363  if (gui->getPasswordFn)
364  return gui->getPasswordFn(gui, flags, token, title, text, buffer, minLen, maxLen, methodId, methodParams, guiid);
365  else if (gui->inputBoxFn)
366  return gui->inputBoxFn(gui, flags, title, text, buffer, minLen, maxLen, guiid);
367  }
369 }
370 
371 
372 
373 int GWEN_Gui_SetPasswordStatus(const char *token,
374  const char *pin,
376  uint32_t guiid)
377 {
378  GWEN_GUI *gui;
379 
380  gui=GWEN_Gui_GetGui();
381  if (gui && gui->setPasswordStatusFn)
382  return gui->setPasswordStatusFn(gui, token, pin, status, guiid);
384 }
385 
386 
387 
388 
#define DBG_ERROR(dbg_logger, format,...)
Definition: debug.h:97
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
#define I18N(m)
Definition: error.c:42
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition: mdigest.c:54
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define GWEN_GUI_INPUT_FLAGS_CONFIRM
Definition: gui.h:211
#define GWEN_GUI_FLAGS_NONINTERACTIVE
Definition: gui.h:992
#define NULL
Definition: binreloc.c:300
int GWEN_Text_EscapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1471
static void _tryStorePasswdInCacheAndStorage(GWEN_GUI *gui, const char *pwName, const char *token, const char *pwBuffer, int userWantsToStorePasswd)
Definition: gui_passwd.c:269
#define GWEN_LOGDOMAIN
Definition: logger.h:32
GWENHYWFAR_API int GWEN_Gui_MessageBox(uint32_t flags, const char *title, const char *text, const char *b1, const char *b2, const char *b3, uint32_t guiid)
Definition: gui_virtual.c:342
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition: mdigest.c:153
int GWEN_PasswordStore_GetPassword(GWEN_PASSWD_STORE *sto, const char *token, char *buffer, int minLen, int maxLen)
Definition: passwdstore.c:695
#define GWEN_GUI_INPUT_FLAGS_DIRECT
Definition: gui.h:226
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWEN_PasswordStore_SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
Definition: passwdstore.c:624
#define DBG_WARN(dbg_logger, format,...)
Definition: debug.h:125
static int GWEN_Gui__HashPair(const char *token, const char *pin, GWEN_BUFFER *buf)
Definition: gui_passwd.c:53
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition: mdigest.c:81
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition: mdigest.c:129
static int _tryReadCachedPasswd(GWEN_GUI *gui, const char *pwName, char *buffer, int minLen, int maxLen)
Definition: gui_passwd.c:180
GWEN_GUI_PASSWORD_STATUS
Definition: gui.h:386
static int GWENHYWFAR_CB GWEN_Gui_Internal_SetPasswordStatus(GWEN_GUI *gui, const char *token, const char *pin, GWEN_GUI_PASSWORD_STATUS status, GWEN_UNUSED uint32_t guiid)
Definition: gui_passwd.c:292
GWENHYWFAR_API int GWEN_Gui_InputBox(uint32_t flags, const char *title, const char *text, char *buffer, int minLen, int maxLen, uint32_t guiid)
Definition: gui_virtual.c:360
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
#define GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS
Definition: gui.h:337
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define GWEN_GUI_INPUT_FLAGS_TAN
Definition: gui.h:222
GWEN_GUI * GWEN_Gui_GetGui(void)
Definition: gui.c:160
struct GWEN_MDIGEST GWEN_MDIGEST
Definition: mdigest.h:25
int GWEN_StringList_RemoveString(GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:326
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
static int _tryReadStoredPasswd(GWEN_GUI *gui, const char *pwName, uint32_t flags, const char *token, char *buffer, int minLen, int maxLen)
Definition: gui_passwd.c:141
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:899
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWEN_GUI_PASSWORD_METHOD
Definition: gui.h:163
#define GWEN_GUI_MSG_FLAGS_TYPE_ERROR
Definition: gui.h:293
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition: mdigest.c:141
unsigned int GWEN_MDigest_GetDigestSize(GWEN_MDIGEST *md)
Definition: mdigest.c:90
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Md5_new(void)
Definition: mdigestgc.c:140
int GWEN_StringList_HasString(const GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:435
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
int GWEN_Gui_GetPassword(uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid)
Definition: gui_passwd.c:348
#define GWEN_GUI_MSG_FLAGS_CONFIRM_B1
Definition: gui.h:299
#define GWEN_ERROR_NOT_FOUND
Definition: error.h:89
static int _tryReadPasswdViaInputBox(GWEN_GUI *gui, uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, uint32_t guiid)
Definition: gui_passwd.c:202
struct GWEN_GUI GWEN_GUI
Definition: gui.h:176
void GWEN_PasswordStore_ClearStoragePasswd(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:76
static int GWENHYWFAR_CB GWEN_Gui_Internal_GetPassword(GWEN_GUI *gui, uint32_t flags, const char *token, const char *title, const char *text, char *pwBuffer, int minLen, int maxLen, GWEN_UNUSED GWEN_GUI_PASSWORD_METHOD methodId, GWEN_UNUSED GWEN_DB_NODE *methodParams, uint32_t guiid)
Definition: gui_passwd.c:84
int GWEN_Gui_SetPasswordStatus(const char *token, const char *pin, GWEN_GUI_PASSWORD_STATUS status, uint32_t guiid)
Definition: gui_passwd.c:373
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
#define GWEN_ERROR_USER_ABORTED
Definition: error.h:65
#define GWEN_ERROR_NO_DATA
Definition: error.h:94
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:944
int GWEN_Text_ToHexBuffer(const char *src, unsigned l, GWEN_BUFFER *buf, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
Definition: text.c:777
#define GWEN_UNUSED
#define GWEN_ERROR_NOT_IMPLEMENTED
Definition: error.h:108