passwordauth/discussion: Document an attempt of using Apache::AuthenHook for a restri...
[ikiwiki] / doc / plugins / passwordauth / discussion.mdwn
1 It's a bit inconvenient that one also has to type in the
2 *Login - Confirm Password* if one only wants to change
3 the *Preferences -- Subscriptions*.  --[[tschwinge]]
4
5 > You don't. The password fields on the preferences fields are only needed
6 > if you want to change your password and should otherwise be left blank.
7 > --[[Joey]]
8
9 >> Aha, then the problem is Firefox, which is automatically filling the
10 >> *Password* field with its previous value, but not filling the
11 >> *Confirm Password* one.  --[[tschwinge]]
12
13 ## easy access to the userdb for apache auth?
14
15 My use case is:
16
17 * restricted ikiwiki
18 * read/edit only allowed from the local network (done with apache restrictions)
19 * edit only for people authenticated (done with vanilla ikiwiki passwordauth)
20
21 I would like to allow people to read/edit the wiki from outside of the
22 local network, if and only if they already have an ikiwiki account.
23
24 [[httpauth]] doesn't fit since it doesn't allow anonymous local users
25 to create their own account. I want a single, local, simple auth
26 database.
27
28 My (naïve?) idea would be:
29
30 * keep the [[passwordauth]] system
31 * provide a way for Apache to use the userdb for authentication if
32 people want to connect from outside
33
34 I looked at the various auth modules for apache2. It seems that none
35 can use a "perl Storable data" file. So, I think some solutions could
36 be:
37
38 * use a sqlite database instead of a perl Storable file
39   * can be used with
40     [mod_auth_dbd](http://httpd.apache.org/docs/2.2/mod/mod_authn_dbd.html) 
41   * requires a change in ikiwiki module [[passwordauth]]
42 * use an external program to read the userdb and talk with
43   [mod_auth_external](http://unixpapa.com/mod_auth_external.html)
44   * requires the maintainance of this external auth proxy over ikiwiki
45     userdb format changes
46   * (I don't know perl)
47 * include this wrapper in ikiwiki
48   * something like `ikiwiki --auth user:pass:userdb` check the
49     `user:pass` pair in `userdb` and returns an Accept/Reject flag to
50     Apache 
51   * requires a change in ikiwiki core
52   * still requires
53     [mod_auth_external](http://unixpapa.com/mod_auth_external.html)
54 * do it with Apache perl sections
55   * (I don't know perl)
56
57 Any opinion/suggestion/solution to this is welcome and appreciated.
58
59 --
60 [[NicolasLimare]]
61
62 For a similar use case, I've been intending to implement
63 [[todo/httpauth_feature_parity_with_passwordauth]], but your idea may
64 actually be the way to go. IMHO, the Perl sections idea is the
65 easiest to setup, but on the long run, I'd prefer ikiwiki to optionnally
66 use a userdb storage backend supported at least by Apache and lighttpd.
67 --[[intrigeri]]
68
69 Tons of CPAN modules may help, but most of them are specific to `mod_perl`,
70 and AFAIK, ikiwiki is generally not run with `mod_perl`. It's not clear to me
71 wether these modules depend on the webapp to be run with `mod_perl` set 
72 as the script handler, or only on `mod_perl` to be installed and loaded.
73
74 * CPAN's `Apache::AuthenHook` allows to plug arbitrary Perl handlers as
75   Apache authentication providers.
76 * CPAN's `Apache::Authen::Program` (`mod_perl`)
77 * [http://www.openfusion.com.au/labs/mod_auth_tkt/](mod_auth_tkt) along with CPAN's
78   `Apache::AuthTkt`
79 --[[intrigeri]]
80
81   I've more or less managed to implement something based on `mod_perl` and
82   `Apache::AuthenHook`, respectively in Debian packages `libapache2-mod-perl2`
83   and `libapache-authenhook-perl`.
84
85   In the Apache VirtualHost configuration, I have added the following:
86
87         PerlLoadModule Apache::AuthenHook
88         PerlModule My::IkiWikiBasicProvider
89
90         <Location /test/>
91                 AuthType Basic
92                 AuthName "wiki"
93                 AuthBasicProvider My::IkiWikiBasicProvider
94                 Require valid-user
95                 ErrorDocument 401 /test/ikiwiki.cgi?do=signin
96         </Location>
97         <LocationMatch "^/test/(ikiwiki\.cgi$|.*\.css$|wikiicons/)">
98                 Satisfy any
99         </LocationMatch>
100
101   The perl module lies in `/etc/apache2/My/IkiWikiBasicProvider.pm`:
102
103         package My::IkiWikiBasicProvider;
104
105         use warnings;
106         use strict;
107         use Apache2::Const -compile => qw(OK DECLINED HTTP_UNAUTHORIZED);
108         use Storable;
109         use Authen::Passphrase;
110
111         sub userinfo_retrieve () {
112                 my $userinfo=eval{ Storable::lock_retrieve("/var/lib/ikiwiki/test/.ikiwiki/userdb") };
113                 return $userinfo;
114         }
115
116         sub handler {
117                 my ($r, $user, $password) = @_;
118                 my $field = "password";
119
120                 if (! defined $password || ! length $password) {
121                         return Apache2::Const::DECLINED;
122                 }
123                 my $userinfo = userinfo_retrieve();
124                 if (! length $user || ! defined $userinfo ||
125                     ! exists $userinfo->{$user} || ! ref $userinfo->{$user}) {
126                         return Apache2::Const::DECLINED;
127                 }
128                 my $ret=0;
129                 if (exists $userinfo->{$user}->{"crypt".$field}) {
130                         error $@ if $@;
131                         my $p = Authen::Passphrase->from_crypt($userinfo->{$user}->{"crypt".$field});
132                         $ret=$p->match($password);
133                 }
134                 elsif (exists $userinfo->{$user}->{$field}) {
135                         $ret=$password eq $userinfo->{$user}->{$field};
136                 }
137                 if ($ret) {
138                         return Apache2::Const::OK;
139                 }
140                 return Apache2::Const::DECLINED;
141         }
142
143         1;
144
145   This setup also allows people with the master password to create their own
146   account.
147
148   I'm not really fluent in Perl, and all this can probably be improved (*or
149   might destroy your computer as it is* and YMMV).
150
151   -- [[Lunar]]