diff options
| author | fukachan <fukachan> | 2002-12-24 10:08:54 +0000 |
|---|---|---|
| committer | fukachan <fukachan> | 2002-12-24 10:08:54 +0000 |
| commit | 922f072ea66f8c9d60e88f141d5d1dedcbba097d (patch) | |
| tree | 1e5987fb08322e39e8fd1ff7cd35397966100caa /fml/lib/FML/Process/Command.pm | |
| parent | 87b8296098c6089bd0f6c10be22a58d2f7c88de0 (diff) | |
| download | fml8-922f072ea66f8c9d60e88f141d5d1dedcbba097d.tar.gz fml8-922f072ea66f8c9d60e88f141d5d1dedcbba097d.tar.bz2 fml8-922f072ea66f8c9d60e88f141d5d1dedcbba097d.zip | |
rename:
o _is_valid_command() -> _config_permit_command()
o _is_valid_syntax() -> _is_safe_syntax()
o _auth_admin() -> _try_admin_auth()
fix changes.
more log of level exceptions.
Diffstat (limited to 'fml/lib/FML/Process/Command.pm')
| -rw-r--r-- | fml/lib/FML/Process/Command.pm | 105 |
1 files changed, 73 insertions, 32 deletions
diff --git a/fml/lib/FML/Process/Command.pm b/fml/lib/FML/Process/Command.pm index 318cd44b..dfa4f6da 100644 --- a/fml/lib/FML/Process/Command.pm +++ b/fml/lib/FML/Process/Command.pm @@ -3,7 +3,7 @@ # Copyright (C) 2000,2001,2002 Ken'ichi Fukamachi # All rights reserved. # -# $FML: Command.pm,v 1.74 2002/09/11 23:18:14 fukachan Exp $ +# $FML: Command.pm,v 1.75 2002/09/22 14:56:52 fukachan Exp $ # package FML::Process::Command; @@ -147,6 +147,7 @@ sub run my ($curproc, $args) = @_; my $pcb = $curproc->{ pcb }; + # permit_xxx() sets the error reason at "check_restriction" in pcb. if ($curproc->permit_command($args)) { $curproc->_evaluate_command_lines($args); } @@ -154,6 +155,7 @@ sub run # XXX rejection of admin use occurs in _evaluate_command_lines() not here. # XXX possible cases are from "system_accounts" or from a not member. else { + # check the error reason by permit_command(). my $reason = $pcb->get("check_restrictions", "deny_reason"); if (defined($reason) && ($reason eq 'reject_system_accounts')) { $curproc->reply_message_nl("error.system_accounts", @@ -164,8 +166,9 @@ sub run "deny request from a not member"); } - # append the incoming message as the reference - my $msg = $curproc->incoming_message(); + # append the incoming message into the error message sent back + # as the reference. + my $msg = $curproc->incoming_message(); $curproc->reply_message( $msg ); unless (defined $reason) { $reason = 'unknown';} @@ -191,8 +194,8 @@ print <<"_EOF_"; Usage: $0 \$ml_home_prefix/\$ml_name [options] - For example, process command of elena ML - $0 /var/spool/ml/elena + For example, process command of elena\@fml.org ML + $0 elena\@fml.org _EOF_ } @@ -200,7 +203,7 @@ _EOF_ =head2 C<finish($args)> - $curproc->inform_reply_messages(); +queue flush and send back the results or error messages. =cut @@ -227,7 +230,7 @@ sub finish # Descriptions: check message of the current process -# whether it contais keyword e.g. "confirm". +# whether it contains keyword e.g. "confirm". # Arguments: OBJ($curproc) ARRAY_REF($ra_data) # Side Effects: none # Return Value: HASH_REF @@ -235,6 +238,7 @@ sub _check_context { my ($curproc, $ra_data) = @_; + # XXX $ra_data = [ split(/\n/, $message ) ]; use FML::Command::DataCheck; my $check = new FML::Command::DataCheck; my $data = $check->find_special_keyword($curproc, $ra_data); @@ -242,16 +246,18 @@ sub _check_context # current process tries to confirm the previous result e.g. subscribe. $data->{ under_confirmation } = $data->{ confirm_keyword } ? 1 : 0; + # XXX-TODO: $data is validated already ? + # XXX-TODO: e.g. check if "confirm_id" is included in cache? return $data; } -# Descriptions: check command (specified in $opts) content: -# syntax check, permission of command use et. al. +# Descriptions: check command (specified in $opts) is valid and permitted +# in the configuration. # Arguments: OBJ($curproc) HASH_REF($args) STR($level) HASH_REF($opts) # Side Effects: none # Return Value: NUM(1 or 0) -sub _is_valid_command +sub _config_permit_command { my ($curproc, $args, $level, $opts) = @_; my $config = $curproc->{ config }; @@ -260,6 +266,7 @@ sub _is_valid_command my $comname = $opts->{ comname }; my $command = $opts->{ command }; + # XXX-TODO: case sensitive ? # use of this command is allowed in FML::Config or not ? if ($config->has_attribute("commands_for_$level", $comname)) { return 1; # o.k. accpet this command. @@ -271,17 +278,24 @@ sub _is_valid_command $curproc->reply_message_nl('command.not_command', "not command, ignored."); } + elsif ($level eq 'stranger') { + ; # ignored. + } + else { + LogWarn("unknown level=$level"); + } + return 0; } } -# Descriptions: validate command syntax +# Descriptions: validate command syntax by FML::Restriction. # Arguments: OBJ($curproc) # HASH_REF($args) HASH_REF($status) HASH_REF($cominfo) # Side Effects: none # Return Value: NUM(1 or 0) -sub _is_valid_syntax +sub _is_safe_syntax { my ($curproc, $args, $status, $cominfo) = @_; my $config = $curproc->{ config }; @@ -301,13 +315,20 @@ sub _is_valid_syntax $curproc->reply_message_nl('command.insecure', "insecure, so ignored."); } + elsif ($level eq 'stranger' || $level eq 'user') { + ; # ignored. + } + else { + LogWarn("unknown level=$level"); + } + return 0; } } -# Descriptions: parse command buffer to make -# argument vector after command name +# Descriptions: parse command buffer to prepare several info +# after use. return info as HASH_REF. # Arguments: OBJ($curproc) HASH_REF($args) STR($fixed_command) # Side Effects: none # Return Value: HASH_REF @@ -360,7 +381,7 @@ sub _get_command_name # Arguments: OBJ($curproc) HASH_REF($args) HASH_REF($optargs) # Side Effects: none # Return Value: NUM(1 or 0) -sub _auth_admin +sub _try_admin_auth { my ($curproc, $args, $optargs) = @_; my $is_auth = 0; @@ -391,6 +412,7 @@ sub _auth_admin } } else { + LogError("fail to load FML::Command::Auth"); return 0; } @@ -399,7 +421,9 @@ sub _auth_admin } -# Descriptions: determine $mode and $level for the current command +# Descriptions: determine $mode and $level for the current command (line). +# We apply this function for each line in command request. +# $mode and $level change line by line. # Arguments: OBJ($curproc) # HASH_REF($args) HASH_REF($status) HAS_REF($command_info) # Side Effects: update $status, $command_info @@ -425,17 +449,22 @@ sub _get_command_mode return '__NEXT__' unless defined $command; return '__NEXT__' unless $command; + # XXX-TODO: $command is clean-ed up already here? + # XXX-TODO: If so, we should check $command =~ /^$confirm_prefix\s+/ ? + # XXX-TODO: it is easy for us not to use regexp in this case? + # Case: "confirm" command. - # It is exceptional strangers can use. - # validate general command except for confirmation + # It is exceptional so that a stranger can use. + # We need to validate commands except for "confirmation" # if $confirm_id is 1, this message must be confirmation reply. if ($command =~ /$confirm_prefix\s+/ && $confirm_id) { # XXX $command may be "> confirm chaddr ...". $comname = $confirm_prefix; # comname = confirm $command =~ s/^.*$comname/$comname/; # normalize $command - my $opts = { comname => $comname, command => $command }; + my $opts = { comname => $comname, command => $command }; - if ($curproc->_is_valid_command($args, "stranger", $opts)) { + # $config permits this command for a stranger? + if ($curproc->_config_permit_command($args, "stranger", $opts)) { $status->{ mode } = 'user'; $status->{ level } = 'stranger'; } @@ -448,7 +477,7 @@ sub _get_command_mode # Case: "admin" command is exceptional. try priviledged mode. elsif ($command =~ /$admin_prefix\s+/) { if ($is_auth) { - Log("admin auth already: $command"); + Log("admin auth-ed already. run <$command>"); } else { # for the first time ? Log("admin try auth"); @@ -456,22 +485,24 @@ sub _get_command_mode my $sender = $curproc->{'credential'}->{'sender'}; my $data = $command; - $data =~ s/.*(password|pass)\s+//; + # XXX-TODO: (password|pass) hard-coded. + $data =~ s/^.*(password|pass)\s+//; my $optargs = { address => $sender, password => $data }; - # try auth by FML::Command::Auth; - $is_auth = $curproc->_auth_admin($args, $optargs); + # XXX simple state machine: update $status->{ is_auth } + $is_auth = $curproc->_try_admin_auth($args, $optargs); $status->{ is_auth } = $is_auth; Log("authenticated as an ML administrator") if $is_auth; } if ($is_admin && $is_auth) { + # XXX-TODO: we need the method normalize_command(). $comname = $comsubname; $command =~ s/^.*$comname/admin $comname/; my $opts = { comname => $comname, command => $command }; my $xmode = 'privileged_user'; - if ($curproc->_is_valid_command($args, $xmode, $opts)) { + if ($curproc->_config_permit_command($args, $xmode, $opts)) { $status->{ mode } = 'admin'; $status->{ level } = 'admin'; $command_info->{ command } = $command; @@ -514,7 +545,7 @@ sub _get_command_mode else { if ($is_member) { my $opts = { comname => $comname, command => $command }; - if ($curproc->_is_valid_command($args, "user", $opts)) { + if ($curproc->_config_permit_command($args, "user", $opts)) { $status->{ mode } = 'user'; $status->{ level } = 'user'; } @@ -526,16 +557,19 @@ sub _get_command_mode } else { my $opts = { comname => $comname, command => $command }; - if ($curproc->_is_valid_command($args, "stranger", $opts)) { + if ($curproc->_config_permit_command($args, "stranger", $opts)) { $status->{ mode } = 'user'; $status->{ level } = 'stranger'; } else { + # XXX invalid condition is satisfied. + # XXX emergency stop if admin mode. if ($status->{ level } eq 'admin') { LogError("command from not member."); LogError("command processing stop."); return '__LAST__'; } + # XXX but just ignore this commnad unless admin mode. else { Log("(debug) ignore $command"); return '__NEXT__'; @@ -708,7 +742,13 @@ sub _evaluate_command_lines last COMMAND; } - # 1.3 valid mode + + # [CAUTION] + # mode = { user, admin }; + # level = { strange, user, admin }; + + + # 1.3 valid mode unless ($mode eq 'user' || $mode eq 'admin') { LogError("command processing stop."); $curproc->__stop_here($args, $status, $cominfo, $orig_command); @@ -725,14 +765,14 @@ sub _evaluate_command_lines } # 3. simple syntax check - unless ($curproc->_is_valid_syntax($args, $status, $cominfo)) { - LogError("invalid syntax"); + unless ($curproc->_is_safe_syntax($args, $status, $cominfo)) { + LogError("invalid/unsafe syntax"); Log("(debug) ignore $fixed_command"); $num_ignored++; next COMMAND; } - # o.k. here we go to execute command + # o.k. here we go to execute this command Log("execute \"$fixed_command\""); $num_processed++; @@ -766,6 +806,7 @@ sub _evaluate_command_lines # execute command ($comname method) under eval(). # XXX $obj = FML::Command object NOT FML::Command::$mode::$command + # XXX-TODO: validate $comname is safe syntax or not. my $comname = $cominfo->{ comname }; eval q{ $obj->$comname($curproc, $command_args); @@ -797,7 +838,7 @@ sub _evaluate_command_lines $curproc->reply_message(" ignored = $num_ignored"); $curproc->reply_message(" total = $num_total"); - # send bak the original input message if needed + # send back the original input message if needed. { my $msg = $curproc->incoming_message(); |
