cvs commit: apache-1.3/src/modules/standard mod_cern_meta.c

1998-08-14 Thread dgaudet
dgaudet 98/08/13 19:49:57

  Modified:src  CHANGES
   src/include alloc.h
   src/main alloc.c http_protocol.c util_script.c
   src/modules/standard mod_cern_meta.c
  Log:
  Add ap_overlap_tables.  Fix various O(n^2) attacks using it.
  
  Revision  ChangesPath
  1.1024+3 -1  apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1023
  retrieving revision 1.1024
  diff -u -r1.1023 -r1.1024
  --- CHANGES   1998/08/13 01:54:59 1.1023
  +++ CHANGES   1998/08/14 02:49:42 1.1024
  @@ -22,7 +22,9 @@
[Jim Jagielski]
   
 *) SECURITY: Eliminate O(n^2) space DoS attacks (and other O(n^2)
  - cpu time attacks) in header parsing.  [Dean Gaudet]
  + cpu time attacks) in header parsing.  Add ap_overlap_tables(),
  + a function which can be used to perform bulk update operations
  + on tables in a more efficient manner.  [Dean Gaudet]
   
 *) SECURITY: Added compile-time and configurable limits for
various aspects of reading a client request to avoid some simple
  
  
  
  1.63  +4 -2  apache-1.3/src/include/alloc.h
  
  Index: alloc.h
  ===
  RCS file: /export/home/cvs/apache-1.3/src/include/alloc.h,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -r1.62 -r1.63
  --- alloc.h   1998/08/09 17:36:24 1.62
  +++ alloc.h   1998/08/14 02:49:45 1.63
  @@ -199,7 +199,7 @@
   int i;
   
   for (i = 0; i < barr->nelts; ++i) {
  - if (merge) {
  + if (flags & AP_OVERLAP_TABLES_MERGE) {
ap_table_mergen(a, belt[i].key, belt[i].val);
}
else {
  @@ -214,7 +214,9 @@
   in an ancestor of a's pool.  In practice b and a are usually from
   the same pool.
   */
  -API_EXPORT(void) ap_overlap_tables(table *a, const table *b, int merge);
  +#define AP_OVERLAP_TABLES_SET(0)
  +#define AP_OVERLAP_TABLES_MERGE  (1)
  +API_EXPORT(void) ap_overlap_tables(table *a, const table *b, unsigned flags);
   
   /* XXX: these know about the definition of struct table in alloc.c.  That
* definition is not here because it is supposed to be private, and by not
  
  
  
  1.99  +157 -0apache-1.3/src/main/alloc.c
  
  Index: alloc.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/main/alloc.c,v
  retrieving revision 1.98
  retrieving revision 1.99
  diff -u -r1.98 -r1.99
  --- alloc.c   1998/08/03 09:14:51 1.98
  +++ alloc.c   1998/08/14 02:49:47 1.99
  @@ -1386,6 +1386,163 @@
   va_end(vp);
   }
   
  +/* Curse libc and the fact that it doesn't guarantee a stable sort.  We
  + * have to enforce stability ourselves by using the order field.  If it
  + * provided a stable sort then we wouldn't even need temporary storage to
  + * do the work below. -djg
  + *
  + * ("stable sort" means that equal keys retain their original relative
  + * ordering in the output.)
  + */
  +typedef struct {
  +char *key;
  +char *val;
  +int order;
  +} overlap_key;
  +
  +static int sort_overlap(const void *va, const void *vb)
  +{
  +const overlap_key *a = va;
  +const overlap_key *b = vb;
  +int r;
  +
  +r = strcasecmp(a->key, b->key);
  +if (r) {
  + return r;
  +}
  +return a->order - b->order;
  +}
  +
  +/* prefer to use the stack for temp storage for overlaps smaller than this */
  +#ifndef AP_OVERLAP_TABLES_ON_STACK
  +#define AP_OVERLAP_TABLES_ON_STACK   (512)
  +#endif
  +
  +API_EXPORT(void) ap_overlap_tables(table *a, const table *b, unsigned flags)
  +{
  +overlap_key cat_keys_buf[AP_OVERLAP_TABLES_ON_STACK];
  +overlap_key *cat_keys;
  +int nkeys;
  +table_entry *e;
  +table_entry *last_e;
  +overlap_key *left;
  +overlap_key *right;
  +overlap_key *last;
  +
  +nkeys = a->a.nelts + b->a.nelts;
  +if (nkeys < AP_OVERLAP_TABLES_ON_STACK) {
  + cat_keys = cat_keys_buf;
  +}
  +else {
  + /* XXX: could use scratch free space in a or b's pool instead...
  +  * which could save an allocation in b's pool.
  +  */
  + cat_keys = ap_palloc(b->a.pool, sizeof(overlap_key) * nkeys);
  +}
  +
  +nkeys = 0;
  +
  +/* Create a list of the entries from a concatenated with the entries
  + * from b.
  + */
  +e = (table_entry *)a->a.elts;
  +last_e = e + a->a.nelts;
  +while (e < last_e) {
  + cat_keys[nkeys].key = e->key;
  + cat_keys[nkeys].val = e->val;
  + cat_keys[nkeys].order = nkeys;
  + ++nkeys;
  + ++e;
  +}
  +
  +e = (table_entry *)b->a.elts;
  +last_e = e + b->a.nelts;
  +while (e < last_e) {
  + cat_keys[nkeys].key = e->key;
  + cat_keys[nkeys].val = e->val;
  + cat_keys[nkeys].order = nkeys;
 

cvs commit: apache-1.3/src/modules/standard mod_cern_meta.c mod_include.c

1998-08-09 Thread dgaudet
dgaudet 98/08/09 10:36:30

  Modified:src/include alloc.h
   src/main http_protocol.c util_script.c
   src/modules/proxy proxy_http.c proxy_util.c
   src/modules/standard mod_cern_meta.c mod_include.c
  Log:
  Just some comments.  Including a proposed ap_overlap_tables function which
  generalizes my new code in get_mime_headers().
  
  Revision  ChangesPath
  1.62  +24 -0 apache-1.3/src/include/alloc.h
  
  Index: alloc.h
  ===
  RCS file: /export/home/cvs/apache-1.3/src/include/alloc.h,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- alloc.h   1998/06/27 18:09:28 1.61
  +++ alloc.h   1998/08/09 17:36:24 1.62
  @@ -192,6 +192,30 @@
   
   API_EXPORT(table *) ap_overlay_tables(pool *p, const table *overlay, const 
table *base);
   
  +/* Conceptually, ap_overlap_tables does this:
  +
  +array_header *barr = ap_table_elts(b);
  +table_entry *belt = (table_entry *)barr->elts;
  +int i;
  +
  +for (i = 0; i < barr->nelts; ++i) {
  + if (merge) {
  + ap_table_mergen(a, belt[i].key, belt[i].val);
  + }
  + else {
  + ap_table_setn(a, belt[i].key, belt[i].val);
  + }
  +}
  +
  +Except that it is more efficient (less space and cpu-time) especially
  +when b has many elements.
  +
  +Notice the assumptions on the keys and values in b -- they must be
  +in an ancestor of a's pool.  In practice b and a are usually from
  +the same pool.
  +*/
  +API_EXPORT(void) ap_overlap_tables(table *a, const table *b, int merge);
  +
   /* XXX: these know about the definition of struct table in alloc.c.  That
* definition is not here because it is supposed to be private, and by not
* placing it here we are able to get compile-time diagnostics from modules
  
  
  
  1.235 +1 -0  apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.234
  retrieving revision 1.235
  diff -u -r1.234 -r1.235
  --- http_protocol.c   1998/08/09 16:57:29 1.234
  +++ http_protocol.c   1998/08/09 17:36:26 1.235
  @@ -739,6 +739,7 @@
   return (signed)a->order - (signed)b->order;
   }
   
  +/* XXX: could use ap_overlap_tables here... which generalizes this code */
   static void get_mime_headers(request_rec *r)
   {
   conn_rec *c = r->connection;
  
  
  
  1.128 +2 -0  apache-1.3/src/main/util_script.c
  
  Index: util_script.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/main/util_script.c,v
  retrieving revision 1.127
  retrieving revision 1.128
  diff -u -r1.127 -r1.128
  --- util_script.c 1998/08/06 18:58:21 1.127
  +++ util_script.c 1998/08/09 17:36:26 1.128
  @@ -188,6 +188,7 @@
   return env;
   }
   
  +/* XXX: this could use ap_overlap_tables */
   API_EXPORT(void) ap_add_common_vars(request_rec *r)
   {
   table *e = r->subprocess_env;
  @@ -546,6 +547,7 @@
ap_table_add(r->err_headers_out, w, l);
}
else {
  + /* XXX: there is an O(n^2) space attack possible here */
ap_table_merge(r->err_headers_out, w, l);
}
   }
  
  
  
  1.55  +1 -0  apache-1.3/src/modules/proxy/proxy_http.c
  
  Index: proxy_http.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- proxy_http.c  1998/08/06 17:30:43 1.54
  +++ proxy_http.c  1998/08/09 17:36:27 1.55
  @@ -425,6 +425,7 @@
continue;
if (!r->assbackwards) {
ap_rvputs(r, hdr[i].field, ": ", hdr[i].value, CRLF, NULL);
  + /* XXX: can't this be ap_table_setn? -djg */
ap_table_set(r->headers_out, hdr[i].field, hdr[i].value);
}
if (cache != NULL)
  
  
  
  1.67  +1 -0  apache-1.3/src/modules/proxy/proxy_util.c
  
  Index: proxy_util.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
  retrieving revision 1.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- proxy_util.c  1998/08/06 17:30:44 1.66
  +++ proxy_util.c  1998/08/09 17:36:28 1.67
  @@ -641,6 +641,7 @@
if (hdrs[i].field == NULL)
continue;
ap_bvputs(fp, hdrs[i].field, ": ", hdrs[i].value, CRLF, NULL);
  + /* XXX: can't this be ap_table_setn? -djg */
ap_table_set(r->headers_out, hdrs[i].field, hdrs[i].value);
   }
   
  
  
  
  1.34  +1 -0  apache-1.3/src/modules/standard/mod_cern_meta.c
  
  Index: mod_cern_meta.c
  ==

cvs commit: apache-1.3/src/modules/standard mod_cern_meta.c mod_mime_magic.c

1998-06-10 Thread dgaudet
dgaudet 98/06/10 02:02:15

  Modified:src  CHANGES
   src/include httpd.h
   src/main util.c util_script.c
   src/modules/standard mod_cern_meta.c mod_mime_magic.c
  Log:
  My "all content-types must be lowercase" change neglected param=value
  pairs... and would downcase the value, which is a case-sensitive thing.
  But, to be honest, the code prior to my changes neglected param=value
  pairs.  Another case where we really should have some core parsing
  routines that understand HTTP rather than the hodge-podge we have
  now.
  
  PR:   2394
  
  Revision  ChangesPath
  1.906 +5 -0  apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.905
  retrieving revision 1.906
  diff -u -r1.905 -r1.906
  --- CHANGES   1998/06/10 08:15:09 1.905
  +++ CHANGES   1998/06/10 09:01:58 1.906
  @@ -1,5 +1,10 @@
   Changes with Apache 1.3.1
   
  +  *) Apache would incorrectly downcase the entire Content-Type passed from
  + CGIs.  This affected server-push scripts and such which use
  + multipart/x-mixed-replace;boundary=ThisRandomString.
  + [Dean Gaudet] PR#2394
  +
 *) PORT: QNX update to properly guess 32-bit systems.
[Sean Boudreau <[EMAIL PROTECTED]>] PR#2390
   
  
  
  
  1.223 +1 -0  apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===
  RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.222
  retrieving revision 1.223
  diff -u -r1.222 -r1.223
  --- httpd.h   1998/06/07 01:22:36 1.222
  +++ httpd.h   1998/06/10 09:02:02 1.223
  @@ -896,6 +896,7 @@
   API_EXPORT(char *) ap_pregsub(pool *p, const char *input, const char *source,
   size_t nmatch, regmatch_t pmatch[]);
   
  +API_EXPORT(void) ap_content_type_tolower(char *);
   API_EXPORT(void) ap_str_tolower(char *);
   API_EXPORT(int) ap_ind(const char *, char);  /* Sigh... */
   API_EXPORT(int) ap_rind(const char *, char);
  
  
  
  1.120 +24 -0 apache-1.3/src/main/util.c
  
  Index: util.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v
  retrieving revision 1.119
  retrieving revision 1.120
  diff -u -r1.119 -r1.120
  --- util.c1998/06/06 19:30:48 1.119
  +++ util.c1998/06/10 09:02:09 1.120
  @@ -1781,3 +1781,27 @@
   return (time1 - time0);
   }
   #endif
  +
  +/* we want to downcase the type/subtype for comparison purposes
  + * but nothing else because ;parameter=foo values are case sensitive.
  + * XXX: in truth we want to downcase parameter names... but really,
  + * apache has never handled parameters and such correctly.  You
  + * also need to compress spaces and such to be able to compare
  + * properly. -djg
  + */
  +API_EXPORT(void) ap_content_type_tolower(char *str)
  +{
  +char *semi;
  +
  +semi = strchr(str, ';');
  +if (semi) {
  + *semi = '\0';
  +}
  +while (*str) {
  + *str = tolower(*str);
  + ++str;
  +}
  +if (semi) {
  + *semi = ';';
  +}
  +}
  
  
  
  1.116 +1 -1  apache-1.3/src/main/util_script.c
  
  Index: util_script.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/main/util_script.c,v
  retrieving revision 1.115
  retrieving revision 1.116
  diff -u -r1.115 -r1.116
  --- util_script.c 1998/05/28 23:26:41 1.115
  +++ util_script.c 1998/06/10 09:02:09 1.116
  @@ -466,7 +466,7 @@
