Branch: Tag:

2001-03-08

2001-03-08 14:35:49 by Per Hedbor <ph@opera.com>

The module level security patterns now use the new authentication API. Placed a lot of modules in groups

Rev: server/base_server/configuration.pike:1.420
Rev: server/base_server/module.pike:1.111
Rev: server/base_server/roxen.pike:1.644
Rev: server/config_interface/dbs/browser.pike:1.10
Rev: server/config_interface/sites/config_left_item.pike:1.50
Rev: server/etc/modules/Roxen.pmod:1.72
Rev: server/modules/configuration/config_tags.pike:1.141
Rev: server/modules/database/sqltag.pike:1.76
Rev: server/modules/filesystems/filesystem.pike:1.96
Rev: server/modules/graphics/atlas.pike:1.4
Rev: server/modules/graphics/business.pike:1.140
Rev: server/modules/graphics/cimg.pike:1.38
Rev: server/modules/graphics/counter.pike:1.40
Rev: server/modules/graphics/gbutton.pike:1.78
Rev: server/modules/graphics/graphic_text.pike:1.260
Rev: server/modules/graphics/pimage.pike:1.25
Rev: server/modules/graphics/tablist.pike:1.52
Rev: server/modules/graphics/wiretap.pike:1.24
Rev: server/modules/scripting/piketag.pike:2.31
Rev: server/modules/security/auth_httpbasic.pike:1.5
Rev: server/modules/security/auth_httpcookie.pike:1.5
Rev: server/modules/security/userdb_system.pike:1.6
Rev: server/modules/tags/accessed.pike:1.41
Rev: server/modules/tags/additional_rxml.pike:1.11
Rev: server/modules/tags/awizard.pike:1.22
Rev: server/modules/tags/check_spelling.pike:1.16
Rev: server/modules/tags/countdown.pike:1.42
Rev: server/modules/tags/diremit.pike:1.7
Rev: server/modules/tags/email.pike:1.6
Rev: server/modules/tags/foldlist.pike:1.29
Rev: server/modules/tags/html_wash.pike:1.15
Rev: server/modules/tags/indirect_href.pike:1.26
Rev: server/modules/tags/killframe.pike:1.33
Rev: server/modules/tags/obox.pike:1.35
Rev: server/modules/tags/rxmlparse.pike:1.54
Rev: server/modules/tags/rxmltags.pike:1.208
Rev: server/modules/tags/sed.pike:1.11
Rev: server/modules/tags/ssi.pike:1.38
Rev: server/modules/tags/tablify.pike:1.63
Rev: server/modules/tags/translation_mod.pike:1.10
Rev: server/modules/tags/vform.pike:1.22
Rev: server/modules/tags/wizard_tag.pike:1.29
Rev: server/modules/tags/wizz.pike:1.2
Rev: server/protocols/http.pike:1.307

