Tatsuki SUGIURA
sugi****@users*****
2006年 7月 12日 (水) 20:41:55 JST
Index: slashjp/plugins/ResKey/ResKey/Checks/ACL.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/ACL.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/ACL.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,44 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: ACL.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::ACL; + +use warnings; +use strict; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +use base 'Slash::ResKey::Key'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + +sub doCheck { + my($self) = @_; + + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + my $acl = $check_vars->{acl}; + my $acl_no = $check_vars->{acl_no}; + + # is_admin is an exception to lack of ACL if adminbypass set + my $acl_nobypass_admin = (!$user->{is_admin} || ( + $user->{is_admin} && !$check_vars->{adminbypass} + )); + + if ($acl && !$user->{acl}{$acl} && $acl_nobypass_admin) { + return(RESKEY_DEATH, [ 'has no acl', { acl => $acl } ]); + } + + # is_admin does not bypass acl_no + if ($acl_no && $user->{acl}{$acl_no}) { + return(RESKEY_DEATH, [ 'has acl_no', { acl => $acl_no } ]); + } + + return RESKEY_SUCCESS; +} + +1; Index: slashjp/plugins/ResKey/ResKey/Checks/AL2.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/AL2.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/AL2.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,35 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: AL2.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::AL2; + +use warnings; +use strict; + +use Exporter; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; +our @EXPORT = qw(AL2Check); + +# simple AL2 check that others can inherit; returns death if check returns true +sub AL2Check { + my($self, $check, $srcids) = @_; + + my $slashdb = getCurrentDB(); + my $user = getCurrentUser(); + + $srcids ||= $user->{srcids}; + + if ($slashdb->checkAL2($srcids, $check)) { + return(RESKEY_DEATH, ["$check al2 failure"]); + } + + return RESKEY_SUCCESS; +} + +1; Index: slashjp/plugins/ResKey/ResKey/Checks/Duration.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/Duration.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/Duration.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,189 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: Duration.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::Duration; + +use warnings; +use strict; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +use base 'Slash::ResKey::Key'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + + +sub doCheckCreate { + my($self) = @_; + + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + if ($check_vars->{adminbypass} && $user->{is_admin}) { + return RESKEY_SUCCESS; + } + + my @return = maxUsesPerTimeframe($self); + return @return || RESKEY_SUCCESS; +} + +sub doCheckTouch { + my($self) = @_; + + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + if ($check_vars->{adminbypass} && $user->{is_admin}) { + return RESKEY_SUCCESS; + } + + my $reskey_obj = $self->get; + + my @return = maxUsesPerTimeframe($self, $reskey_obj); + return @return if @return; + + @return = maxFailures($self, $reskey_obj); + return @return if @return; + + return RESKEY_SUCCESS; +} + +sub doCheckUse { + my($self) = @_; + + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + if ($check_vars->{adminbypass} && $user->{is_admin}) { + return RESKEY_SUCCESS; + } + + my $reskey_obj = $self->get; + + my @return = maxUsesPerTimeframe($self, $reskey_obj); + return @return if @return; + + @return = maxFailures($self, $reskey_obj); + return @return if @return; + + # we only check these on use, not create or touch, because the limits + # are so short that there's no point in checking them until use, so + # as not to increase the chance of giving users a rather spurious error + + @return = minDurationBetweenUses($self, $reskey_obj); + return @return if @return; + + if ($self->origtype ne 'createuse') { + @return = minDurationBetweenCreateAndUse($self, $reskey_obj); + return @return if @return; + } + + return RESKEY_SUCCESS; +} + +sub maxFailures { + my($self, $reskey_obj) = @_; + $reskey_obj ||= {}; + + my $slashdb = getCurrentDB(); + my $check_vars = $self->getCheckVars; + + my $max_failures = $check_vars->{'duration_max-failures'}; + if ($max_failures && $reskey_obj->{rkid}) { + my $where = "rkid=$reskey_obj->{rkid} AND failures > $max_failures"; + my $rows = $slashdb->sqlCount('reskeys', $where); + if ($rows) { + return(RESKEY_DEATH, ['too many failures', { + max_failures => $max_failures, + uses => $rows + }]); + } + } + + return; +} + +sub maxUsesPerTimeframe { + my($self, $reskey_obj) = @_; + $reskey_obj ||= {}; + + my $constants = getCurrentStatic(); + my $slashdb = getCurrentDB(); + my $check_vars = $self->getCheckVars; + + my $max_uses = $check_vars->{'duration_max-uses'}; + my $limit = $constants->{reskey_timeframe}; + if ($max_uses && $limit) { + my $where = $self->getWhereUserClause; + $where .= ' AND rkrid=' . $self->rkrid; + $where .= ' AND is_alive="no" AND '; + $where .= "rkid != '$reskey_obj->{rkid}' AND " if $reskey_obj->{rkid}; + $where .= "submit_ts > DATE_SUB(NOW(), INTERVAL $limit SECOND)"; + + my $rows = $slashdb->sqlCount('reskeys', $where); + if ($rows >= $max_uses) { + return(RESKEY_DEATH, ['too many uses', { + timeframe => $limit, + max_uses => $max_uses, + uses => $rows + }]); + } + } + + return; +} + +sub minDurationBetweenUses { + my($self, $reskey_obj) = @_; + + my $slashdb = getCurrentDB(); + my $check_vars = $self->getCheckVars; + + my $limit = $check_vars->{duration_uses}; + if ($limit) { + my $where = $self->getWhereUserClause; + $where .= ' AND rkrid=' . $self->rkrid; + $where .= ' AND is_alive="no" AND '; + $where .= "rkid != '$reskey_obj->{rkid}' AND " if $reskey_obj->{rkid}; + $where .= "submit_ts > DATE_SUB(NOW(), INTERVAL $limit SECOND)"; + + my $rows = $slashdb->sqlCount('reskeys', $where); + if ($rows) { + return(RESKEY_FAILURE, ['use duration too short', + { duration => $limit } + ]); + } + } + + return; +} + +sub minDurationBetweenCreateAndUse { + my($self, $reskey_obj) = @_; + + my $slashdb = getCurrentDB(); + my $check_vars = $self->getCheckVars; + + my $limit = $check_vars->{'duration_creation-use'}; + if ($limit && $reskey_obj->{rkid}) { + my $where = "rkid=$reskey_obj->{rkid}"; + $where .= ' AND rkrid=' . $self->rkrid; + $where .= ' AND is_alive="no" AND '; + $where .= "create_ts > DATE_SUB(NOW(), INTERVAL $limit SECOND)"; + + my $rows = $slashdb->sqlCount('reskeys', $where); + if ($rows) { + return(RESKEY_FAILURE, ['creation-use duration too short', + { duration => $limit } + ]); + } + } + + return; +} + + +1; Index: slashjp/plugins/ResKey/ResKey/Checks/Post.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/Post.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/Post.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,33 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: Post.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::Post; + +use warnings; +use strict; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +use base 'Slash::ResKey::Key'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + +sub doCheck { + my($self) = @_; + + return RESKEY_NOOP unless $ENV{GATEWAY_INTERFACE}; + + my $user = getCurrentUser(); + + if (!$user->{state}{post}) { + return(RESKEY_FAILURE, ['post method required']); + } + + return RESKEY_SUCCESS; +} + + +1; Index: slashjp/plugins/ResKey/ResKey/Checks/ProxyScan.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/ProxyScan.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/ProxyScan.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,47 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: ProxyScan.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::ProxyScan; + +use warnings; +use strict; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +use base 'Slash::ResKey::Key'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + +sub doCheck { + my($self) = @_; + + if (!$ENV{GATEWAY_INTERFACE}) { + return RESKEY_SUCCESS; + } + + my $reader = getObject('Slash::DB', { db_type => 'reader' }); + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + if ($check_vars->{adminbypass} && $user->{is_admin}) { + return RESKEY_SUCCESS; + } + + if (!$reader->getAL2($user->{srcids}, 'trusted')) { + my $is_proxy = $reader->checkForOpenProxy($user->{srcids}{ip}); + if ($is_proxy) { + return(RESKEY_DEATH, ['open proxy', { + unencoded_ip => $ENV{REMOTE_ADDR}, + port => $is_proxy, + }]); + } + } + + return RESKEY_SUCCESS; +} + + +1; Index: slashjp/plugins/ResKey/ResKey/Checks/User.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey/Checks/User.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey/Checks/User.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,38 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: User.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey::Checks::User; + +use warnings; +use strict; + +use Slash::Utility; +use Slash::Constants ':reskey'; + +use base 'Slash::ResKey::Key'; + +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + +sub doCheck { + my($self) = @_; + + my $user = getCurrentUser(); + my $check_vars = $self->getCheckVars; + + if ($check_vars->{adminbypass} && $user->{is_admin}) { + return RESKEY_SUCCESS; + } + + for my $check (qw(is_admin seclev is_subscriber karma tags_canread_stories tags_canwrite_stories)) { + my $value = $check_vars->{"user_${check}"}; + if (defined $value && length $value && (!$user->{$check} || $user->{$check} < $value)) { + return(RESKEY_DEATH, ["$check too low", { needed => $value }]); + } + } + + return RESKEY_SUCCESS; +} + +1;