Roxen.git / server / base_server / roxen.pike

version» Context lines:

Roxen.git/server/base_server/roxen.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2001, Roxen IS.   //   // The Roxen WebServer main program.   //   // Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.   // ABS and suicide systems contributed freely by Francesco Chemolli    - constant cvs_version="$Id: roxen.pike,v 1.840 2003/11/03 13:04:39 mast Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.841 2003/11/03 14:11:47 grubba Exp $";      //! @appears roxen   //!   //! The Roxen WebServer main program.      // The argument cache. Used by the image cache.   ArgCache argcache;      // Some headerfiles   #define IN_ROXEN
Roxen.git/server/base_server/roxen.pike:5036:   // #endif    }             string code = "";    array variables = ({ " object userdb_module",    " object authmethod = id->conf",    " string realm = \"User\"",    " mapping(string:int|mapping) state = ([])", +  " int shorted = 0;",    }); -  int shorted, patterns, cmd; +     -  +  // Some state variables for optimizing. +  int all_shorted = 1; // All allow patterns have return. +  int need_auth = 0; // We need auth for some checks. +  int patterns; // Number of patterns. +  multiset(string) checks = (<>); // Checks in state. +     foreach( pattern / "\n", string line )    {    line = String.trim_all_whites( line );    if( !strlen(line) || line[0] == '#' )    continue;    sscanf( line, "%[^#]#", line );    -  +  int cmd; +     if( sscanf( line, "allow %s", line ) )    cmd = ALLOW;    else if( sscanf( line, "deny %s", line ) )    cmd = DENY;    else if( sscanf( line, "userdb %s", line ) )    {    line = String.trim_all_whites( line );    if( line == "config_userdb" )    code += " userdb_module = roxen.config_userdb_module;\n";    else if( line == "all" )
Roxen.git/server/base_server/roxen.pike:5090:    continue;    }    else if( sscanf( line, "realm %s", line ) )    {    line = String.trim_all_whites( line );    code += sprintf( " realm = %O;\n", line );    }    else    m->report_notice( LOC_M( 60,"Syntax error in security patterns: "    "Expected 'allow' or 'deny'\n" )); -  shorted = sscanf( line, "%s return", line ); +  int shorted = sscanf( line, "%s return", line );          // Notes on the state variable:    //    // It has several potential entries (currently "ip", "user", "group",    // "time", "date", "referer", "language" and "luck").    // An entry exists in the mapping if a corresponding accept directive    // has been executed. -  // The value in the mapping is 0 (zero) if a successful match against -  // the directive has been executed. -  // The value in the mapping is a mapping if authentication is required. -  // Otherwise the value in the mapping is 1 (one). +  // @mixed +  // @value 0 +  // Successful match. +  // @value 1 +  // Fail with return. +  // @value 2 +  // Fail with authenticate return. +  // @value 3 +  // Fail without return. +  // @value 4 +  // Fail with authenticate without return. +  // @endmixed    // -  // If any entry in the state mapping contains a mapping, that entry -  // will be returned on exit. Otherwise, if there is any non-zero -  // entry in the state mapping it will be returned. If the state -  // mapping only contains zero's zero will be returned. +  // If the checking ends with an ok return (ie shorted == 1) only +  // entries with a value of 3 or higher will be regarded. +  // The highest regarded failure value will be used to determine +  // the action.       foreach(security_checks, array(string|int|array) check)    {    array args;    if (sizeof(args = array_sscanf(line, check[0])) == check[1])    { -  +  // Got a match for this security check.    patterns++; -  string thr_code = "1"; +  int thr_code = 3;    // run instructions.    foreach(check[2], mixed instr )    {    if( functionp( instr ) )    args = instr( @args );    else if( multisetp( instr ) )    {    foreach( (array)instr, string v )    if( !has_value( variables, v ) )    variables += ({ v });    } -  else if( intp( instr ) ) -  thr_code = "authmethod->authenticate_throw( id, realm )"; +  else if( intp( instr ) ) { +  thr_code = 4; +  need_auth = 1; +  }    else if( stringp( instr ) )    {    code += sprintf( instr, @args )+"\n";    if( cmd == DENY )    { -  code += " return " + thr_code + ";\n"; +  code += " return " + +  ((thr_code == 4)?"authmethod->authenticate_throw(id, realm)": +  "1") + +  ";\n";    }    else    { -  code += sprintf(" {\n" -  " state->%s = 0;\n" + -  (shorted?" break;\n":"") + -  " } else if (zero_type(state->%s)) {\n" -  " state->%s = %s;\n" +  if (shorted) { +  // OK with return. Ignore FAIL/return. +  if (checks[check[3]]) { +  code += +  sprintf(" {\n" +  " m_delete(state, %O);\n" +  " shorted = 1;\n" +  " break;\n"    " }\n", -  +  check[3]); +  } else { +  code += +  " {\n" +  " shorted = 1;\n" +  " break;\n" +  " }\n"; +  } +  } else { +  // OK without return. Mark as OK. +  code += +  sprintf(" {\n" +  " state->%s = 0;\n" +  " }\n", +  check[3]); +  all_shorted = 0; +  } +  if (checks[check[3]]) { +  // If not marked, or marked as lower failure +  // set the failure level. +  code += +  sprintf(" else if (zero_type(state->%s) ||\n" +  " (state->%s && state->%s < %d))\n",    check[3], -  check[3], -  check[3], thr_code); +  check[3], check[3], thr_code-(shorted*2)); +  } else { +  code += " else\n";    } -  +  code += sprintf(" {\n" +  " state->%s = %d;\n" +  " }\n", +  check[3], thr_code-(shorted*2)); +  checks[check[3]] = 1;    }    } -  +  }    break;    }    }    }    if( !patterns ) return 0;    code = (" do {\n" +    code +    " } while(0);\n");    code = ("#include <module.h>\n"    "int|mapping f( RequestID id )\n"
Roxen.git/server/base_server/roxen.pike:5174: Inside #if defined(SECURITY_PATTERN_DEBUG) || defined(HTACCESS_DEBUG)
   sprintf(" report_debug(\"Verifying against pattern:\\n\"\n"    "%{ \" \" %O \"\\n\"\n%}"    " \"...\\n\");\n"    "%s"    " report_debug(sprintf(\" Result: %%O\\n\",\n"    " state));\n",    pattern/"\n", code) +   #else /* !SECURITY_PATTERN_DEBUG && !HTACCESS_DEBUG */    code +   #endif /* SECURITY_PATTERN_DEBUG || HTACCESS_DEBUG */ -  " int fail;\n" -  " foreach(values(state), int|mapping value) {\n" -  " if (mappingp(value)) return value;\n" -  " fail = fail || value;\n" -  " }\n" -  " return fail;\n" +  (all_shorted? +  " if(shorted) return 0;\n": +  "")+ +  ((need_auth || !all_shorted)? +  " int fail = 0;\n" +  " foreach(values(state), int value) {\n" +  " if (fail < value) fail = value;\n" +  " }\n": +  "")+ +  (all_shorted? +  "": +  " if (!fail || (shorted && fail < 3)) return 0;\n")+ +  (need_auth? +  " if ((fail-1) & 1)\n" +  " return authmethod->authenticate_throw(id, realm);\n": +  "")+ +  " return 1;\n"    "}\n");   #if defined(SECURITY_PATTERN_DEBUG) || defined(HTACCESS_DEBUG)    report_debug(sprintf("Compiling security pattern:\n"    "%{ %s\n%}\n"    "Code:\n"    "%{ %s\n%}\n",    pattern/"\n",    code/"\n"));   #endif /* SECURITY_PATTERN_DEBUG || HTACCESS_DEBUG */    mixed res = compile_string( code );