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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
|
# This code is a part of Slash, and is released under the GPL.
# Copyright 1997-2001 by Open Source Development Network. See README
# and COPYING for more information, or see http://slashcode.com/.
# $Id: User.pm,v 1.2.2.38 2002/07/03 17:06:09 pudge Exp $
package Slash::Apache::User;
use strict;
use Apache;
use Apache::Constants qw(:common M_GET REDIRECT);
use Apache::Cookie;
use Apache::Request ();
use Apache::File;
use Apache::ModuleConfig;
use AutoLoader ();
use DynaLoader ();
use Slash::Apache ();
use Slash::Utility;
use URI ();
use vars qw($REVISION $VERSION @ISA @QUOTES $USER_MATCH);
@ISA = qw(DynaLoader);
$VERSION = '2.002006'; # v2.2.6
($REVISION) = ' $Revision: 1.2.2.38 $ ' =~ /\$Revision:\s+([^\s]+)/;
bootstrap Slash::Apache::User $VERSION;
# BENDER: Oh, so, just 'cause a robot wants to kill humans
# that makes him a radical?
$USER_MATCH = $Slash::Apache::USER_MATCH;
sub SlashEnableENV ($$$) {
my($cfg, $params, $flag) = @_;
$cfg->{env} = $flag;
}
sub SlashAuthAll ($$$) {
my($cfg, $params, $flag) = @_;
$cfg->{auth} = $flag;
}
# see below for more info on this var
my $srand_called;
# handler method
sub handler {
my($r) = @_;
return DECLINED unless $r->is_main;
# Ok, this will make it so that we can reliably use Apache->request
Apache->request($r);
my $cfg = Apache::ModuleConfig->get($r);
my $dbcfg = Apache::ModuleConfig->get($r, 'Slash::Apache');
my $constants = $dbcfg->{constants};
my $slashdb = $dbcfg->{slashdb};
my $apr = Apache::Request->new($r);
$r->err_header_out('X-Powered-By' => "Slash $Slash::VERSION");
random($r);
# let pass unless / or .pl
my $uri = $r->uri;
if ($constants->{rootdir}) {
my $path = URI->new($constants->{rootdir})->path;
$uri =~ s/^\Q$path//;
}
unless ($cfg->{auth}) {
#unless ($uri =~ m[(?:^/$)|(?:\.pl$)])
unless ($uri =~ m[(?:\.pl$)]) {
$r->subprocess_env(SLASH_USER => $constants->{anonymous_coward_uid});
createCurrentUser();
createCurrentForm();
createCurrentCookie();
return OK;
}
}
$slashdb->sqlConnect;
my $method = $r->method;
# Don't remove this. This solves a known bug in Apache -- brian
$r->method('GET');
# do we need to do this too? i am leaning toward No. -- pudge
# $r->method_number(M_GET);
my @params_array = $apr->param;
my %params;
for (@params_array) {
$params{$_} = $apr->param($_);
}
$params{query_apache} = $apr;
my $form = filter_params(%params);
$form->{query_apache} = $apr;
@{$form}{keys %{$constants->{form_override}}} =
values %{$constants->{form_override}};
my $cookies = Apache::Cookie->fetch;
# So we are either going to pick the user up from
# the form, a cookie, or they will be anonymous
my $uid;
my $op = $form->{op} || '';
if (($op eq 'userlogin' || $form->{'rlogin'}) && length($form->{upasswd}) > 1) {
my $tmpuid = $slashdb->getUserUID($form->{unickname});
($uid, my($newpass)) = userLogin($tmpuid, $form->{upasswd});
# here we want to redirect only if the user has posted via
# GET, and the user has logged in successfully
if ($method eq 'GET' && $uid && ! isAnon($uid)) {
$form->{returnto} =~ s/%3D/=/;
$form->{returnto} =~ s/%3F/?/;
$form->{returnto} = url2abs($newpass
? "$constants->{rootdir}/users.pl?op=changepasswd" .
"¬e=Please+change+your+password+now!"
: $form->{returnto}
? $form->{returnto}
: $uri
);
# not working ... move out into users.pl and index.pl
# I may know why this is the case, we may need
# to send a custom errormessage. -Brian
# $r->err_header_out(Location => $newurl);
# return REDIRECT;
}
} elsif ($op eq 'userclose') {
# It may be faster to just let the delete fail then test -Brian
# well, uid is undef here ... can't use it to test
# until it is defined :-) -- pudge
# Went boom without if. --Brian
# When did we comment out this? This means that even
# if an author logs out, the other authors will
# not know about it. Bad....
#$slashdb->deleteSession(); # if $slashdb->getUser($uid, 'seclev') >= 99;
delete $cookies->{user};
setCookie('user', '');
} elsif ($cookies->{user} and $cookies->{user}->value) {
my($tmpuid, $password) = eatUserCookie($cookies->{user}->value);
($uid, my($cookpasswd)) =
$slashdb->getUserAuthenticate($tmpuid, $password);
if ($uid) {
# set cookie every time, in case session_login
# value changes, or time is almost expired on
# saved cookie, or password changes, or ...
# can't set it every time, it upsets people.
# we need to set it only if password or
# session_login changes. -- pudge
# setCookie('user', bakeUserCookie($uid, $cookpasswd),
# $slashdb->getUser($uid, 'session_login')
# );
} else {
$uid = $constants->{anonymous_coward_uid};
delete $cookies->{user};
setCookie('user', '');
}
}
# This has happened to me a couple of times.
delete $cookies->{user} if ($cookies->{user} and !($cookies->{user}->value));
$uid = $constants->{anonymous_coward_uid} unless defined $uid;
# Ok, yes we could use %ENV here, but if we did and
# if someone ever wrote a module in another language
# or just a cheesy CGI, they would never see it.
$r->subprocess_env(SLASH_USER => $uid);
# This is only used if you have used the directive
# to disallow logins to your site.
# I need to complete this as a feature. -Brian
return DECLINED if $cfg->{auth} && isAnon($uid);
# this needs to get called once per child ... might as well
# have it called here. -- pudge
srand(time ^ ($$ + ($$ << 15))) unless $srand_called;
$srand_called ||= 1;
createCurrentUser(prepareUser($uid, $form, $uri, $cookies, $method));
createCurrentForm($form);
createCurrentCookie($cookies);
createEnv($r) if $cfg->{env};
authors($r) if $form->{'slashcode_authors'};
# Weird hack for getCurrentCache() till I can code up proper logic for it
{
my $cache = getCurrentCache();
if (!exists($cache->{_cache_time}) or ((time() - $cache->{_cache_time}) > $constants->{apache_cache})) {
$cache = {};
$cache->{_cache_time} = time();
}
}
return OK;
}
########################################################
sub createEnv {
my($r) = @_;
my $user = getCurrentUser();
my $form = getCurrentForm();
while (my($key, $val) = each %$user) {
$r->subprocess_env("USER_$key" => $val);
}
while (my($key, $val) = each %$form) {
$r->subprocess_env("FORM_$key" => $val);
}
}
########################################################
# These are very import, do not delete these
sub random {
my($r) = @_;
my $quote = $QUOTES[int(rand(@QUOTES))];
(my($who), $quote) = split(/: */, $quote, 2);
$r->header_out("X-$who" => $quote);
}
sub authors {
my($r) = @_;
$r->header_out('X-Author-Krow' => "You can't grep a dead tree.");
$r->header_out('X-Author-Pudge' => "Bite me.");
$r->header_out('X-Author-CaptTofu' => "I like Tofu.");
}
########################################################
sub userLogin {
my($name, $passwd) = @_;
my $r = Apache->request;
my $cfg = Apache::ModuleConfig->get($r, 'Slash::Apache');
my $slashdb = getCurrentDB();
# Do we want to allow logins with encrypted passwords? -- pudge
# $passwd = substr $passwd, 0, 20;
my($uid, $cookpasswd, $newpass) =
$slashdb->getUserAuthenticate($name, $passwd); #, 1
if (!isAnon($uid)) {
setCookie('user', bakeUserCookie($uid, $cookpasswd),
$slashdb->getUser($uid, 'session_login'));
return($uid, $newpass);
} else {
return getCurrentStatic('anonymous_coward_uid');
}
}
########################################################
sub userdir_handler {
my($r) = @_;
my $constants = getCurrentStatic();
# note that, contrary to the RFC, a + in this handler
# will be treated as a space; the only way to get a +
# is to encode it, such as %2B
my $uri = $r->the_request;
$uri =~ s/^\S+\s+//;
$uri =~ s/\s+\S+$//;
$uri =~ s/\+/ /g;
$uri =~ s/%([a-fA-F0-9]{2})/pack('C', hex($1))/ge;
if ($constants->{rootdir}) {
my $path = URI->new($constants->{rootdir})->path;
$uri =~ s/^\Q$path//;
}
# /my/ or /my can match, but not /mything
if (($uri =~ m[^/~/(.+)]) or ($uri =~ m[^/my (?: /(.*) | /? ) $]x)) {
my $match = $1;
if ($r->header_in('Cookie') =~ $USER_MATCH) {
my($toss, $op) = split /\//, $match, 3;
# Its past five, and the below makes it go -Brian
$op ||= $toss;
if ($op eq 'journal') {
$r->args("op=list");
$r->uri('/journal.pl');
$r->filename($constants->{basedir} . '/journal.pl');
} elsif ($op eq 'discussions') {
$r->args("op=personal_index");
$r->uri('/comments.pl');
$r->filename($constants->{basedir} . '/comments.pl');
} elsif ($op eq 'messages' or $op eq 'inbox') {
$r->args("op=list");
$r->uri('/messages.pl');
$r->filename($constants->{basedir} . '/messages.pl');
} else {
$r->uri('/users.pl');
$r->filename($constants->{basedir} . '/users.pl');
}
return OK;
} else {
$r->uri('/users.pl');
$r->filename($constants->{basedir} . '/users.pl');
return OK;
}
}
# assuming Apache/mod_perl is decoding the URL in ->uri before
# returning it, we have to re-encode it with fixparam(). that
# will change if somehow Apache/mod_perl no longer decodes before
# returning the data. -- pudge
if ($uri =~ m[^/~(.+)]) {
# this won't work if the nick has a "/" in it ...
my($nick, $op) = split /\//, $1, 3;
$nick = fixparam($nick); # make safe to pass back to script
if ($op eq 'journal') {
$r->args("nick=$nick&op=display");
$r->uri('/journal.pl');
$r->filename($constants->{basedir} . '/journal.pl');
} elsif ($op eq 'discussions') {
$r->args("nick=$nick&op=creator_index");
$r->uri('/comments.pl');
$r->filename($constants->{basedir} . '/comments.pl');
} elsif ($op eq 'pubkey') {
$r->args("nick=$nick");
$r->uri('/pubkey.pl');
$r->filename($constants->{basedir} . '/pubkey.pl');
} else {
$r->uri('/users.pl');
$r->filename($constants->{basedir} . '/users.pl');
$r->args("nick=$nick");
}
return OK;
}
return DECLINED;
}
########################################################
#
sub DESTROY { }
@QUOTES = split(/\n/, <<'EOT');
Bender:Fry, of all the friends I've had ... you're the first.
Bender:I hate people who love me. And they hate me.
Bender:Oh no! Not the magnet!
Bender:Bender's a genius!
Bender:Well I don't have anything else planned for today, let's get drunk!
Bender:Forget your stupid theme park! I'm gonna make my own! With hookers! And blackjack! In fact, forget the theme park!
Bender:Oh, no room for Bender, huh? Fine. I'll go build my own lunar lander. With blackjack. And hookers. In fact, forget the lunar lander and the blackjack! Ah, screw the whole thing.
Bender:Oh, so, just 'cause a robot wants to kill humans that makes him a radical?
Bender:There's nothing wrong with murder, just as long as you let Bender whet his beak.
Bender:Bite my shiny, metal ass!
Bender:The laws of science be a harsh mistress.
Bender:In the event of an emergency, my ass can be used as a flotation device.
Bender:Like most of life's problems, this one can be solved with bending.
Bender:Honey, I wouldn't talk about taste if I was wearing a lime green tank top.
Bender:A woman like that you gotta romance first!
Bender:OK, but I don't want anyone thinking we're robosexuals.
Bender:Hey Fry, I'm steering with my ass!
Bender:Care to contribute to the Anti-Mugging-You Fund?
Bender:Want me to smack the corpse around a little?
Bender:My full name is Bender Bending Rodriguez.
Bender:My life, and by extension everyone else's, is meaningless.
Fry:Why couldn't she be the other kind of mermaid, with the fish part on the top and the human part on the bottom?
Fry:There's a lot about my face you don't know.
Fry:Drugs are for losers. And hypnosis is for losers with big weird eyebrows.
Fry:These new hands are great. I'm gonna break them in tonight.
Fry:I refuse to testify on the grounds that my organs will be chopped up into a patty.
Fry:Leela, there's nothing wrong with anything.
Fry:Augh, I am so unlucky. I've run over black cats that were luckier than me.
Fry:That's it! You can only take my money for so long before you take it all and I say enough!
Fry:Leela, Bender, we're going grave-robbing.
Fry:Where's Captain Bender? Off catastrophizing some other planet?
Fry:Would you cram a sock in it, Bender? Those aren't even medals! They're bottle caps and pepperoni slices.
Fry:To Captain Bender! He's the best! ...at being a big jerk who's stupid and his big ugly face is as dumb as a butt!
Fry:People said I was dumb but I proved them!
Fry:It's like a party in my mouth and everyone's throwing up.
Fry:Nowadays people aren't interested in art that's not tattooed on fat guys.
Fry:I don't regret this, but I both rue and lament it.
Fry:I'm gonna be a famous hero just like Neil Armstrong and those other brave guys no one ever heard of.
Fry:Well, thanks to the Internet I'm now bored with sex. Is there a place on the web that panders to my lust for violence?
Fry:Maybe you can't understand this, but I finally found what I need to be happy, and it's not friends, it's things.
Fry:I heard one time you single-handedly defeated a hoard of rampaging somethings in the something something system.
Fry:I'm never gonna get used to the thirty-first century. Caffeinated bacon?
Fry:Professor, please, the fate of the world depends on you getting to second base with Mom.
Fry:They're great! They're like sex except I'm having them.
Fry:No, no, I was just picking my nose.
Fry:How can I live my life if I can't tell good from evil?
Fry:That's a chick show. I prefer programs of the genre: World's Blankiest Blank.
Fry:But this is HDTV. It's got better resolution than the real world.
Fry:I'm gonna be a science fiction hero, just like Uhura, or Captain Janeway, or Xena!
Fry:He's an animal. He belongs in the wild. Or in the circus on one of those tiny tricycles. Now that's entertainment.
Fry:I learned how to handle delicate social situations from a little show called "Three's Company."
Fry:Make up some feelings and tell her you have them.
Fry:I'm flattered, really. If I was gonna do it with a big freaky mud bug, you'd be way up the list.
Fry:I'm not a robot like you. I don't like having disks crammed into me... unless they're Oreos, and then only in the mouth.
Fry:I must be a robot. Why else would human women refuse to date me?
Fry:If this is some kind of scam, I don't get it. You already have my power of attorney.
Fry:Hey look, it's that guy you are!
Fry:That doesn't look like an "L", unless you count lower case.
Fry:Hardy Boys: too easy. Nancy Drew: too hard!
Fry:And then when I feel so stuffed I can't eat any more, I just use the restroom, and then I *can* eat more!
Fry:I'm going to continue never washing this cheek again.
EOT
1;
__END__
=head1 NAME
Slash::Apache::User - Apache Authenticate for Slash user
=head1 SYNOPSIS
use Slash::Apache::User;
=head1 DESCRIPTION
This is the user authenication system for Slash. This is
where you want to be if you want to modify slashcode's
method of authenication. The rest of Slash depends
on finding the UID of the user in the SLASH_USER
environmental variable.
=head1 SEE ALSO
Slash(3), Slash::Apache(3).
=cut
|