1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
--- a/perl/lib/Wallet/Config.pm
+++ b/perl/lib/Wallet/Config.pm
@@ -266,6 +266,27 @@ that is inherited.
=over 4
+=item PWD_TYPE
+
+Specifies the algorithm to use when generating a password. The
+default is RANDOM which specified that random set of printable ASCII
+characters will be used to create a password. The pool of characters
+can be restricted by specifying PWD_CHARACTERS.
+
+The PWD_TYPE can be used to specify the generation of passwords using
+the XKCD inspired perl module Crypt::HSXKPasswd. Three values are
+supported that use preset configuration values: XKCD-DEFAULT,
+XKCD-APPLIED, and XKCD. See the module documentation for the details
+of these presents.
+
+A PWD_TYPE of CUSTOM is supported. If defined then the configuration
+file must contain a Perl function generate_password that returns a
+generated password.
+
+=cut
+
+our $PWD_TYPE = 'RANDOM';
+
=item PWD_FILE_BUCKET
The directory into which to store password objects. Password objects will
@@ -274,7 +295,7 @@ L<Wallet::Object::Password> for the full
directory must be writable by the wallet server and the wallet server must
be able to create subdirectories of it.
-PWD_FILE_BUCKET must be set to use file objects.
+PWD_FILE_BUCKET must be set to use password objects.
=cut
--- a/perl/lib/Wallet/Object/Password.pm
+++ b/perl/lib/Wallet/Object/Password.pm
@@ -52,6 +52,38 @@ sub file_path {
return "$Wallet::Config::PWD_FILE_BUCKET/$hash/$name";
}
+# Returns a password of random characters.
+sub _pwd_random {
+ my ($self) = @_;
+ my $pass = chars ($Wallet::Config::PWD_LENGTH_MIN,
+ $Wallet::Config::PWD_LENGTH_MAX);
+ if ($Wallet::Config::PWD_CHARACTERS) {
+ my @pw_chars = ();
+ for (my $i=0; $i<length($Wallet::Config::PWD_CHARACTERS); $i++) {
+ push @pw_chars, substr($Wallet::Config::PWD_CHARACTERS, $i, 1);
+ }
+ $pass = chars ($Wallet::Config::PWD_LENGTH_MIN,
+ $Wallet::Config::PWD_LENGTH_MAX,
+ \@pw_chars);
+ }
+ return $pass;
+}
+
+# Returns a password using Crypt::HSXKPasswd
+sub _pwd_xkcd {
+ my ($self, $preset) = @_;
+
+ if (! $preset) {
+ $preset = 'XKCD';
+ } else {
+ $preset =~ s/^\-//xms;
+ }
+ require Crypt::HSXKPasswd;
+ my $hsxkpasswd_instance = Crypt::HSXKPasswd->new(preset => $preset);
+ my $pass = $hsxkpasswd_instance->password();
+ return $pass;
+}
+
##############################################################################
# Shared methods
##############################################################################
@@ -75,20 +107,37 @@ sub retrieve {
ob_name => $self->{name});
my $object = $schema->resultset('Object')->find (\%search);
if (!$object->ob_stored_on || $operation eq 'update') {
- unless (open (FILE, '>', $path)) {
- $self->error ("cannot store initial settings for $id: $!\n");
- return;
+ my $pass;
+ if ($Wallet::Config::PWD_TYPE eq 'RANDOM')
+ {
+ $pass = $self->_pwd_random();
+ }
+ elsif ($Wallet::Config::PWD_TYPE
+ =~ /^XKCD(\-APPLIED|\-DEFAULT){0,1}/xms)
+ {
+ $pass = $self->_pwd_xkcd($1);
+ }
+ elsif ($Wallet::Config::PWD_TYPE eq 'CUSTOM')
+ {
+ if (defined(&Wallet::Config::generate_password)) {
+ $pass = Wallet::Config::generate_password();
+ } else {
+ $self->error ("function generate_password() not found\n");
+ return;
+ }
}
- my $pass = chars ($Wallet::Config::PWD_LENGTH_MIN,
- $Wallet::Config::PWD_LENGTH_MAX);
- if ($Wallet::Config::PWD_CHARACTERS) {
- my @pw_chars = ();
- for (my $i=0; $i<length($Wallet::Config::PWD_CHARACTERS); $i++) {
- push @pw_chars, substr($Wallet::Config::PWD_CHARACTERS, $i, 1);
+ else
+ {
+ if (defined($Wallet::Config::PWD_TYPE)) {
+ $self->error ("Unknown PWD_TYPE ($Wallet::Config::PWD_TYPE)\n");
+ } else {
+ $self->error ("PWD_TYPE not set\n");
}
- $pass = chars ($Wallet::Config::PWD_LENGTH_MIN,
- $Wallet::Config::PWD_LENGTH_MAX,
- \@pw_chars);
+ return;
+ }
+ unless (open (FILE, '>', $path)) {
+ $self->error ("cannot open $path $!\n");
+ return;
}
print FILE $pass;
$self->log_action ('store', $user, $host, $time);
|