[PRE-PATCH] move ip subnet details from mod_access to APR

2001-03-14 Thread Jeff Trawick
(and handle IPv4-mapped IPv6 addresses as well as normal IPv6
addresses properly)

Various programs which communicate over an IP network must evaluate an
incoming connection against a configured IP subnet to determine
whether or not the client can access data.  mod_access and TCP
wrappers are examples of such programs.

The current mod_access implementation has problems with IPv6.  It
seems appropriate to move the logic to APR as IPv6 support is added so
that other applications can use the same logic and so that less
IPv4/IPv6 handling is required in the application.

The APR routines will handle the same type of subnet definitions as
the current mod_access:

  a.b.c.d
  a.b.c
  a.b
  a
  a.b.c.d/w.x.y.z
  a.b.c.d/n

In addition, IPv6 subnet definitions will be allowed:

  v6-address-string
  v6-address-string/n

This patch doesn't include the APR implementation nor the APR test
program for IP subnet define/check, as they are not finished yet.

Comments?

Index: modules/aaa/mod_access.c
===
RCS file: /home/cvspublic/httpd-2.0/modules/aaa/mod_access.c,v
retrieving revision 1.30
diff -u -r1.30 mod_access.c
--- modules/aaa/mod_access.c2001/03/09 20:30:31 1.30
+++ modules/aaa/mod_access.c2001/03/14 12:50:03
@@ -94,10 +94,7 @@
 int limited;
 union {
char *from;
-   struct {
-   unsigned long net;
-   unsigned long mask;
-   } ip;
+apr_ipsubnet_t *ip;
 } x;
 enum allowdeny_type type;
 } allowdeny;
@@ -150,20 +147,14 @@
 return NULL;
 }
 
