gwenhywfar  5.10.1
passwdstore.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sat Dec 16 2012
3  copyright : (C) 2012 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 #include "passwdstore_p.h"
31 #include "i18n_l.h"
32 
33 #include <gwenhywfar/gui.h>
34 #include <gwenhywfar/db.h>
35 #include <gwenhywfar/directory.h>
36 #include <gwenhywfar/fslock.h>
37 #include <gwenhywfar/mdigest.h>
38 #include <gwenhywfar/text.h>
39 #include <gwenhywfar/debug.h>
40 #include <gwenhywfar/smalltresor.h>
41 
42 #include <errno.h>
43 
44 
45 
47 {
48  GWEN_PASSWD_STORE *sto;
49 
51  if (fname)
52  sto->fileName=strdup(fname);
53  sto->dbPasswords=NULL;
54 
55  return sto;
56 }
57 
58 
59 
61 {
62  if (sto) {
63  memset(sto->pw, 0, sizeof(sto->pw));
64  if (sto->dbPasswords) {
66  GWEN_DB_Group_free(sto->dbPasswords);
67  sto->dbPasswords=NULL;
68  }
69  free(sto->fileName);
70  GWEN_FREE_OBJECT(sto);
71  }
72 }
73 
74 
75 
77 {
78  assert(sto);
79  memset(sto->pw, 0, GWEN_PASSWDSTORE_PWLEN);
80  if (sto->dbPasswords) {
82  GWEN_DB_Group_free(sto->dbPasswords);
83  sto->dbPasswords=NULL;
84  }
85 }
86 
87 
88 
89 
90 static int readFile(const char *fname, GWEN_BUFFER *dbuf)
91 {
92  FILE *f;
93 
94  f=fopen(fname, "rb");
95  if (f) {
96  while (!feof(f)) {
97  uint32_t l;
98  ssize_t s;
99  char *p;
100 
101  GWEN_Buffer_AllocRoom(dbuf, 1024);
104  s=fread(p, 1, l, f);
105  if (s==0)
106  break;
107  if (s==(ssize_t)-1) {
109  "fread(%s): %s",
110  fname, strerror(errno));
111  fclose(f);
112  return GWEN_ERROR_IO;
113  }
114 
115  GWEN_Buffer_IncrementPos(dbuf, s);
117  }
118 
119  fclose(f);
120  return 0;
121  }
122  else {
123  if (errno==ENOENT) {
124  DBG_INFO(GWEN_LOGDOMAIN, "File [%s] does not exist", fname);
125  return GWEN_ERROR_NOT_FOUND;
126  }
127  else {
129  "fopen(%s): %s",
130  fname, strerror(errno));
131  return GWEN_ERROR_IO;
132  }
133  }
134 }
135 
136 
137 
138 static int writeToFile(FILE *f, const char *p, int len)
139 {
140  while (len>0) {
141  ssize_t l;
142  ssize_t s;
143 
144  l=1024;
145  if (l>len)
146  l=len;
147  s=fwrite(p, 1, l, f);
148  if (s==(ssize_t)-1 || s==0) {
150  "fwrite: %s",
151  strerror(errno));
152  return GWEN_ERROR_IO;
153  }
154  p+=s;
155  len-=s;
156  }
157 
158  return 0;
159 }
160 
161 
162 
163 static int writeFile(const char *fname, const char *p, int len)
164 {
165  FILE *f;
166 
167  f=fopen(fname, "wb");
168  if (f) {
169  int rv;
170 
171  rv=writeToFile(f, p, len);
172  if (rv<0) {
173  DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
174  fclose(f);
175  return rv;
176  }
177  if (fclose(f)) {
178  DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
179  return rv;
180  }
181  }
182  else {
183  DBG_ERROR(GWEN_LOGDOMAIN, "fopen(%s): %s",
184  fname, strerror(errno));
185  return GWEN_ERROR_IO;
186  }
187 
188  return 0;
189 }
190 
191 
192 
193 static int GWEN_PasswordStore_Digest(const uint8_t *t, uint32_t size, GWEN_BUFFER *buf)
194 {
195  GWEN_MDIGEST *md;
196  int rv;
197 
198  /* hash token and pin */
200  rv=GWEN_MDigest_Begin(md);
201  if (rv==0)
202  rv=GWEN_MDigest_Update(md, (const uint8_t *)t, size);
203  if (rv==0)
204  rv=GWEN_MDigest_End(md);
205  if (rv<0) {
206  DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
207  GWEN_MDigest_free(md);
208  return rv;
209  }
210 
212  (const char *)GWEN_MDigest_GetDigestPtr(md),
214  GWEN_MDigest_free(md);
215  return 0;
216 }
217 
218 
219 
220 static int GWEN_PasswordStore_CheckDigest(const uint8_t *t, uint32_t size, const uint8_t *h)
221 {
222  GWEN_MDIGEST *md;
223  int rv;
224 
225  /* hash token and pin */
227  rv=GWEN_MDigest_Begin(md);
228  if (rv==0)
229  rv=GWEN_MDigest_Update(md, (const uint8_t *)t, size);
230  if (rv==0)
231  rv=GWEN_MDigest_End(md);
232  if (rv<0) {
233  DBG_ERROR(GWEN_LOGDOMAIN, "Hash error (%d)", rv);
234  GWEN_MDigest_free(md);
235  return rv;
236  }
237 
238  if (memcmp(h, GWEN_MDigest_GetDigestPtr(md), 20)) {
239  DBG_ERROR(GWEN_LOGDOMAIN, "Bad hash");
240  GWEN_MDigest_free(md);
241  return GWEN_ERROR_BAD_DATA;
242  }
243 
244  GWEN_MDigest_free(md);
245  return 0;
246 }
247 
248 
249 
251 {
252  if (sto->dbPasswords) {
254  GWEN_DB_Group_free(sto->dbPasswords);
255  sto->dbPasswords=NULL;
256  }
257 }
258 
259 
260 
262 {
263  int rv;
264  GWEN_BUFFER *sbuf;
265 
266  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
267  rv=readFile(sto->fileName, sbuf);
268  if (rv<0) {
269  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
270  GWEN_Buffer_free(sbuf);
271  return rv;
272  }
273 
274  if (GWEN_Buffer_GetUsedBytes(sbuf)<1) {
275  DBG_INFO(GWEN_LOGDOMAIN, "Empty file");
276  GWEN_Buffer_free(sbuf);
277  return GWEN_ERROR_NO_DATA;
278  }
279 
280  for (;;) {
281  GWEN_BUFFER *tbuf;
282  uint32_t pos1;
283  uint32_t pos2;
284  uint32_t len;
285 
286  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
287  GWEN_Buffer_AppendString(tbuf, "PASSWORD_STORE_");
288  GWEN_Text_UnescapeToBufferTolerant(sto->fileName, tbuf);
289 
290  if (sto->pw[0]==0) {
292  I18N("Enter Password"),
293  I18N("Please enter the password for the password store.\n"
294  "<html>"
295  "Please enter the password for the <b>password store</b>.</br>"
296  "</html>"),
297  sto->pw,
298  4,
299  sizeof(sto->pw)-1,
300  0);
301  if (rv<0) {
302  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
303  GWEN_Buffer_free(tbuf);
304  GWEN_Buffer_free(sbuf);
305  return rv;
306  }
307  }
308 
309  pos1=GWEN_Buffer_GetPos(secbuf);
310 
311  rv=GWEN_SmallTresor_Decrypt((const uint8_t *) GWEN_Buffer_GetStart(sbuf),
313  sto->pw,
314  secbuf,
315  GWEN_PASSWDSTORE_PW_ITERATIONS,
316  GWEN_PASSWDSTORE_CRYPT_ITERATIONS);
317  GWEN_Buffer_free(tbuf);
318  if (rv<0) {
319  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
320  /* error, reset password */
321  memset(sto->pw, 0, sizeof(sto->pw));
322  }
323  else {
324  /* check and remove hash */
325  pos2=GWEN_Buffer_GetPos(secbuf);
326  len=pos2-pos1;
327 
328  if (len>=20) {
329  const uint8_t *p1;
330  const uint8_t *p2;
331 
332  p1=(const uint8_t *)GWEN_Buffer_GetStart(secbuf)+pos1; /* start of decrypted data */
333  p2=(const uint8_t *)GWEN_Buffer_GetStart(secbuf)+(pos2-20); /* start of hash */
334 
335  rv=GWEN_PasswordStore_CheckDigest(p1, len-20, p2);
336  if (rv<0) {
337  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
338  GWEN_Buffer_free(sbuf);
339  return rv;
340  }
341  else {
342  GWEN_Buffer_Crop(secbuf, 0, pos2-20);
343  break;
344  }
345  }
346  else {
347  DBG_ERROR(GWEN_LOGDOMAIN, "Bad data size (smaller than 20 bytes)");
348  /* reset buffer */
349  GWEN_Buffer_Crop(secbuf, 0, pos1);
350  GWEN_Buffer_free(sbuf);
351  return rv;
352  }
353  }
354  } /* for */
355 
356  GWEN_Buffer_free(sbuf);
357 
358  return 0;
359 }
360 
361 
362 
363 static int GWEN_PasswordStore_EncryptWriteFile(GWEN_PASSWD_STORE *sto, const uint8_t *sec, uint32_t len)
364 {
365  int rv;
366  GWEN_BUFFER *sbuf;
367  GWEN_BUFFER *tbuf;
368 
369  /* make sure the data dir exists */
370  DBG_ERROR(0, "Looking for [%s]", sto->fileName);
372  if (rv<0) {
373  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
374  return rv;
375  }
376 
377  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
378  GWEN_Buffer_AppendString(tbuf, "PASSWORD_STORE_");
379  GWEN_Text_UnescapeToBufferTolerant(sto->fileName, tbuf);
380 
381  /* ask for passwd if not already set */
382  if (sto->pw[0]==0) {
383  if (sto->isNew) {
385  I18N("Create New Password Store"),
386  I18N(
387  "You are about to create a new password store.\n"
388  "Passwords you store here will be encrypted with a passphrase\n"
389  "which you must enter now.\n"
390  "\n"
391 
392  "Later you will only need to remember the passphrase for the\n"
393  "password store, not all the individuell passwords.\n"
394  "\n"
395  "WARNING: Storing your passwords in the password store\n"
396  "can be considered a security risk, especially if the passphrase protecting it\n"
397  "is not strong enough!\n"
398  "\n"
399  "You can safely abort this step, in which case your passwords will not be stored.\n"
400  "\n"
401  "Please enter the passphrase for the password store to be created or abort.\n"
402  "<html>"
403  "<p>You are about to create a new <b>password store</b>.</p>"
404  "<br>"
405  "<p>Passwords you store here will be encrypted with a passphrase "
406  "which you must enter now.</p>"
407  "<p>Later you will only need to remember the passphrase for the "
408  "password store, not all the individuell passwords.<p>"
409  "<p><font color=\"red\">"
410  "<b>Warning:</b> Storing your passwords in the password store "
411  "can be considered a <b>security risk</b>, especially if the passphrase protecting it "
412  "is not strong enough!"
413  "</font></p>"
414  "<p><b>You can safely abort this step</b>, in which case your passwords will not be stored.</p>"
415  "<br>"
416  "<p>Please enter the passphrase for the password store to be created or abort.</p>"
417  "</html>"),
418  sto->pw,
419  4,
420  sizeof(sto->pw)-1,
421  0);
422 
423  }
424  else
426  I18N("Enter Password"),
427  I18N("Please enter the password for the password store.\n"
428  "<html>"
429  "Please enter the password for the <b>password store</b>.</br>"
430  "</html>"),
431  sto->pw,
432  4,
433  sizeof(sto->pw)-1,
434  0);
435  if (rv<0) {
436  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
437  GWEN_Buffer_free(tbuf);
438  return rv;
439  }
440  }
441 
442  GWEN_Buffer_free(tbuf);
443 
444  /* prepare data to write */
445  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
446  tbuf=GWEN_Buffer_new(0, len+20, 0, 1);
447 
448  /* add clear text data */
449  GWEN_Buffer_AppendBytes(tbuf, (const char *) sec, len);
450 
451  /* add hash (20 bytes) */
452  rv=GWEN_PasswordStore_Digest((const uint8_t *) sec, len, tbuf);
453  if (rv<0) {
454  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
455  GWEN_Buffer_free(tbuf);
456  GWEN_Buffer_free(sbuf);
457  return rv;
458  }
459 
460  /* encrypt cleartext */
461  rv=GWEN_SmallTresor_Encrypt((const uint8_t *) GWEN_Buffer_GetStart(tbuf),
463  sto->pw,
464  sbuf,
465  GWEN_PASSWDSTORE_PW_ITERATIONS,
466  GWEN_PASSWDSTORE_CRYPT_ITERATIONS);
467  if (rv<0) {
468  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
469  GWEN_Buffer_free(tbuf);
470  GWEN_Buffer_free(sbuf);
471  return rv;
472  }
474  GWEN_Buffer_free(tbuf);
475 
476  /* write file */
477  rv=writeFile(sto->fileName,
478  GWEN_Buffer_GetStart(sbuf),
480  if (rv<0) {
481  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
482  GWEN_Buffer_free(sbuf);
483  return rv;
484  }
485 
486  GWEN_Buffer_free(sbuf);
487 
488  return 0;
489 }
490 
491 
492 
493 
495 {
496  GWEN_BUFFER *tbuf;
497  int rv;
498 
499  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
500 
502  if (rv<0) {
503  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
504  GWEN_Buffer_free(tbuf);
505  return rv;
506  }
507  sto->isNew=0;
508 
510 
511  sto->dbPasswords=GWEN_DB_Group_new("passwords");
512  rv=GWEN_DB_ReadFromString(sto->dbPasswords,
513  GWEN_Buffer_GetStart(tbuf),
516  if (rv<0) {
517  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
519  GWEN_Buffer_free(tbuf);
520  return rv;
521  }
523 
525  GWEN_Buffer_free(tbuf);
526  return 0;
527 }
528 
529 
530 
532 {
533  if (sto->dbPasswords) {
534  GWEN_BUFFER *tbuf;
535  int rv;
536 
537  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
538  rv=GWEN_DB_WriteToBuffer(sto->dbPasswords, tbuf, GWEN_DB_FLAGS_DEFAULT);
539  if (rv<0) {
540  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
542  GWEN_Buffer_free(tbuf);
543  return rv;
544  }
545 
547  (const uint8_t *) GWEN_Buffer_GetStart(tbuf),
549  if (rv<0) {
550  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
552  GWEN_Buffer_free(tbuf);
553  return rv;
554  }
555 
557  GWEN_Buffer_free(tbuf);
558  return 0;
559  }
560  else {
561  DBG_INFO(GWEN_LOGDOMAIN, "No password db");
562  return GWEN_ERROR_INTERNAL;
563  }
564 }
565 
566 
567 
568 
569 static int GWEN_PasswordStore__SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
570 {
571  GWEN_BUFFER *buf;
572 
573  buf=GWEN_Buffer_new(0, 64, 0, 1);
575 
576  if (secret==NULL)
577  GWEN_DB_DeleteVar(sto->dbPasswords, GWEN_Buffer_GetStart(buf));
578  else
580  GWEN_Buffer_GetStart(buf), secret);
582  GWEN_Buffer_free(buf);
583 
584  return 0;
585 }
586 
587 
588 
589 static int GWEN_PasswordStore__GetPassword(GWEN_PASSWD_STORE *sto, const char *token, char *buffer, int minLen,
590  int maxLen)
591 {
592  GWEN_BUFFER *buf;
593  const char *s;
594 
595  buf=GWEN_Buffer_new(0, 256, 0, 1);
597 
598  s=GWEN_DB_GetCharValue(sto->dbPasswords,
600  0, NULL);
601  if (s) {
602  int i;
603 
604  i=strlen(s);
605  if (i>=minLen && i < maxLen) {
606  memmove(buffer, s, i+1);
607  GWEN_Buffer_free(buf);
608  return 0;
609  }
610  else {
611  DBG_ERROR(GWEN_LOGDOMAIN, "Stored password [%s] is not within size limits (%d), rejecting.",
612  GWEN_Buffer_GetStart(buf), i);
613  }
614  }
615 
616  GWEN_Buffer_free(buf);
617  return GWEN_ERROR_NOT_FOUND;
618 }
619 
620 
621 
622 
623 
624 int GWEN_PasswordStore_SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
625 {
626  GWEN_FSLOCK *lck;
628  int rv;
629 
630  /* make sure path exists */
632  if (rv<0) {
633  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
634  return rv;
635  }
636 
637  /* lock file */
638  lck=GWEN_FSLock_new(sto->fileName, GWEN_FSLock_TypeFile);
639  rs=GWEN_FSLock_Lock(lck, 60*1000, 0);
640  if (rs!=GWEN_FSLock_ResultOk) {
641  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rs);
642  return GWEN_ERROR_IO;
643  }
644 
645  /* read and decrypt file */
647  if (rv<0) {
648  if (rv==GWEN_ERROR_NOT_FOUND || rv==GWEN_ERROR_NO_DATA) {
649  DBG_INFO(GWEN_LOGDOMAIN, "Will create password store [%s]", sto->fileName);
650  if (sto->dbPasswords==NULL) {
651  sto->dbPasswords=GWEN_DB_Group_new("passwords");
653  }
654  sto->isNew=1;
655  }
656  else {
657  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
658  GWEN_FSLock_Unlock(lck);
659  GWEN_FSLock_free(lck);
660  return rv;
661  }
662  }
663 
664  /* set password in db */
665  rv=GWEN_PasswordStore__SetPassword(sto, token, secret);
666  if (rv<0) {
667  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
668  GWEN_FSLock_Unlock(lck);
669  GWEN_FSLock_free(lck);
670  return rv;
671  }
672 
673  /* write file back */
675  if (rv<0) {
676  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
677  GWEN_FSLock_Unlock(lck);
678  GWEN_FSLock_free(lck);
679  return rv;
680  }
681 
682  /* unlock file */
683  GWEN_FSLock_Unlock(lck);
684  GWEN_FSLock_free(lck);
685 
686  /* release passwords */
688 
689  return 0;
690 }
691 
692 
693 
694 
695 int GWEN_PasswordStore_GetPassword(GWEN_PASSWD_STORE *sto, const char *token, char *buffer, int minLen, int maxLen)
696 {
697  int rv;
698  GWEN_FSLOCK *lck;
700 
701  /* make sure path exists */
703  if (rv<0) {
704  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
705  return rv;
706  }
707 
708  /* lock file */
709  lck=GWEN_FSLock_new(sto->fileName, GWEN_FSLock_TypeFile);
710  rs=GWEN_FSLock_Lock(lck, 60*1000, 0);
711  if (rs!=GWEN_FSLock_ResultOk) {
712  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rs);
713  return GWEN_ERROR_IO;
714  }
715 
716  /* read and decode file */
718  if (rv<0) {
719  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
720  GWEN_FSLock_Unlock(lck);
721  GWEN_FSLock_free(lck);
722  return rv;
723  }
724 
725  /* unlock file */
726  GWEN_FSLock_Unlock(lck);
727  GWEN_FSLock_free(lck);
728 
729  /* finally get password, if possible */
730  rv=GWEN_PasswordStore__GetPassword(sto, token, buffer, minLen, maxLen);
731  if (rv<0) {
732  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
733  return rv;
734  }
735 
736  /* release passwords */
738 
739  return 0;
740 }
741 
742 
743 
745 {
746  int rv;
747  GWEN_FSLOCK *lck;
749  int pwErrors;
750  GWEN_DB_NODE *dbVar;
751 
752  /* make sure path exists */
754  if (rv<0) {
755  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
756  return rv;
757  }
758 
759  /* lock file */
760  lck=GWEN_FSLock_new(sto->fileName, GWEN_FSLock_TypeFile);
761  rs=GWEN_FSLock_Lock(lck, 60*1000, 0);
762  if (rs!=GWEN_FSLock_ResultOk) {
763  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rs);
764  return GWEN_ERROR_IO;
765  }
766 
767  /* read and decode file */
769  if (rv<0) {
770  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
771  GWEN_FSLock_Unlock(lck);
772  GWEN_FSLock_free(lck);
773  return rv;
774  }
775 
776  /* unlock file */
777  GWEN_FSLock_Unlock(lck);
778  GWEN_FSLock_free(lck);
779 
780 
781  /* read list of tokens from the file */
782  pwErrors=0;
783  dbVar=GWEN_DB_GetFirstVar(sto->dbPasswords);
784  while (dbVar) {
785  const char *s;
786 
787  s=GWEN_DB_VariableName(dbVar);
788  if (s && *s) {
789  GWEN_BUFFER *buf;
790  int rv;
791 
792  buf=GWEN_Buffer_new(0, 256, 0, 1);
794  if (rv<0) {
795  DBG_ERROR(GWEN_LOGDOMAIN, "Error unescaping token name (%d), ignoring", rv);
796  pwErrors++;
797  }
798  else {
800  }
801  GWEN_Buffer_free(buf);
802  }
803  else
804  pwErrors++;
805 
806  dbVar=GWEN_DB_GetNextVar(dbVar);
807  }
808 
809  /* release passwords */
811 
812  if (pwErrors) {
813  DBG_ERROR(GWEN_LOGDOMAIN, "Got %d errors.", pwErrors);
814  return GWEN_ERROR_GENERIC;
815  }
816 
817  return 0;
818 }
819 
820 
821 
822 
GWENHYWFAR_API int GWEN_DB_WriteToBuffer(GWEN_DB_NODE *n, GWEN_BUFFER *buf, uint32_t dbflags)
Definition: dbrw.c:1061
GWENHYWFAR_API void GWEN_FSLock_free(GWEN_FSLOCK *fl)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
#define I18N(m)
Definition: error.c:42
void GWEN_PasswordStore_free(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:60
static int writeToFile(FILE *f, const char *p, int len)
Definition: passwdstore.c:138
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition: mdigest.c:54
static int readFile(const char *fname, GWEN_BUFFER *dbuf)
Definition: passwdstore.c:90
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:285
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition: buffer.c:528
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
static void GWEN_PasswordStore_SafeFreeDb(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:250
#define GWEN_GUI_INPUT_FLAGS_CONFIRM
Definition: gui.h:211
static int GWEN_PasswordStore_Digest(const uint8_t *t, uint32_t size, GWEN_BUFFER *buf)
Definition: passwdstore.c:193
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
int GWEN_Text_EscapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1471
GWEN_PASSWD_STORE * GWEN_PasswordStore_new(const char *fname)
Definition: passwdstore.c:46
static int GWEN_PasswordStore_ReadDecryptFile(GWEN_PASSWD_STORE *sto, GWEN_BUFFER *secbuf)
Definition: passwdstore.c:261
int GWEN_SmallTresor_Decrypt(const uint8_t *p, uint32_t len, const char *password, GWEN_BUFFER *dst, int passwordIterations, int cryptIterations)
Definition: smalltresor.c:346
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:469
GWENHYWFAR_API int GWEN_DB_ReadFromString(GWEN_DB_NODE *n, const char *str, int len, uint32_t dbflags)
Definition: dbrw.c:1035
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
Definition: db.c:1805
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition: buffer.c:253
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_Text_UnescapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1515
static int GWEN_PasswordStore__SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
Definition: passwdstore.c:569
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:549
#define GWEN_ERROR_IO
Definition: error.h:123
int GWEN_PasswordStore_SetPassword(GWEN_PASSWD_STORE *sto, const char *token, const char *secret)
Definition: passwdstore.c:624
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:452
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition: mdigest.c:81
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition: mdigest.c:129
GWEN_DB_NODE * GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
Definition: db.c:479
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
GWENHYWFAR_API GWEN_FSLOCK * GWEN_FSLock_new(const char *fname, GWEN_FSLOCK_TYPE t)
static int GWEN_PasswordStore_CheckDigest(const uint8_t *t, uint32_t size, const uint8_t *h)
Definition: passwdstore.c:220
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition: mdigestgc.c:158
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_PATH_FLAGS_VARIABLE
Definition: path.h:111
#define GWEN_DB_NODE_FLAGS_SAFE
Definition: db.h:214
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
struct GWEN_MDIGEST GWEN_MDIGEST
Definition: mdigest.h:25
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
const char * GWEN_DB_VariableName(GWEN_DB_NODE *n)
Definition: db.c:1928
GWEN_FSLOCK_RESULT
Definition: fslock.h:71
GWENHYWFAR_API GWEN_FSLOCK_RESULT GWEN_FSLock_Lock(GWEN_FSLOCK *fl, int timeout, uint32_t gid)
static int GWEN_PasswordStore_ReadFile(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:494
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
int GWEN_PasswordStore_GetTokenList(GWEN_PASSWD_STORE *sto, GWEN_STRINGLIST *sl)
Definition: passwdstore.c:744
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:947
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition: mdigest.c:141
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
unsigned int GWEN_MDigest_GetDigestSize(GWEN_MDIGEST *md)
Definition: mdigest.c:90
struct GWEN_PASSWD_STORE GWEN_PASSWD_STORE
Definition: passwdstore.h:37
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
static int GWEN_PasswordStore_WriteFile(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:531
#define GWEN_ERROR_NOT_FOUND
Definition: error.h:89
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
GWEN_DB_NODE * GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
Definition: db.c:500
GWENHYWFAR_API int GWEN_Directory_GetPath(const char *path, unsigned int flags)
struct GWEN_FSLOCK GWEN_FSLOCK
Definition: fslock.h:59
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:361
void GWEN_PasswordStore_ClearStoragePasswd(GWEN_PASSWD_STORE *sto)
Definition: passwdstore.c:76
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
int GWEN_SmallTresor_Encrypt(const uint8_t *src, uint32_t slen, const char *password, GWEN_BUFFER *dst, int passwordIterations, int cryptIterations)
Definition: smalltresor.c:239
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
static int GWEN_PasswordStore__GetPassword(GWEN_PASSWD_STORE *sto, const char *token, char *buffer, int minLen, int maxLen)
Definition: passwdstore.c:589
GWENHYWFAR_API GWEN_FSLOCK_RESULT GWEN_FSLock_Unlock(GWEN_FSLOCK *fl)
#define GWEN_ERROR_NO_DATA
Definition: error.h:94
static int GWEN_PasswordStore_EncryptWriteFile(GWEN_PASSWD_STORE *sto, const uint8_t *sec, uint32_t len)
Definition: passwdstore.c:363
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
void GWEN_Buffer_OverwriteContent(GWEN_BUFFER *bf, int c)
Definition: buffer.c:557
static int writeFile(const char *fname, const char *p, int len)
Definition: passwdstore.c:163