Mercurial > projects > pwm
comparison pwfile.c @ 9:60c8ab006e55
Update metadata
Update password file metadata when saving.
Add and update metadata when creating and modifying records.
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Fri, 28 Jul 2017 09:53:46 +0200 |
parents | 0b1bce8db371 |
children | 17fb30016e64 |
comparison
equal
deleted
inserted
replaced
8:25e227eba3da | 9:60c8ab006e55 |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2016 Guido Berhoerster <guido+pwm@berhoerster.name> | 2 * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name> |
3 * | 3 * |
4 * Permission is hereby granted, free of charge, to any person obtaining | 4 * Permission is hereby granted, free of charge, to any person obtaining |
5 * a copy of this software and associated documentation files (the | 5 * a copy of this software and associated documentation files (the |
6 * "Software"), to deal in the Software without restriction, including | 6 * "Software"), to deal in the Software without restriction, including |
7 * without limitation the rights to use, copy, modify, merge, publish, | 7 * without limitation the rights to use, copy, modify, merge, publish, |
31 #include <string.h> | 31 #include <string.h> |
32 #include <sys/stat.h> | 32 #include <sys/stat.h> |
33 #ifdef HAVE_SYS_TREE_H | 33 #ifdef HAVE_SYS_TREE_H |
34 #include <sys/tree.h> | 34 #include <sys/tree.h> |
35 #endif | 35 #endif |
36 #include <sys/utsname.h> | |
36 #include <unistd.h> | 37 #include <unistd.h> |
38 #include <time.h> | |
37 | 39 |
38 #include "pwfile.h" | 40 #include "pwfile.h" |
39 #include "util.h" | 41 #include "util.h" |
40 | 42 |
41 struct record_id_entry { | 43 struct record_id_entry { |
299 free(backup_filename); | 301 free(backup_filename); |
300 | 302 |
301 return (retval); | 303 return (retval); |
302 } | 304 } |
303 | 305 |
306 static void | |
307 update_file_metadata(struct pws3_file *file) | |
308 { | |
309 struct pws3_field *save_app_field; | |
310 struct pws3_field *save_timestamp_field; | |
311 char *logname; | |
312 const char default_username[] = "unknown user"; | |
313 const char *username; | |
314 size_t username_len; | |
315 struct utsname utsn; | |
316 const char default_hostname[] = "unknown host"; | |
317 const char *hostname; | |
318 char user_host[1024]; | |
319 struct pws3_field *save_user_host_field; | |
320 struct pws3_field *save_user_field; | |
321 struct pws3_field *save_host_field; | |
322 | |
323 save_app_field = | |
324 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_APPLICATION); | |
325 if (save_app_field == NULL) { | |
326 err(1, "pws3_field_create"); | |
327 } | |
328 if (pws3_field_set_text(save_app_field, PACKAGE " V" VERSION) != | |
329 0) { | |
330 err(1, "pws3_field_set_text"); | |
331 } | |
332 pws3_file_set_header_field(file, save_app_field); | |
333 | |
334 save_timestamp_field = | |
335 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_TIMESTAMP); | |
336 if (save_timestamp_field == NULL) { | |
337 err(1, "pws3_field_create"); | |
338 } | |
339 pws3_field_set_time(save_timestamp_field, time(NULL)); | |
340 pws3_file_set_header_field(file, save_timestamp_field); | |
341 | |
342 logname = getenv("LOGNAME"); | |
343 if (logname == NULL) { | |
344 logname = getlogin(); | |
345 } | |
346 username = (logname != NULL) ? logname : default_username; | |
347 username_len = MIN(strlen(username), sizeof (user_host) - 4 - 1); | |
348 hostname = (uname(&utsn) == 0) ? utsn.nodename : default_hostname; | |
349 snprintf(user_host, sizeof (user_host), "%04zx%s%s", username_len, | |
350 username, hostname); | |
351 | |
352 save_user_host_field = | |
353 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER_HOST); | |
354 if (save_user_host_field == NULL) { | |
355 err(1, "pws3_field_create"); | |
356 } | |
357 if (pws3_field_set_text(save_user_host_field, user_host) != 0) { | |
358 err(1, "pws3_field_set_text"); | |
359 } | |
360 pws3_file_set_header_field(file, save_user_host_field); | |
361 | |
362 save_user_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER); | |
363 if (save_user_field == NULL) { | |
364 err(1, "pws3_field_create"); | |
365 } | |
366 if (pws3_field_set_text(save_user_field, logname) != 0) { | |
367 err(1, "pws3_field_set_text"); | |
368 } | |
369 pws3_file_set_header_field(file, save_user_field); | |
370 | |
371 save_host_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_HOST); | |
372 if (save_host_field == NULL) { | |
373 err(1, "pws3_field_create"); | |
374 } | |
375 if (pws3_field_set_text(save_host_field, hostname) != 0) { | |
376 err(1, "pws3_field_set_text"); | |
377 } | |
378 pws3_file_set_header_field(file, save_host_field); | |
379 } | |
380 | |
304 int | 381 int |
305 pwfile_write_file(struct pwm_ctx *ctx) | 382 pwfile_write_file(struct pwm_ctx *ctx) |
306 { | 383 { |
307 int retval = -1; | 384 int retval = -1; |
308 char *tmpfilename = NULL; | 385 char *tmpfilename = NULL; |
309 mode_t old_mode; | 386 mode_t old_mode; |
310 int fd = -1; | 387 int fd = -1; |
311 FILE *fp = NULL; | 388 FILE *fp = NULL; |
312 | 389 |
390 /* update password file metadata */ | |
391 update_file_metadata(ctx->file); | |
392 | |
393 /* make a backup copy of the existing password file */ | |
313 if (make_backup_copy(ctx->filename) != 0) { | 394 if (make_backup_copy(ctx->filename) != 0) { |
314 goto out; | 395 goto out; |
315 } | 396 } |
316 | 397 |
317 xasprintf(&tmpfilename, "%s.XXXXXX", ctx->filename); | 398 xasprintf(&tmpfilename, "%s.XXXXXX", ctx->filename); |
517 } | 598 } |
518 | 599 |
519 static void | 600 static void |
520 update_record(struct pws3_record *pws3_record, struct record *record) | 601 update_record(struct pws3_record *pws3_record, struct record *record) |
521 { | 602 { |
603 time_t now; | |
604 struct pws3_field *ctime_field; | |
605 struct pws3_field *mtime_field; | |
522 struct pws3_field *title_field; | 606 struct pws3_field *title_field; |
523 struct pws3_field *group_field; | 607 struct pws3_field *group_field; |
524 struct pws3_field *username_field; | 608 struct pws3_field *username_field; |
525 struct pws3_field *password_field; | 609 struct pws3_field *password_field; |
610 struct pws3_field *password_mtime_field; | |
526 struct pws3_field *notes_field; | 611 struct pws3_field *notes_field; |
527 struct pws3_field *url_field; | 612 struct pws3_field *url_field; |
613 | |
614 now = time(NULL); | |
615 | |
616 ctime_field = pws3_record_get_field(pws3_record, | |
617 PWS3_RECORD_FIELD_CREATION_TIME); | |
618 if (ctime_field == NULL) { | |
619 ctime_field = pws3_field_create(0, | |
620 PWS3_RECORD_FIELD_CREATION_TIME); | |
621 if (ctime_field == NULL) { | |
622 err(1, "pws3_field_create"); | |
623 } | |
624 pws3_field_set_time(ctime_field, now); | |
625 pws3_record_set_field(pws3_record, ctime_field); | |
626 } | |
627 | |
628 mtime_field = pws3_field_create(0, PWS3_RECORD_FIELD_MODIFICATION_TIME); | |
629 if (mtime_field == NULL) { | |
630 err(1, "pws3_field_create"); | |
631 } | |
632 pws3_field_set_time(mtime_field, now); | |
633 pws3_record_set_field(pws3_record, mtime_field); | |
528 | 634 |
529 if (record->title != NULL) { | 635 if (record->title != NULL) { |
530 title_field = pws3_field_create(0, PWS3_RECORD_FIELD_TITLE); | 636 title_field = pws3_field_create(0, PWS3_RECORD_FIELD_TITLE); |
531 if (title_field == NULL) { | 637 if (title_field == NULL) { |
532 err(1, "pws3_record_field_create"); | 638 err(1, "pws3_field_create"); |
533 } | 639 } |
534 if (pws3_field_set_text(title_field, | 640 if (pws3_field_set_text(title_field, |
535 record->title) != 0) { | 641 record->title) != 0) { |
536 err(1, "pws3_field_set_text"); | 642 err(1, "pws3_field_set_text"); |
537 } | 643 } |
538 pws3_record_set_field(pws3_record, title_field); | 644 pws3_record_set_field(pws3_record, title_field); |
539 } | 645 } |
540 if (record->group != NULL) { | 646 if (record->group != NULL) { |
541 group_field = pws3_field_create(0, PWS3_RECORD_FIELD_GROUP); | 647 group_field = pws3_field_create(0, PWS3_RECORD_FIELD_GROUP); |
542 if (group_field == NULL) { | 648 if (group_field == NULL) { |
543 err(1, "pws3_record_field_create"); | 649 err(1, "pws3_field_create"); |
544 } | 650 } |
545 if (pws3_field_set_text(group_field, | 651 if (pws3_field_set_text(group_field, |
546 record->group) != 0) { | 652 record->group) != 0) { |
547 err(1, "pws3_field_set_text"); | 653 err(1, "pws3_field_set_text"); |
548 } | 654 } |
550 } | 656 } |
551 if (record->username != NULL) { | 657 if (record->username != NULL) { |
552 username_field = pws3_field_create(0, | 658 username_field = pws3_field_create(0, |
553 PWS3_RECORD_FIELD_USERNAME); | 659 PWS3_RECORD_FIELD_USERNAME); |
554 if (username_field == NULL) { | 660 if (username_field == NULL) { |
555 err(1, "pws3_record_field_create"); | 661 err(1, "pws3_field_create"); |
556 } | 662 } |
557 if (pws3_field_set_text(username_field, | 663 if (pws3_field_set_text(username_field, |
558 record->username) != 0) { | 664 record->username) != 0) { |
559 err(1, "pws3_field_set_text"); | 665 err(1, "pws3_field_set_text"); |
560 } | 666 } |
562 } | 668 } |
563 if (record->password != NULL) { | 669 if (record->password != NULL) { |
564 password_field = pws3_field_create(0, | 670 password_field = pws3_field_create(0, |
565 PWS3_RECORD_FIELD_PASSWORD); | 671 PWS3_RECORD_FIELD_PASSWORD); |
566 if (password_field == NULL) { | 672 if (password_field == NULL) { |
567 err(1, "pws3_record_field_create"); | 673 err(1, "pws3_field_create"); |
568 } | 674 } |
569 if (pws3_field_set_text(password_field, | 675 if (pws3_field_set_text(password_field, |
570 record->password) != 0) { | 676 record->password) != 0) { |
571 err(1, "pws3_field_set_text"); | 677 err(1, "pws3_field_set_text"); |
572 } | 678 } |
573 pws3_record_set_field(pws3_record, password_field); | 679 pws3_record_set_field(pws3_record, password_field); |
680 | |
681 password_mtime_field = pws3_field_create(0, | |
682 PWS3_RECORD_FIELD_PASSWORD_MODIFICATION_TIME); | |
683 if (password_mtime_field == NULL) { | |
684 err(1, "pws3_field_create"); | |
685 } | |
686 pws3_field_set_time(password_mtime_field, now); | |
687 pws3_record_set_field(pws3_record, password_mtime_field); | |
574 } | 688 } |
575 if (record->notes != NULL) { | 689 if (record->notes != NULL) { |
576 notes_field = pws3_field_create(0, PWS3_RECORD_FIELD_NOTES); | 690 notes_field = pws3_field_create(0, PWS3_RECORD_FIELD_NOTES); |
577 if (notes_field == NULL) { | 691 if (notes_field == NULL) { |
578 err(1, "pws3_record_field_create"); | 692 err(1, "pws3_field_create"); |
579 } | 693 } |
580 if (pws3_field_set_text(notes_field, record->notes) != 0) { | 694 if (pws3_field_set_text(notes_field, record->notes) != 0) { |
581 err(1, "pws3_field_set_text"); | 695 err(1, "pws3_field_set_text"); |
582 } | 696 } |
583 pws3_record_set_field(pws3_record, notes_field); | 697 pws3_record_set_field(pws3_record, notes_field); |
584 } | 698 } |
585 if (record->url != NULL) { | 699 if (record->url != NULL) { |
586 url_field = pws3_field_create(0, PWS3_RECORD_FIELD_URL); | 700 url_field = pws3_field_create(0, PWS3_RECORD_FIELD_URL); |
587 if (url_field == NULL) { | 701 if (url_field == NULL) { |
588 err(1, "pws3_record_field_create"); | 702 err(1, "pws3_field_create"); |
589 } | 703 } |
590 if (pws3_field_set_text(url_field, record->url) != 0) { | 704 if (pws3_field_set_text(url_field, record->url) != 0) { |
591 err(1, "pws3_field_set_text"); | 705 err(1, "pws3_field_set_text"); |
592 } | 706 } |
593 pws3_record_set_field(pws3_record, url_field); | 707 pws3_record_set_field(pws3_record, url_field); |