2 # Ikiwiki unixauth authentication.
3 package IkiWiki::Plugin::unixauth;
10 hook(type => "getsetup", id => "unixauth", call => \&getsetup);
11 hook(type => "formbuilder_setup", id => "unixauth",
12 call => \&formbuilder_setup);
13 hook(type => "formbuilder", id => "unixauth",
14 call => \&formbuilder);
15 hook(type => "sessioncgi", id => "unixauth", call => \&sessioncgi);
22 example => "checkpassword",
23 description => "type of authenticator; can be 'checkpassword' or 'pwauth'",
29 example => "/path/to/checkpassword",
30 description => "full path and any arguments",
34 unixauth_requiressl => {
37 description => "require SSL? strongly recommended",
42 description => "Unix user authentication",
48 # Checks if a string matches a user's password, and returns true or false.
49 sub checkpassword ($$;$) {
52 my $field=shift || "password";
54 # It's very important that the user not be allowed to log in with
56 if (! length $password) {
61 if (! exists $config{unixauth_type}) {
62 # admin needs to carefully think over his configuration
65 elsif ($config{unixauth_type} eq "checkpassword") {
66 open UNIXAUTH, "|$config{unixauth_command} true 3<&0" or die("Could not run $config{unixauth_type}");
67 print UNIXAUTH "$user\0$password\0Y123456\0";
71 elsif ($config{unixauth_type} eq "pwauth") {
72 open UNIXAUTH, "|$config{unixauth_command}" or die("Could not run $config{unixauth_type}");
73 print UNIXAUTH "$user\n$password\n";
78 # no such authentication type
83 my $userinfo=IkiWiki::userinfo_retrieve();
84 if (! length $user || ! defined $userinfo ||
85 ! exists $userinfo->{$user} || ! ref $userinfo->{$user}) {
86 IkiWiki::userinfo_setall($user, {
96 sub formbuilder_setup (@) {
99 my $form=$params{form};
100 my $session=$params{session};
101 my $cgi=$params{cgi};
103 # if not under SSL, die before even showing a login form,
104 # unless the admin explicitly says it's fine
105 if (! exists $config{unixauth_requiressl}) {
106 $config{unixauth_requiressl} = 1;
108 if ($config{unixauth_requiressl}) {
109 if ((! $config{sslcookie}) || (! exists $ENV{'HTTPS'})) {
110 die("SSL required to login. Contact your administrator.<br>");
114 if ($form->title eq "signin") {
115 $form->field(name => "name", required => 0);
116 $form->field(name => "password", type => "password", required => 0);
118 if ($form->submitted) {
119 my $submittype=$form->submitted;
120 # Set required fields based on how form was submitted.
122 "Login" => [qw(name password)],
124 foreach my $opt (@{$required{$submittype}}) {
125 $form->field(name => $opt, required => 1);
128 # Validate password against name for Login.
129 if ($submittype eq "Login") {
133 checkpassword($form->field("name"), shift);
138 # XXX is this reachable? looks like no
139 elsif ($submittype eq "Login") {
145 IkiWiki::userinfo_get($name, "regdate");
151 # First time settings.
152 $form->field(name => "name");
153 if ($session->param("name")) {
154 $form->field(name => "name", value => $session->param("name"));
158 elsif ($form->title eq "preferences") {
159 $form->field(name => "name", disabled => 1,
160 value => $session->param("name"), force => 1,
161 fieldset => "login");
162 $form->field(name => "password", disabled => 1, type => "password",
163 fieldset => "login"),
167 sub formbuilder (@) {
170 my $form=$params{form};
171 my $session=$params{session};
172 my $cgi=$params{cgi};
173 my $buttons=$params{buttons};
175 if ($form->title eq "signin") {
176 if ($form->submitted && $form->validate) {
177 if ($form->submitted eq 'Login') {
178 $session->param("name", $form->field("name"));
179 IkiWiki::cgi_postsignin($cgi, $session);
183 elsif ($form->title eq "preferences") {
184 if ($form->submitted eq "Save Preferences" && $form->validate) {
185 my $user_name=$form->field('name');
190 sub sessioncgi ($$) {