# HG changeset patch # User Guido Berhoerster # Date 1501228426 -7200 # Node ID 60c8ab006e551a576bf6ad0689920940f1a43ae1 # Parent 25e227eba3daced81e9681a1f5d02c9ad114df23 Update metadata Update password file metadata when saving. Add and update metadata when creating and modifying records. diff -r 25e227eba3da -r 60c8ab006e55 pwfile.c --- a/pwfile.c Fri Jul 28 08:20:38 2017 +0200 +++ b/pwfile.c Fri Jul 28 09:53:46 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Guido Berhoerster + * Copyright (C) 2017 Guido Berhoerster * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -33,7 +33,9 @@ #ifdef HAVE_SYS_TREE_H #include #endif +#include #include +#include #include "pwfile.h" #include "util.h" @@ -301,6 +303,81 @@ return (retval); } +static void +update_file_metadata(struct pws3_file *file) +{ + struct pws3_field *save_app_field; + struct pws3_field *save_timestamp_field; + char *logname; + const char default_username[] = "unknown user"; + const char *username; + size_t username_len; + struct utsname utsn; + const char default_hostname[] = "unknown host"; + const char *hostname; + char user_host[1024]; + struct pws3_field *save_user_host_field; + struct pws3_field *save_user_field; + struct pws3_field *save_host_field; + + save_app_field = + pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_APPLICATION); + if (save_app_field == NULL) { + err(1, "pws3_field_create"); + } + if (pws3_field_set_text(save_app_field, PACKAGE " V" VERSION) != + 0) { + err(1, "pws3_field_set_text"); + } + pws3_file_set_header_field(file, save_app_field); + + save_timestamp_field = + pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_TIMESTAMP); + if (save_timestamp_field == NULL) { + err(1, "pws3_field_create"); + } + pws3_field_set_time(save_timestamp_field, time(NULL)); + pws3_file_set_header_field(file, save_timestamp_field); + + logname = getenv("LOGNAME"); + if (logname == NULL) { + logname = getlogin(); + } + username = (logname != NULL) ? logname : default_username; + username_len = MIN(strlen(username), sizeof (user_host) - 4 - 1); + hostname = (uname(&utsn) == 0) ? utsn.nodename : default_hostname; + snprintf(user_host, sizeof (user_host), "%04zx%s%s", username_len, + username, hostname); + + save_user_host_field = + pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER_HOST); + if (save_user_host_field == NULL) { + err(1, "pws3_field_create"); + } + if (pws3_field_set_text(save_user_host_field, user_host) != 0) { + err(1, "pws3_field_set_text"); + } + pws3_file_set_header_field(file, save_user_host_field); + + save_user_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER); + if (save_user_field == NULL) { + err(1, "pws3_field_create"); + } + if (pws3_field_set_text(save_user_field, logname) != 0) { + err(1, "pws3_field_set_text"); + } + pws3_file_set_header_field(file, save_user_field); + + save_host_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_HOST); + if (save_host_field == NULL) { + err(1, "pws3_field_create"); + } + if (pws3_field_set_text(save_host_field, hostname) != 0) { + err(1, "pws3_field_set_text"); + } + pws3_file_set_header_field(file, save_host_field); +} + int pwfile_write_file(struct pwm_ctx *ctx) { @@ -310,6 +387,10 @@ int fd = -1; FILE *fp = NULL; + /* update password file metadata */ + update_file_metadata(ctx->file); + + /* make a backup copy of the existing password file */ if (make_backup_copy(ctx->filename) != 0) { goto out; } @@ -519,17 +600,42 @@ static void update_record(struct pws3_record *pws3_record, struct record *record) { + time_t now; + struct pws3_field *ctime_field; + struct pws3_field *mtime_field; struct pws3_field *title_field; struct pws3_field *group_field; struct pws3_field *username_field; struct pws3_field *password_field; + struct pws3_field *password_mtime_field; struct pws3_field *notes_field; struct pws3_field *url_field; + now = time(NULL); + + ctime_field = pws3_record_get_field(pws3_record, + PWS3_RECORD_FIELD_CREATION_TIME); + if (ctime_field == NULL) { + ctime_field = pws3_field_create(0, + PWS3_RECORD_FIELD_CREATION_TIME); + if (ctime_field == NULL) { + err(1, "pws3_field_create"); + } + pws3_field_set_time(ctime_field, now); + pws3_record_set_field(pws3_record, ctime_field); + } + + mtime_field = pws3_field_create(0, PWS3_RECORD_FIELD_MODIFICATION_TIME); + if (mtime_field == NULL) { + err(1, "pws3_field_create"); + } + pws3_field_set_time(mtime_field, now); + pws3_record_set_field(pws3_record, mtime_field); + if (record->title != NULL) { title_field = pws3_field_create(0, PWS3_RECORD_FIELD_TITLE); if (title_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(title_field, record->title) != 0) { @@ -540,7 +646,7 @@ if (record->group != NULL) { group_field = pws3_field_create(0, PWS3_RECORD_FIELD_GROUP); if (group_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(group_field, record->group) != 0) { @@ -552,7 +658,7 @@ username_field = pws3_field_create(0, PWS3_RECORD_FIELD_USERNAME); if (username_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(username_field, record->username) != 0) { @@ -564,18 +670,26 @@ password_field = pws3_field_create(0, PWS3_RECORD_FIELD_PASSWORD); if (password_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(password_field, record->password) != 0) { err(1, "pws3_field_set_text"); } pws3_record_set_field(pws3_record, password_field); + + password_mtime_field = pws3_field_create(0, + PWS3_RECORD_FIELD_PASSWORD_MODIFICATION_TIME); + if (password_mtime_field == NULL) { + err(1, "pws3_field_create"); + } + pws3_field_set_time(password_mtime_field, now); + pws3_record_set_field(pws3_record, password_mtime_field); } if (record->notes != NULL) { notes_field = pws3_field_create(0, PWS3_RECORD_FIELD_NOTES); if (notes_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(notes_field, record->notes) != 0) { err(1, "pws3_field_set_text"); @@ -585,7 +699,7 @@ if (record->url != NULL) { url_field = pws3_field_create(0, PWS3_RECORD_FIELD_URL); if (url_field == NULL) { - err(1, "pws3_record_field_create"); + err(1, "pws3_field_create"); } if (pws3_field_set_text(url_field, record->url) != 0) { err(1, "pws3_field_set_text"); diff -r 25e227eba3da -r 60c8ab006e55 util.h --- a/util.h Fri Jul 28 08:20:38 2017 +0200 +++ b/util.h Fri Jul 28 09:53:46 2017 +0200 @@ -32,6 +32,9 @@ #define COUNTOF(x) ((sizeof (x)/sizeof (0[x])) / ((size_t)(!(sizeof (x) % \ sizeof (0[x]))))) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + void * xmalloc(size_t); void * xrealloc(void *, size_t); char * xstrdup(const char *);