-static int is_ip(const char *host)
-{
-while ((*host == '.') || apr_isdigit(*host))
-   host++;
-return (*host == '\0');
-}
-
 static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from, 
  const char *where_c)
 {
 access_dir_conf *d = (access_dir_conf *) dv;
 allowdeny *a;
-char *s;
 char *where = apr_pstrdup(cmd-pool, where_c);
+char *s;
+apr_status_t rv;
 
 if (strcasecmp(from, from))
return allow and deny must be followed by 'from';
@@ -179,90 +170,25 @@
 }
 else if (!strcasecmp(where, all)) {
a-type = T_ALL;
-
 }
 else if ((s = strchr(where, '/'))) {
-   unsigned long mask;
-
-   a-type = T_IP;
-   /* trample on where, we won't be using it any more */
-   *s++ = '\0';
-
-   if (!is_ip(where)
-   || (a-x.ip.net = apr_inet_addr(where)) == APR_INADDR_NONE) {
-   a-type = T_FAIL;
-   return syntax error in network portion of network/netmask;
-   }
-
-   /* is_ip just tests if it matches [\d.]+ */
-   if (!is_ip(s)) {
-   a-type = T_FAIL;
-   return syntax error in mask portion of network/netmask;
-   }
-   /* is it in /a.b.c.d form? */
-   if (strchr(s, '.')) {
-   mask = apr_inet_addr(s);
-   if (mask == APR_INADDR_NONE) {
-   a-type = T_FAIL;
-   return syntax error in mask portion of network/netmask;
-   }
-   }
-   else {
-   /* assume it's in /nnn form */
-   mask = atoi(s);
-   if (mask  32 || mask = 0) {
-   a-type = T_FAIL;
-   return invalid mask in network/netmask;
-   }
-   mask = 0xUL  (32 - mask);
-   mask = htonl(mask);
-   }
-   a-x.ip.mask = mask;
-a-x.ip.net  = (a-x.ip.net  mask);   /* pjr - This fixes PR 4770 */
-}
-else if (apr_isdigit(*where)  is_ip(where)) {
-   /* legacy syntax for ip addrs: a.b.c. == a.b.c.0/24 for example */
-   int shift;
-   char *t;
-   int octet;
-
-   a-type = T_IP;
-   /* parse components */
-   s = where;
-   a-x.ip.net = 0;
-   a-x.ip.mask = 0;
-   shift = 24;
-   while (*s) {
-   t = s;
-   if (!apr_isdigit(*t)) {
-   a-type = T_FAIL;
-   return invalid ip address;
-   }
-   while (apr_isdigit(*t)) {
-   ++t;
-   }
-   if (*t == '.') {
-   *t++ = 0;
-   }
-   else if (*t) {
-   a-type = T_FAIL;
-   return invalid ip address;
-   }
-   if (shift  0) {
-   return invalid ip address, only 4 octets allowed;
-   }
-   octet = atoi(s);
-   if (octet  0 || octet  255) {
-   a-type = T_FAIL;
-   return each octet must be between 0 and 255 inclusive;
-   }
-   a-x.ip.net |= octet  shift;
-   a-x.ip.mask |= 0xFFUL  shift;
-   s = t;
-   shift -= 8;
-   }
-   a-x.ip.net = ntohl(a-x.ip.net);
-   a-x.ip.mask = ntohl(a-x.ip.mask);
+*s++ = '\0';
+rv = apr_ipsubnet_create(a-x.ip, where, s, cmd-pool);
+if (rv != APR_SUCCESS) {
+/* XXX build APR error string from rv and return it */
+return some APR error 

Re: apr_realpath

2001-03-14 Thread Kevin Pilch-Bisson
Here are some things I got from this.

On Tue, Mar 13, 2001 at 01:40:02AM -0600, William A. Rowe, Jr. wrote:
 Here is what I've worked up thus far for Unix... n'er mind the _more_ 
 complicated
 Win32 beast [all I could do to get the _root_ parsing finished tonight!]
 
 So feel free to look at the server root parse function, and the unix 
 implementation
 of apr_filepath_merge(), and let me know if I've gone off in the wrong 
 direction.
 
 Survey; is there any reason -not- to canonicalize a name, ever (/./ 
 elimination, etc)?

Not that I can think of.
 
 Is there a decent semantic to append a missing trailing slash for a directory 
 vs. a file?

Not sure exactly what you are asking.
 
 Should we have a char** input argument for addpath (who cares about realpath) 
 so that
 we can actually return the user the existing path, while incrementing the 
 pointer to the
 start of the non-existinant path (a slow operation, by request only)?

Why?
 
 Should we persist in forcing Win32 to use slashes, or should we return 
 backslashes?

Subversion uses native path separators. I don't know what the rest of
APR/Apache do.
 
 Last comment (not a q)... I will round out the Win32 code and add 
 apr_pathname_segment()
 fn to pull apart a path, which is what I got out of kevin's request, and what 
 I need
 for the Apache core.

Actually, I am looking for a function to portably, always get an absolut
path from a given string.  I'll try to give you a use case for it.  In
subversion, we have the idea of commits, where you can give a list of
targets on the command line.

[EMAIL PROTECTED]:/home/kevin/repos$ svn commit file1 dir/file2 
/home/kevin/repos/dir2/file3

From that command, we would like to be able to take the three file
arguments, and find out what is the deepest directory which is common to
all three targets, since that is where we have to start making changes
to our repository.  In the above example that would be
/home/kevin/repos.  We already have a function which takes a list of
(absolute) targets, finds the common part of the path, and converts the
other targets to relative paths from that base.  Now we need a portable
way to convert the targets given above into absolute paths.  The
problem we ran into is that while realpath exists on unix, and _fullpath
exists on win32, there is nothing (that we knew about anyway, on BeOS).
Also, realpath is known to be broken on some older versions of Solaris,
in that it merely canonicalizes a path if it is below the cwd.  For now,
we are just using realpath and _fullpath (and not putting our heads in
the sand with respect to Solaris and BeOS.

 
 Bill
 
 Index: file_io/unix/filepath.c
 ===
 RCS file: filepath.c
 diff -N filepath.c
 --- /dev/null Mon Mar 12 23:32:12 2001
 +++ filepath.c Mon Mar 12 23:32:23 2001
 @@ -0,0 +1,233 @@
 +/* 
 + * The Apache Software License, Version 1.1
 + *
 + * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 + * reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + *
 + * 1. Redistributions of source code must retain the above copyright
 + *notice, this list of conditions and the following disclaimer.
 + *
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *notice, this list of conditions and the following disclaimer in
 + *the documentation and/or other materials provided with the
 + *distribution.
 + *
 + * 3. The end-user documentation included with the redistribution,
 + *if any, must include the following acknowledgment:
 + *   This product includes software developed by the
 + *Apache Software Foundation (http://www.apache.org/).
 + *Alternately, this acknowledgment may appear in the software itself,
 + *if and wherever such third-party acknowledgments normally appear.
 + *
 + * 4. The names Apache and Apache Software Foundation must
 + *not be used to endorse or promote products derived from this
 + *software without prior written permission. For written
 + *permission, please contact [EMAIL PROTECTED]
 + *
 + * 5. Products derived from this software may not be called Apache,
 + *nor may Apache appear in their name, without prior written
 + *permission of the Apache Software Foundation.
 + *
 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 + * USE, DATA, 

builconf APR and httpd2.0

2001-03-14 Thread jean-frederic clere
Hi,

I have noted that buildconf of httpd2.0 creates links for the libtool
needed elements and the APR one copies them in the build subdirectory:
+++
$ ls -lt
srclib/apr/build/ltconfig  
-rwxr-xr-x   1 VTX3 Spain  97913 Mar 14 16:26
srclib/apr/build/ltconfig 
$ ls -l
ltconfig
lrwxrwxrwx   1 VTX3 Spain 33 Mar 14 16:33 ltconfig -
/usr/local/share/libtool/ltconfig   
  
$ 
+++

Is this a bug or a Feature?

Cheers

Jean-frederic


Re: builconf APR and httpd2.0

2001-03-14 Thread rbb

This is most definately a bug.  APR should have a copy of the libtool
files, and ANY APR application should just use those files.  There is no
reason for httpd-2.0 to create links anyplace, it should just use APR's
version.

Ryan

On Wed, 14 Mar 2001, jean-frederic clere wrote:

 Hi,

 I have noted that buildconf of httpd2.0 creates links for the libtool
 needed elements and the APR one copies them in the build subdirectory:
 +++
 $ ls -lt
 srclib/apr/build/ltconfig
 -rwxr-xr-x   1 VTX3 Spain  97913 Mar 14 16:26
 srclib/apr/build/ltconfig
 $ ls -l
 ltconfig
 lrwxrwxrwx   1 VTX3 Spain 33 Mar 14 16:33 ltconfig -
 /usr/local/share/libtool/ltconfig
 $
 +++

 Is this a bug or a Feature?

 Cheers

 Jean-frederic




___
Ryan Bloom  [EMAIL PROTECTED]
406 29th St.
San Francisco, CA 94131
---



Re: apr_realpath

2001-03-14 Thread Kevin Pilch-Bisson
On Wed, Mar 14, 2001 at 09:38:21AM -0600, William A. Rowe, Jr. wrote:
 From: Kevin Pilch-Bisson [EMAIL PROTECTED]
 Sent: Wednesday, March 14, 2001 7:48 AM
 
  Attachment
 
 Huge favor, if you would, look into why all your posts are going in as text 
 file
 attachments?  At least they appear so on my pathetic Win32 email client.

Sorry, I think it has to do with the way mutt handles pgp signing
messages.  I'm not going to sign this one, so hopefully it won't do so.

Offhand, which pathetic win32 client.

 
 To answer your questions:
 
 apr_filepath_merge(char **newpath, char *rootpath, char **addedpath, 
 APR_FILEPATH_TRUEPATH, p)
 
 would allow us to take rootpath of '/usr/local/bin' and addedpath of 
 'apache/secure/conf',
 merge them into '/usr/local/bin/apache/' [an existing path] and leave 
 addedpath pointing
 to 'secure/conf' [the non-existant portion of addedpath.]  The user can do 
 whatever they like
 to make them work.

[snip explanation]

OOhhh, now I understand.  I like!

 
 My only other 'simple' solution, if that flag is passed, is to append a 
 second string following
 the null of the root string.  If they pass that flag, the user is guarenteed 
 a second null 
 (even if the entire given path was existed, so the non-existant result is 
 empty.)
 
 Since that is alien to everything we have done in APR, I'm hesistant to try 
 it.

No, no, no.  I don't like that at all.
 
 
 I didn't miss your question on comparing paths, we need to add these other 
 functions:

Actually, for now I think I can do what I need with just
apr_filepath_merge, with NULL, rootpath arguments.  (We have existing
svn functions to do the rest, although in time they would probably be
re-worked to use the below).

 
 apr_status_t apr_filepath_root(char** pathroot, char** name, apr_pool_t *p)
 Which returns the canonical form of the pathroot and returns the first 
 non-root
 part of name (e.g. '/foo' is '/' 'foo' on unix, 'c:\foo' is 'c:\' 'foo' 
 and
 '//machine/share/foo' is '//machine/share/' 'foo' on win32)
 Handles incomplete roots ('c:foo' on win32 is 'c:', 'foo', but returns a 
 status
 of APR_EINCOMPLETE).

Would there be a way to convert an incomplete path to a complete path?
(change drive to c:, getpwd, append foo, in the above example)
 
 apr_status_t apr_filepath_elements_count(int *n, char *path)
 counts the elements given in the file path.  
 [counts the root as one element]
 
 apr_status_t apr_filepath_elements_get(char **segments, char *path, int 
 first, int last, apr_pool_t *p)
 returns the requested elements of the file path.
 All even numbered elements are delimiters, so 0 is the delimited root,
 1 is the first name, 2 is the delimiter, 3 is the second name.
 While more complex, this presupposes some platform could have a multi-byte
 delimiter (unlikely, but consider a utf-8 path delimiter char that is more
 than a single byte, not true of '/' or '\', but it's easier to code for it
 now than change it later.)
 
 The even/odd theory falls apart for relative paths like foo/bar unless we 
 return an
 empty string for foo, so this needs more thought.

Will keep thinking about this.

 
 apr_status_t apr_filepath_common(char** result, char* a, char* b, apr_pool_t 
 *p)
 returns the segments that match, comparing from the beginning.
 The user must canonicalize the paths first with apr_filepath_merge.
 /foo/bar compared to /foo/barstool  returns  /foo/
 compare does not distinguish between '/' and '\' on win32/os2 - they 
 compare equal.
 If a and b were char**, we could point at the first uncommon element, but 
 a strlen
 of result provides the same answer, no?  [This isn't true of the above 
 example that
 is changing the case, eliminating trailing '.'s and ' 's from win32 
 names, and 
 converting short aliases to true names).
 
 Canonicalizing first to the truename is required before apr_filepath_common 
 can be
 trusted on Win32 or OS2, since c:/thislongname/ is also c:/THISLO~1/

Canonicalizing is done by apr_filepath_merge, with NULL rootpath, right?
 
 Bill

-- 
~
Kevin Pilch-Bissonhttp://www.pilch-bisson.net
 Historically speaking, the presences of wheels in Unix
 has never precluded their reinvention. - Larry Wall
~


Re: apr_realpath

2001-03-14 Thread cmpilato
Kevin Pilch-Bisson [EMAIL PROTECTED] writes:

 Sorry, I think it has to do with the way mutt handles pgp signing
 messages.  I'm not going to sign this one, so hopefully it won't do so.
 
 Offhand, which pathetic win32 client.

X-Mailer: Microsoft Outlook Express 5.50.4133.2400

Just a guess. :-)




Re: apr_realpath

2001-03-14 Thread Kevin Pilch-Bisson
On Wed, Mar 14, 2001 at 12:34:39PM -0600, [EMAIL PROTECTED] wrote:
 Kevin Pilch-Bisson [EMAIL PROTECTED] writes:
 
  Sorry, I think it has to do with the way mutt handles pgp signing
  messages.  I'm not going to sign this one, so hopefully it won't do so.
  
  Offhand, which pathetic win32 client.
 
 X-Mailer: Microsoft Outlook Express 5.50.4133.2400
 
 Just a guess. :-)
 
Doh! I have ignores set up for most standard mail headers.

Don't I feel silly.
 

-- 
~
Kevin Pilch-Bissonhttp://www.pilch-bisson.net
 Historically speaking, the presences of wheels in Unix
 has never precluded their reinvention. - Larry Wall
~


Re: apr_realpath

2001-03-14 Thread William A. Rowe, Jr.
From: Kevin Pilch-Bisson [EMAIL PROTECTED]
Sent: Wednesday, March 14, 2001 11:39 AM


 Sorry, I think it has to do with the way mutt handles pgp signing
 messages.  I'm not going to sign this one, so hopefully it won't do so.
 
 Offhand, which pathetic win32 client.

Message is fine, I'm using MeSsed Outlook Express (which actually, usually 
handles
pgp signed messages, as opposed to the MS Office Outlook).  

  apr_status_t apr_filepath_root(char** pathroot, char** name, apr_pool_t *p)
  Which returns the canonical form of the pathroot and returns the first 
  non-root
  part of name (e.g. '/foo' is '/' 'foo' on unix, 'c:\foo' is 'c:\' 'foo' 
  and
  '//machine/share/foo' is '//machine/share/' 'foo' on win32)
  Handles incomplete roots ('c:foo' on win32 is 'c:', 'foo', but returns 
  a status
  of APR_EINCOMPLETE).
 
 Would there be a way to convert an incomplete path to a complete path?
 (change drive to c:, getpwd, append foo, in the above example)

That is what apr_filepath_merge does for you.  You can pass a partial root [/ 
or d:]
apr_filepath_root over to apr_filepath_merge as the addpath (with a null root). 
 That
will return a true root.  apr_filepath_root is as much to help 
apr_filepath_merge
(and any other app) break apart the root from a name, since the root is very 
platform
specific (moreso than any other part of this debate.)  Look at netware 
machine/sys:/
versus win32/os2, toss in unc names and unix remote volumes and ugh, what a 
mess.

  apr_status_t apr_filepath_common(char** result, char* a, char* b, 
  apr_pool_t *p)
  returns the segments that match, comparing from the beginning.
  The user must canonicalize the paths first with apr_filepath_merge.
  /foo/bar compared to /foo/barstool  returns  /foo/
  compare does not distinguish between '/' and '\' on win32/os2 - they 
  compare equal.
  If a and b were char**, we could point at the first uncommon element, 
  but a strlen
  of result provides the same answer, no?  [This isn't true of the above 
  example that
  is changing the case, eliminating trailing '.'s and ' 's from win32 
  names, and 
  converting short aliases to true names).
  
  Canonicalizing first to the truename is required before apr_filepath_common 
  can be
  trusted on Win32 or OS2, since c:/thislongname/ is also c:/THISLO~1/
 
 Canonicalizing is done by apr_filepath_merge, with NULL rootpath, right?

Yes, or by merging the untrusted path onto a known canonical path (say a 
ServerRoot or
DocumentRoot already canonicalized within Apache's server structure.)




Re: apr_realpath

2001-03-14 Thread William A. Rowe, Jr.
From: Kevin Pilch-Bisson [EMAIL PROTECTED]
Sent: Wednesday, March 14, 2001 3:08 PM


   Would there be a way to convert an incomplete path to a complete path?
   (change drive to c:, getpwd, append foo, in the above example)
  
  That is what apr_filepath_merge does for you.  You can pass a partial root 
  [/ or d:]
  apr_filepath_root over to apr_filepath_merge as the addpath (with a null 
  root).  That
  will return a true root.  apr_filepath_root is as much to help 
  apr_filepath_merge
  (and any other app) break apart the root from a name, since the root is 
  very platform
  specific (moreso than any other part of this debate.)  Look at netware 
  machine/sys:/
  versus win32/os2, toss in unc names and unix remote volumes and ugh, what a 
  mess.
  
 I believe you, I am just a little confused as to the process.  Say I do
 the following:
 
 C:\mywork\subversion\  svn commit C:foo
 
 which eventually reaches the following code.
 
 char added_path[][] = { C:foo, NULL };
 (or should this be { C:, foo, NULL }; ?)
 char *newpath;
 apr_filepath_merge(newpath, NULL, added_path, APR_FILEPATH_TRUEPATH, p);
 
 What do I get back from apr_filepath_merge?  Or more to the point, how
 can I get C:\mywork\subversion\foo as newpath?

Simply, rootpath == NULL uses CWD, therefore c:\mywork\subversion.


char *newpath = foo
char **addpath = newpath
char **newpath;

apr_filepath_merge(newpath, NULL, addpath, APR_FILEPATH_TRUEPATH, p);

If foo exists, newpath == c:\mywork\subversion\foo, and addpath += 4
(points to the trailing NULL of the string you passed).

If foo is not found, newpath == c:\mywork\subversion\ and addpath didn't
change (the path wasn't found.

If you pass foo/bar as addpath, and foo exists, then .../foo/ is retured
for newpath, and addpath += 4 (pointing at bar) if bar was not found.

Of course, without APR_FILEPATH_TRUEPATH, the whole thing just returns, and
doesn't care if the path names are real.  With APR_FILEPATH_TRUECASE, those
parts that exist are returned with the correct case followed by the remaining
given path, since it also doesn't care if the files exist, only that the
names that exist are the proper case.  Both of these would set point addpath
to it's own trailing NULL.

The Q. remains, do we want char** addpath, or simply a char* with no feedback
of existing v.s. nonexisting path components?

Bill