projects/pwm

changeset 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 Jul 28 09:53:46 2017 +0200 (2017-07-28)
parents 25e227eba3da
children 17fb30016e64
files pwfile.c util.h
line diff
     1.1 --- a/pwfile.c	Fri Jul 28 08:20:38 2017 +0200
     1.2 +++ b/pwfile.c	Fri Jul 28 09:53:46 2017 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (C) 2016 Guido Berhoerster <guido+pwm@berhoerster.name>
     1.6 + * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name>
     1.7   *
     1.8   * Permission is hereby granted, free of charge, to any person obtaining
     1.9   * a copy of this software and associated documentation files (the
    1.10 @@ -33,7 +33,9 @@
    1.11  #ifdef	HAVE_SYS_TREE_H
    1.12  #include <sys/tree.h>
    1.13  #endif
    1.14 +#include <sys/utsname.h>
    1.15  #include <unistd.h>
    1.16 +#include <time.h>
    1.17  
    1.18  #include "pwfile.h"
    1.19  #include "util.h"
    1.20 @@ -301,6 +303,81 @@
    1.21  	return (retval);
    1.22  }
    1.23  
    1.24 +static void
    1.25 +update_file_metadata(struct pws3_file *file)
    1.26 +{
    1.27 +	struct pws3_field *save_app_field;
    1.28 +	struct pws3_field *save_timestamp_field;
    1.29 +	char		*logname;
    1.30 +	const char	default_username[] = "unknown user";
    1.31 +	const char	*username;
    1.32 +	size_t		username_len;
    1.33 +	struct utsname	utsn;
    1.34 +	const char	default_hostname[] = "unknown host";
    1.35 +	const char	*hostname;
    1.36 +	char		user_host[1024];
    1.37 +	struct pws3_field *save_user_host_field;
    1.38 +	struct pws3_field *save_user_field;
    1.39 +	struct pws3_field *save_host_field;
    1.40 +
    1.41 +	save_app_field =
    1.42 +	    pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_APPLICATION);
    1.43 +	if (save_app_field == NULL) {
    1.44 +		err(1, "pws3_field_create");
    1.45 +	}
    1.46 +	if (pws3_field_set_text(save_app_field, PACKAGE " V" VERSION) !=
    1.47 +	    0) {
    1.48 +		err(1, "pws3_field_set_text");
    1.49 +	}
    1.50 +	pws3_file_set_header_field(file, save_app_field);
    1.51 +
    1.52 +	save_timestamp_field =
    1.53 +	    pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_TIMESTAMP);
    1.54 +	if (save_timestamp_field == NULL) {
    1.55 +		err(1, "pws3_field_create");
    1.56 +	}
    1.57 +	pws3_field_set_time(save_timestamp_field, time(NULL));
    1.58 +	pws3_file_set_header_field(file, save_timestamp_field);
    1.59 +
    1.60 +	logname = getenv("LOGNAME");
    1.61 +	if (logname == NULL) {
    1.62 +		logname = getlogin();
    1.63 +	}
    1.64 +	username = (logname != NULL) ? logname : default_username;
    1.65 +	username_len = MIN(strlen(username), sizeof (user_host) - 4 - 1);
    1.66 +	hostname = (uname(&utsn) == 0) ? utsn.nodename : default_hostname;
    1.67 +	snprintf(user_host, sizeof (user_host), "%04zx%s%s", username_len,
    1.68 +	    username, hostname);
    1.69 +
    1.70 +	save_user_host_field =
    1.71 +	    pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER_HOST);
    1.72 +	if (save_user_host_field == NULL) {
    1.73 +		err(1, "pws3_field_create");
    1.74 +	}
    1.75 +	if (pws3_field_set_text(save_user_host_field, user_host) != 0) {
    1.76 +		err(1, "pws3_field_set_text");
    1.77 +	}
    1.78 +	pws3_file_set_header_field(file, save_user_host_field);
    1.79 +
    1.80 +	save_user_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER);
    1.81 +	if (save_user_field == NULL) {
    1.82 +		err(1, "pws3_field_create");
    1.83 +	}
    1.84 +	if (pws3_field_set_text(save_user_field, logname) != 0) {
    1.85 +		err(1, "pws3_field_set_text");
    1.86 +	}
    1.87 +	pws3_file_set_header_field(file, save_user_field);
    1.88 +
    1.89 +	save_host_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_HOST);
    1.90 +	if (save_host_field == NULL) {
    1.91 +		err(1, "pws3_field_create");
    1.92 +	}
    1.93 +	if (pws3_field_set_text(save_host_field, hostname) != 0) {
    1.94 +		err(1, "pws3_field_set_text");
    1.95 +	}
    1.96 +	pws3_file_set_header_field(file, save_host_field);
    1.97 +}
    1.98 +
    1.99  int
   1.100  pwfile_write_file(struct pwm_ctx *ctx)
   1.101  {
   1.102 @@ -310,6 +387,10 @@
   1.103  	int	fd = -1;
   1.104  	FILE	*fp = NULL;
   1.105  
   1.106 +	/* update password file metadata */
   1.107 +	update_file_metadata(ctx->file);
   1.108 +
   1.109 +	/* make a backup copy of the existing password file */
   1.110  	if (make_backup_copy(ctx->filename) != 0) {
   1.111  		goto out;
   1.112  	}
   1.113 @@ -519,17 +600,42 @@
   1.114  static void
   1.115  update_record(struct pws3_record *pws3_record, struct record *record)
   1.116  {
   1.117 +	time_t		now;
   1.118 +	struct pws3_field *ctime_field;
   1.119 +	struct pws3_field *mtime_field;
   1.120  	struct pws3_field *title_field;
   1.121  	struct pws3_field *group_field;
   1.122  	struct pws3_field *username_field;
   1.123  	struct pws3_field *password_field;
   1.124 +	struct pws3_field *password_mtime_field;
   1.125  	struct pws3_field *notes_field;
   1.126  	struct pws3_field *url_field;
   1.127  
   1.128 +	now = time(NULL);
   1.129 +
   1.130 +	ctime_field = pws3_record_get_field(pws3_record,
   1.131 +	    PWS3_RECORD_FIELD_CREATION_TIME);
   1.132 +	if (ctime_field == NULL) {
   1.133 +		ctime_field = pws3_field_create(0,
   1.134 +		    PWS3_RECORD_FIELD_CREATION_TIME);
   1.135 +		if (ctime_field == NULL) {
   1.136 +			err(1, "pws3_field_create");
   1.137 +		}
   1.138 +		pws3_field_set_time(ctime_field, now);
   1.139 +		pws3_record_set_field(pws3_record, ctime_field);
   1.140 +	}
   1.141 +
   1.142 +	mtime_field = pws3_field_create(0, PWS3_RECORD_FIELD_MODIFICATION_TIME);
   1.143 +	if (mtime_field == NULL) {
   1.144 +		err(1, "pws3_field_create");
   1.145 +	}
   1.146 +	pws3_field_set_time(mtime_field, now);
   1.147 +	pws3_record_set_field(pws3_record, mtime_field);
   1.148 +
   1.149  	if (record->title != NULL) {
   1.150  		title_field = pws3_field_create(0, PWS3_RECORD_FIELD_TITLE);
   1.151  		if (title_field == NULL) {
   1.152 -			err(1, "pws3_record_field_create");
   1.153 +			err(1, "pws3_field_create");
   1.154  		}
   1.155  		if (pws3_field_set_text(title_field,
   1.156  		    record->title) != 0) {
   1.157 @@ -540,7 +646,7 @@
   1.158  	if (record->group != NULL) {
   1.159  		group_field = pws3_field_create(0, PWS3_RECORD_FIELD_GROUP);
   1.160  		if (group_field == NULL) {
   1.161 -			err(1, "pws3_record_field_create");
   1.162 +			err(1, "pws3_field_create");
   1.163  		}
   1.164  		if (pws3_field_set_text(group_field,
   1.165  		    record->group) != 0) {
   1.166 @@ -552,7 +658,7 @@
   1.167  		username_field = pws3_field_create(0,
   1.168  		    PWS3_RECORD_FIELD_USERNAME);
   1.169  		if (username_field == NULL) {
   1.170 -			err(1, "pws3_record_field_create");
   1.171 +			err(1, "pws3_field_create");
   1.172  		}
   1.173  		if (pws3_field_set_text(username_field,
   1.174  		    record->username) != 0) {
   1.175 @@ -564,18 +670,26 @@
   1.176  		password_field = pws3_field_create(0,
   1.177  		    PWS3_RECORD_FIELD_PASSWORD);
   1.178  		if (password_field == NULL) {
   1.179 -			err(1, "pws3_record_field_create");
   1.180 +			err(1, "pws3_field_create");
   1.181  		}
   1.182  		if (pws3_field_set_text(password_field,
   1.183  		    record->password) != 0) {
   1.184  			err(1, "pws3_field_set_text");
   1.185  		}
   1.186  		pws3_record_set_field(pws3_record, password_field);
   1.187 +
   1.188 +		password_mtime_field = pws3_field_create(0,
   1.189 +		    PWS3_RECORD_FIELD_PASSWORD_MODIFICATION_TIME);
   1.190 +		if (password_mtime_field == NULL) {
   1.191 +			err(1, "pws3_field_create");
   1.192 +		}
   1.193 +		pws3_field_set_time(password_mtime_field, now);
   1.194 +		pws3_record_set_field(pws3_record, password_mtime_field);
   1.195  	}
   1.196  	if (record->notes != NULL) {
   1.197  		notes_field = pws3_field_create(0, PWS3_RECORD_FIELD_NOTES);
   1.198  		if (notes_field == NULL) {
   1.199 -			err(1, "pws3_record_field_create");
   1.200 +			err(1, "pws3_field_create");
   1.201  		}
   1.202  		if (pws3_field_set_text(notes_field, record->notes) != 0) {
   1.203  			err(1, "pws3_field_set_text");
   1.204 @@ -585,7 +699,7 @@
   1.205  	if (record->url != NULL) {
   1.206  		url_field = pws3_field_create(0, PWS3_RECORD_FIELD_URL);
   1.207  		if (url_field == NULL) {
   1.208 -			err(1, "pws3_record_field_create");
   1.209 +			err(1, "pws3_field_create");
   1.210  		}
   1.211  		if (pws3_field_set_text(url_field, record->url) != 0) {
   1.212  			err(1, "pws3_field_set_text");
     2.1 --- a/util.h	Fri Jul 28 08:20:38 2017 +0200
     2.2 +++ b/util.h	Fri Jul 28 09:53:46 2017 +0200
     2.3 @@ -32,6 +32,9 @@
     2.4  #define	COUNTOF(x)	((sizeof (x)/sizeof (0[x])) / ((size_t)(!(sizeof (x) % \
     2.5      sizeof (0[x])))))
     2.6  
     2.7 +#define	MAX(x, y)	(((x) > (y)) ? (x) : (y))
     2.8 +#define	MIN(x, y)	(((x) < (y)) ? (x) : (y))
     2.9 +
    2.10  void *	xmalloc(size_t);
    2.11  void *	xrealloc(void *, size_t);
    2.12  char *	xstrdup(const char *);