gwenhywfar 5.12.0
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
28static 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);
35static int _tryReadCachedPasswd(GWEN_GUI *gui, const char *pwName, char *buffer, int minLen, int maxLen);
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
53static 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
141int _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) {
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
180int _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 rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, pwBuffer);
283 if (rv<0) {
284 DBG_WARN(GWEN_LOGDOMAIN, "Could not store password (%d)", rv);
285 }
286 }
287}
288
289
290
292 const char *token,
293 const char *pin,
295 GWEN_UNUSED uint32_t guiid)
296{
297 if (token==NULL && pin==NULL && status==GWEN_Gui_PasswordStatus_Remove) {
298 /* complete cleaning is requested */
299 if (gui->passwdStore)
301 if (gui->persistentPasswords==0)
302 GWEN_DB_ClearGroup(gui->dbPasswords, NULL);
303 }
304 else {
305 GWEN_BUFFER *hbuf;
306
307 /* setting ststus of a specific password/pin */
308 hbuf=GWEN_Buffer_new(0, 64, 0, 1);
309 GWEN_Gui__HashPair(token, pin, hbuf);
310 if (status==GWEN_Gui_PasswordStatus_Bad) {
311 GWEN_StringList_AppendString(gui->badPasswords,
313 0, 1);
314 /* remove from permanent passwd storage */
315 if (gui->passwdStore) {
316 int rv;
317
318 rv=GWEN_PasswordStore_SetPassword(gui->passwdStore, token, NULL);
319 if (rv<0) {
320 DBG_WARN(GWEN_LOGDOMAIN, "Could not remove password from storage (%d)", rv);
321 }
322 }
323
324 if (gui->dbPasswords) {
325 GWEN_BUFFER *buf;
326
327 buf=GWEN_Buffer_new(0, 256, 0, 1);
329
330 GWEN_DB_DeleteVar(gui->dbPasswords, GWEN_Buffer_GetStart(buf));
331 }
332 }
333 else if (status==GWEN_Gui_PasswordStatus_Ok ||
335 if (gui->persistentPasswords==0)
336 GWEN_StringList_RemoveString(gui->badPasswords, GWEN_Buffer_GetStart(hbuf));
337 }
338 GWEN_Buffer_free(hbuf);
339 }
340
341 return 0;
342}
343
344
345
346int GWEN_Gui_GetPassword(uint32_t flags,
347 const char *token,
348 const char *title,
349 const char *text,
350 char *buffer,
351 int minLen,
352 int maxLen,
354 GWEN_DB_NODE *methodParams,
355 uint32_t guiid)
356{
357 GWEN_GUI *gui;
358
359 gui=GWEN_Gui_GetGui();
360 if (gui) {
361 if (gui->getPasswordFn)
362 return gui->getPasswordFn(gui, flags, token, title, text, buffer, minLen, maxLen, methodId, methodParams, guiid);
363 else if (gui->inputBoxFn)
364 return gui->inputBoxFn(gui, flags, title, text, buffer, minLen, maxLen, guiid);
365 }
367}
368
369
370
371int GWEN_Gui_SetPasswordStatus(const char *token,
372 const char *pin,
374 uint32_t guiid)
375{
376 GWEN_GUI *gui;
377
378 gui=GWEN_Gui_GetGui();
379 if (gui && gui->setPasswordStatusFn)
380 return gui->setPasswordStatusFn(gui, token, pin, status, guiid);
382}
383
384
385
386
#define NULL
Definition binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition db.c:971
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
Definition db.c:944
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition db.c:899
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_WARN(dbg_logger, format,...)
Definition debug.h:125
#define I18N(m)
Definition error.c:42
#define GWEN_ERROR_NOT_IMPLEMENTED
Definition error.h:108
#define GWEN_ERROR_INTERNAL
Definition error.h:125
#define GWEN_ERROR_USER_ABORTED
Definition error.h:65
#define GWEN_ERROR_NOT_FOUND
Definition error.h:89
#define GWEN_ERROR_NO_DATA
Definition error.h:94
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
GWEN_GUI * GWEN_Gui_GetGui(void)
Definition gui.c:160
GWENHYWFAR_API int GWEN_Gui_InputBox(uint32_t flags, const char *title, const char *text, char *buffer, int minLen, int maxLen, uint32_t guiid)
GWEN_GUI_PASSWORD_METHOD
Definition gui.h:163
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)
#define GWEN_GUI_MSG_FLAGS_CONFIRM_B1
Definition gui.h:299
#define GWEN_GUI_MSG_FLAGS_TYPE_ERROR
Definition gui.h:293
#define GWEN_GUI_INPUT_FLAGS_DIRECT
Definition gui.h:226
#define GWEN_GUI_FLAGS_NONINTERACTIVE
Definition gui.h:992
#define GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS
Definition gui.h:337
#define GWEN_GUI_INPUT_FLAGS_TAN
Definition gui.h:222
GWEN_GUI_PASSWORD_STATUS
Definition gui.h:386
@ GWEN_Gui_PasswordStatus_Bad
Definition gui.h:387
@ GWEN_Gui_PasswordStatus_Ok
Definition gui.h:389
@ GWEN_Gui_PasswordStatus_Remove
Definition gui.h:392
#define GWEN_GUI_INPUT_FLAGS_CONFIRM
Definition gui.h:211
struct GWEN_GUI GWEN_GUI
Definition gui.h:176
static int GWEN_Gui__HashPair(const char *token, const char *pin, GWEN_BUFFER *buf)
Definition gui_passwd.c:53
int GWEN_Gui_SetPasswordStatus(const char *token, const char *pin, GWEN_GUI_PASSWORD_STATUS status, uint32_t guiid)
Definition gui_passwd.c:371
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:346
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
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
static void _tryStorePasswdInCacheAndStorage(GWEN_GUI *gui, const char *pwName, const char *token, const char *pwBuffer, int userWantsToStorePasswd)
Definition gui_passwd.c:269
static int _tryReadCachedPasswd(GWEN_GUI *gui, const char *pwName, char *buffer, int minLen, int maxLen)
Definition gui_passwd.c:180
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
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:291
#define GWEN_UNUSED
#define GWENHYWFAR_CB
#define GWEN_LOGDOMAIN
Definition logger.h:35
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition mdigest.c:129
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition mdigest.c:141
unsigned int GWEN_MDigest_GetDigestSize(GWEN_MDIGEST *md)
Definition mdigest.c:90
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition mdigest.c:81
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition mdigest.c:54
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition mdigest.c:153
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Md5_new(void)
Definition mdigestgc.c:140
struct GWEN_MDIGEST GWEN_MDIGEST
Definition mdigest.h:25
int GWEN_PasswordStore_GetPassword(GWEN_PASSWD_STORE *sto, const char *token, char *buffer, int minLen, int maxLen)
void GWEN_PasswordStore_ClearStoragePasswd(GWEN_PASSWD_STORE *sto)
Definition passwdstore.c:76
int GWEN_PasswordStore_SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition stringlist.c:245
int GWEN_StringList_HasString(const GWEN_STRINGLIST *sl, const char *s)
Definition stringlist.c:435
int GWEN_StringList_RemoveString(GWEN_STRINGLIST *sl, const char *s)
Definition stringlist.c:326
int GWEN_Text_ToHexBuffer(const char *src, unsigned l, GWEN_BUFFER *buf, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
Definition text.c:777
int GWEN_Text_EscapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
Definition text.c:1471