4:   // 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.643 2001/03/06 13:38:15 per Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.644 2001/03/08 14:35:40 per Exp $";      // Used when running threaded to find out which thread is the backend thread.   Thread.Thread backend_thread;
554: Inside #if defined(THREADS)
   "Client will not get any response from Roxen.\n"),*/    describe_backtrace(q));    if (q = catch {h = 0;}) { -  report_error(LOC_M(5, "Uncaught error in1942 handler thread: %s Client" +  report_error(LOC_M(5, "Uncaught error in handler thread: %s Client"    "will not get any response from Roxen.")+"\n",    describe_backtrace(q));    }
3847:   }       + array security_checks = ({ +  "ip=%s:%s",2,({ +  lambda( string a, string b ){ +  int net = Roxen.ip_to_int( a ); +  int mask = Roxen.ip_to_int( b ); +  net &= mask; +  return ({ net, sprintf("%c",mask)[0] }); +  }, +  " if( (Roxen.ip_to_int( id->remoteaddr ) & %[1]d) == %[0]d ) ", +  }), +  "ip=%s/%d",2,({ +  lambda( string a, int b ){ +  int net = Roxen.ip_to_int( a ); +  int mask = ((~0<<(32-b))&0xffffffff); +  net &= mask; +  return ({ net, sprintf("%c",mask)[0] }); +  }, +  " if( (Roxen.ip_to_int( id->remoteaddr ) & %[1]d) == %[0]d ) ", +  }), +  "ip=%s",1,({ +  " if( glob( %[0]O, id->remoteaddr ) ) ", +  }), +  "user=%s",1,({ +  1, +  lambda( string x ) { +  return ({sprintf("(< %{%O, %}>)", x/"," )}); +  }, +  " if( (user || (user = authmethod->authenticate( id, userdb_module )))\n" +  " && ((%[0]s->any) || (%[0]s[user->name()])) ) ", +  (< " User user" >), +  }), +  "group=%s",1,({ +  1, +  lambda( string x ) { +  return ({sprintf("(< %{%O, %}>)", x/"," )}); +  }, +  " if( (user || (user = authmethod->authenticate( id, userdb_module )))\n" +  " && ((%[0]s->any) || sizeof(mkmultiset(user->groups())&%[0]s)))", +  (<" User user" >), +  }), +  "dns=%s",1,({ +  }), +  "time=%d:%d-%d:%d",4,({ +  }), + });    -  +  + function(RequestID:mapping|int) compile_security_pattern( string pattern, +  RoxenModule m ) + //. Parse a security pattern and return a function that when called + //. will do the checks required by the format. + //. + //. The syntax is: + //. + //. userdb userdatabase module + //. authmethod authentication module + //. realm realm name + //. + //. Below, CMD is one of 'allow' and 'deny' + //. + //. CMD ip=ip/bits[,ip/bits] [return] + //. CMD ip=ip:mask[,ip:mask] [return] + //. CMD ip=pattern [return] + //. + //. CMD user=name[,name,...] [return] + //. CMD group=name[,name,...] [return] + //. + //. CMD dns=pattern [return] + //. + //. CMD time=<start>-<stop> [return] + //. times in HH:mm format + //. + //. pattern is a glob pattern. + //. + //. return means that reaching this command results in immediate + //. return, only useful for 'allow'. + //. + //. 'deny' always implies a return, no futher testing is done if a + //. 'deny' match. + { +  string code = ""; +  multiset variables = (< " object userdb_module", +  " object authmethod = id->conf", +  " string realm = \"User\"", +  " int|mapping fail">); +  int shorted, patterns, cmd; + #define DENY 0 + #define ALLOW 1 +  +  foreach( pattern / "\n", string line ) +  { +  line = String.trim_all_whites( line ); +  if( !strlen(line) || line[0] == '#' ) +  continue; +  sscanf( line, "%[^#]#", line ); +  +  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" ) +  code += " userdb_module = 0;\n"; +  else if( !m->my_configuration()->find_user_database( line ) ) +  m->report_notice( LOC_M( 0,"Syntax error in security patterns: " +  "Cannot find the user database '"+ +  line+"'\n" )); +  else +  code += +  sprintf(" userdb_module = id->conf->find_user_database( %O );\n", +  line); +  continue; +  } +  else if( sscanf( line, "authmethod %s", line ) ) +  { +  line = String.trim_all_whites( line ); +  if( line == "all" ) +  code += " authmethod = id->conf;\n"; +  else if( !m->my_configuration()->find_auth_module( line ) ) +  m->report_notice( LOC_M( 0,"Syntax error in security patterns: " +  "Cannot find the auth method '"+ +  line+"'\n" )); +  else +  code += +  sprintf(" authmethod = id->conf->find_auth_module( %O );\n", +  line); +  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( 0,"Syntax error in security patterns: " +  "Expected 'allow' or 'deny'\n" )); +  shorted = sscanf( line, "%s return", line ); +  +  +  for( int i = 0; i<sizeof( security_checks ); i+=3 ) +  { +  string check = security_checks[i]; +  array args; +  if( sizeof( args = array_sscanf( line, check ) ) +  == security_checks[i+1] ) +  { +  patterns++; +  int thr; +  // run instructions. +  foreach( security_checks[ i+2 ], mixed instr ) +  { +  if( functionp( instr ) ) +  args = instr( @args ); +  else if( multisetp( instr ) ) +  variables |= instr; +  else if( intp( instr ) ) +  thr = instr; +  else if( stringp( instr ) ) +  { +  code += sprintf( instr, @args )+"\n"; +  if( cmd == DENY ) +  { +  if( thr ) +  code += " return authmethod->authenticate_throw( id, realm );\n"; +  else +  code += " return 1;\n"; +  } +  else +  { +  if( shorted ) +  { +  code += " return fail;\n"; +  code += " else\n"; +  if( thr ) +  code += " return authmethod->authenticate_throw( id, realm );\n"; +  else +  code += " return fail || 1;\n"; +  } +  else +  { +  code += " ;\n"; +  code += " else\n"; +  if( thr ) +  code += " fail=authmethod->authenticate_throw( id, realm );\n"; +  else +  code += " if( !fail ) fail=1;\n"; +  } +  } +  } +  } +  break; +  } +  } +  } +  if( !patterns ) +  return 0; +  +  code = +  "int|mapping f( RequestID id )\n" +  "{\n" + sort( indices( variables ) )*";\n" + ";\n" +  "" + code + " return fail;\n}\n"; +  +  werror( "Da Code:\n%s\n", code ); +  +  return compile_string( code )()->f; + #undef DENY + #undef ALLOW + } +  +    static string cached_hostname = gethostname();      class LogFile(string fname)