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);