*endp-- = '\0';
   
r->content_type = ap_pstrdup(r->pool, l);
  - ap_str_tolower(r->content_type);
  + ap_content_type_tolower(r->content_type);
}
/*
 * If the script returned a specific status, that's what
  
  
  
  1.30  +1 -1  apache-1.3/src/modules/standard/mod_cern_meta.c
  
  Index: mod_cern_meta.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_cern_meta.c,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- mod_cern_meta.c   1998/06/09 05:22:11 1.29
  +++ mod_cern_meta.c   1998/06/10 09:02:12 1.30
  @@ -269,7 +269,7 @@
*endp-- = '\0';
   
r->content_type = ap_pstrdup(r->pool, l);
  - ap_str_tolower(r->content_type);
  + ap_content_type_tolower(r->content_type);
}
else if (!strcasecmp(w, "Status")) {
sscanf(l, "%d", &r->status);
  
  
  
  1.34  +1 -1  apache-1.3/src/modules/standard/mod_mime_magic.c
  
  Index: mod_mime_magic.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard

cvs commit: apache-1.3/src/modules/standard mod_cern_meta.c

1998-06-09 Thread dgaudet
dgaudet 98/06/08 22:22:12

  Modified:src  CHANGES
   src/modules/standard mod_cern_meta.c
  Log:
  Missing usage for MetaFiles directive.
  
  PR:   2384
  Submitted by: David MacKenzie <[EMAIL PROTECTED]>
  
  Revision  ChangesPath
  1.900 +3 -0  apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.899
  retrieving revision 1.900
  diff -u -r1.899 -r1.900
  --- CHANGES   1998/06/09 04:41:26 1.899
  +++ CHANGES   1998/06/09 05:22:10 1.900
  @@ -1,5 +1,8 @@
   Changes with Apache 1.3.1
   
  +  *) Fix missing usage description for MetaFiles directive.
  + [David MacKenzie <[EMAIL PROTECTED]>] PR#2384
  +
 *) mod_log_config wouldn't let vhosts use log formats defined in the
main server.  [Christof Damian <[EMAIL PROTECTED]>] PR#2090
   
  
  
  
  1.29  +2 -1  apache-1.3/src/modules/standard/mod_cern_meta.c
  
  Index: mod_cern_meta.c
  ===
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_cern_meta.c,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- mod_cern_meta.c   1998/04/11 12:00:45 1.28
  +++ mod_cern_meta.c   1998/06/09 05:22:11 1.29
  @@ -217,7 +217,8 @@
   
   static const command_rec cern_meta_cmds[] =
   {
  -{"MetaFiles", set_metafiles, NULL, DIR_CMD_PERMS, FLAG, NULL},
  +{"MetaFiles", set_metafiles, NULL, DIR_CMD_PERMS, FLAG,
  +"Limited to 'on' or 'off'"},
   {"MetaDir", set_metadir, NULL, DIR_CMD_PERMS, TAKE1,
"the name of the directory containing meta files"},
   {"MetaSuffix", set_metasuffix, NULL, DIR_CMD_PERMS, TAKE1,